SpringCloud 组件之 Gateway (微服务网关)
-
概述
不同的微服务会有不同的网络地址,客户端需要调用多个服务的接口才能完成一个业务需求。
-
网关的作用
1.整合各个微服务功能,形成一套系统 (最主要的作用) 2.在微服务网关中实现日志的统一记录 3.用户的操作跟踪 4.限流 5.用户权限认证
-
业务场景结构,不使用网关微服务系统
—> | 文件系统:1001APP -> | 用户系统:1002 -> | 订单系统:1003
缺点
11.页面对接很多个域名(微服务),非常繁琐 22.安全隐患,微服务暴露的接口增加,增加服务器的受攻击面积 33.跨域问题 44.认证复杂,调用每个系统都要认证一次
######加入网关微服务系统
1 —> | 文件系统:1001 2 APP -> Gateway -> | 用户系统:1002 3 -> | 订单系统:1003
优点
11.安全,提供了统一的访问接口,减少了服务器的受攻击面积 22.提供了统一的跨域解决方案 33.提供了统一的认证服务,只需要在网关系统认证一次 44.提供了统一的日志记录操作 55.提供了限流功能,保护微服务防止雪崩效应发生
-
扩展 - 实现微服务网关的其他技术
nginx:高性能的HTTP和反向代理web服务器 和gateway不在一个比较体系里面,属于最外层流量的拦截,所处的位置不一样。 nginx抵御第一波并发流量,gateway主要是做路由功能 一般最外层的一定是nginx这种抗压能力很强的web服务器 Gateway分布式部署后,就可以加一个nginx服务器,客户端先进入nginx后,再由ng分发到Gateway上面去
zuul:用的很少,被淘汰了
spring-cloud-gateway:spring出品,基于spring的网关项目,集成断路器、路径重写,性能比Zuul好
- 构建Gateway工程
Maven依赖
1<dependency> 2 <groupId>org.springframework.cloud</groupId> 3 <artifactId>spring‐cloud‐starter‐gateway</artifactId> 4</dependency> 5<dependency> 6 <groupId>org.springframework.cloud</groupId> 7 <artifactId>spring‐cloud‐starter‐netflix‐hystrix</artifactId> 8</dependency>
GatewayApplication.java
1@SpringBootApplication 2@EnableEurekaClient 3public class GatewayApplication { 4 public static void main(String[] args) { 5 SpringApplication.run(GatewayApplication.class, args); 6 } 7}
application.yml
1server: 2 port: 8001 3 4spring: 5 application: 6 name: sysgateway 7 cloud: 8 gateway: 9 # 跨域设置 10 globalcors: # 全局配置 11 cors‐configurations: 12 '[/**]': # 匹配所有请求 13 allowedOrigins: "*" # 跨域处理 允许所有的域 14 allowedMethods: # 支持的方法 15 ‐ GET 16 ‐ POST 17 ‐ PUT 18 ‐ DELETE 19 # 路由 20 routes: 21 ‐ id: goods # 唯一标识 22 23 # 直接路由到一个微服务地址,分布式的时候多个地址用lb 24 #uri: http://192.168.1.16:7001 # 用户请求需要路由到该服务的url 25 # lb方式,负载均衡,goods表示微服务的名称[集群环境] 26 uri: lb://goods 27 28 predicates: # 路由断言,路由配置规则 29 30 # 下面3中配置方式1.Host 2.-Path 3.filters 31 # 1. Host路由配置方式 32 #- Host=goods.abc.com** # 用户请求的域名配置规则,所有以goods.abc.com的请求都路由到http://192.168.1.16:7001 33 34 # 2. 路径匹配过滤配置方式 35 #- Path=/goods/** # 所有以/goods/开头的请求都路由到http://192.168.1.16:7001 36 37 # 3. filters 38 #filters: 39 # 自动去掉一个路径 40 # 将请求路径中的第一个路径去掉,路径以 / 区分 41 # 浏览器请求地址:http://goods.abc.com/api/goods/list,会自动去掉第一个路径变成了 http://goods.abc.com/goods/list 42 #- StripPrefix=1 43 #- Path=/api/goods/** 44 45 # 自动加上一个路径,所有请求 46 #- StripPrefix=1 47 #- Path=/** 48 # 浏览器请求地址:http://goods.abc.com/list,会自动加上/goods路径变成了 http://goods.abc.com/goods/list 49 #- PrefixPath=/goods
-
限流
限流位置: 网关 -> 限流操作 -> 微服务系统
限流怎么做? 1.令牌桶算法:Redis客户端有实现(RateLimter);google的Guava包中也有实现。 令牌的数量:最大限额、最小限额。 1)所有的请求在处理之前都需要拿到一个可用的令牌才会被处理; 2)根据限流大小,设置按照一定的速率往桶里添加令牌; 3)桶设置最大的放置令牌限制,当桶满时、新添加的令牌就被丢弃或者拒绝; 4)请求达到后首先要获取令牌桶中的令牌,拿着令牌才可以进行其他的业务逻辑,处理 完业务逻辑之后,将令牌直接删除; 5)令牌桶有最低限额,当桶中的令牌达到最低限额的时候,请求处理完之后将不会删除令牌,以此保证足够的限流 2.漏桶算法 3.计算算法 原理:未达到流量阈值:放行;达到流量阈值:返回249
-
Redis实现的限流
Maven依赖
1<dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring‐boot‐starter‐data‐redis‐reactive</artifactId> 4 <version>2.1.3.RELEASE</version> 5</dependency>
GatewayApplicatioin.java
1@Bean 2public KeyResolver ipKeyResolver() { 3 return new KeyResolver() { 4 @Override 5 public Mono<String> resolve(ServerWebExchange exchange) { 6 String ip = exchange.getRequest().getRemoteAddress().getHostName(); 7 return Mono.just(ip); 8 } 9 }; 10}
application.yml
1spring.cloud.gateway.routes.filters: 2 3‐ name: RequestRateLimiter # 局部限流过滤器,固定的不能改 4 args: 5 key‐resolver: "#{@ipKeyResolver}" # Bean 对象的名字,SpEL表达式根据#{@beanName}从Spring容器中获取Bean对象 6 redis‐rate‐limiter.replenishRate: 1 # 每秒钟只允许1个请求 7 redis‐rate‐limiter.burstCapacity: 10 # 令牌桶总容量,并发请求数
######并发模拟工具:Apache JMeter

