一、Zuul简介

            Zuul是Netflix开源的微服务网关,它可以与eureka,ribbon,hystrix等组件配合使用。Zuul的核心是一系列的过滤器,这些过滤器可以完成一下的功能:

           1)身份认证与安全: 识别每个资源的验证要求,并拒绝那些与要求不符合的请求。

           2)审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生产试图。

           3) 动态路由:动态地将请求路由到不同的后端集群。

           4) 压力测试: 逐渐增加指向集群的流量,以了解性能。

           5)负载分配:   为每一种负载类型分配对应容量,并弃用超出限定值的请求。

           6)静态响应处理: 在边缘位置直接建立响应部分,从而避免其转发到内部集群。

           7)多区域弹性: 跨域AWS Region进行请求路由,旨在实现ELB(Elastric Load Balancing)使用的多样化,以及让系统的边缘更贴近系统的使用者。

二、使用springboot编写Zuul网关

       1.第一种方式,不使用eureka来转发

          第一步, 添加依赖:

   <!--zuul网关包-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>

         第二步,在启动类上添加注解@EnableZuulProxy

        第三步,配置application.properties文件,给payment服务和expense服务配置路由,其中payment服务是单节点的,expense服务是双节点的,详细配置:

    

server.port=9000
spring.application.name=microservice-gateway-zuul
eureka.instance.prefer-ip-address=true
eureka.instance.instance-id=192.168.2.1:9000
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.client.enabled=false
eureka.instance.lease-renewal-interval-in-seconds =30
#Eureka服务端在收到最后一次心跳之后等待的时间上限,单位为秒,超过则剔除(客户端告诉服务端按照此规则等待自己)
eureka.instance.lease-expiration-duration-in-seconds =30


##添加路由配置单个实例的方法如下,此方法可以不用将网关注册到eureka上面,zuul接到请求后,
会直接根据下面定义的规则来进行http请求转发
##添加路由payment
zuul.routes.payment-demo.service-id=payment-demo
zuul.routes.payment-demo.path=/payment-demo/**
zuul.routes.payment-demo.url=http://localhost:9098/


##如果有多个实例应该怎么配置,可以通过配置地址服务列表的形式来访问
zuul.routes.expense-demo.service-id=expense-demo
zuul.routes.expense-demo.path=/expense-demo/**
ribbon.eureka.enabled=false
#不使用eureka的话,需要使用ribbon来实现多节点选择的负载均衡
expense-demo.ribbon.listOfServers=http://localhost:9096/,http://localhost:9097/

 

 

分别访问:

http://127.0.0.1:9000/payment-demo/api/wallet/hello

http://127.0.0.1:9000/expense-demo/api/report/get/info/by/id/?id=1

成功访问payment服务下:

expense服务下:

 上面介绍的是不使用eureka来用zuul进行单实例和多实例转发。

    2. 第二种方式是使用eureka来转发

          直接将zuul注册到eureka上,访问eureka上面的服务名称就可以访问到对应的服务了。

          添加springcloud的zuul组件依赖和eureka依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.11.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example.hand</groupId>
    <artifactId>microservice-springcloud-zuul</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>microservice-springcloud-zuul</name>
    <description>project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR4</spring-cloud.version>
    </properties>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!--eureka依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--zuul网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

   此时的zuul服务的properties文件相比上面的要简单的多:

server.port=9000
spring.application.name=microservice-gateway-zuul
eureka.instance.prefer-ip-address=true
eureka.instance.instance-id=192.168.2.1:9000
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.instance.lease-renewal-interval-in-seconds =30
#Eureka服务端在收到最后一次心跳之后等待的时间上限,单位为秒,超过则剔除(客户端告诉服务端按照此规则等待自己)
eureka.instance.lease-expiration-duration-in-seconds =30


 注册到eureka上的效果如下:

  

然后分别访问单实例的payment服务和多实例的expense服务,访问的格式为: host:port/服务名/**

 

如果你想要zuul只代理部分服务,可以通过配置ignore-service来忽略指定的服务不被zuul所代理,假如忽略掉expense服务,可以添加以下配置:

zuul.ignored-services=expense

 再次访问:

而在eureka上的payment服务仍然可以正常的被zuul代理:

可以发现,使用eureka来转发时,需要的配置要简单很多,可以根据不同的场景和需求来选择哪一种方式来转发。

 

三、总结

 1)除了上述的转发方式,还有一种简单的配置方式: feign-consumer为微服务名, /api-a/路径为该微服务下的路径,访问/api-a/**会转发到feign-consumer服务上。

zuul.routes.feign-consumer=/api-a/**

2)可以使用forward 将请求转发到本地:

zuul:
  routes:
    serviceA:
      path: /serviceA/**
      url: forward:/serviceB


会发现该服务会转发到本地的/serviceB路径上,其中serviceA后面需要家/**,否则访问会出现404。

 注意:   forward后面一定要加“/” ,否则启动会报错: 

Caused by: org.yaml.snakeyaml.scanner.ScannerException: mapping values are not allowed here
 in 'reader', line 7, column 19:
          url: forward:

 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐