Spring Cloud 學習筆記(一) -服務治理

Spring Cloud Eureka 服務治理

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

  • 服務註冊:
    在服務框架中, 通常會構建一個註冊中心,每個服務啓動時向註冊中心登記自己提供的服務,並將自身信息(主機,端口、協議等)告知註冊中心,註冊中心按照服務名分類組織服務清單。
  • 服務發現:
    在服務的框架下,服務間的調用不再通過指定具體的實例地址來實現, 而是通過服務名發起請求來實現,所以服務調用方在調用服務接口的時候,並不知道具體的服務實例位置。因此,調用方需要向服務註冊中心諮詢服務,並獲取所有服務的實例清單。
  • Spring Cloud Eureka, 使用netfix Eureka來實現服務註冊和發現, 他既包含服務端,也包含客戶端組件, 服務端我們也稱爲服務註冊中心,Eureka客戶端主要處理服務的發現和註冊。

搭建服務註冊中心

1、 創建一個SpringBoot 工程,命名爲eureka-server, 並在pom.xml中引入依賴。

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

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

2、 通過註解@EnableEurekaServer 啓動一個服務註冊中心提供給其他應用進行對話。
如下:

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(EurekaServerApplication.class).web(true).run(args);
    }
}

3、 默認情況下, 該服務的註冊中心也會將自己作爲客戶端來嘗試註冊自己,所以我們要禁用它的客戶端註冊行爲,只需要在application.yml中添加以下配置:

server:
  port: 8081

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
  • euraka.client.register-with-enreka: 設爲false,代表不向註冊中心註冊自己
  • eureka.client.fetch-registry : 由於註冊中心的職責是維護服務實例,他並不需要去檢索服務, 所以設置爲false
    4、 啓動應用,並訪問 http://localhost:8081/ ,可以看到Eureka的信息面板,其中Instance currently registered with Eureka 欄是空的,說明該註冊中心還沒有註冊任何服務。

註冊服務提供者

在完成服務註冊中心搭建之後,接下來嘗試將一個既有的Springboot應用加入到Eureka的服務治理體系中去。
1、 pom.xml中增加Spring Cloud Eureka模塊的依賴,如下:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

2、 添加/hello 請求處理接口

@RestController
public class HelloController {
    @Autowired
    private DiscoveryClient discoveryClient;

    @RequestMapping("/hello")
    public String index(){
        ServiceInstance instance = discoveryClient.getLocalServiceInstance();
        System.out.println("Hello host:"+instance.getHost()+",service_id:"+instance.getServiceId());
        return "Hello Word";
    }
}

3、 在主類中添加註解

@EnableEurekaClient
@SpringBootApplication
public class EurekaClientApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(
                EurekaClientApplication.class)
                .web(true).run(args);
    }

}

4、配置application.yml

spring:
  application:
    name: eureka-client
server:
  port: 8083
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8081/eureka/
  • spring.application.name 屬性爲服務名
  • eureka.client.serviceUrl.defaultZone=http://localhost:8081/eureka/ 指定服務註冊中心的地址

5、啓動程序, 再次訪問 http://localhost:8081/ ,可以看到Eureka的信息面板,其中Instance currently registered with Eureka 有一條註冊服務信息的信息。

Ribbon 服務的發現與消費

下面嘗試構建一個服務消費者,它主要有兩個目標,發現服務以及消費服務。其中發現服務由eureka的客戶端來完成,而服務的消費的任務是由Ribbon完成。Ribbon 是一個基於HTTP和TCP的客戶端的負載均衡器。下面創建一個簡單的例子:

1、 首先在8082和8083端口號下,啓動eurake-client,這時候可以在註冊中心界面可以看到名爲enreka-cilent 下有兩個實例。
2、 創建一個SpringBoot 基礎工程來實現服務消費者,取名爲service-ribbon,並在pom.xml中添加依賴,如下:

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

3、配置application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/
server:
  port: 8085
spring:
  application:
    name: service-ribbon

4、 創建應用主類,並通過@EnableDiscoveryClient 註解讓該應用注入爲Eureka客戶端應用,以獲取服務發現的能力,同時,在該類中創建RestTemplate的Spring Bean實例,並通過@LoadBalanced註解開啓客戶端負載均衡,如下:

@EnableDiscoveryClient
@SpringBootApplication
public class ServiceRibbonApplication {

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

    public static void main(String[] args) {
        SpringApplication.run(ServiceRibbonApplication.class, args);
    }
}
@RestController
public class ConsumerController {
    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/ribbon-consumer")
    public String helloConsumer(){
        return restTemplate.getForEntity("http://EUREKA-CLIENT/hello",String.class).getBody();
    }
}

5、這是我們啓動應用,再註冊中心的面板上看到8085的服務已經啓動,多次輸入http://localhost:8085/ribbon-consumer ,會在EUREKA-CLIENT服務的8082、8083控制檯交替打印日誌。


Eureka詳解——服務治理機制

1、 服務提供者

  • 服務註冊
    “服務提供者”在啓動的時候會通過發送REST請求的方式將自己註冊到Eureka Server 上, 同時帶上自身服務的一些元數據信息,Eureka Server 接收到這個REST請求之後,將元數據信息保存在一個雙層結構的Map中,其中一層是的key是服務名,第二層的key 是具體服務的實例名
  • 服務同步
    如果兩個服務提供者分別註冊到兩個不同的服務註冊中心上, 也就是說,他們的信息分別被兩個服務註冊中心所維護,此時, 由於服務註冊中心之間因爲互相註冊爲服務,當服務提供者發送註冊請求到一個服務註冊中心時,他會將該請求轉發給集羣中相連的其他的註冊中心, 從而實現註冊中心之間的服務同步。
  • 服務續約
    再註冊玩服務之後,服務提供者會維護一個心跳來告訴Eureka Server,說明這個服務正在啓用。

    eureka.instance.lease-renewal-interval-in-seconds=30 定義服務續約任務的調用間隔時間
    eureka.instance.lease-expiration-duration-in-seconds=90 定義服務失效的時間

2、 服務消費者

  • 獲取服務
    獲取服務首先要保證 該服務已在Eureka Server中註冊, 必須確保enreka.client.fetch-registry=true參數沒有被修改稱false, 該值默認爲true

    enreka.client.fetch-registry=true 是否檢索服務

    eureka.client.registry-fetch-interval-seconds = 30 修改緩存清單的更新時間

  • 服務調用
    服務消費者在獲取服務清單後,通過服務名可以獲得具體提供服務的實例名和該實例的元數據信息,之後,客戶端可以改居自己的需求決定具體調用哪個實例,Ribbon中會默認採用輪訓的方式進行調用,從而實現客戶端的負載均衡。

  • 服務下線
    當服務實例進行正常關閉時,會觸發一個服務下線的REST請求給Eureka Server ,告訴服務註冊中心,這時服務端收到該請求後,將該服務狀態設置爲顯現(DOWN),並把下線事件傳播出去

3、 服務註冊中心

  • 失效剔除
    當服務實例沒有正常下線時,可能是其他原因導致服務故障,而註冊中心沒有收到下線請求。爲了將折現無法提供服務的實例剔除,Eureka Server 在啓動的時候會創建一個定時任務,默認60S將當前清單中沒有續約的服務剔除掉

  • 自我保護
    Eureka Server 在運行期間,會統計心跳失敗比例在15分鐘之內是否會低於85%,如果低於情況(可能是網絡不穩定導致),Eureka Server 會將當前實例註冊信息保護起來,讓這些實例不會過期,儘可能保護這些註冊信息。但是,這段時間內實例若出現問題,那麼客戶端很容易拿到的實際已經不存在的服務實例,會出現調用失敗的情況, 所以客戶端必須要有容錯機制,比如請求重試、斷路器等機制。

4、 高可用eurake 配置

通過運行多個實例並請求他們相互註冊,可以使Eureka更具彈性和可用性。事實上,這是默認的行爲,所以你需要做的只是爲對方添加一個有效的serviceUrl;您可以向系統添加多個對等體,只要它們至少一個邊緣彼此連接,則它們將在它們之間同步註冊

eureka:
  instance:
    prefer-ip-address: true
  client:
    register-with-eureka: false
    serviceUrl:
      defaultZone: http://127.0.0.1:8082/eureka/
spring:
  application:
    name: eureka-server01

-------
eureka:
  instance:
    prefer-ip-address: true
  client:
    register-with-eureka: false
    serviceUrl:
      defaultZone: http://127.0.0.1:8081/eureka/
server:
  port: 8082
spring:
  application:
    name: eureka-server02
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章