Spring Cloud學習(1)——單節點Eureka Server

閱讀的書籍爲《Spring Cloud 微服務實戰》。

基本概念

服務治理

服務治理可以說是微服務架構中最爲核心和基礎的模塊,主要用來實現各個微服務實例的自動化註冊與發現。

早期微服務系統中,服務不多,可以通過靜態配置來完成服務的調用。但是隨着業務的發展,系統功能越來越複雜,相應的微服務應用也不斷增加,靜態配置就越來越難以維護,故需要實現微服務實例的自動化註冊與發現

服務註冊

在服務治理框架中,通常都會構建一個註冊中心,每個服務單元都向註冊中心登記自己提供的服務,將主機與端口號、版本號、通信協議等一些附加信息告知註冊中心,註冊中心按服務名分類組織服務清單。
服務註冊中心還需要以心跳的方式去監測清單中的服務是否可用,若不可用,從服務清單中剔除,達到排除故障服務的效果。

服務發現

在服務治理框架下運作,服務間的調用不再通過指定具體的實例地址來實現,而是通過向服務名發起請求調用實現。

Eureka服務端

即爲服務註冊中心。
如果以集羣模式部署,當集羣中有分片出現故障時,Eureka就會轉入自我保護模式。它允許在分片故障期間繼續提供服務的發現與註冊,當故障分片恢復運行的時候,集羣中的其他分片會把它們的狀態再次同步回來。
不同可用區域的服務註冊中心通過異步模式互相複製各自的狀態,這意味着任意給定的時間點,每個實例關於所有服務的狀態是有細微差別的

Eureka客戶端

主要處理服務的註冊與發現,在應用程序運行時,客戶端向註冊中心註冊自身提供的服務並週期性地發送心跳來更新它的服務租約。
同時它也能從服務端查詢當前註冊的服務信息,並把它們緩存到本地並週期性地刷新服務狀態。

搭建服務註冊中心

  • 使用IDEA搭建一個基礎的Spring Boot工程,在pom.xml中引入Eureka必要的依賴內容。
  • 通過@EnableEurekaServer註解啓動一個服務註冊中心。如下:
@EnableEurekaServer
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
  • 在默認設置下,該服務註冊中心也會將自己作爲客戶端來嘗試註冊它自己,需要禁用它的客戶端註冊行爲。在application.properties中增加如下配置:
server.port=1111
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
#關閉保護機制
eureka.server.enable-self-preservation=false

eureka.client.register-with-eureka設置爲false代表不向註冊中心註冊自己。
eureka.client.fetch-registry設置爲false,代表不需要去檢索服務。
eureka.server.enable-self-preservation=false,代表關閉保護機制。

Eureka會因爲15分鐘內超過85%的實例丟失心跳而觸發保護機制,觸發保護機制後,Eureka Server會將當前實例註冊信息保護起來,讓這些實例不會過期。但在保護期內,可能實例出現了問題,那麼客戶端就很容易拿到實際已經不存在的實例,出現調用失敗的情況。生產環境,需要客戶端有容錯機制,比如請求重試、斷路器等。在此,本地調試時關閉保護機制,確保註冊中心可以將不可用的實例正確剔除。

這裏寫圖片描述
其中Instances currently registered with Eureka欄爲空,說明該註冊中心還沒有註冊任何服務。

註冊服務提供者

  • 使用IDEA重新搭建一個基礎的Spring Boot工程,在pom.xml中引入Eureka必要的依賴內容。
  • 主類中加上@EnableDiscoveryClient註解,激活Eureka中的DiscoveryClient實現。
package com.example.helloworld;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class HelloworldApplication {
    public static void main(String[] args) {
        SpringApplication.run(HelloworldApplication.class, args);
    }
}
  • 在該工程的主類同級目錄下創建一個RESTful API實現代碼。通過注入DiscoveryClient對象,在日誌中打印出服務的相關內容。
package com.example.helloworld.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.apache.log4j.Logger;
import java.util.List;
@RestController
public class HelloworldController {
    private final Logger log = Logger.getLogger(getClass());
    @Autowired
    private DiscoveryClient discoveryClient;
    @RequestMapping(value = "/helloworld", method = RequestMethod.GET)
    public String helloworld() {
        System.out.println("discoveryClient.getServices().size() = " + discoveryClient.getServices().size());
        for (String s : discoveryClient.getServices()) {
            System.out.println("services " + s);
            List<ServiceInstance> serviceInstances = discoveryClient.getInstances(s);
            for (ServiceInstance si : serviceInstances) {
                System.out.println("    services:" + s + ":getHost()=" + si.getHost());
                System.out.println("    services:" + s + ":getPort()=" + si.getPort());
                System.out.println("    services:" + s + ":getServiceId()=" + si.getServiceId());
                System.out.println("    services:" + s + ":getUri()=" + si.getUri());
                System.out.println("    services:" + s + ":getMetadata()=" + si.getMetadata());
            }
        }
        return "hello world";
    }
}
  • 在application.properties中增加如下配置:
spring.application.name=hello-world-service
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
  • 啓動服務

可以在該服務的控制檯看到如下輸出:
這裏寫圖片描述
可以在服務註冊中心的控制檯看到如下輸出:
這裏寫圖片描述
訪問Eureka的信息面板
這裏寫圖片描述

可以在註冊服務的控制檯查看到它從服務註冊中心獲取到的服務相關信息。
這裏寫圖片描述

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