spring cloud zuul网关的作用
- 统一入口
- 负载均衡
- 动态路由
- 熔断
- 过滤器
统一入口
微服务架构下,系统有多个服务,不能每个服务一个对外地址,用户需要一个统一的系统入口进行操作,故zuul网关是系统的统一入口。
为微服务云平台提供统一的入口是API网关最主要的用途,除此之外,网关还可承担认证授权、访问控制、路由、负载均衡、缓存、日志、限流限额、转换、映射、过滤、熔断、注册、服务编排、API管理、监控、统计分析等等非业务性的功能。上句摘自(https://blog.csdn.net/nsxqf/article/details/90679742)
负载均衡
Zuul中包含了Ribbon的依赖,故本身具有负载均衡的能力,无需任何配置,默认采用轮询的方式进行负载均衡。
动态路由
zuul网关支持两种方式的路由配置:
- path+serviceId(即服务名)
- path+路径:端口
微服务系统数量众多,每个系统又可能有多台服务器进行负载均衡,如果使用如上path+路径:端口的方式进行路由配置,运维人员的工作量较大,一般采用如上第一种配置方式Path+serviceId的方式。
采用path+serviceId的方式进行配置的优点:
- 动态服务器扩展,无需手动维护路由配置
使用服务注册中心后,服务是动态注册的。服务注册中心自动维护了每个服务名对应的多台服务器的ip+端口列表。比如需要增加一台服务器进行负载均衡,只需要在新的机器上部署服务并启动,服务会自动注册到服务注册中心,和nginx ip+端口配置的方式相比,实现了负载动态扩展。
zuul自身会注册为eureka服务,和eureka结合使用,eureka自动维护服务实例。
zuul网关是从服务注册中心拉取服务对应的多台服务器的ip及端口,故采用path+serviceId配置方式,服务的注册是动态的;反之每增加或减少一台服务器,都需要手动修改路由配置。
zuul网关路由配置示例:
通过zuul.routes.<路由名>.path
与zuul.routes.<路由名>.serviceId
示例1:
zuul:
routes:
service-provider:
path: /eureka-service/**
serviceId: eureka-service
示例2:
#zuul.routes.mis_dingding_consumer.path=/mis_dingding_consumer/**
#zuul.routes.mis_dingding_consumer.serviceId=mis_dingding_consumer
#zuul.routes.mis_baoxiao_service.path=/mis_baoxiao_service/**
#zuul.routes.mis_baoxiao_service.serviceId=mis_baoxiao_service
如有兴趣了解zuul网关完整搭建过程,可查看我的博文:https://blog.csdn.net/u014161595/article/details/103472852
动态路由配置
和spring cloud config动态刷新机制结合使用,可以实现路由动态配置。无需停止服务,配置立即生效。
如有兴趣了解spring cloud config完整搭建过程,可查看我的博文:https://blog.csdn.net/u014161595/article/details/103505451
熔断机制
Zuul中包含了Hystrix和Ribbon的依赖,所以Zuul拥有线程隔离和断路器的自我保护功能。
需要注意的是传统路由也就是使用path与url映射关系来配置路由规则的时候,对于路由转发的请求不会使用HystrixCommand来包装,所以没有线程隔离和断路器的保护,并且也不会有负载均衡的能力。所以我们在使用Zuul的时候推荐使用path与serviceId的组合来进行配置。
熔断机制内容摘自(https://www.cnblogs.com/hellxz/p/9282756.html)
过滤器
在服务网关中可以完成一系列的横切功能,例如权限校验、限流以及监控等,这些都可以通过过滤器完成(其实路由转发也是通过过滤器实现的)。
上述所说的横切功能(以权限校验为例)可以写在三个位置:
- 每个服务自己实现一遍
- 写到一个公共的服务中,然后其他所有服务都依赖这个服务
- 写到服务网关的前置过滤器中,所有请求过来进行权限校验
第一种,缺点太明显,基本不用;第二种,相较于第一点好很多,代码开发不会冗余,但是有两个缺点:
- 由于每个服务引入了这个公共服务,那么相当于在每个服务中都引入了相同的权限校验的代码,使得每个服务的jar包大小无故增加了一些,尤其是对于使用docker镜像进行部署的场景,jar越小越好;
- 由于每个服务都引入了这个公共服务,那么我们后续升级这个服务可能就比较困难,而且公共服务的功能越多,升级就越难,而且假设我们改变了公共服务中的权限校验的方式,想让所有的服务都去使用新的权限校验方式,我们就需要将之前所有的服务都重新引包,编译部署。
而服务网关恰好可以解决这样的问题:
- 将权限校验的逻辑写在网关的过滤器中,后端服务不需要关注权限校验的代码,所以服务的jar包中也不会引入权限校验的逻辑,不会增加jar包大小;
- 如果想修改权限校验的逻辑,只需要修改网关中的权限校验过滤器即可,而不需要升级所有已存在的微服务。
过滤器内容摘自(https://zhuanlan.zhihu.com/p/101341556)