1. 程式人生 > >Eureka、Ribbon和Feign

Eureka、Ribbon和Feign

Talk is cheap,show me the code , 書上得來終覺淺,絕知此事要躬行。在自己真正實現的過程中,會遇到很多莫名其妙的問題,而正是在解決這些問題的過程中,你會發現自己之前思維的盲點。

引子

看完《微服務設計》後,算是補上了自己在服務化這塊的理論知識,在業界,一般有兩種微服務的實踐方法:基於dubbo的微服務架構、基於Spring Cloud的微服務架構。從概念上來講,Dubbo和Spring Cloud並不能放在一起對比,因為Dubbo僅僅是一個RPC框架,實現Java程式的遠端呼叫,實施服務化的中介軟體則需要自己開發;而Spring Cloud則是實施微服務的一系列套件,包括:服務註冊與發現、斷路器、服務狀態監控、配置管理、智慧路由、一次性令牌、全域性鎖、分散式會話管理、叢集狀態管理等。

在有贊,我們基於Dubbo實施服務化,剛開始是基於ZooKeeper進行服務註冊與發現,現在已經轉成使用Etcd。我這次學習Spring Cloud,則是想成體系得學習下微服務架構的實現,也許能夠對基於Dubbo實施微服務架構有所借鑑。

Spring Cloud下有很多工程:

  • Spring Cloud Config:依靠git倉庫實現的中心化配置管理。配置資源可以對映到Spring的不同開發環境中,但是也可以使用在非Spring應用中。
  • Spring Cloud Netflix:不同的Netflix OSS元件的集合:Eureka、Hystrix、Zuul、Archaius等。
  • Spring Cloud Bus:事件匯流排,利用分散式訊息將多個服務連線起來。非常適合在叢集中傳播狀態的改變事件(例如:配置變更事件)
  • Spring Cloud Consul:服務發現和配置管理,由Hashicorp團隊開發。

我決定先從Spring Cloud Netflix看起,它提供瞭如下的功能特性:

  • 服務發現:Eureka-server例項作為服務提供者,可以註冊到服務註冊中心,Eureka客戶端可以通過Spring管理的bean發現例項;
  • 服務發現:巢狀式的Eureka服務可以通過宣告式的Java配置檔案建立;
  • 斷路器:利用註解,可以建立一個簡單的Hystrix客戶端;
  • 斷路器:通過Java配置檔案可以建立內嵌的Hystrix控制面板;
  • 宣告式REST客戶端:使用Feign可以建立宣告式、模板化的HTTP客戶端;
  • 客戶端負載均衡器:Ribbon
  • 路由器和過濾器:Zuul可以在微服務架構中提供路由功能、身份驗證、服務遷移、金絲雀釋出等功能。

本文計劃利用Eureka實現一個簡答的服務註冊於發現的例子,需要建立三個角色:服務註冊中心、服務提供者、服務消費者。

實踐

1. 服務註冊中心

在IDEA中建立一個Spring Cloud工程,引入Eureka-Server包,pom檔案整體如下:

<?xml version="1.0" encoding="UTF-8"?><projectxmlns="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>org.example.springcloud</groupId><artifactId>service-register</artifactId><version>1.0-SNAPSHOT</version><!-- spring boot的parent 配置檔案,有大部分spring boot需要用的Jar包 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.1.RELEASE</version></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.8</java.version></properties><!-- spring boot的maven打包外掛 --><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><dependencies><!-- eureka-server --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId></dependency><!-- spring boot test--><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>Camden.SR5</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement></project>

在src/main/java包下建立一個名為hello的包,然後建立 EurekaServiceRegisterApplication 類,並用@EnableEurekaServer和@SpringBootApplication兩個註解修飾,後者是Spring Boot應用都需要用的,這裡不作過多解釋;@EnableEurekaServer註解的作用是觸發Spring Boot的自動配置機制,由於我們之前在pom檔案中匯入了eureka-server,spring boot會在容器中建立對應的bean。EurekaServiceRegisterApplication的程式碼如下:

package hello;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;/**
 * Created by IntelliJ IDEA.
 * User: duqi
 * Date: 2017/3/2
 * Time: 20:02
 */@EnableEurekaServer//通過@EnableEurekaServer啟動一個服務註冊中心給其他應用使用@SpringBootApplicationpublicclassEurekaServiceRegisterApplication{publicstaticvoidmain(String[] args){SpringApplication.run(EurekaServiceRegisterApplication.class, args);}}

在application.properties中還需要增加如下配置,才能建立一個真正可以使用的服務註冊中心。

#註冊服務的埠號
server.port=8761#是否需要註冊到註冊中心,因為該專案本身作為服務註冊中心,所以為false
eureka.client.register-with-eureka=false#是否需要從註冊中心獲取服務列表,原因同上,為false
eureka.client.fetch-registry=false#註冊伺服器的地址:服務提供者和服務消費者都要依賴這個地址
eureka.client.service-url.defaultZone=http://localhost:${server.port}/eureka

logging.level.com.netflix.eureka=OFF
logging.level.com.netflix.discovery=OFF

啟動註冊服務,並訪問: http://localhost:8761 ,就可以看到如下介面。

服務註冊中心後臺

2. 服務提供者

建立一個Spring Boot工程,代表服務提供者,該服務提供者會暴露一個加法服務,接受客戶端傳來的加數和被加數,並返回兩者的和。

工程的pom檔案內容如下:

<?xml version="1.0" encoding="UTF-8"?><projectxmlns="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>org.example.springcloud</groupId><artifactId>service-client</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.1.RELEASE</version><relativePath/></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.8</java.version></properties><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId><scope>test</scope></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework