Spring Boot + Spring Cloud 構建微服務系統(一):服務註冊和發現(Consul)

使用Consul提供註冊和發現服務

什麼是 Consul

Consul 是 HashiCorp 公司推出的開源工具,用於實現分佈式系統的服務發現與配置。與其它分佈式服務註冊與發現的方案,Consul 的方案更「一站式」,內置了服務註冊與發現框架、分佈一致性協議實現、健康檢查、Key/Value 存儲、多數據中心方案,再也不須要依賴其它工具(好比 ZooKeeper 等)。使用起來也較爲簡單。Consul 使用 Go 語言編寫,所以具備自然可移植性(支持Linux、windows和Mac OS X);安裝包僅包含一個可執行文件,方便部署,與 Docker 等輕量級容器可無縫配合。html

Consul 安裝

訪問 Consul 官網 ,根據操做系統類型,選擇下載 Consul 的最新版本。我這裏選擇windows版本。java

下載下來是一個zip壓縮包,解壓以後,是一個exe可執行文件。git

 打開CMD終端,進入consul.exe所在目錄,執行以下命令啓動Consul服務。web

cd C:\consul_1.3.0_windows_amd64  # 進入consul.exe所在目錄
consul agent
-dev # 啓動服務, -dev 表示開發模式運行,另外還有 -server 表示服務模式運行

啓動過程信息以下圖所示。spring

啓動成功以後,訪問 http://localhost:8500 , 能夠查看 Consul 管理界面。windows

 

Consul 服務提供者

服務註冊發現中心有了,如今咱們來開發服務提供者。瀏覽器

新建項目 spring-cloud-consul-producer,添加如下依賴。app

pom.xml負載均衡

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

說明:框架

spring-boot-starter-actuator 健康檢查依賴於此包。

spring-cloud-starter-consul-discovery Spring Cloud Consul 的支持。

注意添加Spring Cloud的依賴配置,完整內容參見源碼pom文件。

  <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>

添加配置

在配置文件添加內容以下。

application.yml

server:
  port: 8511
spring:
  application:
    name: spring-cloud-consul-producer
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        serviceName: service-producer    # 註冊到consul的服務名稱

Consul 的地址和端口號默認是 localhost:8500 ,若是不是這個地址能夠自行配置,consul服務會佔用8502接口,因此不要用850一、8502。
spring.cloud.consul.discovery.serviceName 是指註冊到 Consul 的服務名稱,後期客戶端會根據這個名稱來進行服務調用。

修改啓動類

 修改啓動器類,添加 @EnableDiscoveryClient 註解,開啓服務發現支持。

package com.louis.spring.cloud.consul.producer;

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

@EnableDiscoveryClient
@SpringBootApplication
public class ConsuleProducerApplication {

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

添加服務

新建 HelloController,提供 hello 接口, 返回 hello consul 字符串。

package com.louis.spring.cloud.consul.producer.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello() {
        return "hello consul.";
    }
}

爲了模擬註冊均衡負載,複製一份上面的項目,重命名爲 spring-cloud-consul-producer2 ,修改對應的端口爲 8512,修改 hello 方法的返回值爲:"helle consul two",修改完成後依次啓動兩個項目,啓動成功以後刷新Consul管理界面,發現咱們註冊的service-producer服務,並有2個節點實例。

點擊進入節點詳情頁面,能夠看到咱們註冊的8511和8512兩個服務提供者節點實例。

Consul 消費者

服務註冊發現中心有了,服務提供者也有了,如今咱們來開發服務消費者。

新建項目 spring-cloud-consul-comsumer,依賴同提供者。

添加配置

修改配置文件以下。

application.yml

server:
  port: 8521
spring:
  application:
    name: spring-cloud-consul-consumer
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        register: false    #設置不須要註冊到 consul 中

客戶端能夠設置是否註冊到 Consul 中,具體須要根據咱們的業務來選擇,通常在須要對外提供服務時進行註冊。

啓動器類

ConsuleConsumerApplication.java

package com.louis.spring.cloud.consul.producer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConsuleConsumerApplication {

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

服務消費者

添加消費服務測試類,添加兩個接口,一個查詢全部咱們註冊的服務,另外一個從咱們註冊的服務中選取一個服務,採用輪詢的方式。

ServiceController.java

package com.louis.spring.cloud.consul.producer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ServiceController {

    @Autowired
    private LoadBalancerClient loadBalancerClient;
    @Autowired
    private DiscoveryClient discoveryClient;

   /**
     * 獲取全部服務
     */
    @RequestMapping("/services")
    public Object services() {
        return discoveryClient.getInstances("service-producer");
    }

    /**
     * 從全部服務中選擇一個服務(輪詢)
     */
    @RequestMapping("/discover")
    public Object discover() {
        return loadBalancerClient.choose("service-producer").getUri().toString();
    }
}

添加完成以後,啓動項目, 訪問 http://localhost:8521/services,返回兩個服務,分別是咱們註冊的8511和8512。

[{
    "serviceId": "service-producer",
    "host": "GG20J1G2E.logon.ds.ge.com",
    "port": 8511,
    "secure": false,
    "metadata": {
        "secure": "false"
    },
    "uri": "http://GG20J1G2E.logon.ds.ge.com:8511",
    "scheme": null
}, {
    "serviceId": "service-producer",
    "host": "GG20J1G2E.logon.ds.ge.com",
    "port": 8512,
    "secure": false,
    "metadata": {
        "secure": "false"
    },
    "uri": "http://GG20J1G2E.logon.ds.ge.com:8512",
    "scheme": null
}]

反覆訪問 http://localhost:8521/discover,結果交替返回服務8511和8512,由於默認的負載均衡器是採用輪詢的方式。

http://GG20J1G2E.logon.ds.ge.com:8511
http://GG20J1G2E.logon.ds.ge.com:8512
...

8511 和 8512 兩個服務會交替出現,從而實現了獲取服務端地址的均衡負載。

大多數狀況下咱們但願使用均衡負載的形式去獲取服務端提供的服務,所以使用第二種方法來模擬調用服務端提供的 hello 方法。

建立 CallHelloController.java

package com.louis.spring.cloud.consul.producer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class CallHelloController {

    @Autowired
    private LoadBalancerClient loadBalancer;

    @RequestMapping("/call")
    public String call() {
        ServiceInstance serviceInstance = loadBalancer.choose("service-producer");
        System.out.println("服務地址:" + serviceInstance.getUri());
        System.out.println("服務名稱:" + serviceInstance.getServiceId());

        String callServiceResult = new RestTemplate().getForObject(serviceInstance.getUri().toString() + "/hello", String.class);
        System.out.println(callServiceResult);
        return callServiceResult;
    }

}

使用 RestTemplate 進行遠程調用。添加完以後重啓 spring-cloud-consul-consumer 項目。

在瀏覽器中訪問地址:http://localhost:8521/call,依次返回結果以下:

helle consul
helle consul two
...

 

源碼下載

碼雲:https://gitee.com/liuge1988/spring-cloud-demo.git


做者:朝雨憶輕塵
出處:https://www.cnblogs.com/xifengxiaoma/ 版權全部,歡迎轉載,轉載請註明原文做者及出處。

相關文章
相關標籤/搜索