註冊中心-Eureka

Eureka註冊中心-介紹

又稱服務中心,管理各類服務功能包括服務的註冊、發現、熔斷、負載、降級等。java

使用背景

  • 任何一個服務都不能直接去掉用,都須要經過註冊中心來調用。經過服務中心來獲取服務你不須要關注你調用的項目IP地址,由幾臺服務器組成,每次直接去服務中心獲取可使用的服務去調用既可。
  • 因爲各類服務都註冊到了服務中心,就有了不少高級功能條件。
    好比幾臺服務提供相同服務來作客戶端負載均衡(Ribbon);
    監控服務器調用成功率來作斷路器(Hystrix),移除服務列表中的故障點;
    監控服務調用時間來對不一樣的服務器設置不一樣的權重、智能路有(Zuul)等等;

SpringCloud -Eureka註冊中心

Spring Cloud 封裝了 Netflix 公司開發的 Eureka 模塊來實現服務註冊和發現。Eureka 採用了 C-S 的設計架構。
Eureka Server 做爲服務註冊功能的服務器,它是服務註冊中心。而系統中的其餘微服務,使用 Eureka 的客戶端鏈接到 Eureka Server,並維持心跳鏈接。這樣系統的維護人員就能夠經過 Eureka Server 來監控系統中各個微服務是否正常運行。Spring Cloud 的一些其餘模塊(好比Zuul)就能夠經過 Eureka Server 來發現系統中的其餘微服務,並執行相關的邏輯。web

Eureka由兩個組件組成:Eureka服務器和Eureka客戶端。spring

  • Eureka服務器用做服務註冊服務器。
  • Eureka客戶端是一個java客戶端,用來簡化與服務器的交互、做爲輪詢負載均衡器,並提供服務的故障切換支持。
  • Netflix在其生產環境中使用的是另外的客戶端,它提供基於流量、資源利用率以及出錯狀態的加權負載均衡。

Eureka架構圖

上圖簡要描述了Eureka的基本架構,由3個角色組成:服務器

一、Eureka Server架構

  • Eureka Server 做爲一個獨立的部署單元,以 REST API 的形式爲服務實例提供了註冊、管理和查詢等操做。同時,Eureka Server 也爲咱們提供了可視化的監控頁面,能夠直觀地看到各個 Eureka Server 當前的運行狀態和全部已註冊服務的狀況。

二、Service Providerapp

  • 服務提供方
  • 將自身服務註冊到Eureka,從而使服務消費方可以找到

三、Service Consumer負載均衡

  • 服務消費方
  • 從Eureka獲取註冊服務列表,從而可以消費服務

上手-Eureka Server

1.建立一個基礎的Spring Boot工程,pom中添加依賴ide

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
   <!-- 引入Eureka-server相關jar-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
    </dependency>
    
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Brixton.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
         </dependency>
    </dependencies>
</dependencyManagement>

2.啓動代碼中添加@EnableEurekaServer註解spring-boot

@SpringBootApplication
@EnableEurekaServer
public class SpringCloudEurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudEurekaApplication.class, args);
    }
}

3.默認設置下,該服務註冊中心也會將本身做爲客戶端來嘗試註冊它本身,因此咱們須要禁用它的客戶端註冊行爲,在application.properties添加如下配置:微服務

spring.application.name=Eureka Server

server.port=7001
#表示是否將本身註冊到Eureka Server,默認爲true
eureka.client.register-with-eureka=false  

#表示是否從Eureka Server獲取註冊信息,默認爲true
eureka.client.fetch-registry=false 

#設置與Eureka Server交互的地址,查詢服務和註冊服務都須要依賴這個地址。默認是http://localhost:8761/eureka ;多個地址可以使用 , 分隔
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/

application.yml形式(下面再也不給出)

eureka:
    client:
        fetch-registry: 
        register-with-eureka: false
        serviceUrl:
            defaultZone: http://localhost:${server.port}/eureka/
server:
    port: 7001
spring:
    application:
        name: Eureka Server

啓動工程後,訪問:http://localhost:7001/ 能夠看到沒有任何服務

上手-Eureka Client

建立提供服務的客戶端,並向服務註冊中心註冊本身。實現一個RESTful API,經過傳入兩個參數a和b,最後返回a + b的結果

1.建立一個基礎的Spring Boot工程,pom中添加依賴

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <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</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Brixton.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
    </dependencies>
</dependencyManagement>

2.實現/add請求處理接口,經過DiscoveryClient對象,在日誌中打印出服務實例的相關內容

@RestController
public class ComputeController {

    private final Logger logger = Logger.getLogger(getClass());

    @Autowired
    private DiscoveryClient client;

    @RequestMapping(value = "/add" ,method = RequestMethod.GET)
    public Integer add(@RequestParam Integer a, @RequestParam Integer b) {
        ServiceInstance instance = client.getLocalServiceInstance();
        Integer r = a + b;
        logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r);
        return r;
    }

}

3.啓動代碼中添加@EnableDiscoveryClient註解,該註解能激活Eureka中的DiscoveryClient實現,才能實現Controller中對服務信息的輸出。

@SpringBootApplication
@EnableEurekaServer
public class SpringCloudEurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudEurekaApplication.class, args);
    }
}

4.在application.properties添加如下配置:

#能夠指定微服務的名稱後續在調用的時候只須要使用該名稱就能夠進行服務的訪問。
spring.application.name=Eureka Client   

server.port=8001    #端口
#屬性對應服務註冊中心的配置內容,指定服務註冊中心的位置
eureka.client.serviceUrl.defaultZone=http://localhost:7001/eureka/

啓動工程後,再次訪問: http://localhost:7001/ 能夠看到定義的服務被註冊了

中止服務

1.直接停掉服務。

默認狀況下,若是Eureka Server在90秒沒有收到Eureka客戶的續約,它會將實例從其註冊表中刪除。但這種作法的很差之處在於, 客戶端已經中止了運行,但仍然在註冊中心的列表中。 雖然經過必定的負載均衡策略或使用熔斷器可讓服務正常進行,但有沒有方法讓註冊中心立刻知道服務已經下線呢?

2.爲了讓註冊中心立刻知道服務要下線, 能夠向eureka 註冊中心發送delete請求

格式爲 /eureka/apps/{application.name}(application的name)/劃紅線的地址

劃紅線的地址   eureka.client.instance.instance-id

下面是下線一個hello-service的例子。

下圖是用postman 發送delete請求

值得注意的是,Eureka客戶端每隔一段時間(默認30秒)會發送一次心跳到註冊中心續約。若是經過這種方式下線了一個服務,而沒有及時停掉的話,該服務很快又會回到服務列表中。

因此,能夠先停掉服務,再發送請求將其從列表中移除。

http://127.0.0.1:7001/eureka/apps/config-server/WINDOWS-61L7RBP:config-server:8769

3.客戶端主動通知註冊中心下線

若是你的eureka客戶端是是一個spring boot應用,能夠經過調用如下代碼通知註冊中心下線。

DiscoveryManager.getInstance().shutdownComponent();

例子以下,在eureka client 中

@RestController
public class HelloController {
    @Autowired
    private DiscoveryClient client;
 
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String index() {
        java.util.List<ServiceInstance> instances = client.getInstances("hello-service");       
        return "Hello World";
    }
    
    @RequestMapping(value = "/offline", method = RequestMethod.GET)
    public void offLine(){
        DiscoveryManager.getInstance().shutdownComponent();
    }   
}

GET 請求 127.0.0.1:6020/offline

相關文章
相關標籤/搜索