SpringCloud(1)-Eureka相關配置

marigo發表於2024-05-19

1.新建Module-註冊中心

image.png|338
作為註冊中心

1.1配置 pom.xml

<!-- 引入 eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

1.2配置application.yml

server:
  port: 9001

eureka:
  instance:
    hostname: localhost # Eureka 服務端的主機名
  client:
    register-with-eureka: false # 是否將自己註冊到 Eureka 服務端,表明自己是一個 Eureka 註冊中心,職責是維護服務例項,並不需要註冊自己
    fetch-registry: false # 是否從 Eureka 服務端獲取註冊資訊
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #設定與 eureka server 互動的模組,查詢服務和註冊服務都需要依賴這個地址

1.3新建啟動類

@SpringBootApplication
@EnableEurekaServer //開啟Eureka服務
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}

1.4測試

瀏覽器訪問 http://localhost:9001/
image.png

2.服務提供者

配置服務提供者的Module資訊

2.1 服務提供者引入eureka-client依賴

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

2.2 配置application.yml

eureka:
  client:
    register-with-eureka: true # 將自己註冊到 Eureka 服務端
    fetch-registry: true # 是否從 Eureka 服務端獲取註冊資訊,預設為true,叢集必須為true,才能配合負載均衡
    service-url:
      defaultZone: http://localhost:9001/eureka/ #設定與 eureka server 互動的模組,查詢服務和註冊服務都需要依賴這個地址

2.3 設定啟動類

@SpringBootApplication
@EnableEurekaClient //開啟Eureka客戶端
public class MemberApplication {
    public static void main(String[] args) {
        SpringApplication.run(MemberApplication.class, args);
    }
}

2.4 測試

啟動客戶端的啟動類後,訪問 localhost:9001,會看到新註冊的例項
image.png
例項的名稱是怎麼確定的呢,這是在我們的application.yml自定義的

spring:  
  application:  
    name: member-service-provider #配置應用的名稱

3.服務消費者

配置服務消費者的Module資訊

3.1 引入依賴

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

3.2 配置 application.yml

eureka:
  client:
    register-with-eureka: true # 將自己註冊到 Eureka 服務端
    fetch-registry: true # 是否從 Eureka 服務端獲取註冊資訊,預設為true,叢集必須為true,才能配合負載均衡
    service-url:
      defaultZone: http://localhost:9001/eureka/ #表示關聯的eureka服務端地址,註冊/拉取服務資訊

3.3 配置啟動類

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

3.4 測試

啟動,測試
image.png

4.Eureka自我保護模式

在以上測試中,我們會發現eureka頁面中有以下紅色提示:
image.png

  • 預設情況下EurekaClient定時向EurekaServer端傳送心跳包
  • 如果Eureka在server端在一定時間內(預設90秒)沒有收到EurekaClient傳送心跳包便會直接從服務註冊列表中剔除該服務
  • 如果Eureka 開啟了自我保護模式/機制, 那麼在短時間(90秒中)內丟失了大量的服務例項心跳,這時候EurekaServer會開啟自我保護機制,不會剔除該服務(該現象可能出現在如果網路不通或者阻塞) 因為客戶端還能正常傳送心跳,只是網路延遲問題,而保護機制是為了解決此問題而產生的
  • 可以在eureka-server端禁用自我保護模式,設定application.yml
  server:
    enable-self-preservation: false # 關閉自我保護機制
    eviction-interval-timer-in-ms: 6000 # 設定心跳檢測的時間間隔,預設是60秒
  • 設定eureka-client端 application.yml
eureka:
  instance:
    lease-expiration-duration-in-seconds: 5 # Eureka服務端在收到最後一次心跳後等待時間上限,單位為秒,預設90秒,超過這個時間服務端會將例項從註冊列表中剔除
    lease-renewal-interval-in-seconds: 2 # eureka客戶端向服務端傳送心跳的時間間隔,單位為秒,預設30秒

5.搭建EurekaServer叢集

微服務RPC遠端服務呼叫最核心的是實現高可用,如果註冊中心只有1個,那麼一旦出現故障,導致整個服務環境都不可用,解決方案就是搭建Eureka註冊中心叢集,並且實現負載均衡和故障容錯。

5.1 新建Module-第二個註冊中心

配置過程如第一個註冊中心,區別是appication.yml的配置:

server:
  port: 9002

eureka:
  instance:
    hostname: eureka9002.com # 區別於9001的註冊中心
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://eureka9001:9001/eureka/ # 相互註冊

因為是相互註冊,所以把第一個註冊中心的hostname改成了eureka9001.com

server:
  port: 9001

eureka:
  instance:
    hostname: eureka9001.com # Eureka 服務端的主機名
  client:
    register-with-eureka: false 
    fetch-registry: false 
    service-url:
      defaultZone: http://eureka9002.com:9002/eureka/ 

5.2 設定系統hosts

C:\Windows\System32\drivers\etc\hosts 加入

#eureka 主機名和 ip 對映
127.0.0.1 eureka9001.com
127.0.0.1 eureka9002.com

5.3 測試

瀏覽器開啟對應的地址,會發現互相指向,按理說配置好hosts檔案後,我應該訪問eureka9001.com/9001eureka9002.com/9002,但是沒能成功,先用localhost:9001localhost:9002 進行測試
image.png|199
image.png|178

5.4 服務提供者註冊到Eureka叢集

註冊到多個eureka即可
image.png
啟動後,進行測試,也就是到localhost:9001localhost:9002 檢視註冊成功

5.5 服務消費者註冊到Eureaka叢集

註冊到多個eureka
image.png

6.搭建服務提供方叢集

Eureka已經搭建好叢集,實際中服務提供方也是會有多個形成一個叢集

6.1 新建一個新的服務提供方

複製貼上第一個服務提供方的程式碼,唯一要必須修改的地方是埠號,我們設定成10003,其中spring.application.name 必須統一,因為要作為一個叢集提供服務
進行測試:
image.png

7.服務消費者使用服務叢集

7.1 修改Controller

原先的Controller如下,具體來說,MEMBER_SERVICE_PROVIDER_URL被固定了:

@RestController
@Slf4j
public class MemberConsumerController {
    public static final String MEMBER_SERVICE_PROVIDER_URL = "http://localhost:10002";
    @Resource
    private RestTemplate restTemplate;
    @PostMapping("/member/consumer/save")
    public Result<Member> save(Member member) {
        return restTemplate.postForObject(MEMBER_SERVICE_PROVIDER_URL + "/member/save", member, Result.class);
    }

    @GetMapping("/member/consumer/get/{id}")
    public Result<Member> get(@PathVariable("id") Long id) {
        return restTemplate.getForObject(MEMBER_SERVICE_PROVIDER_URL + "/member/get/" + id, Result.class);
    }

}

我們修改成服務提供者[叢集]的註冊別名:
image.png|407
修改後:

public static final String MEMBER_SERVICE_PROVIDER_URL = "http://MEMBER-SERVICE-PROVIDER";

因為我們現在的服務提供者是叢集,所以需要使用負載均衡,加上註解@LoadBalanced賦予RestTemplate負載均衡的能力, [即選擇 MEMBER-SERVICE-PROVIDER 某一個服務訪問]

@Configuration
public class CustomizationBean {

    // 注入 RestTemplate
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

7.2 測試

啟動服務消費者,進行測試
image.png|500
再傳送一次
image.png|500
會發現當前負載均衡的策略是輪詢演算法

8.獲取Eureka Server服務註冊資訊

以服務消費者為例獲取eureka的服務註冊資訊

8.1 修改Controller

我們在cotroller加入程式碼

    @Resource
    private DiscoveryClient discoveryClient;
    @GetMapping("/member/consumer/discovery")
    public Object discovery() {
        List<String> services = discoveryClient.getServices();
        for (String element : services) {
            System.out.println("======== 服 務 名 " + element +
                    "=======================");
            List<ServiceInstance> instances = discoveryClient.getInstances(element);
            for (ServiceInstance instance : instances) {
                System.out.println(instance.getServiceId() + "\t" + instance.getHost() + "\t" + instance.getPort() + "\t" + instance.getUri());
            }
        }
        return this.discoveryClient;
    }

其中,DiscoverClient引入下面包的:
image.png

8.2 修改啟動類

新增@EnableDiscoveryClient註解

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

8.3 測試

啟動後,瀏覽器訪問http://localhost/member/consumer/discovery
瀏覽器返回:

{
  "services": [
    "member-service-consumer",
    "member-service-provider"
  ],
  "order": 0
}

後臺返回:
image.png

相關文章