赞
踩
为微服务架构提供一种简单有效的统一的 API 路由管理方式。
API网关
API 网关是一个处于应用程序或服务(提供 REST API 接口服务)之前的系统
REST API 接口服务就被 API 网关保护起来,对所有的调用者透明
隐藏在 API 网关后面的业务系统就可以专注于创建和管理服务,而不用去处理这些策略性的基础设施。
职能
为什么需要网关
Gateway 可以看做是一个 Zuul 1.x 的升级版和代替品,比 Zuul 2 更早的使用 Netty 实现异步 IO。
从而实现了一个简单、比 Zuul 1.x 更高效的、与 Spring Cloud 紧密配合的 API 网关。
GateWay的几个重要概念:
本步骤如下:
<!--网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos服务发现依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
package com.example.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient //Nacos注册
public class GateWayApplication {
public static void main(String[] args) {
SpringApplication.run(GateWayApplication.class,args);
}
}
server: port: 10010 # 网关端口 spring: application: name: gateway # 服务名称 cloud: nacos: server-addr: localhost:8848 # nacos地址 gateway: routes: # 网关路由配置 - id: user-service # 路由id,自定义,只要唯一即可 # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址 uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称 predicates: # 路由断言,也就是判断请求是否符合路由规则的条件 - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求 routes: # 网关路由配置 - id: order-service # 路由id,自定义,只要唯一即可 # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址 uri: lb://orderservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称 predicates: # 路由断言,也就是判断请求是否符合路由规则的条件 - Path=/order/** # 这个是按照路径匹配,只要以/user/开头就符合要求
启动nacos、启动user-service 同时注入到nacos中
在http://localhost:10010/user/1中即可访问user-service
名称 | 说明 | 示例 |
---|---|---|
After | 是某个时问点后的请求 | - After=2037-01-20T17:42:47.789-07:0O[America/Denver] |
Before | 是某个时问点之前的请求 | - Before=2031-04-13T15:14:47.433+08:0O[Asia/Shanghai] |
Between | 是某两个时间点之前的请求 | -Between=2037-01-20T17:42:47.789-07:0O[America/Denver]. 2037-01-21T17:42:47.789-07:0o[America/Denver] |
Cookie | 请求必须包含某些cookie | - Cookie=chocolate,ch.p |
Header | 请求必须包含某些header | - Header=x-Request-ld,ld+ |
Host | 请求必须是访问某个host(域名) | - Host=+.somehost.org.t.anotherhost.org |
Method | 请求方式必须是指定方式 | -Method=GET,POS1 |
Path | 请求路径必须符合指定规则 | - Path-/red/{segment}./blue/*- |
Query | 请求参数必须包含指定参数 | - Query=name, Jack或者-Query=name |
RemoteAddr | 请求者的ip必须是指定范围 | - RemoteAddr=192.168.1.1/24 |
Weight | 权重处理 |
GateWayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理
Spring提供了30+的路由过滤工厂
详见:
https://www.springcloud.cc/spring-cloud-greenwich.html#_gatewayfilter_factories
示例:给所有进入userservice的请求添加一个请求头
给所有进入userservice的请求添加一个请求头:Truth=itcast is freaking asewome!
实现方式:
在gateway中修改application.yml文件,给userservice的路由添加过滤器:
server: port: 10010 # 网关端口 spring: application: name: gateway # 服务名称 cloud: nacos: server-addr: localhost:8848 # nacos地址 gateway: routes: # 网关路由配置 - id: user-service # 路由id,自定义,只要唯一即可 # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址 uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称 predicates: # 路由断言,也就是判断请求是否符合路由规则的条件 - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求 routes: # 网关路由配置 filters: - AddRequestHeader=Truth, Itcast is freaking amesome! #添加请求头 - id: order-service # 路由id,自定义,只要唯一即可 # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址 uri: lb://orderservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称 predicates: # 路由断言,也就是判断请求是否符合路由规则的条件 - Path=/order/** # 这个是按照路径匹配,只要以/user/开头就符合要求
这个配置则是:
server: port: 10010 # 网关端口 spring: application: name: gateway # 服务名称 cloud: nacos: server-addr: localhost:8848 # nacos地址 gateway: routes: # 网关路由配置 - id: user-service # 路由id,自定义,只要唯一即可 # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址 uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称 predicates: # 路由断言,也就是判断请求是否符合路由规则的条件 - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求 routes: # 网关路由配置 filters: - AddRequestHeader=Truth, Itcast is freaking amesome! #添加请求头 - id: order-service # 路由id,自定义,只要唯一即可 # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址 uri: lb://orderservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称 predicates: # 路由断言,也就是判断请求是否符合路由规则的条件 - Path=/order/** # 这个是按照路径匹配,只要以/user/开头就符合要求 default-filters: - AddRequestHeader=Truth, Itcast is freaking amesome! #添加请求头
全局过滤器的作用也是处理一切进入网关的请求和微服务响应,于GateWayFilter的作用一样
区别在于GateWayFilter通过配置定义,处理逻辑是固定的
而GlobalFilter的逻辑需要自己写代码实现
实现GlobalFilter的接口
exchange: 请求上下文,里面可以获取Request、Response等信息
chain 用来把请求委托给下一个过滤器
定义一个过滤器:
package com.example.gateway; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.util.MultiValueMap; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @Component //@Order(-1) //顺序注解 或接Ordered接口 public class AuthorizeFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { /* * 1. 获取请求参数*/ ServerHttpRequest request = exchange.getRequest(); MultiValueMap<String, String> queryParams = request.getQueryParams(); // 2. 获取参数中的authorization参数\ String authorization = queryParams.getFirst("authorization"); // 3. 判断参数值是否等于admin if("admin".equals(authorization)){ // 4. 是则放行,从过滤器链里找下一个 Mono<Void> filter = chain.filter(exchange); return filter; } // 5. 否则拦截、设置状态码 else{ exchange.getResponse().setStatusCode(HttpStatus.valueOf(401)); return exchange.getResponse().setComplete(); } } @Override public int getOrder() { return 0; } }
什么是跨域问题
跨域:域名不一致就是跨域,主要包括:
域名不同: www.taobao.com 和 www.taobao.org
域名相同,端口不同:localhost:8080和localhost8081
跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题
解决跨域问题
在gateway服务的application.yml文件中,添加下面的配置:
spring: cloud: gateway: # 。。。 globalcors: # 全局的跨域处理 add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题 corsConfigurations: '[/**]': allowedOrigins: # 允许哪些网站的跨域请求 - "http://localhost:8090" allowedMethods: # 允许的跨域ajax的请求方式 - "GET" - "POST" - "DELETE" - "PUT" - "OPTIONS" allowedHeaders: "*" # 允许在请求中携带的头信息 allowCredentials: true # 是否允许携带cookie maxAge: 360000 # 这次跨域检测的有效期
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。