走進Spring Cloud之七 簡單Zuul(路由閘道器)(Greenwich版本)
API Gateway
在 Spring Cloud 的在微服務架構中,前端的應用往往是不可以直接呼叫我們提供的微服務,而是通過一個API Gateway根據請求的url,路由到相應的服務。當新增API Gateway後,在第三方呼叫端和服務提供方之間就建立了一面牆,這面牆直接與呼叫方通訊進行許可權控制,後將請求均衡分發給後臺服務端。
API Gateway是一個更為智慧的應用伺服器,它的定義類似於面向物件設計模式中的Facade模式,它的存在就像是整個微服務架構系統的門面一樣,所有的外部客戶端訪問都需要經過它來進行排程和過濾。它除了要實現請求路由、 負載均衡、 校驗過濾等功能之外,還需要更多能力,比如與服務治理框架的結合、請求轉發時的熔斷機制、服務的聚合等一系列高階功能。
Spring Cloud官方推出的第二代閘道器框架Spring Cloud Gateway,取代Spring Cloud Zuul閘道器。
Spring Cloud Zuul
在SpringCloud中了提供了基於Netflix Zuul實現的API閘道器元件Spring Cloud Zuul。
SpringCloud Zuul可以通過與SpringCloud Eureka進行整合,將自身註冊為Eureka服務治理下的應用,同時從Eureka中獲得了所有其他微服務的例項資訊。這樣的設計非常巧妙地將服務治理體系中維護的例項資訊利用起來,使得將維護服務例項的工作交給了服務治理框架自動完成,不再需要人工介入。
SpringCloud Zuul提供了一套過濾器機制,它可以 很好地支援這樣的任務。開發者可以通過使用Zuul來建立各種校驗過濾器,然後指定哪些規則的請求需要執行校驗邏輯,只有通過校驗的才會被路由到具體的微服務介面,不然就返回錯誤提示。通過這樣的改造,各個業務層的微服務應用就不再需要非業務性質的校驗邏輯了,這使得我們的微服務應用可以更專注千業務邏輯的開發,同時微服務的自動化測試也變得更容易實現。
我們可以利用SpringCloud Zuul完成路由轉發和過濾器的功能/api/user
轉發到到user服務,/api/shop
轉發到到shop服務。
service-zuul
新建moudle ->service-zuul
pom.xml
修改pom.xml新增spring-cloud-starter-netflix-zuul依賴
<?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">
<parent>
<artifactId>scexample</artifactId>
<groupId>com.pubutech</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-zuul</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
</dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
在resources目錄下新建application.yml並且新增配置資訊
eureka:
client:
service-url:
#設定與Eureka Server互動的地址,查詢服務和註冊服務都需要依賴這個地址。預設是http://localhost:8761/eureka ;多個地址可使用 , 分隔。
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/
server:
port: 8070
spring:
application:
name: service-zuul
zuul:
routes:
#/api-a/ 開頭匹配到service-producer
api-a:
path: /api-a/**
serviceId: service-producer
#/api-b/ 開頭匹配到service-producer
api-b:
path: /api-b/**
serviceId: service-producer
#匹配/github/直接重定向到https://github.com/
github:
path: /github/**
url: https://github.com/
ServiceZuulApplication.java
構建SpringBoot啟動應用ServiceZuulApplication
@EnableEurekaClient
@EnableDiscoveryClient
//支援閘道器路由
@EnableZuulProxy
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class ServiceZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceZuulApplication.class, args);
}
}
啟動測試
啟動我們的producer和zuul 再次訪問 localhost:8761
此時我們的服務註冊成功.
此時,我們訪問http://localhost:8070/github/xx github成功訪問。
此時,我們繼續訪問http://localhost:8070/api-a/hello?name=jason
遠端服務也呼叫成功。
由此可見,zuul可以為我們成功分發我們的服務。
負載均衡
前面我們已經成功測試了zuul的路由功能,接下來演示一下,zuul的負載均衡功能。
為了演示負載均衡,我們需要啟動多個producer,這裡我們對service-producer子moudle稍作改動
application-test.yml
service-producer子moudle的resources目錄新建application-test.yml,為了服務執行在同一臺機器,我們可以修改執行埠
server:
port: 8091
spring:
application:
name: service-producer
eureka:
client:
service-url:
#設定與Eureka Server互動的地址,查詢服務和註冊服務都需要依賴這個地址。預設是http://localhost:8761/eureka ;多個地址可使用 , 分隔。
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/
ProducerController.java
修改ProducerController服務,體現出我們的服務是來自於那裡。
@RestController
public class ProducerController {
@Value("${server.port}")
String port;
@RequestMapping("/hello")
public String hello(@RequestParam String name) {
return "hello "+name+",from "+ port+ " this is new world";
}
}
啟動測試
這裡還是一樣,順序啟動我們的註冊中心,zuul. 然後分別
java -jar service-producer-0.0.1-SNAPSHOT.jar
java -jar service-producer-0.0.1-SNAPSHOT.jar --spring.profiles.active=test
此時訪問http://localhost:8761/
我們已經有多個服務者了。
此時訪問http://localhost:8070/api-a/hello?name=jason
再次訪問http://localhost:8070/api-a/hello?name=jason
看見在多服務提供者的時候我們最終的服務者會負載均衡。