微服務實戰——Spring Cloud + Zuul Gateway + Eureka集成

上一篇簡單說了SpringCloud與Eureka的集成。主要解決了微服務間的服務註冊及調用的問題。這一篇集成Zuul,然後結合SpringCloud、Eureka、Zuul環境下進行真實系統聯調,幫助更好的對這些組件的理解。畢竟,實戰纔是學習最快的方法。前端

1、聊聊網關

上篇也提到過,微服務下,各個業務模塊都被拆分紅相互獨立的微服務。雖然註冊中心(如Eureka)解決了服務內部的註冊發現、健康檢查等問題。可是如何與外部服務進行通訊又是一個新的問題了。git

舉個栗子

某初創公司,剛剛經歷了一次大的架構改革。將原有的單體架構分解成了不少的微服務進行獨立部署。這些微服務包括用戶鑑權系統、訂單系統、定時任務系統等等。而原有的JSP也被改形成基於HTML下的靜態頁面進行先後端分離部署。github

那麼問題來了,由於先後端是分開的,前端同窗在調用後端不一樣服務時要定義各類不一樣的URI進行調用,管理起來太麻煩,並且,這種狀況下一旦後端服務郵編,有須要從新對域名進行解析,這也側面增長了運維同窗的工做量。而更可怕的是這又與如今你們都在提倡的DevOps徹底相悖了。web

2、說了這麼多我用Nginx不就好了麼

是的,用Nginx的確是能幫助解決服務統一入口的問題。可是由於Nginx比較偏運維性質,並且其路由配置所有都是基於配置文件的硬編碼方式進行處理。一旦後臺服務發生變化,配置也須要及時更改。這樣也沒有徹底解決上述問題。spring

這時候,網關的出現讓我看到了曙光。經過服務名就能夠進行路由轉發,熔斷限流,日誌監控,最主要的是能夠開發人員本身經過配置就能輕鬆實現,不用每次都求運維人員去作解析。這樣豈不是也是更符合DevOps了呢。segmentfault

3、Zuul

Zuul簡單介紹

Zuul在英文中是怪獸的意思,寓意看門神獸。由大名鼎鼎的Netflix開源。並被Pivotal集成入Spring Cloud體系。當前流行的爲1.X與2.X系列。主要區別爲Zuul從2.X系列開始採用非阻塞異步模式,大大提高了其性能。他是基於filter機制進行工做。有統一入口、健康檢查、藍綠部署、金絲雀發佈、日誌監控、路由轉發等功能。也可集成Ribbon、Hystrix增長負載均衡、熔斷的功能。後端

Zuul架構

20200119214049

Spring Cloud Zuul

實際開發中能夠根據選擇去集成Zuul網關。也可直接選擇Spring集成好的Spring Cloud Zuul方便更快的使用起來。本篇重點是集成Spring Cloud Zuul。api

關於Spring Cloud Zuul與Netflix Zuul相比仍是有些許不同的。他是基於SpringBoot + Netflix Zuul內核而成,去掉了原有的動態過濾器加載。因此生產環境中仍是根據須要本身選擇。瀏覽器

4、話很少說請看代碼

老規矩,附上源碼地址SpingCloud+Zuul+Eureka

操做步驟

  • 仍是在原來的spring-cloud-demo(上一篇地址SpringCloud+Eureka)項目上,右鍵建立一個新的model.具體步驟再也不贅述。建立完成後項目結構以下:
    20200119215800
  • 引入Zuul依賴
    主要依賴以下:架構

    <!-- 引入Zuul starter -->
    <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
      </dependency>
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter</artifactId>
      </dependency>
      <!-- 鏈接Eureka -->
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
      </dependency>
  • 建立業務模塊provider、consumer,方法跟上一步同樣。建立後項目結構以下:
    20200119220736

    • 其中provider爲服務提供者,提供基礎服務的微服務
    • consumer爲服務的主要調用者。下一章會講服務之間基於接口(Feign)的調用
  • 配置Zuul路由轉發以及ribbon、hystrix

    spring.application.name = zuul-gateway
      logging.level.org.spring.framework.security = INFO
      #hystrix設置 時間要大於Ribbon時間總和
      hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds = 90000
      eureka.instance.instance-id = ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/
      #經過eureka發現的服務。使用ribbon
      ribbon.ReadTimeout = 20000
      ribbon.ConnectTimeout = 20000
      zuul.ignoredServices = '*'
      #設置不走ribbon的time-out時間
      zuul.host.connect-timeout-millis = 20000
      zuul.host.socket-timeout-millis = 20000
      #只要訪問以/api/開頭的多層目錄均可以路由到服務名爲kxtop-provider的服務上.
      zuul.routes.kxtop-provider.path = /api/**
      zuul.routes.kxtop-provider.service-id= kxtop-provider
      zuul.routes.kxtop-provider.stripPrefix = false
      #kxtop-consumer配置
      zuul.routes.kxtop-consumer.path = /consumer/**
      zuul.routes.kxtop-consumer.service-id = kxtop-consumer
      zuul.routes.kxtop-consumer.stripPrefix = false
      server.port = 4000
      management.endpoints.web.exposure.include = *
  • 建立Zuul啓動類

    @EnableDiscoveryClient  //做爲Eureka發現者
      @EnableZuulProxy        //開啓Zuul
      @SpringBootApplication
      public class ZuulGatewayApplication {
    
          public static void main(String[] args) {
              SpringApplication.run(ZuulGatewayApplication.class);
          }
      }
  • 分別配置provider、consumer配置文件及啓動類

    provider

    spring.application.name = kxtop-provider
    server.port = 5000
    eureka.instance.instance-id = ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/
    logging.level.org.spring.framework.security = INFO
    server.servlet.context-path = /api
    management.endpoints.web.exposure.include = *
    -------------------------
    
    @EnableDiscoveryClient
    @SpringBootApplication
    public class ProviderApplication {
        public static void main(String[] args) {
            SpringApplication.run(ProviderApplication.class);
        }
    }

    consumer

    spring.application.name = kxtop-consumer
    server.port = 6000
    eureka.instance.instance-id = ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/
    
    logging.level.org.spring.framework.security = INFO
    server.servlet.context-path = /consumer
    management.endpoints.web.exposure.include = *
    --------------------------
    
    @EnableDiscoveryClient
    @SpringBootApplication
    public class ConsumerApplication {
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApplication.class);
        }
    }
  • 總體測試

    1. 啓動Eureka並瀏覽器打開localhost:8761
      20200119222937
    2. 分別啓動項目Zuul、provider、consumer
      20200119223556

      • 保證每一個服務都正常運行
      • 服務端口對照

        服務名 端口號
        zuul-gateway 4000
        provider 5000
        consumer 6000
    3. 刷新瀏覽器查看效果(能夠看到,服務都已經註冊成功且處於UP狀態)
      20200119224623
    4. postman測試網關調用

      • provider模塊新建TestGatewayController,並重啓provider

        @RestController
          @RequestMapping("/test-gateway")
            public class TestGatewayController {
                @GetMapping
                public String testGateway() {
                    return "Hi! 我是Consumer服務中的TestGatewayController.";
                }
            }
      • 訪問localhost:4000/api/test-gateway

        20200119225241

      • 出現上面這句話,訪問成功。請注意:咱們訪問的是localhost的4000 端口,也就是配置的Zuul的端口哦,而輸出【Hi! 我是Consumer服務中的TestGatewayController】這句話的方法則是在端口爲5000的consumer模塊中定義的。這就就證實咱們以配置的網關和服務註冊發現是正確的。固然你也能夠作更多的測試。

5、後續

下一篇會針對以上的整合作更加詳細的配置,咱們會基於ZuulGateway去作更豐富測試(好比provider、consumer模塊若是是部署集羣網關該怎樣處理?他們之間的負載均衡策略又是怎樣的?鏈接超時、惡意訪問怎樣作熔斷限流?服務之間如何調用?),進行接近生產級項目的配置。敬請關注!

持續學習,記錄點滴。更多請點擊查看原文

相關文章
相關標籤/搜索