ZUUL是Netflix开源的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用,Zuul组件的核心是一系列的过滤器,这些过滤器可以完成以下功能:
- 动态路由:动态将请求路由到不同后端集群
- 压力测试:逐渐增加指向集群的流量,以了解性能
- 负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求
- 静态响应处理:边缘位置进行响应,避免转发到内部集群
- 身份认证和安全: 识别每一个资源的验证要求,并拒绝那些不符的请求。Spring Cloud对Zuul进行了整合和增强。
Spring Cloud对Zuul进行了整合和增强
创建工程导入依赖
1 |
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.cloud<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-cloud-starter-netflix-zuul<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>2.1.0.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> |
编写启动类
1 |
<span class="token annotation punctuation">@SpringBootApplication</span> <span class="token annotation punctuation">@EnableZuulProxy</span> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ZuulServerApplication</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span>String<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> SpringApplication<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span>ZuulServerApplication<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
@EnableZuulProxy : 通过 @EnableZuulProxy 注解开启Zuul网管功能
编写配置
创建配置文件 application.yml ,并添加相应配置
1 |
<span class="token key atrule">server</span><span class="token punctuation">:</span> <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">8080 </span> <span class="token key atrule">spring</span><span class="token punctuation">:</span> <span class="token key atrule">application</span><span class="token punctuation">:</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> api<span class="token punctuation">-</span>gateway |
最直观的理解:“路由”是指根据请求URL,将请求分配到对应的处理程序。在微服务体系中,Zuul负责接收所有的请求。根据不同的URL匹配规则,将不同的请求转发到不同的微服务处理。
1 |
<span class="token key atrule">zuul</span><span class="token punctuation">:</span> <span class="token key atrule">routes</span><span class="token punctuation">:</span> <span class="token key atrule">product-service</span><span class="token punctuation">:</span> <span class="token key atrule">path</span><span class="token punctuation">:</span> /product<span class="token punctuation">-</span>service/** <span class="token key atrule">url</span><span class="token punctuation">:</span> http<span class="token punctuation">:</span>//127.0.0.1<span class="token punctuation">:</span><span class="token number">9002 </span> <span class="token key atrule">sensitiveHeaders</span><span class="token punctuation">:</span> |
只需要在application.yml文件中配置路由规则即可:
- product-service:配置路由id,可以随意取名
- url:映射路径对应的实际url地址
- path:配置映射路径,这里将所有请求前缀为/product-service/的请求,转发到http://127.0.0.1:
9002处理
配置好Zuul路由之后启动服务,在浏览器中输入 http://localhost:8080/product/service/product/1 ,即可访问到订单微服务。
3.1 面向服务的路由
微服务一般是由几十、上百个服务组成,对于一个URL请求,最终会确认一个服务实例进行处理。如果对每个服务实例手动指定一个唯一访问地址,然后根据URL去手动实现请求匹配,这样做显然就不合理。
Zuul支持与Eureka整合开发,根据ServiceID自动的从注册中心中获取服务地址并转发请求,这样做的好处不仅可以通过单个端点来访问应用的所有服务,而且在添加或移除服务实例的时候不用修改Zuul的路由配置。
(1)添加Eureka客户端依赖
1 |
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework.cloud<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-cloud-starter-netflix-eureka-client<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> |
(2)开启Eureka客户端发现功能
1 |
<span class="token annotation punctuation">@SpringBootApplication</span> <span class="token annotation punctuation">@EnableZuulProxy</span> <span class="token annotation punctuation">@EnableDiscoveryClient</span> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ZuulServerApplication</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span>String<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> SpringApplication<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span>ZuulServerApplication<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
(3)添加Eureka配置,获取服务信息
1 |
<span class="token key atrule">eureka</span><span class="token punctuation">:</span> <span class="token key atrule">client</span><span class="token punctuation">:</span> <span class="token key atrule">serviceUrl</span><span class="token punctuation">:</span> <span class="token key atrule">defaultZone</span><span class="token punctuation">:</span> http<span class="token punctuation">:</span>//127.0.0.1<span class="token punctuation">:</span>8761/eureka/ <span class="token key atrule">registry-fetch-interval-seconds</span><span class="token punctuation">:</span> <span class="token number">5 </span> <span class="token key atrule">instance</span><span class="token punctuation">:</span> <span class="token key atrule">preferIpAddress</span><span class="token punctuation">:</span> <span class="token boolean important">true</span> <span class="token key atrule">ip-address</span><span class="token punctuation">:</span> 127.0.0.1 |
(4)修改映射配置,通过服务名称获取
因为已经有了Eureka客户端,我们可以从Eureka获取服务的地址信息,因此映射时无需指定IP地址,而是通过服务名称来访问,而且Zuul已经集成了Ribbon的负载均衡功能。
1 |
<span class="token key atrule">zuul</span><span class="token punctuation">:</span> <span class="token key atrule">routes</span><span class="token punctuation">:</span> <span class="token key atrule">product-service</span><span class="token punctuation">:</span> <span class="token key atrule">path</span><span class="token punctuation">:</span> /product<span class="token punctuation">-</span>service/** <span class="token key atrule">serviceId</span><span class="token punctuation">:</span> shop<span class="token punctuation">-</span>service<span class="token punctuation">-</span>product |
serviceId: 指定需要转发的微服务实例名称
3.2 简化的路由配置
在刚才的配置中,我们的规则是这样的:
zuul.routes.<route>.path=/xxx/**
: 来指定映射路径。 是自定义的路由名zuul.routes.<route>.serviceId=/product-service
:来指定服务名。
而大多数情况下,我们的 路由名称往往和服务名会写成一样的。因此Zuul就提供了一种简化的配置语法:zuul.routes.<serviceId>=<path>
上面的配置可以简化为一条:
1 |
<span class="token key atrule">zuul</span><span class="token punctuation">:</span> <span class="token key atrule">routes</span><span class="token punctuation">:</span> <span class="token key atrule">shop-service-product</span><span class="token punctuation">:</span> /product<span class="token punctuation">-</span>service/** |
3.3 默认的路由规则
在使用Zuul的过程中,上面讲述的规则已经大大的简化了配置项。但是当服务较多时,配置也是比较繁琐的。因此Zuul就指定了默认的路由规则:
默认情况下,一切服务的映射路径就是服务名本身,例如服务名为: shop-service-product
,则默认的映射路径就是: /shop-serviceproduct/**