网关是什么,网关是一切外部访问程序的入口,他控制这这个服务架构的出入,鉴权,代理,流控,监控等.
官网地址: https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.3.RELEASE/reference/html/#gateway-starter
Spring Cloud Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架
网关在微服务架构中的位置 作用:
反向代理鉴权流量控制熔断日志监控等等gateway的特性:
动态路由路由断言(Predicate)和过滤(filter)继承Hystrix的断路器功能继承springcloud的服务注册与发现功能请求限流支持路劲重写gateway和zuul的区别
gateway是基于NIO的,非阻塞式架构模型zuul是基于阻塞IO模型的.gateway还支持webSocket,并且与spring紧密集成.步骤:
请求发送到handler Mapping上,handler mapping对比predicate(断言)匹配路劲.在发送到web handler上,handler在经过一系列的过滤链.经过过滤链之后才是发送到具体的微服务上请求服务.再请求之后还会经过一系列的过滤链,回到web handler.web handler再返回给handler mapping.总结:路由转发,断言匹配,过滤,执行业务
(1) 建module 略 (2) 改pom
<!--新增gateway--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>(3) 写yml
server: port: 9527 spring: application: name: cloud-gateway cloud: gateway: routes: #路由地址1 - id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8001 #匹配后提供服务的路由地址 predicates: - Path=/payment/get/** #断言,路径相匹配的进行路由 #路由地址2 - id: payment_routh2 uri: http://localhost:8001 predicates: - Path=/payment/lb/** #断言,路径相匹配的进行路由 #eureka,本服务也需要注册到eureka上 eureka: instance: hostname: cloud-gateway-service client: service-url: register-with-eureka: true fetch-registry: true defaultZone: http://eureka7001.com:7001/eureka(4) 主启动 没有特定的启动类
@SpringBootApplication @EnableEurekaClient public class GateWayMain9527 { public static void main(String[] args) { SpringApplication.run( GateWayMain9527.class,args); } }(5) 测试
1)第一步,Eureka2)第二步,启动8001的服务3)第三步,启动gateway网关服务 #查看两个服务是否已经注册到eureka上了 4)验证浏览器是否能够通过网关访问到8001上的服务. 8001项目上/payment/lb接口的代码 //自己手写轮询算法访问测试的请求路劲 @GetMapping(value = "/payment/lb") public String getPaymentLB(){ return serverPort+""; }测试结果
1) yml配置(建议使用)
spring: application: name: cloud-gateway cloud: gateway: discovery: locator: enabled: true #开启路由发现功能 routes: - id: payment_routh2 #uri: http://localhost:8001 uri: lb://cloud-payment-service #动态路由 predicates: #下面的断言条件,首字母必须大写 - Path=/payment/lb/** #断言,路径相匹配的进行路由 - After=2020-06-19T14:51:51.252+08:00[Asia/Shanghai] #断言 发送的时间要在这个时间之后 #- Cookie=username,gl #断言,携带cookie,username=gl #- Header=X-Request-Id, \d+ #请求头中要有X-Request-Id属性并且值为整数的正则表达式 #- Host=**.atguigu.com #断言 主机 #- Method=GET #断言 请求方式为GET请求 #- Query=username, \d+ #要有参数名称并且是正整数才能路由 filters: - AddRequestHeader=X-Request-red, blue # 第二个路由地址 - id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名 #uri: http://localhost:8001 #匹配后提供服务的路由地址 uri: lb://cloud-payment-service #动态路由 predicates: #断言,路径相匹配的进行路由 - Path=/payment/** - After=2020-06-19T14:51:51.252+08:00[Asia/Shanghai] - Cookie=username,gl2) 代码注入 通过代码注入RouteLocator bean的方式,配置路由
@Configuration public class GateWayConfig { /** * 代码配置路由规则bean */ @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) { RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes(); /** * gl_baidu_01:路由名 * path:路由路劲 * uri:路由转发的服务或者服务地址 * ... */ routes.route("gl_baidu_01", r -> r.path("/tiyu").uri("http://news.baidu.com")).build(); return routes.build(); } }默认情况,gateway从通过微服务名称,从注册中心获取服务地址,并且可以实现负载均衡算法.
uri: lb://cloud-payment-service #lb:表示使用负载均衡算法,必须使用 #cloud-payment-service:表示调用的服务名称
参考官网: https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.3.RELEASE/reference/html/#gateway-request-predicates-factories
1) 是什么? 这是用于匹配路由路劲的规则,只有满足predicate(断言)定义的规则才可能被转发到下一级步骤.
2) 常用的predicate属性如下:
predicates: #下面的断言条件,条件的首字母必须大写 - Path=/payment/lb/** #断言,路径相匹配的进行路由 - After=2020-06-19T14:51:51.252+08:00[Asia/Shanghai] #断言 发送的时间要在这个时间之后 - Cookie=username,gl #断言,携带cookie,username=gl - Header=X-Request-Id, \d+ #请求头中要有X-Request-Id属性并且值为整数的正则表达式 - Host=**.atguigu.com #断言 主机 - Method=GET #断言 请求方式为GET请求 - Query=username, \d+ #要有参数名称并且是正整数才能路由参考官网: https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.3.RELEASE/reference/html/#gateway-request-predicates-factories
1) 是什么? filter(过滤器)这是过滤请求,将请求过滤,可以实现权限,日志,熔断等规则.
2) filter的种类
[1]GatewayFilter #单一的过滤器 作用:这种方式配置的是针对单一路由路劲的过滤器规则. 配置方式:
filters: #过滤器规则 - AddRequestHeader=X-Request-red, blue #将所有的请求头中添加, X-Request-red:blue - AddRequestParameter=red, blue #将所有的请求中添加参数,red,blue - name: Hystrix #添加hystrix熔断 args: name: fallbackcmd fallbackUri: forward:/incaseoffailureusethis #熔断方法[2] GlobalFilter #全局的过滤器, 作用:全局日志记录/统一网关鉴权 配置方式:
/** *GlobalFilter:全局filter顶级接口. *Ordered :过滤器级别顶级接口 */ @Component @Slf4j public class MyLogGateWayFilter implements GlobalFilter,Ordered { /** * 定义filter(过滤器) * @param exchange request相关对象 * @param chain 过滤链 * @return */ @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { log.info("==================come in MyLogGateWayFilter:" + new Date()); String username = exchange.getRequest().getQueryParams().getFirst("username"); if(username == null){ log.error("===============你没有登陆参数,无权访问"); exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE); return exchange.getResponse().setComplete(); } return chain.filter(exchange); } /** * 过滤器的级别 * @return */ @Override public int getOrder() { return 0; } }3) filter的作用时机
pre #请求之前,在业务逻辑之前post #请求之后,在业务逻辑之后