開發與維運

一文搞懂微服務架構之註冊中心

思維導圖

在這裡插入圖片描述

文章已收錄Github精選,歡迎Starhttps://github.com/yehongzhi/learningSummary

一、前言

伴隨著Eurka2.0版本已停止維護,開始要考慮使用微服務新一代的開源的註冊中心替代Eureka。

目前據我瞭解,Consul和Nacos是比較流行的兩種替代方案。這篇文章就介紹一下這兩種註冊中心在微服務中的簡單使用,希望對讀者有所幫助。

二、註冊中心的作用

註冊中心在微服務的架構中相當於一個“服務的通訊錄”。當一個服務啟動時,需要向註冊中心註冊服務,註冊中心保存了所有服務的服務名稱和服務地址的映射關係。當服務A想調用服務D時,則從註冊中心獲取服務D的服務地址,然後調用。

我畫張圖給大家描述會更清楚一點,大概如下:
在這裡插入圖片描述
可能會有人問,為什麼不直接通過服務地址調用服務D呢,還要從註冊中心去獲取服務D的服務地址。因為一個服務背後是不止一臺機器的,比如服務D可能在實際生產中是由三臺機器支持的,對外只暴露一個服務名稱,這樣可以避免寫死服務的IP地址在代碼中(寫在配置文件裡),在服務擴展時就非常方便了。

除了服務註冊之外,註冊中心還提供服務訂閱,當有新的服務註冊時,註冊中心會實時推送到各個服務。

還有服務健康監測,可以在管理界面看到註冊中心中的服務的狀態。

三、Consul

由Go語言開發,支持多數據中心分佈式高可用的服務發佈和服務註冊,採用ralt算法保證服務的一致性,且支持健康檢查。

3.1 安裝(win10版)

第一步,上官網下載安裝包。

第二步,解壓zip包,並配置環境變量。

在這裡插入圖片描述
第三步,唱跳rap籃球鍵ctrl+R,cmd,輸入命令consul

這就安裝成功了,超簡單!輸入consul -version驗證一下,會顯示版本號:

第四步,啟動。輸入命令consul.exe agent -dev本地啟動:

第五步,在瀏覽器中輸入http://localhost:8500打開管理界面。

3.2 服務註冊

接下來就需要創建兩個服務,分別是訂單(order)和用戶(user),註冊到consul。下面我就演示其中一個user服務。

首先創建一個SpringBoot工程,Maven配置如下:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
</parent>
<groupId>io.github.yehongzhi</groupId>
<artifactId>user</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency><!-- 健康監測的包 -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency><!-- spring-cloud-consul服務治理的jar包 -->
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        <version>2.0.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

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

然後yml配置文件如下:

server:
  port: 8601
spring:
  application:
    name: user
  cloud:
    consul:
      port: 8500
      host: 127.0.0.1
      discovery:
        service-name: user
        instance-id: ${spring.application.name}:${spring.cloud.consul.host}:${server.port}
        health-check-path: /actuator/health
        health-check-interval: 10s
        prefer-ip-address: true
        heartbeat:
          enabled: true

在啟動類加上開啟服務註冊的註解:

@SpringBootApplication
@EnableDiscoveryClient
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }

}

最後啟動項目即可,我這裡啟動兩個user,端口號分別是8601,8602:
在這裡插入圖片描述

3.3 服務調用

再創建一個訂單項目(order),和user配置類似,註冊服務到consul中。

下面演示一下用order服務調用user服務,首先定義user的接口:

@RestController
@RequestMapping("/mall/user")
public class UserController {
    @RequestMapping("/list")
    public Map<String, Object> list() throws Exception {
        Map<String, Object> userMap = new HashMap<>();
        userMap.put("1號佳麗", "李嘉欣");
        userMap.put("2號佳麗", "袁詠儀");
        userMap.put("3號佳麗", "張敏");
        userMap.put("4號佳麗", "張曼玉");
        return userMap;
    }
}

接著在order服務調用user服務,使用RestTemplate的方式:

@RestController
@RequestMapping("/mall/order")
public class OrderController {

    @Resource
    private LoadBalancerClient loadBalancerClient;

    @RequestMapping("/callUser")
    public String list() throws Exception {
        //從註冊中心中獲取user服務實例,包括服務的IP,端口號等信息
        ServiceInstance instance = loadBalancerClient.choose("user");
        //調用user服務
        String userList = new RestTemplate().getForObject(instance.getUri().toString() + "/mall/user/list", String.class);
        return "調用" + instance.getServiceId() + "服務,端口號:" + instance.getPort() + ",返回結果:" + userList;
    }
}

啟動兩個user服務,一個order服務,調用order的接口,可以看到結果:
在這裡插入圖片描述
在這裡插入圖片描述
負載均衡默認是輪詢訪問,所以交替調用8601和8602的user服務。

consul的簡單入門就講到這裡了,除了服務治理之外,consul還可以用於做配置中心,讀者有興趣可以自己探索一下。我這裡用的是dev模式,相當於單機模式,僅用於學習,實際生產的話肯定是集群模式,後面如果有時間我再專門寫一篇演示一下consul集群的搭建。

下面講另一款註冊中心,阿里出品的Nacos。

四、Nacos

以下介紹來源於官網:

Nacos 致力於幫助您發現、配置和管理微服務。Nacos 提供了一組簡單易用的特性集,幫助您快速實現動態服務發現、服務配置、服務元數據及流量管理

Nacos 幫助您更敏捷和容易地構建、交付和管理微服務平臺。 Nacos 是構建以“服務”為中心的現代應用架構 (例如微服務範式、雲原生範式) 的服務基礎設施。

總結就是,Nacos提供三種功能:服務發現及管理、動態配置服務、動態DNS服務。

我這裡主要講服務發現,也就是作為註冊中心的功能。

4.1 安裝

首先下載安裝包,目前穩定版是1.3.1,推薦在Linux或者Mac系統上使用,我懶得開虛擬機,所以我就直接在win系統安裝。
在這裡插入圖片描述
我這裡僅用於學習,使用單機模式,官網上介紹,雙擊startup.cmd文件啟動即可。


實際上,會報錯。

在這裡插入圖片描述
這個錯誤,我發現github上有人提出來,再後面加個參數就可以了。

但是又有人說後面的版本已經優化了,沒有這個錯誤。反正如果遇到的話,就加個參數啟動吧。完整命令是startup.cmd -m standalone

如果不想在啟動命令後面加參數,可以配置mysql(版本要求:5.6.5+),初始化mysql數據庫,數據庫初始化文件:nacos-mysql.sql。
在這裡插入圖片描述
修改conf/application.properties文件配置:

db.num=1
db.url.0=jdbc:mysql://數據庫地址:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=賬號
db.password=密碼

啟動成功,命令行窗口可以看到以下提示:

啟動成功後,可以在瀏覽器打開http://localhost:8848/nacos/,進入管理界面。賬號密碼默認都是nacos。
在這裡插入圖片描述
在這裡插入圖片描述

4.2 服務註冊

接下來還是一樣,創建兩個服務註冊到nacos,為了跟前面的區分,項目名後綴加上"nacos"。首先添加maven配置,如下:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Finchley.SR1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>0.2.2.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency><!-- SpringWeb依賴 -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency><!-- SpringCloud nacos服務發現的依賴 -->
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
</dependencies>

啟動類加上註解@EnableDiscoveryClient。

@SpringBootApplication
@EnableDiscoveryClient
public class UsernacosApplication {
    public static void main(String[] args) {
        SpringApplication.run(UsernacosApplication.class, args);
    }
}

配置文件application.properties文件加上配置。

server.port=8070
spring.application.name=usernacos
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

創建一個UserController接口,提供給其他微服務調用。

@RestController
@RequestMapping("/mall/userNacos")
public class UserController {
    @RequestMapping("/list")
    public Map<String, Object> list() {
        Map<String, Object> userMap = new HashMap<>();
        userMap.put("周杰倫", "愛在西元前");
        userMap.put("張學友", "只想一生跟你走");
        userMap.put("劉德華", "忘情水");
        userMap.put("陳奕迅", "K歌之王");
        userMap.put("衛蘭", "就算世界沒有童話");
        return userMap;
    }
}

運行啟動類的main方法,可以看到註冊中心多了一個usernacos服務。

4.3 服務調用

相同的配置和方法,再創建一個ordernacos服務,作為消費者。

@RestController
@RequestMapping("/mall/orderNacos")
public class OrderController {
    @Resource
    private LoadBalancerClient loadBalancerClient;

    @RequestMapping("/callUser")
    public String callUser() {
        ServiceInstance instance = loadBalancerClient.choose("usernacos");
        String url = instance.getUri().toString() + "/mall/userNacos/list";
        RestTemplate restTemplate = new RestTemplate();
        //調用usernacos服務
        String result = restTemplate.getForObject(url, String.class);
        return "調用" + instance.getServiceId() + "服務,端口號:" + instance.getPort() + ",返回結果:" + result;
    }
}

啟動2個usernacos服務,1個ordernacos服務。

測試接口http://localhost:8170/mall/orderNacos/callUser,order能順利調用user,默認負載均衡策略也是輪詢機制。
在這裡插入圖片描述
在這裡插入圖片描述

五、總結

國內用的比較多的是Nacos,我覺得原因有幾點:

  • 因為阿里目前用的就是Nacos,經歷過雙十一,各種秒殺活動等高併發場景的驗證。
  • 文檔比較齊全,關鍵有中文文檔,對於國內很多英文水平不是很好的開發者看起來真的很爽。
  • 很多從阿里出來的程序員,把阿里的技術帶到了各個中小型互聯網公司,一般技術選型肯定選自己熟悉的嘛。
  • 管理界面有中(英)文版本,易於操作。
  • 還有社區比較活躍,很多問題可以在網上找到解決方案。

這篇文章主要介紹了SpringCloud微服務關於註冊中心的兩種流行的實現方案,接下來還會繼續介紹其他關於微服務的組件,敬請期待。

上面所有例子的代碼都上傳Github了:

https://github.com/yehongzhi/mall

覺得有用就點個贊吧,你的點贊是我創作的最大動力~

拒絕做一條鹹魚,我是一個努力讓大家記住的程序員。我們下期再見!!!
在這裡插入圖片描述

能力有限,如果有什麼錯誤或者不當之處,請大家批評指正,一起學習交流!

Leave a Reply

Your email address will not be published. Required fields are marked *