Spring Cloud Eureka

服務(wù)治理

服務(wù)治理是微服務(wù)架構(gòu)中最為核心和基礎(chǔ)的模塊,它主要用來(lái)實(shí)現(xiàn)各個(gè)微服務(wù)實(shí)例的自動(dòng)化注冊(cè)和發(fā)現(xiàn)。
在微服務(wù)架構(gòu)體系中,每個(gè)服務(wù)都是相對(duì)獨(dú)立的,包括其部署、擴(kuò)展和升級(jí),都不應(yīng)和其他服務(wù)產(chǎn)生耦合。但是微服務(wù)之間是無(wú)法避免業(yè)務(wù)關(guān)系的,也就是說(shuō)服務(wù)之間需要互相調(diào)用。對(duì)于Restful接口而言,服務(wù)A要調(diào)用服務(wù)B的接口,必須知道具體的url,這樣服務(wù)A就必須與服務(wù)B的部署位置產(chǎn)生依賴(lài)關(guān)系。另一方面,為了實(shí)現(xiàn)服務(wù)B的高可用,不論采用服務(wù)端負(fù)載均衡還是客戶(hù)端負(fù)載均衡,都需要手工維護(hù)服務(wù)B的實(shí)例列表。
為了解決微服務(wù)架構(gòu)中的服務(wù)實(shí)例維護(hù)問(wèn)題,產(chǎn)生了大量的服務(wù)治理框架和產(chǎn)品。服務(wù)治理的功能主要有一下幾點(diǎn):

  • 對(duì)開(kāi)發(fā)新服務(wù)和升級(jí)現(xiàn)有服務(wù)的計(jì)劃管理服務(wù)的生命周期;
  • 確保升級(jí)服務(wù)不會(huì)影響目前的服務(wù)消費(fèi)者制定方針來(lái)限制服務(wù)行為;
  • 制定所有服務(wù)都要遵從的規(guī)則,確保服務(wù)的一致性監(jiān)控服務(wù)的性能;
  • 由于服務(wù)組合,服務(wù)停機(jī)和性能低下的后果是嚴(yán)重的。通過(guò)監(jiān)控服務(wù)的性能和可用性,當(dāng)問(wèn)題出現(xiàn)的時(shí)候能馬上采取應(yīng)對(duì)措施;
  • 管理由誰(shuí)來(lái)調(diào)用服務(wù)、怎樣調(diào)用服務(wù)

服務(wù)注冊(cè)

在服務(wù)治理框架中,通常需要一個(gè)注冊(cè)中心。每個(gè)服務(wù)想注冊(cè)中心登記自己提供的服務(wù),將服務(wù)的位置、調(diào)用方式等告知注冊(cè)中心。注冊(cè)中心會(huì)按服務(wù)名分類(lèi)組織分類(lèi)清單。另外服務(wù)注冊(cè)中心還需定時(shí)監(jiān)控清單中的服務(wù)的健康狀態(tài),及時(shí)剔除不可用的實(shí)例。

服務(wù)發(fā)現(xiàn)

在服務(wù)治理框架下,服務(wù)之間的調(diào)用不在依賴(lài)于服務(wù)的具體位置(如ip:port),而是通過(guò)服務(wù)名調(diào)用,從而將服務(wù)的部署從微服務(wù)的調(diào)用中解決關(guān)聯(lián)。通過(guò)服務(wù)名調(diào)用,還可以方便地實(shí)現(xiàn)負(fù)載均衡。由于服務(wù)注冊(cè),我們有一份清單可以找到某個(gè)服務(wù)的具體實(shí)例,若是服務(wù)不止一個(gè)實(shí)例,我們可以很方便地動(dòng)態(tài)選擇服務(wù)的實(shí)例進(jìn)行調(diào)用,從而實(shí)現(xiàn)負(fù)載均衡。這也有利于服務(wù)的橫向擴(kuò)展,實(shí)現(xiàn)高可用。

Spring Cloud Eureka

Netflix Eureka是Netflix開(kāi)發(fā)的一套基于jvm和restful的服務(wù)治理框架。其服務(wù)端是用java語(yǔ)言編寫(xiě),主要適用于java實(shí)現(xiàn)的分布式系統(tǒng)。但是其通信協(xié)議為基于http的restful,所以客戶(hù)端理論上用什么語(yǔ)言實(shí)現(xiàn)都可以。這也是微服務(wù)的一大特點(diǎn),服務(wù)可以根據(jù)自身特點(diǎn)選用相應(yīng)的語(yǔ)言或平臺(tái)實(shí)現(xiàn),不必局限于同一的平臺(tái)。

搭建服務(wù)注冊(cè)中心

Spring Cloud中的微服務(wù)就是一個(gè)個(gè)Spring Boot應(yīng)用程序,服務(wù)注冊(cè)中心也不例外。按上篇文章的步驟,搭建一個(gè)spring boot模塊。

新建一個(gè)gradle模塊,artifactId設(shè)為eureka-server

完善項(xiàng)目目錄

修改build.gradle,引入spring-cloud-starter-eureka-server

group 'com.zhuangqf.demo'
version '1.0-SNAPSHOT'

dependencies {
    compile "org.springframework.cloud:spring-cloud-starter-eureka-server"
    compile "org.springframework.boot:spring-boot-starter-web"
}

添加Application啟動(dòng)類(lèi),通過(guò)EnableEurekaServer注解啟動(dòng)一個(gè)注冊(cè)服務(wù)中心。

@EnableEurekaServer
@SpringBootApplication
public class Application {

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

}

添加application.yml:

spring:
  application:
    name: eureka-server
server:
  port: 9000

eureka:
  instance:
    instance-id: ${spring.cloud.client.ipAddress}:${server.port}
    hostname: ${spring.cloud.client.ipAddress}
  client:
    fetch-registry: false
    register-with-eureka: false
    serviceUrl.defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

先重點(diǎn)關(guān)注eureka.client配置:

  • eureka.client.fetch-registry 默認(rèn)為true,是否拉取注冊(cè)的實(shí)例信息,注冊(cè)中心不需要遠(yuǎn)程調(diào)用實(shí)例,所以不需要檢索服務(wù),設(shè)為false。
  • eureka.client.register-with-eureka 對(duì)于單注冊(cè)中心,不需要向自己注冊(cè)
  • eureka.client.serviceUrl.defaultZone 注冊(cè)中心地址
啟動(dòng)后訪問(wèn)localhost:9000

接入客戶(hù)端

注冊(cè)中心已經(jīng)跑起來(lái)了,那么怎么讓我們的服務(wù)注冊(cè)到注冊(cè)中心呢?讓我們對(duì)之前寫(xiě)過(guò)的example模塊做一些改造。

在example模塊的build.gradle中添加依賴(lài)

compile "org.springframework.cloud:spring-cloud-starter-eureka"

相應(yīng)的,在Application類(lèi)加一個(gè)注解:

@SpringBootApplication
@EnableDiscoveryClient
public class Application {

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

}

接著,在application.yml中指定注冊(cè)地址:

eureka:
  instance:
    instance-id: ${spring.cloud.client.ipAddress}:${server.port}
    hostname: ${spring.cloud.client.ipAddress}
  client:
    serviceUrl.defaultZone: http://localhost:9000/eureka/

啟動(dòng)后訪問(wèn)localhhost:9000

高可用注冊(cè)中心

高可用集群是指以減少服務(wù)中斷時(shí)間為目的的服務(wù)器集群技術(shù)。它通過(guò)保護(hù)用戶(hù)的業(yè)務(wù)程序?qū)ν獠婚g斷提供的服務(wù),把因軟件/硬件/人為造成的故障對(duì)業(yè)務(wù)的影響降低到最小程度。

在微服務(wù)架構(gòu)系統(tǒng)中,故障是不可能避免的。Eureka Server的設(shè)計(jì)一開(kāi)始就考慮了高可用的問(wèn)題,在Eureka的服務(wù)治理設(shè)計(jì)中,所有節(jié)點(diǎn)既是服務(wù)提供方,又是服務(wù)消費(fèi)方,服務(wù)注冊(cè)中心也不例外。

Eureka Server的高可用實(shí)際上是將自己作為服務(wù)向其他服務(wù)注冊(cè)中心注冊(cè)自己,這樣就可以形成一組互相注冊(cè)的服務(wù)注冊(cè)中心。注冊(cè)中心之間會(huì)共享彼此的服務(wù)清單,注冊(cè)中心可以在一個(gè)zone中,也可以按業(yè)務(wù)或服務(wù)的部署位置分為多個(gè)zone。

在這里,我們先簡(jiǎn)單實(shí)現(xiàn)同一個(gè)zone的兩個(gè)注冊(cè)中心,讓它們彼此注冊(cè),實(shí)現(xiàn)高可用。

首先,在eureka-server的application.yml中增加以下配置

-- peer1
server.port: 9001

eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    serviceUrl.defaultZone: http://${eureka.instance.hostname}:9002/eureka

-- peer2
server.port: 9002

eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    serviceUrl.defaultZone: http://${eureka.instance.hostname}:9001/eureka

peer1和peer2是可選的兩組配置,在配置中,我們從彼此注冊(cè)到對(duì)方。

peer的啟動(dòng)配置,增加了`--spring.profiles.active=peer`作為啟動(dòng)參數(shù)

分別啟動(dòng)peer1和peer2

peer1注冊(cè)到了peer2服務(wù)器
peer2注冊(cè)到了peer1服務(wù)器

啟動(dòng)example

修改example的注冊(cè)服務(wù)器地址:


example注冊(cè)到了peer1和peer2中

此時(shí),peer1或者peer2有一個(gè)出現(xiàn)故障在短時(shí)間內(nèi)不會(huì)對(duì)系統(tǒng)的業(yè)務(wù)有太大的影響,因?yàn)榱硪粋€(gè)注冊(cè)中心可以臨時(shí)性承接所有的流量。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容