上一篇簡單說了SpringCloud與Eureka的集成。主要解決了微服務間的服務註冊及調用的問題。這一篇集成Zuul,然後結合SpringCloud、Eureka、Zuul環境下進行真實系統聯調,幫助更好的對這些組件的理解。畢竟,實戰纔是學習最快的方法。前端
上篇也提到過,微服務下,各個業務模塊都被拆分紅相互獨立的微服務。雖然註冊中心(如Eureka)解決了服務內部的註冊發現、健康檢查等問題。可是如何與外部服務進行通訊又是一個新的問題了。git
某初創公司,剛剛經歷了一次大的架構改革。將原有的單體架構分解成了不少的微服務進行獨立部署。這些微服務包括用戶鑑權系統、訂單系統、定時任務系統等等。而原有的JSP也被改形成基於HTML下的靜態頁面進行先後端分離部署。github
那麼問題來了,由於先後端是分開的,前端同窗在調用後端不一樣服務時要定義各類不一樣的URI進行調用,管理起來太麻煩,並且,這種狀況下一旦後端服務郵編,有須要從新對域名進行解析,這也側面增長了運維同窗的工做量。而更可怕的是這又與如今你們都在提倡的DevOps徹底相悖了。web
是的,用Nginx的確是能幫助解決服務統一入口的問題。可是由於Nginx比較偏運維性質,並且其路由配置所有都是基於配置文件的硬編碼方式進行處理。一旦後臺服務發生變化,配置也須要及時更改。這樣也沒有徹底解決上述問題。spring
這時候,網關的出現讓我看到了曙光。經過服務名就能夠進行路由轉發,熔斷限流,日誌監控,最主要的是能夠開發人員本身經過配置就能輕鬆實現,不用每次都求運維人員去作解析。這樣豈不是也是更符合DevOps了呢。segmentfault
Zuul在英文中是怪獸的意思,寓意看門神獸。由大名鼎鼎的Netflix開源。並被Pivotal集成入Spring Cloud體系。當前流行的爲1.X與2.X系列。主要區別爲Zuul從2.X系列開始採用非阻塞異步模式,大大提高了其性能。他是基於filter機制進行工做。有統一入口、健康檢查、藍綠部署、金絲雀發佈、日誌監控、路由轉發等功能。也可集成Ribbon、Hystrix增長負載均衡、熔斷的功能。後端
實際開發中能夠根據選擇去集成Zuul網關。也可直接選擇Spring集成好的Spring Cloud Zuul方便更快的使用起來。本篇重點是集成Spring Cloud Zuul。api
關於Spring Cloud Zuul與Netflix Zuul相比仍是有些許不同的。他是基於SpringBoot + Netflix Zuul內核而成,去掉了原有的動態過濾器加載。因此生產環境中仍是根據須要本身選擇。瀏覽器
引入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,方法跟上一步同樣。建立後項目結構以下:
配置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); } }
總體測試
localhost:8761
分別啓動項目Zuul、provider、consumer
服務端口對照
服務名 | 端口號 |
---|---|
zuul-gateway | 4000 |
provider | 5000 |
consumer | 6000 |
postman測試網關調用
provider模塊新建TestGatewayController,並重啓provider
@RestController @RequestMapping("/test-gateway") public class TestGatewayController { @GetMapping public String testGateway() { return "Hi! 我是Consumer服務中的TestGatewayController."; } }
下一篇會針對以上的整合作更加詳細的配置,咱們會基於ZuulGateway去作更豐富測試(好比provider、consumer模塊若是是部署集羣網關該怎樣處理?他們之間的負載均衡策略又是怎樣的?鏈接超時、惡意訪問怎樣作熔斷限流?服務之間如何調用?),進行接近生產級項目的配置。敬請關注!
持續學習,記錄點滴。更多請點擊查看原文