微服务网关的主要作用:
1.整合各个微服务功能,形成一套系统
2.在微服务网关中实现日志统一记录
3.实现用户的操作跟踪
4.实现限流操作
5.用户权限认证操作
不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下问题:
1.客户端会多次请求不同的微服务,增加了客户端的复杂性
2.存在跨域请求,在一定场景下处理相对复杂
3.认证复杂,每个服务都需要独立认证
4.难以重构,随着项目的迭代,可能需要重新划分新的微服务,例如可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会很难实施
5.某些微服务可能使用了防火墙、浏览器不友好的协议,直接访问会有一定困难
6.安全隐患,服务端暴漏的接口增加,增加服务器受攻击的面积
我们可以使用微服务网关解决上述问题。
微服务网关的优点:
1.安全,提供了统一访问入口,降低了服务器受攻击面积
2.提供了统一跨域解决方案
3.提供了统一日志记录操作,可以进行统一监控
4.提供了统一权限认证支持
5.提供了微服务限流功能,可以保护微服务,防止雪崩效应发生
微服务网关的最主要作用:整合各个微服务功能,形成一套或者多套系统。
微服务网关技术:
nginx:Nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务,与zuul和gateway不是一个级别的,它提供最外层流量的拦截,以抗高并发、稳定、耗能少出名。
zuul:Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。
spring cloud gateway:是Spring出品的基于Spring的网关项目,集成断路器,路径重写,性能比zuul好。
在实际开发中,因为nginx抗高并发的特点,且它的端口默认为80,用Nginx抵御用户请求的第一波并发流量,gateway网关的主要作用是将请求路由到各个微服务上,整合各个微服务的功能,形成一套或多套系统,一般要做gateway网关集群。
微服务网关相关功能实现:
1.跨域功能配置
2.网关过滤功能配置
路由断言:路由规则
2.1:Host过滤配置
2.2:Path路径过滤配置
2.3:StripPrefix过滤配置(去掉请求中的前缀)
2.4:PrefixPath过滤配置(在请求中添加前缀)
2.5:LoadBalancerClient路由过滤器(客户端负载均衡)
上面的路由配置每次都会将请求给指定的URL处理,但如果在以后的生产环境中,并发量较大的时候,我们需要根据服务的名称来判断做负载均衡操作,可以使用LoadBalancerClient来实现负载均衡调用。
LoadBalancerClient会作用在url以lb开头的路由,然后利用loadBalancer来获取服务实例,构造目标requestUrl,设置到GATEWAY_REQUEST_URL_ATTR属性中,供NettyRoutingFilter使用。
3.网关限流
当我们的系统被频繁请求的时候,就有可能将系统压垮,为了解决这一问题,需要在每一个微服务中做限流操作,但是如果有了网关,就可以在网关中做限流操作,因为所有的请求都需要通过网关系统才能路由到微服务中。实际开发中我们可以通过Nginx进行第一次限流,但是经过限流后依然会有很大的流量通过,为了避免流量全部涌入某个微服务,可以在网关进行第二次限流,来保护微服务,防止雪崩效应。
微服务网关限流策略:
1.令牌桶算法
2.漏桶算法
3.计数算法
令牌桶算法:
令牌桶算法 是比较常见的限流算法之一:
1.所有的请求在处理之前都需要拿到一个可用的令牌才会被处理
2.根据限流大小,设置按照一定的速率往令牌桶(比如redis)里添加令牌
3.桶设置最大的放置令牌限制,当桶满时、新添加的就会被丢弃或被拒绝
4.请求达到后,首先要获取令牌桶中的令牌,拿着令牌才可以进行其他的业务逻辑,处理完业务逻辑之后,将令牌直接删除
5.令牌桶有最低限额,当桶中令牌达到最低限额的时候,请求处理完之后将不会删除令牌,依此保证足够的限流
1.我们可以根据IP来限流,比如每个IP每秒只能请求几次,在GateWayWebApplication定义Key,获取客户端IP,将IP作为Key
/**
* 创建用户唯一标识,使用IP作为用户唯一标识,来根据IP进行限流操作
*/
@Bean(name = "ipKeyResolver")
public KeyResolver userKeyResolver(){
return new KeyResolver() {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
//获取用户IP
String ip = exchange.getRequest().getRemoteAddress().getHostString();
return Mono.just(ip);
}
};
}
2.在yml配置
#局部限流过滤器
-name: RequestRateLimiter #请求数限流,名字不能随便写,使用默认的factory
args:
#用户身份唯一识别标识符
key-resolver: "#{@ipKeyResolver}"
#每秒只允许有1个请求
redis-rate-limiter.replenishRate: 1
#允许并发有5个请求(宽限个数)
redis-rate-limiter.burstCapacity: 5