SpringCloud從入門到進階(五)——路由接入Zuul及其單點部署

內容html

  單體應用中各個模塊拆分紅獨立的系統,逐步演變出微服務架構。爲了屏蔽微服務內部的複雜調用,引入了Zuul做爲微服務調用的統一入口。本文介紹了Zuul的經常使用配置和使用,並經過簡單的演示進行了測試。java

版本git

  IDE:IDEA 2017.2.2 x64github

  JDK:1.8.0_171spring

  manve:3.3.3apache

  SpringBoot:1.5.9.RELEASE服務器

  SpringCloud:Dalston.SR1網絡

適合人羣架構

  ​Java開發人員app

說明

  轉載請說明出處:SpringCloud從入門到進階(五)——路由接入Zuul及其單點部署

  GitHub倉庫地址: https://github.com/leo-zz/SpringCloudDemo/tree/master/Zuul

參考

       Linux入門實踐筆記(二)--Jar包運行與關閉

       SpringCloud從入門到進階(二)——註冊中心Eureka的僞分佈式部署

Zuul介紹

  路由器的概念想必你們都接觸過——家庭上網必備無線路由器。它將手機、電腦等設備的聯網請求轉發到電信運行商的網關,實現設備的網絡通訊。Zuul是微服務架構中扮演路由角色的組件,它是基於JVM的路由器,同時是服務端的負載均衡器。全部的外部微服務請求都會通過Zuul,由Zuul根據URL的信息將請求轉發給對應的微服務進行處理。

  Zuul內置了Ribbon和hystrix,從eureka中獲取微服務實例的信息,由Ribbon肯定接收請求的微服務實例。全部的請求都經過hystrix處理,於是能夠經過Hystrix的監控工具觀察請求熔斷的狀況。一旦接口熔斷環路開啓,Zuul將不會再將請求轉發給該服務。

項目路徑

pom.xml

  配置maven的依賴文件pom.xml,引入SpringBoot,SpringCloud,Eureka Client和Zuul的依賴,以及Spring Boot打包的Maven插件。

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.leo</groupId>
    <artifactId>zuul</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 經過繼承的方式引入spring boot  -->
    <!--parent標籤用於指定父pom-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>

    <!--properties標籤用於聲明一些常量,例如源碼編碼爲UTF-8,輸出代碼也爲UTF-8,Java版本爲1.8-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Dalston.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <!--eureka client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <!--zuul組件實現網關的路由轉發和負載均衡-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>
    </dependencies>

    <!--子Module不會繼承該依賴,除非顯示聲明-->
    <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>

    <!-- Spring Boot的Maven插件,使用Maven插件的方式來啓動Spring Boot工程
若是不添加該插件在使用mvn命令打包的jar有問題,執行時會報錯:xxx.jar中沒有主清單屬性-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
yaml

​   本示例以單點的方式部署Zuul,將全部profiles的公共配置提取到yaml文件的頂部,以便後期進行高可用版本的部署。此外進行了Eureka Client、Zuul路由,logback日誌等相關內容的配置。

Eureka Client的配置

​  eureka.instance.instance-id,配置了實例的id。

​  eureka.client.service-url.defaultZone,配置了Eureka Server集羣的地址。

Zuul路由的配置

​  zuul.prefix屬性,爲全部請求添加統一的前綴,默認爲空串,即不添加前綴。能夠經過該屬性實現API接口的版本號控制,好比此處設置爲"/v1"表示API接口爲v1版本,注意前綴要以"/"開頭。

​  zuul.routes屬性,用於配置路由器的路由信息。其中的zuul.routes.path屬性表示url的匹配規則,zuul.routes.serviceId表示處理該路由的微服務的application name。

​  本示例配置了兩條路由,名稱爲routeA和routeB,分別將"/routea"和"/routeb"開頭的url請求轉發給微服務application-serviceA和application-serviceB進行處理。初次接觸SpringCloud的童鞋要注意,這裏的application-serviceA和application-serviceB都是微服務的應用名,即spring.application.name屬性;不是eureka client的實例名稱,eureka.instance.instance-id屬性。

日誌的配置

  ​logging.file屬性,配置了日誌文件的位置和名稱。日誌的配置默認讀取classpath下的logback-spring.xml。

spring:
  application:
    name: application-gatewayservice
  profiles:
    active: peer1
#Zuul的配置
zuul:
  #經過zuul.prefix屬性配置前綴,爲全部請求添加統一的前綴,默認爲空串,即不添加前綴。
  #能夠經過該屬性實現API接口的版本號控制,注意前綴要以"/"開頭,此處設置爲"/v1"表示API接口爲v1版本。
  prefix: /v1
  #若是某服務存在多個實例,Zuul結合Ribbon會作負載均衡,將請求均分的部分路由到不一樣的服務實例
  #zuul.routes屬性配置路由器的路由信息。
  routes:
    #路由的名稱是用戶自定義的,須要指定它的path和serviceld,兩者規定了將指定規則的請求Url路由到指定的Serviceld
    #符合/routea/** 規則的請求轉發給微服務springcloud-serviceA
    routeA:
      path: /routea/**
      serviceId: application-serviceA #此處是spring的applicationname,即Eureka的服務名,而非instance-id 實例名。
    #符合/routeb/** 規則的請求轉發給微服務springcloud-serviceB
    routeB:
      path: /routeb/**
      serviceId: application-serviceB
#指明日誌存放位置
logging:
  file: logs/application-gatewayservice-${server.port}.logs
#配置了Eureka Server集羣的地址
eureka:
  client:
    service-url:
      defaultZone: http://172.26.125.114:7001/eureka,http://172.26.125.115:7001/eureka,http://172.26.125.118:7001/eureka
---
spring:
  profiles: peer1
server:
  port: 7081

#Eureka實例名的配置
eureka:
  instance:
    instance-id: springcloud-gatewayservice-A7-7081

#actuator的配置
management:
  port: 7181
  security:
    enabled: false

---
spring:
  profiles: peer2
server:
  port: 7082

#Eureka實例名的配置
eureka:
  instance:
    instance-id: springcloud-gatewayservice-A7-7082

#actuator的配置
management:
  port: 7182
  security:
    enabled: false

logback-spring.xml

  本實例的日誌按照日期、文件大小、日誌級別進行分割,並將不一樣的級別或日期將記錄到不一樣的日誌文件中,而且日誌的大小超過限定值後會自動切割,詳細請參考SpringBoot從入門到進階——學會Logback日誌的配置和搭建,具體參數此處略去。

SpringApplication

  主程序類中,增長@EnableZuulProxy開啓Zuul路由功能。增長@EnableEurekaClient開啓Eureka Client的功能。

@EnableZuulProxy //開啓Zuul的功能
@EnableEurekaClient//開啓Eureka Client的功能。
@SpringBootApplication
public class GatewayServiceApplicaton {
    public static void main(String[] args) {
        SpringApplication.run(GatewayServiceApplicaton.class,args);
    }
}
Zuul斷路器 

  Zuul的自定義斷路器,在請求路由的響應超時或請求失敗後,Zuul會進行服務熔斷,並執行MyFallbackProvider中配置的回調方法。本示例在回調函數中添加了統一的錯誤提示信息,斷路器同時能夠避免請求線程阻塞帶來的服務雪崩的危害。

  ​MyFallbackProvider實現了ZuulFallbackProvider接口,經過實現其中的方法對斷路器進行配置:

​  getRoute()方法用於配置該斷路器匹配的請求的url規則,此處爲"*",表示MyFallbackProvider會處理全部的路由請求。fallbackResponse()方法經過返回ClientHttpResponse接口的對象,ClientHttpResponse接口規定了回調響應的具體邏輯,表示返回到客戶端的HTTP響應,包括HTTP狀態碼、響應頭、響應體等信息。

@Component
public class MyFallbackProvider implements ZuulFallbackProvider {

    /**
     * getRoute()方法,用於指定熔斷功能應用於哪些路由的服務。
     * 若是須要全部的路由服務都加熔斷功能,只須要在getRoute()方法上返回"*"的匹配符,
     */
    @Override
    public String getRoute() {
        return "*"; //全部路由服務都增長熔斷。
    }

    /**
     * fallbackResponse()爲進入熔斷功能時執行的邏輯
     */
    @Override
    public ClientHttpResponse fallbackResponse() {
        return new ClientHttpResponse() {
            //設置響應的HTTP狀態碼(HttpStatus中的enum值)
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.SERVICE_UNAVAILABLE;
            }

            //設置響應的HTTP狀態碼(數字,能夠是非標準的狀態碼)
            @Override
            public int getRawStatusCode() throws IOException {
                return 503;
            }

            //設置響應的HTTP狀態文本信息
            @Override
            public String getStatusText() throws IOException {
                return "Service_Fallbcak";
            }

            //關閉響應,用於釋放資源
            @Override
            public void close() {

            }

            //以輸入流的形式返回響應體的信息
            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream("您好,服務出現故障,請重試。".getBytes("utf-8"));
            }

            //返回響應頭的信息
            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
                return headers;
            }
        };
    }
}

啓動與測試

  項目的打包、部署過程以前文檔已經寫明,可參考:SpringCloud從入門到進階(二)——註冊中心Eureka的僞分佈式部署

#啓動jar包。
[user@Serverjars]$ java -Dspring.profiles.active=peer1 -jar zuul-1.0-SNAPSHOT.jar

  訪問eureka服務器,能夠看到zuul微服務處於up狀態,項目成功啓動。

1540277505269

  使用postman請求url"http://localhost:7081/v1/routea/upload",該url符合"/v1/routea/**",由路由規則可知,該url匹配路由routeA,會被轉發到微服務springcloud-serviceA。可是因爲微服務還未部署,所以請求對應接口會報503錯誤(走MyFallbackProvider執行服務熔斷)。

  若是請求url不能匹配到zuul上的路由規則,則會報404錯誤。

補充:使用Zipkin監控路由Zuul的請求處理。

  爲了監控請求處理的耗時狀況,會在路由端和微服務端增長鏈路追蹤組件Zipkin,具體配置請參考後續章節。

相關文章
相關標籤/搜索