Spring Cloud 入門教程(九): 路由網關zuul


在微服務架構中,需要幾個關鍵的組件,服務注冊與發現、服務消費、負載均衡、斷路器、智能路由、配置管理等,由這幾個組件可以組建一個簡單的微服務架構。客戶端的請求首先經過負載均衡(zuul、Ngnix),再到達服務網關(zuul集群),然后再到具體的服務,服務統一注冊到高可用的服務注冊中心集群,服務的所有的配置文件由配置服務管理(下一篇文章講述),配置服務的配置文件放在Git倉庫,方便開發人員隨時改配置。

1. Zuul介紹

Zuul的主要功能是路由和過濾器。路由功能是微服務的一部分,比如/api/user映射到user服務,/api/shop映射到shop服務。zuul實現了負載均衡。以下是微服務結構中,Zuul的基本流程。在接下來的步驟中,我們來創建一個zuul服務, 將/api-feign/**映射到我們之前創建feign-service, 將/api-ribbon/**映射到之前的ribbon-service服務。

 2. 創建Zuul的Maven工程,其中關於zuul的依賴是

<dependency>
     <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>

 完整pom.xml如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6     <groupId>cm.chry</groupId>
 7     <artifactId>spring.helloworld.zuul.service</artifactId>
 8     <version>0.0.1-SNAPSHOT</version>
 9     <name>spring.helloworld.zuul.service</name>
10     <description>zuul service demo</description>
11     <parent>
12         <groupId>org.springframework.boot</groupId>
13         <artifactId>spring-boot-starter-parent</artifactId>
14         <version>1.5.3.RELEASE</version>
15         <relativePath/> <!-- lookup parent from repository -->
16     </parent>
17 
18     <properties>
19         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
20         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
21         <java.version>1.8</java.version>
22     </properties>
23 
24     <dependencies>
25         <dependency>
26             <groupId>org.springframework.cloud</groupId>
27             <artifactId>spring-cloud-starter-eureka</artifactId>
28         </dependency>
29         <dependency>
30             <groupId>org.springframework.boot</groupId>
31             <artifactId>spring-boot-starter-web</artifactId>
32         </dependency>
33         <dependency>
34             <groupId>org.springframework.cloud</groupId>
35             <artifactId>spring-cloud-starter-zuul</artifactId>
36         </dependency>
37         <dependency>
38             <groupId>org.springframework.boot</groupId>
39             <artifactId>spring-boot-starter-test</artifactId>
40             <scope>test</scope>
41         </dependency>
42     </dependencies>
43 
44     <dependencyManagement>
45         <dependencies>
46             <dependency>
47                 <groupId>org.springframework.cloud</groupId>
48                 <artifactId>spring-cloud-dependencies</artifactId>
49                 <version>Dalston.RC1</version>
50                 <type>pom</type>
51                 <scope>import</scope>
52             </dependency>
53         </dependencies>
54     </dependencyManagement>
55 
56     <build>
57         <plugins>
58             <plugin>
59                 <groupId>org.springframework.boot</groupId>
60                 <artifactId>spring-boot-maven-plugin</artifactId>
61             </plugin>
62         </plugins>
63     </build>
64 
65     <repositories>
66         <repository>
67             <id>spring-milestones</id>
68             <name>Spring Milestones</name>
69             <url>https://repo.spring.io/milestone</url>
70             <snapshots>
71                 <enabled>false</enabled>
72             </snapshots>
73         </repository>
74     </repositories>
75 </project>
pom.xml

3. 創建啟動類: 使用@EnableZuulProxy注解

 1 package spring.helloworld.zuul.service;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
 6 import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
 7 
 8 @EnableZuulProxy
 9 @EnableEurekaClient
10 @SpringBootApplication
11 public class ServiceZuulApplication {
12     public static void main(String[] args) {
13         SpringApplication.run(ServiceZuulApplication.class, args);
14     }
15 }

4. 編寫zuul服務配置:

簡單配置兩個路由, 一個路由到ribbon,一個路由到feign; 由於都注冊到eureka服務中心,所以都用通過serviceId來發現服務具體地址, path是路由的地址映射關系

 1 eureka:
 2     client:
 3         serviceUrl:
 4             defaultZone: http://localhost:8761/eureka/
 5 server:
 6     port: 8904
 7 spring:
 8     application:
 9         name: service-zuul
10 zuul:
11  routes:
12     ribbo:
13       path: /api-ribbon/**
14       serviceId: service-ribbon
15     feign:
16       path: /api-feign/**
17       serviceId: service-feign

這時啟動zuul服務, 然后訪問http://localhost:8904/api-ribbon可直接路由到http://localhost:8901/.  

http://localhost:8904/api-feign/hello可路由到http://localhost:8902/hello

5. Zuul過濾器

zuul還提供了過濾功能, 只要實現接口ZuulFilter即可對請求先進行篩選和過濾之后再路由到具體服務。

 1 package spring.helloworld.zuul.service;
 2 
 3 import javax.servlet.http.HttpServletRequest;
 4 
 5 import org.slf4j.Logger;
 6 import org.slf4j.LoggerFactory;
 7 import org.springframework.stereotype.Component;
 8 
 9 import com.netflix.zuul.ZuulFilter;
10 import com.netflix.zuul.context.RequestContext;
11 
12 @Component
13 public class DemoFilter extends ZuulFilter {
14     private static Logger log = LoggerFactory.getLogger(DemoFilter.class);
15     @Override
16     public String filterType() {
17         return "pre";
18     }
19 
20     @Override
21     public int filterOrder() {
22         return 0;
23     }
24 
25     @Override
26     public boolean shouldFilter() {
27         return true;
28     }
29 
30     @Override
31     public Object run() {
32         RequestContext ctx = RequestContext.getCurrentContext();
33         HttpServletRequest request = ctx.getRequest();
34         String s = String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString());
35         log.info(s);
36         return null;
37     }
38 }

filterType:返回一個字符串代表過濾器的類型,在zuul中定義了四種不同生命周期的過濾器類型,具體如下: 

  • pre:路由之前
  • routing:路由之時
  • post: 路由之后
  • error:發送錯誤調用

filterOrder:過濾的順序 

  • pre:路由之前
  • routing:路由之時
  • post: 路由之后
  • error:發送錯誤調用

shouldFilter:這里可以寫邏輯判斷,是否要過濾,本文true,永遠過濾。 

run:過濾器的具體邏輯,這里只是將請求的URL簡單些到日志中

上一篇:Spring Cloud 入門教程(八): 斷路器指標數據監控Hystrix Dashboard 和 Turbine

下一篇:Spring Cloud 入門教程(十):和RabbitMQ的整合 -- 消息總線Spring Cloud Netflix Bus


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM