Consul註冊中心

Consul註冊中心

1.理解Consul

Consul 是 HashiCorp 公司推出的開源工具,用於實現分佈式系統的服務發現與配置。與其它分佈式

服務註冊與發現的方案,Consul 的方案更“一站式”,內置了服務註冊與發現框架、分佈一致性協議實現、健康檢查、Key/Value 存儲、多數據中心方案,不再需要依賴其它工具(比如 ZooKeeper 等),使用起來也較爲簡單。

Consul 使用 Go 語言編寫,因此具有天然可移植性(支持Linux、Windows 和 Mac OS);安裝包僅包含一個可執行文件,方便部署,與 Docker 等輕量級容器可無縫配合。

2.Consul特性

  • 算法服務發現
  • 健康檢查
  • Key/Value 存儲多數據
  • 中心
  • 支持 http 和 dns 協議接口官方
  • 提供 web 管理界面

3.Consul角色

client:客戶端,無狀態,將 HTTP 和 DNS 接口請求轉發給局域網內的服務端集羣。

server:服務端,保存配置信息,高可用集羣,每個數據中心的 server 數量推薦爲 3 個或者 5 個。

4.Consul工作原理

在這裏插入圖片描述

服務發現以及註冊

當服務 Producer 啓動時,會將自己的 Ip/host 等信息通過發送請求告知 Consul,Consul 接收到 Producer 的註冊信息後,每隔 10s(默認)會向 Producer 發送一個健康檢查的請求,檢驗 Producer 是否健康。

服務調用

當 Consumer 請求 Product 時,會先從 Consul 中拿到存儲 Product 服務的 IP 和 Port 的臨時表(temp table),從temp table 表中任選一個· Producer 的 IP 和 Port, 然後根據這個 IP 和 Port,發送訪問請求; temp table 表只包含通過了健康檢查的 Producer 信息,並且每隔 10s(默認)更新。

5.Consul安裝

Eureka 其實就是個 Servlet 程序,跑在 Servlet 容器中;Consul 則是用 go 語言編寫的第三方工具需要單獨安裝使用。

下載:訪問 Consul 官網: https://www.consul.io 下載 Consul 的最新版本。

**安裝:**單節點我們在 Windows 安裝,集羣環境在Linux 安裝

單節點

cd 到對應的目錄下,使用 cmd 啓動 Consul

#-dev 表示開發模式運行 ,另外還有-server 表示服務模式運行
consul agent -dev -client=0.0.0.0

爲了方便啓動,也可以在 consul.exe 同級目錄下創建一個腳本來啓動,腳本內容如下:

consul agent -dev -client=0.0.0.0
pause

訪問:http://localhost:8500/

6.Consul案例

創建項目,創建一個pom父工程
添加依賴
 <!-- 繼承 spring-boot-starter-parent 依賴 -->
    <!-- 使用繼承方式,實現複用,符合繼承的都可以被使用 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
    </parent>

    <!--
        集中定義依賴組件版本號,但不引入,
        在子工程中用到聲明的依賴時,可以不加依賴的版本號,
        這樣可以統一管理工程中用到的依賴版本
     -->
    <properties>
        <!-- Spring Cloud Hoxton.SR1 依賴 -->
        <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
    </properties>

    <!-- 項目依賴管理 父項目只是聲明依賴,子項目需要寫明需要的依賴(可以省略版本信息) -->
    <dependencyManagement>
        <dependencies>
            <!-- spring cloud 依賴 -->
            <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>
服務提供者service-provider
創建項目
添加依賴
<!-- 繼承父依賴 -->
    <parent>
        <groupId>com.shsxt</groupId>
        <artifactId>consul-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>

      <!-- netflix eureka client 依賴 -->
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-consul-discovery</artifactId>
      </dependency>
      <!-- spring boot actuator 依賴 -->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-actuator</artifactId>
      </dependency>
      <!-- spring boot web 依賴 -->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <!-- lombok 依賴 -->
      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <scope>provided</scope>
      </dependency>

      <!-- spring boot test 依賴 -->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <scope>test</scope>
          <exclusions>
              <exclusion>
                  <groupId>org.junit.vintage</groupId>
                  <artifactId>junit-vintage-engine</artifactId>
              </exclusion>
          </exclusions>
      </dependency>

配置文件
spring:
  application:
    name: service-provider # 應用名稱
  # 配置 Consul 註冊中心
  cloud:
    consul:
      # 註冊中心的訪問地址
      host: localhost
      port: 8500
      # 服務提供者信息
      discovery:
        register: true                                # 是否需要註冊
        instance-id: ${spring.application.name}-01    # 註冊實例 id(必須唯一)
        service-name: ${spring.application.name}      # 服務名稱
        port: ${server.port}                          # 服務端口
        prefer-ip-address: true                       # 是否使用 ip 地址註冊
        ip-address: ${spring.cloud.client.ip-address} # 服務請求 ip

# 端口
server:
  port: 8601

編寫服務

User.java

package com.shsxt.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
//@AllArgsConstructor
public class User implements Serializable {

    private Integer id;
    private String username;
    private Integer age;

    public User(Integer id, String username, Integer age) {
        this.id = id;
        this.username = username;
        this.age = age;
    }
}

UserService.java

/**
 * 用戶服務
 */
public interface UserService {

    /**
     * 查詢用戶列表
     *
     * @return
     */
    List<User> selectUserList();

}
/**
 * 用戶服務
 */
@Service
public class UserServiceImpl implements UserService {

    /**
     * 查詢用戶列表
     *
     * @return
     */
    @Override
    public List<User> selectUserList() {
        return Arrays.asList(
                new User(1, "張三", 20),
                new User(2, "李四", 21),
                new User(3, "王五", 22)
        );
    }

}
控制層
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 查詢用戶列表
     *
     * @return
     */
    @GetMapping("/list")
    public List<User> selectUserList() {
        return userService.selectUserList();
    }

}
啓動類
@SpringBootApplication
public class ServiceProviderApplication {

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

}

訪問: http://localhost:8500/

服務消費者service-consumer
創建項目
添加依賴
 <!-- 繼承父依賴 -->
    <parent>
        <groupId>com.shsxt</groupId>
        <artifactId>consul-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
      <!-- netflix eureka client 依賴 -->
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-consul-discovery</artifactId>
      </dependency>
      <!-- spring boot actuator 依賴 -->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-actuator</artifactId>
      </dependency>
      <!-- spring boot web 依賴 -->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <!-- lombok 依賴 -->
      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <scope>provided</scope>
      </dependency>

      <!-- spring boot test 依賴 -->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <scope>test</scope>
          <exclusions>
              <exclusion>
                  <groupId>org.junit.vintage</groupId>
                  <artifactId>junit-vintage-engine</artifactId>
              </exclusion>
          </exclusions>
      </dependency>
  </dependencies>
配置文件
spring:
  application:
    name: service-consumer # 應用名稱
  # 配置 Consul 註冊中心
  cloud:
    consul:
      # 註冊中心的訪問地址
      host: localhost
      port: 8500
      # 服務提供者信息
      discovery:
        register: false                               # 是否需要註冊
        instance-id: ${spring.application.name}-01    # 註冊實例 id(必須唯一)
        service-name: ${spring.application.name}      # 服務名稱
        port: ${server.port}                          # 服務端口
        prefer-ip-address: true                       # 是否使用 ip 地址註冊
        ip-address: ${spring.cloud.client.ip-address} # 服務請求 ip

# 端口
server:
  port: 8701

消費服務
package com.shsxt.pojo;

import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
//@AllArgsConstructor
public class User implements Serializable {

    private Integer id;
    private String username;
    private Integer age;

    public User(Integer id, String username, Integer age) {
        this.id = id;
        this.username = username;
        this.age = age;
    }
}
/**
 * 用戶服務
 */
public interface UserService {


    /**
     * 查詢用戶列表
     *
     * @return
     */
    List<User> selectUserList();

}
/**
 * 用戶服務
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 查詢用戶列表
     *
     * @return
     */
    @Override
    public List<User> selectUserList() {
        // ResponseEntity: 封裝了返回數據
        ResponseEntity<List<User>> response = restTemplate.exchange(
                "http://service-provider/user/list",
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<User>>() {});
        return response.getBody();
    }
}
控制層
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 用戶管理
     *
     * @return
     */
    @GetMapping("/manage")
    public List<User> userManage() {
        return userService.selectUserList();
    }

}
啓動類
@SpringBootApplication
public class ServiceConsumerApplication {

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

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

訪問:http://localhost:8701/user/manage

7.Consul集羣

環境準備
服務器 IP Consul 類型 Node 節點
192.168.10.101 server server-01
192.168.10.102 server server-02
192.168.10.103 server server-03
192.168.10.1 client client-01
安裝

安裝 unzip 命令,創建 consul 目錄,將 consul 解壓至指定目錄。

yum -y install unzip                                        # 安裝 unzip 2  
mkdir -p /usr/local/consul                                  # 創建 consul 目錄    unzip consul_1.6.2_linux_amd64.zip -d /usr/local/consul/    # 解壓至 consul 目錄   
mkdir -p /usr/local/consul/data                             # 創建 consul 數據目錄
啓動
註冊中心服務端

以server 服務模式運行三臺註冊中心

	# node-01
	./consul agent -server -bind=192.168.10.101 -client=0.0.0.0 -ui -bootstrapexpect=3 -data-dir=/usr/local/consul/data/ -node=server-01
	# node-02
	./consul agent -server -bind=192.168.10.102 -client=0.0.0.0 -ui -bootstrapexpect=3 -data-dir=/usr/local/consul/data/ -node=server-02
	# node-03
	./consul agent -server -bind=192.168.10.103 -client=0.0.0.0 -ui -bootstrapexpect=3 -data-dir=/usr/local/consul/data/ -node=server-03

參數含義如下:

-server :以服務端身份啓動(註冊中心)

-bind :表示綁定到哪個 ip

-client :指定客戶端訪問的 ip,0.0.0.0 表示不限客戶端 ip

-ui :開啓 web 界面訪問

-bootstrap-expect=3 :表示 server 集羣最低節點數爲 3,低於這個值將工作不正常(注:類似

ZooKeeper一樣,通常集羣數爲奇數方便選舉,Consul 採用的是 Ra 算法)

-data-dir :表示指定數據的存放目錄(該目錄必須存在,需提前創建好)

-node :表示節點在 web ui 中顯示的名稱

註冊中心客戶端
  consul agent -client=0.0.0.0 -bind=192.168.10.1 -data-dir=D:\Example\consol\data node=client-01
關聯集羣

在 server-02 和 server-03 和 client-01 節點中輸入以下命令建立集羣關係。

/consul join 192.168.10.101
集羣狀態

在任意一臺服務器中輸入以下命令可查看集羣中所有節點信息。

/consul members

訪問: http://192.168.10.101:8500/ 或者 http://192.168.10.102:8500/ 或者 http://192.168.10.103:8

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