天天看點

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

1、Eureka基礎知識

1.1 什麼是服務治理

Spring Cloud封裝了Netflix公司開發的 Eureka 子產品來實作服務治理;

在傳統的RPC遠端過程調用架構中,管理每個服務與服務之間的依賴關系比較複雜,是以需要使用服務治理。管理服務之間的依賴關系,實作服務的調用,負載均衡和容錯等,實作服務發現與注冊。

1.2 什麼是服務注冊與發現

Eureka 采用了 C/S 的設計架構, Eureka Server 作為服務注冊功能的伺服器,它是服務注冊中心,而系統中的其他微服務,使用Eureka的用戶端連接配接到Eureka Server 并維持心跳連接配接。這樣系統的維護人員就可以通過Eureka Server 來監控系統中各個微服務是否正常運作。

在服務注冊與發現中,有一個注冊中心。當伺服器啟動的時候,會把目前自己伺服器的資訊 比如:服務位址、通訊位址等以别名方式注冊到中心上。另一方(消費者|服務提供者)就以該别名的方式去注冊中心上擷取到實際的服務通訊位址,然後再實作本地RPC調用。RPC遠端調用架構的核心設計思想:在于注冊中心,因為注冊中心管理每個服務之間的一個依賴關系(服務治理概念)。再任何RPC遠端架構中,都會有一個注冊中心(存放服務位址相關資訊(接口位址))

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

1.3 Eureka的兩元件

Eureka包含兩元件:Eureka Server 和 Eureka Client

1.3.1 EurekaServer

Eureka Server 提供服務注冊服務。各個微服務節點通過配置啟動後,會在 Eureka Server中進行注冊;這樣Eureka Server中的系統資料庫中将會存儲所有可用服務節點的資訊,服務節點的資訊可以在界面中直覺看到。

1.3.2 Eureka Client

Eureka Client 通過注冊中心進行通路其他服務,是一個Java用戶端;用于簡化 Eureka Server 的互動。用戶端同時也具備一個内置的,使用輪詢(round-robin)負載算法的負載均衡器。在應用啟動後,将會向Eureka Server 發送心跳(預設周期30秒)。如果 Eureka Server 在多個心跳周期内,沒有接收到某個節點的心跳, Eureka Server 将會從服務系統資料庫中把這個服務節點移除(預設90秒)。

2、單機Eureka建構

2.1 建立服務注冊中心子產品:cloud-eureka-server7001

2.1.1 建立Module

跟之前的建立訂單和支付子產品一樣的方式建立一個Module,名稱為 cloud-eureka-server7001 。

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

2.1.2 改pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud2020</artifactId>
        <groupId>com.zdw.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-eureka-server7001</artifactId>
    <description>eureka服務注冊中心的服務端</description>

    <dependencies>
        <!--eureka-server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>com.zdw.springcloud</groupId>
            <artifactId>cloud-api-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--一般為通用配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
           

在以前,Eureka的依賴是沒有區分用戶端和服務端的。

<!--eureka-server以前的坐标-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
           

2.1.3 寫yml

server:
  port: 7001
spring:
  application:
    name: cloud-eureka-service
eureka:
  instance:
    # eureka服務端的執行個體名稱 # 單機
    hostname: localhost
  client:
    # false表示不向注冊中心注冊自己
    register-with-eureka: false
    # false表示自己端就是注冊中心,我的職責就是維護服務執行個體,并不需要檢索服務
    fetch-registry: false
    service-url:
      # 設定與Eureka Server互動的位址查詢服務和注冊服務都需要依賴這個位址  # 單機
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
           

2.1.4 主啟動

package com.zdw.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer  //表示這是一個Eureka Server 端
public class EurekaMain7001 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaMain7001.class,args);
    }
}
           

注意:@EnableEurekaServer : 表示這是一個Eureka Server 端,這個不能忘記

2.1.5 測試

啟動eureka7001,浏覽器通路:http://localhost:7001/

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

No application available沒有服務被發現 因為沒有注冊服務進來目前不可能有服務被發現。

2.2 把payment8001注冊到Eureka7001

2.2.1 改pom

修改cloud-provider-payment8001的pom檔案,引入Eureka Client的依賴:

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

2.2.2 改yml

修改 cloud-provider-payment8001的application.yml檔案,添加Eureka的配置:

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      # 單擊版
      defaultZone: http://localhost:7001/eureka
           

eureka 是頂格寫的。

2.2.3 修改主啟動類

給主啟動類加上注解:@EnableEurekaClient 這是一個Eureka的client端

package com.zdw.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient  //這是一個Eureka的client端
public class PaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8001.class,args);
    }
}
           

2.2.4 測試

啟動payment8001,浏覽器通路 : http://localhost:7001/ ,檢視cloud-provider-payment8001是否注冊到了Eureka注冊中心:

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

可以看到界面多了一個 CLOUD-PAYMENT-SERVICE(對應是application.yml中的spring.application.name=cloud-eureka-service) 應用,并且是UP狀态,同時我們通路之前的:http://localhost:8001/payment/get/1 也可以通路到資料。

2.3 把order80注冊到Eureka7001

2.3.1 改pom

修改cloud-consumer-order80服務的pom檔案,添加eureka-client 依賴:

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

2.3.2 改yml

修改cloud-consumer-order80服務的application.yml檔案,添加Eureka的配置:

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka
           

2.3.3 修改主啟動類

主啟動類上添加注解:@EnableEurekaClient

package com.zdw.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient  //這是一個Eureka的client端
public class OrderMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderMain80.class,args);
    }
}
           

2.3.4 測試

啟動order80,浏覽器通路:http://localhost:7001/

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

2.4 讓order80通過Eureka通路payment8001

2.4.1 改OrderController的通路位址

上面,我們已經把order80和payment8001注冊到了Eureka注冊中心,但是此時,我們通路:http://localhost/consumer/payment/get/1 的時候,并不是走的注冊中心,因為我們之前的OrderController中是這樣的:

package com.zdw.springcloud.controller;

@RestController
@Slf4j
public class OrderController {

    //支付服務的位址
    public static final String PAYMENT_URL = "http://localhost:8001";
}
           

我們是寫死了8001的位址:public static final String PAYMENT_URL = “http://localhost:8001”; 現在我們改成 通過payment8001注冊到Eureka的别名:CLOUD-PAYMENT-SERVICE 來通路 payment8001.

@RestController
@Slf4j
public class OrderController {
    //支付服務的位址
    //public static final String PAYMENT_URL = "http://localhost:8001";
    public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
}
           

2.4.2 修改OrderConfig配置類

在配置類OrderConfig中,當注冊RestTemplate的時候,在方法上添加注解:@LoadBalanced

import org.springframework.cloud.client.loadbalancer.LoadBalanced;

@Configuration
public class OrderConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
           

2.4.3 測試

浏覽器通路:http://localhost/consumer/payment/get/1 可以正常通路到資料,說明我們是成功的

3、叢集Eureka建構

3.1 叢集Ereuka的原理

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

3.2 Eureka叢集環境搭建

3.2.1 搭建Eureka7002

參照cloud-eureka-server7001建立一個新的Module:cloud-eureka-server7002,它和cloud-eureka-server7001的不同展現端口和yml的配置;

每個Eureka之間的關系是 :互相注冊,互相守望。也就是自己要關聯叢集中的其他Eureka。

1、建module

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

2、改pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud2020</artifactId>
        <groupId>com.zdw.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-eureka-server7002</artifactId>
    <description>eureka服務注冊中心的服務端</description>
    <dependencies>
        <!--eureka-server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>com.zdw.springcloud</groupId>
            <artifactId>cloud-api-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--一般為通用配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>
           

3、寫yml

server:
  port: 7002
spring:
  application:
    name: cloud-eureka-service
eureka:
  instance:
    # eureka服務端的執行個體名稱 # 單機
    # hostname: localhost
    hostname: eureka7002.com
  client:
    # false表示不向注冊中心注冊自己
    register-with-eureka: false
    # false表示自己端就是注冊中心,我的職責就是維護服務執行個體,并不需要檢索服務
    fetch-registry: false
    service-url:
      # 設定與Eureka Server互動的位址查詢服務和注冊服務都需要依賴這個位址  # 單機
      # defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      # 互相注冊
      defaultZone: http://eureka7001.com:7001/eureka/
           

注意:hostname: eureka7002.com 這裡不再是localhost,因為我們是一台實體機,上面要運作兩個Eureka,是以需要修改 C:\Windows\System32\drivers\etc 目錄下面的hosts檔案:添加下面兩行配置,把127.0.0.1映射到eureka7001.com和eureka7002.com

# SpringCloud
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
           

是以,cloud-eureka-server7002的yml檔案也要修改:

server:
  port: 7001
spring:
  application:
    name: cloud-eureka-service
eureka:
  instance:
    # eureka服務端的執行個體名稱 # 單機
    # hostname: localhost
    hostname: eureka7001.com
  client:
    # false表示不向注冊中心注冊自己
    register-with-eureka: false
    # false表示自己端就是注冊中心,我的職責就是維護服務執行個體,并不需要檢索服務
    fetch-registry: false
    service-url:
      # 設定與Eureka Server互動的位址查詢服務和注冊服務都需要依賴這個位址  # 單機
      # defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      # 互相注冊
      defaultZone: http://eureka7002.com:7002/eureka/
           

4、主啟動

package com.zdw.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

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

@EnableEurekaServer 記得加上這個注解

5、測試

啟動cloud-eureka-server7001和cloud-eureka-server7002,浏覽器分别通路:http://localhost:7001/和http://localhost:7002/:

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護
SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

這就達到了互相注冊, 互相守望的效果

4、把payment8001和order80注冊到上面的eureka叢集

4.1 把payment8001注冊到上面的eureka叢集

修改cloud-provider-payment8001的yml檔案的defaultZone的值:

server:
  port: 8001
spring:
  application:
    name: cloud-payment-service
  datasource:
    # 目前資料源操作類型
    type: com.alibaba.druid.pool.DruidDataSource
    # mysql驅動類
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cloud2020?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: 123

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      # 單擊版
      # defaultZone: http://localhost:7001/eureka
      # 叢集版
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
  instance:
    instance-id: payment8001
    # 通路路徑可以顯示ip位址
    prefer-ip-address: true

mybatis:
  mapper-locations: classpath*:mapper/*.xml
  type-aliases-package: com.zdw.springcloud.entities
           

4.2 把order80注冊到上面的eureka叢集

修改cloud-consumer-order80的yml檔案的defaultZone的值:

server:
  port: 80
spring:
  application:
    name: cloud-consumer-order

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      # defaultZone: http://localhost:7001/eureka
      # 叢集版
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
  instance:
    instance-id: order80
    # 通路路徑可以顯示ip位址
    prefer-ip-address: true
           

4.3 測試

首先啟動先要啟動EurekaServer,7001/7002服務,然後啟動cloud-provider-payment8001,最後啟動 cloud-consumer-order80

浏覽器通路:http://localhost:7001/

浏覽器通路:http://localhost:7002/

浏覽器通路:http://localhost:8001/payment/get/1

浏覽器通路:http://localhost/consumer/payment/get/1

不出意外的話,應該都是正常的。

5、payment支付子產品叢集搭建

服務提供方一般都是叢集配置的,是以我們可以參照 cloud-provider-payment8001 建立一個新子產品:cloud-provider-payment8002,然後也把它注冊到Eureka 注冊中心,配置好負載均衡之後,order80就可以按照預設的輪詢機制,通路8001和8002兩個服務了。

5.1 建立cloud-provider-payment8002

cloud-provider-payment8002 的建立方式和cloud-provider-payment8001完全是一樣的(包括業務代碼,MyBatis的Mapper檔案等),可以照抄,是以相關的代碼和pom配置可以去 cloud-provider-payment8001 拷貝;我們隻要修改yml配置檔案和主啟動類就差不多了。

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

5.2 改yml

server:
  port: 8002
spring:
  application:
    name: cloud-payment-service
  datasource:
    # 目前資料源操作類型
    type: com.alibaba.druid.pool.DruidDataSource
    # mysql驅動類
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cloud2020?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: 123

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      # 單擊版
      # defaultZone: http://localhost:7001/eureka
      # 叢集版
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
  instance:
    instance-id: payment8002
    # 通路路徑可以顯示ip位址
    prefer-ip-address: true

mybatis:
  mapper-locations: classpath*:mapper/*.xml
  type-aliases-package: com.zdw.springcloud.entities
           

主要是port 和 instance-id 不同

5.3 主啟動

package com.zdw.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient  //這是一個Eureka的client端
public class PaymentMain8002 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8002.class,args);
    }
}
           

@EnableEurekaClient 注解不能少

6、負載均衡測試

上面我們已經建立了兩個Eureka,兩個支付子產品:8001和8002,還有一個用戶端訂單子產品order80,現在我們要測試Eureka的負載均衡。首先要注意的是,在order80 的配置類OrderConfig中,注冊RestTemplate到IOC容器的時候,一定要加上注解:@LoadBalanced(預設的負載均衡算法是輪詢)。

6.1 RestTemplate上面@LoadBalanced

這步操作我們之前已經加過了,不然的話之前的通路就會報錯,這裡隻是為了強調,現在再來仔細的檢視一下order80子產品的OrderConfig類:

package com.zdw.springcloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class OrderConfig {

    /**
     * 注冊RestTemplate
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
           

6.2 啟動測試

先要啟動EurekaServer,7001/7002服務

再要啟動服務提供者provider,8001/8002服務

最後啟動order80 服務:

浏覽器通路:http://eureka7001.com:7001/ http://eureka7002.com:7002/ 可以看到他們兩已經互相注冊了,同時其他的三個微服務8001,8002,80都注冊了

浏覽器通路:http://localhost:8001/payment/get/1 http://localhost:8002/payment/get/1 都能正常通路到資料,說明8001和8002的服務是正常的;

浏覽器多次通路:http://localhost/consumer/payment/get/1 可以看到:

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護
SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

這兩個是交替出現的,這也正是我們想要的結果,由8001和8002的叢集環境一起為order80提供服務,預設的負載均衡機制就是輪詢。

7、服務注冊發現@EnableDiscoveryClient

對于注冊到eureka裡面的微服務,可以通過服務發現來獲得該服務的資訊;

要想暴露微服務的資訊,主要有兩步:

1、主啟動類加上注解:@EnableDiscoveryClient

2、在Controller中,通過 DiscoveryClient 擷取微服務資訊,并傳回給浏覽器;

7.1 payment8001配置服務發現

7.1.1 PaymentMain8001主啟動類添加注解@EnableDiscoveryClient

package com.zdw.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient  //這是一個Eureka的client端
@EnableDiscoveryClient  //服務發現開啟
public class PaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8001.class,args);
    }
}
           

7.1.2 添加一個Controller

package com.zdw.springcloud.controller;

import lombok.extern.slf4j.Slf4j;
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.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@Slf4j
public class DiscoveryClientController {

    @Autowired
    DiscoveryClient discoveryClient;

    @GetMapping("/discovery/info")
    public Object discovery(){
        List<String> services = discoveryClient.getServices();
        for(String element : services){
            System.out.println("******   "+element);
        }
        //通過服務别名擷取服務的執行個體
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        for(ServiceInstance instance : instances){
            System.out.println("服務主機:"+instance.getHost()+",服務端口:"+instance.getPort()+",服務ID"+instance.getServiceId()+",服務uri:"+instance.getUri());
        }
        return discoveryClient;
    }
}
           

7.2 payment8002和order80配置服務發現

參照payment8001的方式進行配置即可。

然後啟動工程,浏覽器檢視效果:

http://localhost:8001/discovery/info

http://localhost:8002/discovery/info

http://localhost/discovery/info

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

8、Eureka的自我保護

8.1 什麼是Eureka保護機制

首先我們看看Eureka的保護機制是什麼,就可以通路 eureka7001.com:7001:

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

這一行紅色的字(EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.)就是Eureka進入了保護模式。

保護模式主要用于一組用戶端和Eureka Server之間存在網絡分區場景下的保護。一旦進入保護模式,Eureka Server 将會嘗試保護其服務系統資料庫的資訊,不會删除服務系統資料庫中的資料,也就是不會登出任何微服務。

8.2 為什麼出現Eureka的自我保護機制

為了防止Eureka Client可以正常運作,但是與Eureka Server網絡不通的情況下,Eureka Server會立刻删除Eureka Client。

預設情況下,如果Eureka Server在一定時間内沒有收到某個微服務執行個體的心跳,Eureka Server 就會将這個執行個體登出(預設是90秒)。但是當網絡發生故障(延時,卡頓,擁擠)時,微服務和Eureka Server 無法正常通信,但是微服務本身是健康的,此時不應該登出該微服務。是以為了解決這個問題,Eureka就有一種自我保護機制,當Eureka Server在短時間内丢失過多用戶端時,那麼就會進入自我保護模式:

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

它的設計哲學是:甯可保留錯誤的服務注冊資訊,也不盲目登出任何可能健康的服務注冊資訊。

總之,保護模式是一種應對網絡異常的安全保護措施。使用自我保護模式,可以讓Eureka更加健壯、穩定。一句話總結就是:某時刻 一個微服務不可用了,Eureka不會立刻清理,依舊會對該服務的資訊進行儲存。屬于CAP裡面的AP分支

8.3 關閉Eureka的自我保護

出産預設,自我保護機制是開啟的,eureka.server.enable-self-preservation=true,使用eureka.server.enable-self-preservation=false 可以禁用自我保護模式;Eureka用戶端向服務端發送心跳的時間間隔,機關為秒(預設是30秒),Eureka服務端在收到最後一次心跳後等待時間上限 ,機關為秒(預設是90秒),逾時剔除服務。

8.3.1 Eureka Server 7001/7002的修改

要關閉Eureka的自我保護,就要在7001和7002的yml配置中添加下面的配置:

server:
  port: 7001
spring:
  application:
    name: cloud-eureka-service
eureka:
  instance:
    # eureka服務端的執行個體名稱 # 單機
    # hostname: localhost
    hostname: eureka7001.com
  server:
    # 禁用自我保護,保證不可用服務被及時删除
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 2000
  client:
    # false表示不向注冊中心注冊自己
    register-with-eureka: false
    # false表示自己端就是注冊中心,我的職責就是維護服務執行個體,并不需要檢索服務
    fetch-registry: false
    service-url:
      # 設定與Eureka Server互動的位址查詢服務和注冊服務都需要依賴這個位址  # 單機
      # defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      # 互相注冊
      defaultZone: http://eureka7002.com:7002/eureka/
           
server:
    # 禁用自我保護,保證不可用服務被及時删除
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 2000
           

這些是新增的配置,7001和7002都加上這些配置

8.3.2 payment8001和8002,order80修改

在 payment8001和8002,order80的yml配置中添加下面的配置:

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      # 單擊版
      # defaultZone: http://localhost:7001/eureka
      # 叢集版
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
  instance:
    instance-id: payment8001
    # 通路路徑可以顯示ip位址
    prefer-ip-address: true
    #Eureka用戶端向服務端發送心跳的實際間隔,機關為秒(預設為30秒)
    lease-renewal-interval-in-seconds: 1
    #Eureka服務端收到最後一次心跳後等待時間上線,機關為秒(預設為90秒) 逾時将剔除服務
    lease-expiration-duration-in-seconds: 2
           
#Eureka用戶端向服務端發送心跳的實際間隔,機關為秒(預設為30秒)
    lease-renewal-interval-in-seconds: 1
    #Eureka服務端收到最後一次心跳後等待時間上線,機關為秒(預設為90秒) 逾時将剔除服務
    lease-expiration-duration-in-seconds: 2
           

這兩個是新增的配置

分别啟動上面的五個微服務,檢視效果:

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

如果關閉8001和80,再次檢視效果:發現關閉的服務立馬就被Eureka Server給剔除了。

SpringCloud05-Eureka服務注冊與發現1、Eureka基礎知識2、單機Eureka建構3、叢集Eureka建構5、測試4、把payment8001和order80注冊到上面的eureka叢集5、payment支付子產品叢集搭建6、負載均衡測試7、服務注冊發現@EnableDiscoveryClient8、Eureka的自我保護

繼續閱讀