小白的學習筆記——eureka註冊中心

superNeumann發表於2024-03-18

在服務呼叫關係中,會有兩個不同的角色:

服務提供者:一次業務中,被其它微服務呼叫的服務。(提供介面給其它微服務)
服務消費者:一次業務中,呼叫其它微服務的服務。(呼叫其它微服務提供的介面)

但是,服務提供者與服務消費者的角色並不是絕對的,而是相對於業務而言。
如果服務A呼叫了服務B,而服務B又呼叫了服務C,服務B是提供者還是消費者??

  • 對於A呼叫B的業務而言:A是服務消費者,B是服務提供者
  • 對於B呼叫C的業務而言:B是服務消費者,C是服務提供者

因此,服務B既可以是服務提供者,也可以是服務消費者

在之前的例子中,user-service是服務提供者,order-service是服務消費者。
現在假設我們的服務提供者user-service部署了多個例項:
image
image
image
那麼現在就出現新的問題了:

  • order-service在發起遠端呼叫的時候,該如何得知user-service例項的ip地址和埠?
  • 有多個user-service例項地址,order-service呼叫時該如何選擇?
  • order-service如何得知某個user-service例項是否依然健康,是不是已經當機?

透過SpringCloud的註冊中心Eureka就可以解決這些問題。

Eureka架構

在Eureka架構中,微服務角色有兩類:

EurekaServer:服務端,註冊中心

  • 記錄服務資訊
  • 心跳監控

EurekaClient:客戶端

  • Provider:服務提供者,如例子中的 user-service
    • 註冊自己的資訊到EurekaServer
    • 每隔30秒向EurekaServer傳送心跳
  • consumer:服務消費者,如例子中的 order-service
    • 根據服務名稱從EurekaServer拉取服務列表
    • 基於服務列表做負載均衡,選中一個微服務後發起遠端呼叫

這樣我就可以回答前面幾個問題了

問題1:order-service在發起遠端呼叫的時候,該如何得知user-service例項的ip地址和埠?
答:

  1. user-service服務例項啟動後,將自己的資訊註冊到eureka-server(EurekaServer)。
  2. eureka-server儲存服務名稱到服務例項地址列表的對映關係
  3. order-service根據服務名稱,拉取例項地址列表。這個叫服務發現或服務拉取

問題2:有多個user-service例項地址,order-service呼叫時該如何選擇?
答:

  1. order-service從例項列表中利用負載均衡演算法選中一個例項地址
  2. 向該例項地址發起遠端呼叫

問題3:order-service如何得知某個user-service例項是否依然健康,是不是已經當機?
答:

  1. user-service會每隔一段時間(預設30秒)向eureka-server發起請求,報告自己狀態,稱為心跳
  2. 當超過一定時間沒有傳送心跳時,eureka-server會認為微服務例項故障,將該例項從服務列表中剔除
  3. order-service拉取服務時,就能將故障例項排除了

搭建EurekaServer

一、註冊服務端
首先要註冊中心服務端:eureka-server,這必須是一個獨立的微服務。

二、引入依賴
建立好eureka-server服務後,需要引入SpringCloud為eureka提供的starter依賴:

    <dependency><!-- eureka服務端-->
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>

三、編寫啟動類
給eureka-server服務編寫一個啟動類,一定要新增一個@EnableEurekaServer註解,開啟eureka的註冊中心功能:

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

四、編寫配置檔案
編寫一個application.yml檔案,內容如下:

server:
  port: 10086
spring:
  application:
    name: eureka-server
eureka:
  client:
    service-url: 
      defaultZone: http://127.0.0.1:10086/eureka

五、測試
啟動微服務,然後在瀏覽器訪問:http://127.0.0.1:10086 ,就可以看到下面頁面:image

服務註冊

接下來,將user-service註冊到eureka-server中去。

一、引入依賴
在user-service的pom檔案中,引入下面的eureka-client依賴:

 <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 </dependency>

二、修改配置檔案
在user-service中,修改application.yml檔案,新增服務名稱、eureka地址:

spring:
  application:
    name: userservice
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka

三、啟動多個user-service例項
為了模擬啟動了多個user-service例項,可以新增一個SpringBoot的啟動配置,再啟動一個user-service,需要修改埠號。

在啟動兩個user-service例項後,檢視eureka-server管理頁面:image

服務發現

將order-service的邏輯修改:向eureka-server拉取user-service的資訊,實現服務發現。

一、引入依賴
在order-service的pom檔案中,引入下面的eureka-client依賴:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

二、修改配置檔案
在order-service中,修改application.yml檔案,新增服務名稱、eureka地址:

spring:
  application:
    name: orderservice
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka

三、服務拉取和負載均衡
去eureka-server中拉取user-service服務的例項列表,並且實現負載均衡。

在order-service的RestTemplateConfig類中,給RestTemplate這個Bean新增一個@LoadBalanced註解:

@Configuration
public class RestTemplateConfig {

    @Bean
    @LoadBalanced   //標識次方法發起的http請求會被Ribbon攔截
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

修改order-service服務中的OrderService類中的queryOrderById方法。修改訪問的url路徑,用服務名代替ip、埠:

點選檢視程式碼

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查詢訂單
        Order order = orderMapper.findById(orderId);
        // 2.利用RestTemplate發起http請求,查詢使用者
        //url路徑
        String url = "http://userserices/user/" +  order.getUserId();
        //傳送http請求,實現遠端呼叫
        User user = restTemplate.getForObject(url, User.class);  //反序列化
        // 3.封裝user資訊
        order.setUser(user);
        // 4.返回
        return order;
    }
}

spring會自動幫助我們從eureka-server端,根據userservice這個服務名稱,獲取例項列表,而後完成負載均衡。

總結:

  1. 搭建EurekaServer

    • 引入eureka-server依賴
    • 新增@EnableEurekaServer註解
    • 在application.yml中配置eureka地址
  2. 服務註冊

    • 引入eureka-client依賴
    • 在application.yml中配置eureka地址
  3. 服務發現

    • 引入eureka-client依賴
    • 在application.yml中配置eureka地址
    • 給RestTemplate新增@LoadBalanced註解
    • 用服務提供者的服務名稱遠端呼叫

相關文章