spring cloud 系列文章(一)Eureka 使用

介紹

關於 Eureka

Eureka 是由 Netfix 開發的服務註冊發現組件,後來 spring cloud 將其集成到其子項目 spring-cloud-netfix 中。Eureka 本身是基於 REST 的服務,在集羣中主要用於服務管理。Eureka 提供了 Java 的客戶端組件,同時該客戶端組件實現了負載均衡的功能,爲業務組件的集羣部署創造了條件。我們可以很簡單的將業務組件註冊到 Eureka 中,由 Eureka 維護這些服務的列表並自動檢查組件的狀態。

Eureka 架構

常見的 Eureka 架構,由若干個(一般2~3個) Eureka 服務器、若干個 Eureka 客戶端組成,客戶端可以向服務器獲取服務並進行服務調用。
Eureka架構圖
由圖可以看到服務器支持集羣部署,每個服務器作爲對方服務器的客戶端進行相互註冊與複製,客戶端也支持部署多個實例,這樣一來,保證了 Eureka 集羣的高可用性。

快速開始

構建 Eureka 服務端

在 IDEA 中通過 Spring Initializr 先創建一個名稱爲 eureka-server 的 Spring Boot 項目作爲 Eureka 服務端,在 pom.xml 引入 eureka 服務端的依賴:

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

在啓動類上加上 @EnableEurekaServer 註解:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication .class,args);
    }

}

在 application.yml 配置文件中加入如下配置:

server:
  port: 8761
spring:
  application:
    name: ek-server
eureka:
  instance:
    hostname: ek-server
    instance-id: ${spring.application.name}:${server.port}
  client:
  	# 是否將自己的信息註冊到 Eureka 服務器
    register-with-eureka: false
    # 是否到 Eureka 服務器中抓取註冊信息
    fetch-registry: false
    service-url:
      default-zone: http://localhost:8761/eureka/
  server:
    # 關閉保護模式,生產模式下要開啓
    enable-self-preservation: false

這裏把設置 register-with-eurekafetch-registry 屬性爲 false,不然啓動服務的時候會報錯。因爲 eureka 服務端本身也可以作爲客戶端註冊到別的服務端上,組成一個服務端集羣。由於我們演示只需要一個服務端就可以,所以把這兩個屬性都設置爲 false。

這樣我們的 Eureka 服務端就寫好了,啓動項目,訪問 localhost:8761,出現如下界面證明我們的服務端已經正常啓動:
Eureka 服務端界面

編寫服務提供者

在微服務裏面,通常習慣將一個應用稱之爲服務,所以服務提供者,是指註冊到註冊中心,並提供服務的應用。
同樣新建一個 Spring Boot 項目,名稱爲 ek-provider,先引入 Eureka 客戶端的依賴:

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

配置文件中加入如下配置:

server:
  port: 8081
spring:
  application:
    name: ek-client
eureka:
  instance:
    hostname: ek-client
  client:
    service-url:
      # 服務端註冊地址
      default-zone: http://localhost:8761/eureka/

default-zone 配置的是服務註冊的地址。接着在啓動類加上 Eureka 客戶端註解 @EnableEurekaClient

@SpringBootApplication
@EnableEurekaClient
public class EurekaClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaClientApplication .class,args);
    }

}

也可以將 @EnableEurekaClient 註解換成 @EnableDiscoveryClient 註解,兩者的區別是@EnableEurekaClient 註解只能在使用 Eureka 作爲註冊中心使用,而當使用別的註冊中心的時候, @EnableDiscoveryClient 註解也能用

編寫 HelloController,提供一個簡單的 rest 服務:

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "hello world";
    }
}

啓動客戶端,然後刷新 Eureka 服務端頁面( localhost:8761),可以看到我們的客戶端已經註冊上去了:
Eureka Client 註冊到 Eureka 服務端上

編寫服務調用者

服務調用者同樣需要註冊到註冊中心,可以進行服務的查找與調用。新建 ek-invoker 項目,加入如下依賴:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- eureka客戶端 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!-- ribbon負載均衡 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
</dependencies>

這裏我們用了 ribbon 做負載均衡,因爲服務提供者可能部署多個,而且可以動態擴容,這時候,就需要負載均衡機制來幫我們解決如何選擇調用者的問題。

application.yml 配置如下:

server:
  port: 8082
spring:
  application:
    name: ek-invoker

eureka:
  instance:
    hostname: ek-invoker
  client:
    service-url:
      # 服務端註冊地址
      default-zone: http://localhost:8761/eureka/

最後編寫調用代碼,新建 InvokerController:

@RestController
@Configuration
public class InvokerController {

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

    @Autowired
    public RestTemplate restTemplate;

    @GetMapping("/router")
    public String router(){
        return restTemplate.getForObject("http://ek-client/hello", String.class);
    }

}

注意 getForObject 方法的 url 參數,不是 http://localhost:8081/hello ,而是指定應用的名稱。這裏使用 Ribbon 提供的 @LoadBalanced 註解修飾 RestTemplate,這樣RestTemplate 便有了負載均衡的能力,只需要將 url 的域名換成應用的應用名,Ribbon 就會到 Eureka 服務端中查找該名稱的應用,並根據負載均衡算法,選擇合適的應用。

啓動 ek-invoker 應用,在 eureka 監控頁面可以看到我們的服務已經註冊上去了:
eureka 界面
訪問 localhost:8082/router,可以看到瀏覽器輸出 hello world,根據輸出可知,服務調用方正確尋找到提供方,並順利調用了提供方的 /hello 接口。

公衆號

可以關注我的公衆號,不定時更新工作中的踩坑經歷,及一些工作思考
在這裏插入圖片描述

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