1. 程式人生 > >Spring Cloud微服務(3)之閘道器Zuul

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對映的方式進行跳轉,結果是一樣的,如下圖。