SpringCloud之Zuul

Posted Firm陈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud之Zuul相关的知识,希望对你有一定的参考价值。

1.什么是API网关
在微服务架构中,通常会有多个服务提供者。设想一个电商系统,可能会有商品、订单、支付、用户等多个类型的服务,而每个类型的服务数量也会随着整个系统体量的增大也会随之增长和变更。作为UI端,在展示页面时可能需要从多个微服务中聚合数据,而且服务的划分位置结构可能会有所改变。网关就可以对外暴露聚合API,屏蔽内部微服务的微小变动,保持整个系统的稳定性。
当然这只是网关众多功能中的一部分,它还可以做负载均衡,统一鉴权,协议转换,监控监测等一系列功能。

2.为什么使用网关
(1)使用网关可以统一进行鉴权,如果在微服务系统中不使用网关那么在每一个微服务中都需要进行鉴权,不仅增加系统的复杂性,而且也影响用户体验
(2)使用网关鉴权可以有效的保护微服务,只暴露自己的网关,将其他的微服务可以隐藏在内网中通过防火墙进行保护
(3)易于监控,可以在网关中直接统一收集监控数据并将其推送到外部系统进行分析
(4)减少客户端与各个微服务之间的交互次数

3.什么是Zuul
Zuul是Spring Cloud全家桶中的微服务API网关。
所有从设备或网站来的请求都会经过Zuul到达后端的Netflix应用程序。作为一个边界性质的应用程序,Zuul提供了动态路由、监控、弹性负载和安全功能。Zuul底层利用各种filter实现如下功能:
认证和安全 识别每个需要认证的资源,拒绝不符合要求的请求。
性能监测 在服务边界追踪并统计数据,提供精确的生产视图。
动态路由 根据需要将请求动态路由到后端集群。
压力测试 逐渐增加对集群的流量以了解其性能。
负载卸载 预先为每种类型的请求分配容量,当请求超过容量时自动丢弃。
静态资源处理 直接在边界返回某些响应。

4.Zuul网关的作用
网关有以下几个作用:

统一入口:未全部为服务提供一个唯一的入口,网关起到外部和内部隔离的作用,保障了后台服务的安全性。
鉴权校验:识别每个请求的权限,拒绝不符合要求的请求。
动态路由:动态的将请求路由到不同的后端集群中。
减少客户端与服务端的耦合:服务可以独立发展,通过网关层来做映射
在这里插入图片描述
5.编写一个Zuul网关
(1)新建一个gateway-zuul-demo模块,在依赖项处添加【Cloud Discovery->Eureka Discovery和Cloud Rouing->Zuul】。
(2)修改入口类,增加EnableZuulProxy注解

@SpringBootApplication
@EnableZuulProxy
public class GatewayZuulDemoApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(GatewayZuulDemoApplication.class, args);
    }
}

(3)修改appliation.yml

server:
  port: 9006
spring:
  application:
    name: gateway-zuul-demo
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
  instance:
    prefer-ip-address: true

(4)启动Eureka Server、Rest-Demo和Gateway-Zuul-Demo,在浏览器中输入http://localhost:9006/rest-demo/user/xdlysk获取返回结果。
从上面的例子中的地址可以看出来默认Zuul的路由方式是:http://ZUULHOST:ZUULPORT/serviceId/**。
如果启动多个Rest-Demo可以发现Zuul里面还内置了Ribbon的负载均衡功能。

5.路由配置
Zuul提供了一套简单且强大路由配置策略,利用路由配置我们可以完成对微服务和URL更精确的控制。
(1)重写指定微服务的访问路径:

zuul:
  routes:
    rest-demo: /rest/**

这表示将rest-demo微服务的地址映射到/rest/**路径。

(2)忽略指定微服务:

zuul:
  ignored-services: rest-demo,xxx-service

使用“*”可忽略所有微服务,多个指定微服务以半角逗号分隔。

(3)忽略所有微服务,只路由指定微服务:

zuul:
  ignored-services: *
  routes:
    rest-demo: /rest/**

(4)路由别名:

zuul:
  routes:
    route-name: #路由别名,无其他意义,与例1效果一致
      service-id: rest-demo
      path: /rest/**

(5)指定path和URL

zuul:
  routes:
    route-name:
      url: http://localhost:8000/
      path: /rest/**

此例将http://ZUULHOST:ZUULPORT/rest/映射到http://localhost:8000/。同时由于并非用service-id定位服务,所以也无法使用负载均衡功能。

(6)即指定path和URL,又保留Zuul的Hystrix、Ribbon特性

zuul:
  routes:
    route-name: #路由别名,无其他意义,与例1效果一致
      service-id: rest-demo
      path: /rest/**
ribbon:
  eureka:
    enable: false #为Ribbon禁用Eureka
rest-demo:
  ribbon:
    listOfServers: localhost:9000,localhost:9001

(7)借助PatternServiceRouteMapper实现路由的正则匹配

@Bean
public PatternServiceRouteMapper serviceRouteMapper(){
    /**
     * A RegExp Pattern that extract needed information from a service ID. Ex :
     * "(?<name>.*)-(?<version>v.*$)"
     */
    //private Pattern servicePattern;
    /**
     * A RegExp that refer to named groups define in servicePattern. Ex :
     * "${version}/${name}"
     */
    //private String routePattern;
    return new PatternServiceRouteMapper("(?<name>^.+)-(?<version>v.+$)", "${version}/${name}");
}

此例可以将rest-demo-v1映射为/v1/rest-demo/**。

(8)路由前缀

zuul:
  prefix: /api
  strip-prefix: true
  routes:
    rest-demo: /rest/**

此时访问Zuul的/api/rest/user/xdlysk会被转发到/rest-demo/user/xdlysk。

(9)忽略某些微服务中的某些路径

zuul:
  ignoredPatterns: /**/user/* #忽略所有包含/user/的地址请求
  routes:
    route-demo:
      service-Id: rest-demo
      path: /rest/**

以上是关于SpringCloud之Zuul的主要内容,如果未能解决你的问题,请参考以下文章

微服务架构整理-(十二SpringCloud实战之Zuul网关)

八springcloud之服务网关zuul

springcloud实践之api网关:zuul

SpringCloud(Hoxton.SR3)基础篇:第八章SpringCloud之Zuul网关原理及其配置

SpringCloud之zuul网关

SpringCloud - Spring Cloud 之 Zuul和Gateway网关(十四)