SpringCloud組件——Eureka服務治理

【推薦】2019 Java 開發者跳槽指南.pdf(吐血整理) >>> hot3.png

1、什麼是是服務治理

    1、服務治理是微服務架構中最核心的模塊,實現對各個服務的自動化註冊以及服務發現機制。那麼爲什麼需要服務治理呢?

    假如項目中只有A和B兩個服務,A服務需要調用B服務,如果將這個調用方式寫死在代碼中(比如通過HTTP請求的方式調用,將B服務的請求路徑寫死在服務A調用B服務的代碼中),那麼一旦B服務的請求路徑需要發送改變,就必須要同時修改A服務中的代碼,非常麻煩。

    而且更復雜的是,通常爲了保證服務高可用,都會將服務B和A部署多個實例,總不可能在每一個A中都去維護一個服務B的列表吧,而且還需要手動實現服務B的負載均衡,無論是後期的維護還是代碼的實現都是非常複雜的。更恐怖的是,現實中一個項目可能會具有幾十上百個服務,每個服務之間都可能具有多個調用關係,而且每個服務都會有多個部署實例以及負載均衡,完全無法想象如果靠人力進行服務治理會有多恐怖。

    所以,必須要有一個自動化的服務治理機制,減輕工作量,提高代碼可維護性。

    2、簡單來說,服務治理就是服務註冊以及服務發現,簡單原理如下:

(1)服務註冊:在服務治理框架中,都會構建維護一個註冊中心,每個服務都會將自己註冊到這裏,比如服務的服務名、ip地址與端口號、通信協議等一系列數據存儲在註冊中心,註冊中心按照服務的名稱分類,形成一個服務清單。

    比如A服務部署了三個實例(192.168.10.01:8080,192.168.10.01:8081,192.168.10.01:8082),B服務也部署了三個實例,(192.168.10.02:8080,192.168.10.02:8081,192.168.10.02:8082),當這些服務全都啓動並且向服務中心註冊自己後,那麼服務中心的註冊表會維護一個類似下表的數據表,同時註冊中心還必須要定時向每個服務做一個心跳檢測,判斷列表中的某個地址下的服務是否可用,如果不可用還需要進行剔除,實現排除故障服務的效果。

服務名 請求地址
A 192.168.10.01:8080,192.168.10.01:8081,192.168.10.01:8082
B 192.168.10.02:8080,192.168.10.02:8081,192.168.10.02:8082

(2)服務發現:有了服務治理框架後,服務間的調用方式不需要指定具體的路徑進行調用,而是通過服務名來實現調用,服務調用方不知道具體的調用實例位置,所以需要通過服務註冊中心來獲取該服務名對應的所有實例清單列表。比如上述的A如果要調用B,首先要從服務中心獲取到B的實例地址(192.168.10.02:8080,192.168.10.02:8081,192.168.10.02:8082),然後再從這些地址中挑一個進行服務調用(這一塊就涉及到了負載均衡)。

    爲了提高性能,可能會有一個緩存機制,即會將服務註冊中心提供的服務實例地址清單緩存一份到本地,這樣就不用每次調用其他服務都要請求一次服務中心來獲取清單。但是這樣又會有一個問題,如果某個實例服務掛了並且被註冊中心剔除了,但本地緩存中的服務實例清單中仍然存在怎麼辦?如果對其調用肯定會出錯,導致整個功能異常,後續將會討論這個問題。

    對於同一個服務,無論其部署了多少個實例,都必須保證他們具有同一個服務名,這是服務發現的保證。

2、Eureka實現服務治理

    1. 在SpringCloud中,通過Eureka實現服務治理(服務註冊與發現),Eureka分爲服務端和客戶端組件,服務端就是服務實例清單數據中心,維護保存所有的服務信息,而客戶端是整合到了各個服務中,服務要通過這個客戶端來向Eureka服務端進行註冊以及調用其他服務。服務端與客戶端均採用Java編寫,所以Eureka適用於Java開發的微服務系統,但是並不是只能用於Java,因爲Eureka是通過HTTP請求實現的服務調用,所以對於其他語言,只需要自己開發一套客戶端即可使用。

    2. 對於Eureka的服務端,也就是服務註冊中心,可以實現高可用配置部署,即集羣化部署,這樣就保證了即使一臺服務註冊中心掛了,其他的服務註冊中心仍然能夠提供服務。

    3. Eureka實現服務治理的簡單實現:

(1)首先,搭建服務註冊中心,也就是Eureka的服務端。

新建Springboot工程,引入Eureka相關的jar包依賴什麼的就不說了。直接看配置代碼

首先要在SpringBoot項目的啓動類上添加一個@EnableEurekaServer註解

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerDemoApplication {

    public static void main(String[] args) {

        SpringApplication.run(EurekaServerDemoApplication.class, args);
    }

}

然後在application.properties進行詳細配置,簡答配置示例如下

server.port=8081

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:8081/eureka/

eureka.client.register-with-eureka=false:因爲當前項目工程就是服務註冊中心,所以不需要向自己註冊自己,設置爲false

eureka.client.fetch-registry=false:註冊中心的責任就是維護服務實例,所以不需要檢索服務,也設置爲false。

這兩個配置參數是用來表示向服務中心進行註冊的,對於服務(Eureka客戶端)來說,是不能配置爲false的,但服務註冊中心可以配置爲false,上面兩個配置都配置爲false是因爲現在的服務註冊中心是單體,不是集羣部署,不具備高可用性,所以設爲false,一旦需要高可用進行集羣部署服務註冊中心時,上面兩個參數不設置爲false,默認爲true即可。

對於eureka.client.serviceUrl.defaultZone=http://localhost:8081/eureka/這一行配置,其實個人剛開始覺得並不需要,因爲當前服務註冊中心並不需要向其他服務註冊中心進行註冊,所以就沒配置,可以啓動並且正常運行,但啓動後當前服務註冊中心會一直報錯,問題原因可以參考https://www.jianshu.com/p/788745f7dc7d

完成配置後,啓動該項目,瀏覽器訪問http://localhost:8081/就可以看到Eureka的可視化管理界面。

bf9825c450270910f1d6762d6942e578b06.jpg

(2)創建服務工程,註冊服務提供者:

創建一個SpringBoot項目工程,在SpringBoot啓動類上加上@EnableDiscoveryClient註解,

@EnableDiscoveryClient
@SpringBootApplication
public class EurekaClientDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaClientDemoApplication.class, args);
    }

}

寫一個簡單的Controller類作爲提供的服務,響應一個字符串即可

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String sayHello() {
        return "hello";
    }
}

然後就是配置文件,主要配置服務註冊中心的地址,以及當前服務的服務名

server.port=8082
spring.application.name=hello-service
eureka.client.serviceUrl.defaultZone=http://localhost:8081/eureka/

此時,當前服務就可以註冊到Eureka服務註冊中心了,啓動兩個工程,打開Eureka可視化管理界面,在Instances這一欄就可以看到註冊的hello-service服務

1a87f060809698f38c98b18ca1138975cd8.jpg

現在就已經完成了服務的註冊。

3、Eureka實現高可用

    1. Eureka爲了實現高可用,Eureka服務註冊中心,也就是Eureka的服務端可以採用集羣部署模式。Eureka的集羣部署實際上就是將服務註冊中心作爲一個服務向其他服務註冊中心註冊自己,形成一組互相註冊的服務註冊中心,進而實現服務註冊中心之間的服務清單同步,達到高可用的效果,即使一個服務註冊中心節點掛了,那麼也依然會有其他服務註冊中心節點頂替。

    2. Eureka服務註冊中心集羣配置:

(1)在上面的單節點服務註冊中心中,因爲不需要向其他節點註冊,所以加了兩行配置

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

但現在要搭建集羣模式,這兩行配置就要取消。然後分別創建兩個服務註冊中心項目工程peer1和peer2,其主要的配置如下

//peer1的application.properties中的主要配置
server.port=8084
spring.application.name=eureka-server
eureka.client.serviceUrl.defaultZone=http://localhost:8085/eureka

//peer2的application.properties中的主要配置
server.port=8085
spring.application.name=eureka-server
eureka.client.serviceUrl.defaultZone=http://localhost:8084/eureka

(2)啓動這兩個工程,在瀏覽器中打開Eureka可視化界面,就能看到互相註冊的服務,在Instances currently registered這一欄可以看到Eureka-server服務有兩個實例

d59c3359ea9ad328f08a0d876ce9aa400e8.jpg

(3)上面是這有兩個服務註冊中心互相註冊的情況,如果有數十個服務註冊中心互相,其主要配置還是在eureka.client.serviceUrl.defaultZone這一個配置上,如果要註冊到多個服務註冊中心,就使用逗號將各個服務祖冊中心的路徑隔開。

(4)服務註冊中心集羣搭建完成,那麼在配置一下服務註冊,在服務提供者工程中,其主要配置還是在eureka.client.serviceUrl.defaultZone這一個配置上,要註冊到多個服務註冊中心,就使用逗號將各個服務祖冊中心的路徑隔開。比如上面創建的hello-service服務工程,其配置應該爲

server.port=8082
spring.application.name=hello-service
eureka.client.serviceUrl.defaultZone=http://localhost:8084/eureka/,http://localhost:8085/eureka/

其實只寫集羣中某一個服務註冊中心的路徑地址,服務註冊中心集羣中的其餘節點也能感知到註冊的服務,因爲集羣節點之間會一直做一個已註冊服務清單數據同步。

但是之所以服務要註冊到所有服務註冊中心節點,是擔心萬一該服務A註冊的服務中心節點B掛了,集羣中的其餘服務註冊中心節點依舊能維持服務A處於服務清單之中並檢測其心跳狀態,而該服務也能與服務中心集羣保持着服務清單數據的同步,否則如果該服務註冊的服務中心掛了,那麼該服務就會無法再與服務註冊中心集羣進行一個服務清單數據的同步操作,也就無法保證能夠保證服務發現。

 

關於服務調用方,後面結合Ribbon和Feign組件進行講解。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章