做ppt选小图案的网站,江苏建设网站酒店装修合同范本,可以发广告的100个网站,wordpress dux5文章目录 Gateway搭建路由#xff08;route#xff09;断言#xff08;Predicate #xff09;自定义断言 过滤器#xff08;filter#xff09;自定义全局过滤器 引言 在传统的单体项目中#xff0c;前端和后端的交互相对简单#xff0c;只需通过一个调用地址即可实现。… 文章目录 Gateway搭建路由route断言Predicate 自定义断言 过滤器filter自定义全局过滤器 引言 在传统的单体项目中前端和后端的交互相对简单只需通过一个调用地址即可实现。然而随着微服务架构的兴起后端服务被拆分成多个微服务这给前端带来了新的挑战需要记住每个微服务的地址才能进行交互。显然这种做法不仅繁琐还容易导致前端代码的不可维护性和耦合度的增加。为了解决这一问题网关应运而生 在微服务中比较常见的网关有Spring Cloud Gateway、Netflix Zuul等等由于Zuul已经停止维护了并且Spring Cloud Gateway 在性能、灵活性、易用性和社区支持等方面都具有优势所以现目前常用Gateway作为微服务的网关。
Gateway搭建
版本说明
spring-cloud.versionGreenwich.SR5/spring-cloud.version
spring-cloud-alibaba.version2.1.2.RELEASE/spring-cloud-alibaba.version创建一个Gateway微服务项目引入依赖
dependencies!--Gateway--dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-gateway/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependency
/dependencies再写个启动类启动即可
下面介绍Gateway的配置三要素路由route、断言Predicate 、过滤器filter
路由route 在网关中路由决定了请求应该被转发到哪个后端服务处理路由功能使得网关能够将请求动态地转发到不同的后端服务从而实现请求的分发和负载均衡。
从代码中不难看出路由的配置主要有下面几个属性
spring:cloud:gateway:## 路由routes:## id名称任意,唯一即可- id: gateway-service-01## 路由转发的uriuri: http://localhost:8011- id: gateway-service-02uri: http://localhost:8012 routes下面是可以配置多个路由的如上图所示那到底什么时候走8011什么时候走8012呢这就需要用到Gateway中非常重要的组件Predicate断言
断言Predicate 简单来说Gateway的断言就是一种条件判断用来控制请求向那个路由转发可以根据需要灵活地定制路由规则。 在Gateway中内置的断言有很多可以根据不同的属性进行配置,提供的路由断言工厂有如下几个 比如有根据请求路径的PathRoutePredicateFactory,有根据请求方法的MethodRoutePredicateFactory,有根据请求头的HeaderRoutePredicateFactory等等因为这些断言的命名都是有规范的都是xxxRoutePredicateFactory的格式所以在配置的时候只需要写前面部分的名称就行了比如Path,Method。
好现在我们就来配置一个根据Path的断言
spring:cloud:gateway:## 路由routes:## id名称任意,唯一即可- id: gateway-service-01## 路由转发的uriuri: http://localhost:8011## 配置断言predicates:## 满足/api/orderService/** 这个请求路径的,都会被路由到http://localhost:8011- Path/api/orderService/**- id: gateway-service-02uri: http://localhost:8012## 配置断言predicates:## 满足/api/userService/** 这个请求路径的,都会被路由到http://localhost:8012- Path/api/userService/**当然断言可以配置多个之间是and的关系比如我们可以配置权重比例
spring:cloud:gateway:## 路由routes:## id名称任意,唯一即可- id: gateway-service-01## 路由转发的uriuri: http://localhost:8011## 配置断言predicates:## 满足/api/orderService/** 这个请求路径的,都会被路由到http://localhost:8011- Path/api/orderService/**- id: gateway-service-02uri: http://localhost:8012## 配置断言predicates:## 满足/api/userService/** 这个请求路径的,都会被路由到http://localhost:8012- Path/api/userService/**## 同一分组按照权重进行分配流量这里分配了60%## 第一个userGroup是分组名第二个参数是权重- WeightuserGroup, 6- id: gateway-service-03uri: http://localhost:8013predicates:- Path/api/userService/**- WeightuserGroup, 4 这里路由gateway-service-02和gateway-service-03断言的Path都是一样的但是加了Weight权重当大量请求过来时路由到8012的流量大约有60%路由到8013的流量大约有40%做到负载均衡的作用。
下面建立OrderService和UserService服务进行验证
// userService
RestController
RequestMapping(/api/userService)
Slf4j
public class UserController {GetMapping(/test)public ResponseEntityString testOrder() {log.info(进入userService...);return ResponseEntity.ok().body(进入userService);}
}// orderService
RestController
RequestMapping(/api/orderService)
Slf4j
public class OrderController {GetMapping(/test)public ResponseEntityString testOrder(){log.info(进入orderService...);return ResponseEntity.ok().body(进入orderService);}
}我这里启动网关服务一个订单服务两个用户服务
启动两个userService是为了测试权重的配置
输入地址注意这里是网关的IP端口
http://localhost:8010/api/orderService/test
http://localhost:8010/api/userService/test
网关配置的Path起到了效果
再测试下权重的配置
连续访问http://localhost:8010/api/userService/test 10次
可以看出和我们在网关配置的比例大致相等做到了按权重分发请求流量
自定义断言
接下来我们自己定义一个断言来试试
/*** 自定义一个指定时间访问的断言* 1.类名称必须是配置RoutePredicateFactory* 2.必须继承AbstractRoutePredicateFactory自定义的内部类*/
Component
public class MyHourRoutePredicateFactory extends AbstractRoutePredicateFactoryMyHourRoutePredicateFactory.MyConfig {/*** 必须用无参构造*/public MyHourRoutePredicateFactory() {super(MyHourRoutePredicateFactory.MyConfig.class);}/*** 通过apply进行逻辑判断 true就是匹配成功 false匹配失败** param config* return*/Overridepublic PredicateServerWebExchange apply(MyHourRoutePredicateFactory.MyConfig config) {return new PredicateServerWebExchange() {Overridepublic boolean test(ServerWebExchange serverWebExchange) {// 获取当前时间LocalDateTime now LocalDateTime.now();int hour now.getHour();// 判断时间是否大于配置的时间if (hour config.getMyHour()) {return true;}return false;}};}/*** 读取配置文件的参数值赋值到配置类中的属性上** return*/Overridepublic ListString shortcutFieldOrder() {// 顺序必须必须和yml文件中的配置顺序一致return Arrays.asList(myHour);}/*** 接收配置参数*/DataNoArgsConstructorpublic static class MyConfig {private int myHour;}}
我们直接在OrderService增加这个配置
spring:cloud:gateway:## 路由routes:## id名称任意,唯一即可- id: gateway-service-01## 路由转发的uriuri: http://localhost:8011## 配置断言predicates:## 满足/api/orderService/** 这个请求路径的,都会被路由到http://localhost:8011- Path/api/orderService/**## 自定义的断言 当前时间在16点后才允许访问- MyHour16 如上图所示当前时间是15点未到16点不能访问我再把时间配置为15点试试
顺利进入
过滤器filter 接下来介绍下另外一个重要组件过滤器路由过滤器会对请求或响应做相应的处理Gateway目前有30多种内置的过滤器具体可参考 https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories
其中分为局部过滤器和全局过滤器。
常见的局部过滤器
名称说明AddRequestHeaderGatewayFilterFactory添加一个请求头RemoveRequestHeaderGatewayFilterFactory移除一个请求头RemoveResponseHeaderGatewayFilterFactory移除一个响应头RequestRateLimiterGatewayFilterFactory请求限流设置AddResponseHeaderGatewayFilterFactory添加一个响应头
我们简单举个例子使用AddResponseHeaderGatewayFilterFactory为请求添加响应头
配置的时候还是和断言一样的只需要写前面的AddResponseHeader即可
spring:cloud:gateway:## 路由routes:## id名称任意,唯一即可- id: gateway-service-01## 路由转发的uriuri: http://localhost:8011## 配置断言predicates:## 满足/api/orderService/** 这个请求路径的,都会被路由到http://localhost:8011- Path/api/orderService/**- MyHour15# 过滤器配置局部filters:- AddResponseHeadermyKey,myVal访问下就可以看到设置的值已经在响应头了
但是对于其他的请求是没有的下面将配置一个默认过滤器配置 也是个全局过滤器默认过滤器default-filters的配置和routes是平级的。
server:port: 8010spring:cloud:gateway:## 路由routes:## id名称任意,唯一即可- id: gateway-service-01## 路由转发的uriuri: http://localhost:8011## 配置断言predicates:## 满足/api/orderService/** 这个请求路径的,都会被路由到http://localhost:8011- Path/api/orderService/**- MyHour15- id: gateway-service-02uri: http://localhost:8012## 配置断言predicates:## 满足/api/userService/** 这个请求路径的,都会被路由到http://localhost:8012- Path/api/userService/**## 同一分组按照权重进行分配流量这里分配了60%## 第一个userGroup是分组名第二个参数是权重- WeightuserGroup, 6- id: gateway-service-03uri: http://localhost:8013predicates:- Path/api/userService/**- WeightuserGroup, 4# 默认过滤器对所有路由生效default-filters:- AddResponseHeadermyKey,myVal 配置一个全局生效
自定义全局过滤器 和断言一样也可以自定义过滤器自定义局部过滤器需要extends AbstractGatewayFilterFactory自定义全局过滤器需要实现GlobalFilter ,我们这里定义一个全局的过滤器吧。
/*** 全局过滤器 认证*/
Component
Order(-1)
public class MyGatewayFilter implements GlobalFilter {Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 1.获取请求参数MultiValueMapString, String params exchange.getRequest().getQueryParams();// 2.获取user参数String userName params.getFirst(name);if (root.equals(userName)) {return chain.filter(exchange);// 继续执行后续的过滤器}// 3.拦截exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);// 禁止访问return exchange.getResponse().setComplete();}
}我们可以定义多个过滤器那么Order的值就决定了执行的先后顺序 Order的值越大优先级越低值越小优先级越高 定义Order的值有两种方式
实现Ordered接口重写getOrder方法实用Order注解
过滤器的执行顺序默认过滤器default-filters ---- 局部过滤器------ 全局过滤器