這兩天工作有點忙 是以學習的進度也慢下來了 今天記錄一下zuul
首先先放個圖
我們使用了SpringCloud Netflix 中的Eureka實作了服務注冊中心以及服務的注冊和發現,兒服務件通過Ribbon或者Feign實作服務的消費以及負載均衡。為了使服務叢集更加健壯,使用Hystrix的熔斷機制來避免微服務架構中個别服務出現異常時引起的故障蔓延。
在該架構中我們的服務叢集包括,内部服務Service A 和Service B ,他們都會注冊與訂閱服務至Eureka 服務中心,而open Service 是一個對外的服務,通過均衡負載公開至服務調用方。我們現在就來看看對外服務
下面是我從某處摘抄來的,比較高大上
- 首先,破壞了服務無狀态特點。為了保證對外服務的安全性,我們需要實作對服務通路的權限控制,而開放服務的權限控制機制将會貫穿并污染整個開放服務的業務邏輯,這會帶來的最直接問題是,破壞了服務叢集中REST API無狀态的特點。從具體開發和測試的角度來說,在工作中除了要考慮實際的業務邏輯之外,還需要額外可續對接口通路的控制處理。
- 其次,無法直接複用既有接口。當我們需要對一個即有的叢集内通路接口,實作外部服務通路時,我們不得不通過在原有接口上增加校驗邏輯,或增加一個代理調用來實作權限控制,無法直接複用原有的接口。
為了解決這麼高大上的問題 我們就來說說服務網關
我們需要将權限控制這樣的東西從我們的服務單元中抽離出去,而最合适這些邏輯的地方就是處于對外通路最前端的地方,我們需要一個更強大一些的均衡負載器,它就是我們要說的服務網關
服務網關是微服務架構中不可或缺的一部分。通過服務網關統一向外提供REST API的過程中,除了具備服務路由,負載均衡功能之外,還具備了權限控制等功能。SpringCloud Netflix 中的Zuul就擔任了這樣一個角色,為微服務架構提供了前門保護的作用,同時将權限控制這些較重的非業務邏輯内容遷移到服務路由層面,使得服務叢集主題能夠具備更高的可複用性和可測試性。
下面進入正題,還是基于我們之前的工程
首先建立一個新的SpringBoot工程 service_zuul 需要依賴
web
eureka
zuul
pom檔案是這樣的
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.chunying</groupId>
<artifactId>zuul</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>zuul</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Camden.SR6</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</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>
主類加注解@EnableEurekaClient 向注冊中心注冊,@EnableZuulProxy 開啟zuul
package com.chunying.zuul;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
我們先來說服務的路由轉發,當然是在配置檔案中配置的,有兩種配置方法
第一種配置URL與另一個服務路徑對應
server.port=8766
spring.application.name=service_zuul
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
#routes to url 所有通路api-a-url/**的通路都映射到localhost:2222上
zuul.routes.api-a-url.path=/api-a-url/**
zuul.routes.api-a-url.url=http://localhost:2222/
端口8766 , 服務名稱service_zuul , 服務中心位址http://localhost:8761/eureka/
下面的就重要了
zuul.routes.api-a-url.path=/api-a-url/**
zuul.routes.api-a-url.url=http://localhost:2222/
表示将所有/api-a-url/**的通路都映射到http://localhost:2222上面,也就是當通路http://localhost:1111/api-a-url/xxxx時會路由到http://localhost:2222/xxxx上面 , 我這裡沒有做測試 因為我并不喜歡用這種方法
是以我們看第二種:
第二種是通過服務名,
#routes to url 用eureka 服務名字進行負載調用
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.url=service_ribbon
zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.url=service_feign
這裡要注意path與url之前的 api-a是自定義的 但是必須要一一對應 否則就映射丢啦,這裡的url使用的是我們之前ribbon和feign的服務名稱。也就是說在通路/api-a/**時會路由到service_ribbon ,通路/api-b/時會路由到service_feign
啟動我們所有的五個服務serv 8761 , client 8762、8763 (和之前的一樣啟動兩個哈), service_ribbon 8764 , service_feign 8765 ,service_zuul 8766。
啟動成功
通路 http://localhost:8766/api-b/hello?name=ying
浏覽器交替出現
hello!8763,ying,come here
hello!8762,ying,come here
通路http://localhost:8766/api-a/hello?name=ying 是一樣的 說明就成功了,我在練習這裡的時候出現了一個問題,在第一次通路的時候總是會逾時,繼續就不會出現。
還沒有找到解決辦法 ,感覺配置一下逾時時間就可以了~~好了服務路由配置就記錄到這裡了,繼續加油咯