Spring Cloud微服務(3)之閘道器Zuul
1.介紹
古語有云:一夫當關,萬夫莫開。
閘道器Zuul就在系統中起到同樣的作用,它是系統的門戶、城市的關隘、公園的檢票口。
服務閘道器API Gateway可以有很多實現方法,如Nginx、Zuul,甚至是一個Node.js的服務端。它們最重要的作用是為前臺提供後臺服務的聚合,提供一個統一的服務出口,
解除它們之間的耦合,同時負責鑑權、認證、安全和跳轉等作用。
Zuul是邊緣服務,用來提供動態路由、監控、鑑權、安全、排程等功能,將許可權控制等一些業務邏輯抽離出來,單獨放到Zuul裡,使得服務元件更簡單,具有更好的可複用
性。
Zuul是反向代理工具,代理了後臺的所有服務端,前端請求不需要知道真正的服務端是誰,只要交給Zuul就可以了,Zuul負責路由到真正的服務商。
2.如何使用
首先需要一個 eureka server 用於服務發現,然後需要兩個不同的服務來驗證 zuul 的路由功能。兩個服務分別是 order service 和 product service,還需要路由 zuul service。
第一步:建立 order-service 工程。
專案結構如圖:
(1)程式程式碼如下。
package com.hole; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @EnableDiscoveryClient @SpringBootApplication @RestController public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } @RequestMapping(value = "/hello",method = RequestMethod.GET) public ResponseEntity<String> hello(){ return new ResponseEntity<String>("hello order service!", HttpStatus.OK); } }
(2)application.properties配置如下。
spring.application.name=order-service
server.port=3331
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
eureka.instance.lease-renewal-interval-in-seconds=50
eureka.instance.lease-expiration-duration-in-seconds=30
其中spring.application.name 配置的是服務ID,對應在Eureka監控介面看到的服務名稱,相當於服務的別名,被呼叫時會被引用,如在 Zuul中配置路由就會用到這個名稱。
(3)pom.xml 配置同 上一節 Eureka 客戶端配置,不再贅述。
第二步:建立 product-service 工程。
工程結構如圖所示:
(1)程式程式碼如下。
package com.hole;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@EnableDiscoveryClient
@SpringBootApplication
@RestController
public class ProductServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ProductServiceApplication.class, args);
}
@RequestMapping(value = "/hello",method = RequestMethod.GET)
public ResponseEntity<String> hello(){
return new ResponseEntity<String>("hello product service!", HttpStatus.OK);
}
}
(2)application.properties配置如下:
spring.application.name=product-service
server.port=2221
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
eureka.instance.lease-renewal-interval-in-seconds=50
eureka.instance.lease-expiration-duration-in-seconds=30
第三步:建立 zuul-service 工程。
目錄結構如下圖所示:
(1)工程增加 Zuul 依賴,pom.xml增加。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
(2)啟動類增加一行註解 @EnableZuulProxy,這樣就開啟了Zuul 的功能。
package com.hole;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@EnableZuulProxy
@SpringBootApplication
@EnableDiscoveryClient
public class ZuulServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulServiceApplication.class, args);
}
}
(3)application.properties 增加路由的配置。
spring.application.name=zuul-service
server.port=8765
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
# routes to serviceId
zuul.routes.product-service.path=/product-service/**
zuul.routes.product-service.serviceId=product-service
zuul.routes.order-service.path=/order-service/**
zuul.routes.order-service.serviceId=order-service
# routes to url
zuul.routes.product-service-url.path=/product-service-url/**
zuul.routes.product-service-url.url=http://localhost:2221/
zuul.routes..order-service-url.path=/order-service-url/**
zuul.routes..order-service-url.url=http://localhost:3331/
其中 order-service替換成任何名稱都可以,只要path 和 serviceId 成對出現即可。這樣所有 /product-services/** 過來的請求都會轉發到 product-service 服務上;所有
/order-service/** 過來的請求都被轉發到 order-service服務上。
還可以通過 url 來做對映,相對於 serviceId 的方式來說更復雜一些,因為需要知道具體的 IP地址,不如直接飲用示例名方便。
第四步:啟動
將 eureka-server、zuul-service、product-service、order-service 四個工程啟動,在監控介面可以看到啟動成功。
第五步:驗證。
分別單獨驗證兩個服務 product-service、order-service 是否可以正常使用,經驗證都可以訪問。如圖:
接下來驗證Zuul 路由功能。如圖可以看出路由功能已經生效,可以正常的通過服務ID對映的方式進行跳轉。
同樣可以通過URL對映的方式進行跳轉,結果是一樣的,如下圖。