1. 程式人生 > >記一次學習配置叢集eureka,註冊生成者、消費端,實現簡單的服務呼叫

記一次學習配置叢集eureka,註冊生成者、消費端,實現簡單的服務呼叫

總結一次基於SpringCloud,Greenwich.SR2版本部署叢集eureka,註冊生產者、消費者並進行簡單呼叫的流程。

一、配置叢集eureka伺服器

1.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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.czc.springclouddemo</groupId>
    <artifactId>springclouddemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>


其中 <dependencyManagement>標籤為必須,作用是版本管理,標識子專案和父專案中依賴的版本,這裡我猜測可能是規範了引入的spring-cloud-starter-netflix-eureka-server依賴裡面依賴的部分jar包的版本,當然也只是猜測,網上查了一下沒查到,就不深究了。

2.yml配置

首先介紹下單機eureka的單機配置:

spring:
  application:
    name: eureka-server
server:
  port: 7000
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false ##是否向下面的defaultZone,eureka伺服器註冊自己,這裡是單機,所以不用
    fetch-registry: false ## 是否從下面的defaultZone拉取註冊的伺服器節點或服務,因為是單機,所以也不用
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

如果需要叢集部署節點則使用一下配置:

spring:
  application:
    name: eureka-server
server:
  port: 7000
eureka:
  instance:
    hostname: peer1
  client:
    ## 如果不為true 將不會註冊到另一臺eureka
    register-with-eureka: true
    fetch-registry: true
    service-url:
      ## 如果部署的不止兩臺eureka服務,有3臺以上可以以逗號分隔
	  ## 這裡只是將本臺eureka服務註冊到另一臺上
      defaultZone: http://peer2:7001/eureka/

這裡url中我寫的peer1和peer2我修改了本地host檔案,直接指向的是127.0.0.1,不修改的話直接寫localhost也行。

叢集部署很簡單,就是將eureka伺服器,節點註冊配置為相互註冊就行了,另一臺配置除了url配置的是7000埠,其他都一樣就不寫了。

3.啟動類

啟動類很簡單,直接使用@EnableEurekaServer註解就行了。

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

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

}

4.實際效果

registered-replicas 表示節點副本,available-replicas表示的可用節點副本-心跳正常。

二、註冊生產者或消費者

1.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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.czc.springclouddemo</groupId>
    <artifactId>eureka-producer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-producer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

核心關於springcloud的依賴就是spring-cloud-starter-netflix-eureka-client,而註冊中心是spring-cloud-starter-netflix-eureka-server。

2.yml,註冊到註冊中心

spring:
  application:
    name: eureka-producer
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7000/eureka/,http://localhost:7001/eureka/
server:
  port: 8000

消費者就不舉例了,都是一樣的。

3.提供生產者服務

RestController
@RequestMapping("/hello")
public class HelloController {
    @GetMapping("/")
    public String hello(@RequestParam String name) {
        return "Hello, " + name + " " + new Date();
    }
}

三、消費者呼叫:

呼叫方式有三種:

  1. 以LoadBalancerClient方式呼叫-負載均衡客戶端
  2. 以Ribbon方式呼叫-提供負載均衡,比LoadBalancerClient更簡便,自動選擇服務例項,預設以輪詢方式呼叫
  3. 以Feign方式呼叫-整合了Ribbon和Hystrix,最常用,能提供容錯保護(預設關閉)。需新增spring-cloud-starter-openfeign依賴。

下面是消費者端程式碼:

(1)啟動類:

package com.czc.springclouddemo.eurekaconsumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableFeignClients
public class EurekaConsumerApplication {
    /**
      * LoadBalancerClient 方式呼叫
      */
    @Bean("LoadBalancerClient")
    public RestTemplate restTemplateLoadBalancerClient() {
        return new RestTemplate();
    }

    /**
     *  ribbon方式呼叫
     *
     */
    @LoadBalanced
    @Bean("ribbon")
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

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

這裡註冊了兩個不同的restTemplate,用於分別以LoadBalancerClient和ribbon方式呼叫服務。

@EnableFeignClients 則表示啟用Feign。這個註解獨立於上面兩種方式,不互相依賴。

(2)定義feign介面:

@FeignClient(name = "eureka-producer")
public interface HelloRemote {
    @GetMapping("/hello/")
    String hello(@RequestParam(value = "name") String name);
}

這裡的@RequestParam註解為必須表示傳送到服務端請求的請求引數欄位名。@FeignClient(name = "eureka-producer")表示呼叫的服務名。

(3)Controler中的程式碼呼叫:

@RequestMapping("/hello")
@RestController
public class HelloController {

    @Autowired
    private LoadBalancerClient client;

    @Autowired
    @Qualifier("LoadBalancerClient")
    private RestTemplate restTemplate1LoadBalancerClient;

    @Autowired
    @Qualifier("ribbon")
    private RestTemplate restTemplateRibbon;

    @Autowired
    private HelloRemote helloRemote;



    /**
      * LoadBalancerClient 方式呼叫
      */
    @GetMapping("/loadBalancerClient")
    public String helloLoadBalancerClient(@RequestParam String name) {
        name += "!";
        ServiceInstance instance = client.choose("eureka-producer");
        String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/hello/?name=" + name;
        return restTemplate1LoadBalancerClient.getForObject(url, String.class);
    }


    /**
     * ribbon 方式呼叫
     */
    @GetMapping("/ribbon")
    public String helloRibbon(@RequestParam String name) {
        name += "!";
        String url = "http://eureka-producer/hello/?name=" + name;
        return restTemplateRibbon.getForObject(url, String.class);
    }

    /**
      * feign方式呼叫(最常用)
      */
    @GetMapping("/feign/{name}")
    public String index(@PathVariable("name") String name) {
        return helloRemote.hello(name + "!");
    }

}

四、參考

Spring Cloud(二):服務註冊與發現 Eureka【Finchley 版】

Spring Cloud(三):服務提供與呼叫 Eureka