gateway
Spring cloud Gateway 使用得webflux 中得reactor-netty 响应编程组件。 底层使用得netty框架。
鉴权 流量控制 熔断 日志监控
zuul 1.x 基于servlet 2.5 阻塞架构。 不支持任何长连接 (websocket) zuul设计和nginx 有点像。每次i/o操作都是从工作线程中选择一个执行。 请求线程被阻塞工作线程完成。zuul2. 理念先进。 netty非阻塞和支持长连接。 zuul2. 比 zuul1 快了1.6倍。。
gateway是异步非阻塞,支持长连接websocket,(长链接就是服务端主动给客户端推送消息)。
zuul1.x模型采用tomcat容器,使用servlet io处理器,每个请求会绑定一个线程,一旦高并发线程数太多卡。在传统的web框架中 spring mvc struts2 都是基于servlet容器基础之上运行。
gateway用webflux,servlet 3.1 版本之后 才用异步非阻塞(AIO)的支持。 而webflux 是一个经典的非阻塞异步的框架。
一。路由配置
1.新建子项目,引pom.xml
<dependencies> <!--gateway--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!--eureka-client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- 引入自己定义的api通用包,可以使用Payment支付Entity --> <dependency> <groupId>com.etc.cloud</groupId> <artifactId>cloud-api-commons</artifactId> </dependency> <!--一般基础配置类--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
2.新建application.yml
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:8001 #匹配后提供服务的路由地址
# uri: lb://cloud-payment-service #匹配后提供服务的路由地址,lb是@loadbanlence负载均衡意思,可以负载均衡这个服务
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由
- id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:8001 #匹配后提供服务的路由地址
predicates:
- Path=/payment/lb/** # 断言,路径相匹配的进行路由
eureka:
instance:
hostname: cloud-gateway-service
client: #服务提供者provider注册进eureka服务列表内
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://eureka7001.com:7001/eureka
这是在yml文件中配置相关路由信息
3.还一种方法在类中配置路由
@Configuration public class GatewayConfig { @Bean public RouteLocator constom(RouteLocatorBuilder builder) { RouteLocatorBuilder.Builder routes = builder.routes(); routes.route("path_route", r -> r.path("/guoji").uri("https://news.baidu.com/guoji")); return routes.build(); } @Bean public RouteLocator constom2(RouteLocatorBuilder builder) { RouteLocatorBuilder.Builder routes = builder.routes(); routes.route("path_route", r -> r.path("/guonei").uri("https://news.baidu.com/guonei")); return routes.build(); } @Bean public RouteLocator constom3(RouteLocatorBuilder builder) { RouteLocatorBuilder.Builder routes = builder.routes(); routes.route("path_route", r -> r.path("/mil").uri("https://news.baidu.com/mil")); return routes.build(); } }
这里配了三个路由,访问http://localhost:9527/guoji 就可以去配好的地址
4.新建main方法
@EnableEurekaClient @SpringBootApplication @Slf4j public class GatewayMain9527 { public static void main(String[] args) { SpringApplication.run( GatewayMain9527.class,args); log.info("****************GatewayMain9527 启动 ************ "); } }
二。过滤器
spring cloud gateway 内置了多种过滤器。 他们都由 gatewayfilter工程类产生
GlobalFilter 全局过滤器 GatewayFileter 将应用到单个路由或者一个分组的路由上
自定义一个GlobalFilter:
@Component @Slf4j public class MyLogGatewayFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { log.info("come in global filter:{}" , new Date()); ServerHttpRequest request = exchange.getRequest(); String uname = request.getQueryParams().getFirst("uname"); if (StringUtils.isEmpty(uname)){ log.error("用户为null 非法用户"); exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE); return exchange.getResponse().setComplete(); } return chain.filter(exchange); } /**Ordered 是顺序 * 过滤器加载的顺序越小。 优先级越高 * @return */ @Override public int getOrder() { return 0; } }
加上这个类之后,任何请求都要携带uname才行,他是全局过滤
三。断言器
YML里配置断言:
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由
- After=2020-08-24T15:08:59.777+08:00[Asia/Shanghai]
时间可以用ZonedDateTime now = ZonedDateTime.now();获取
eq:
- Before=2020-08-26T15:08:59.777+08:00[Asia/Shanghai]
- Between=2020-08-24T15:08:59.777+08:00[Asia/Shanghai],2020-08-24T15:22:59.777+08:00[Asia/Shanghai]
- Method=GET
- Cookie=username, wgslcuky
- Host=**.somehost.org,**.anotherhost.org,{sub}.myhost.org
- RemoteAddr=192.168.1.1/24
#如果请求的客户端的ip地址是192.168.1.1 到192.168.1.24 之间的范围都是返回true