折騰一個周末,寫個Nacos可真不容易
大家好,我是雷小帥!之前一直有讀者想了解學習 Nacos,這次學習教程終于來了,相信你看完本文肯定可以入個門,再也不怕聽不懂架構師之間的對話啦!
什么是 Nacos
Nacos 是阿里巴巴開源的一款優秀的中間件,在分布式微服務場景下用的非常多。
Nacos 英文全稱 Naming and Configuration Service,其中 Na 是 naming 的縮寫,注冊中心;co為 configuration 的縮寫, 配置中心;
不管是配置中心還是注冊中心本質都是圍著服務(微服務)轉的,用官方的話來說:服務在 Nacos 里是一等公民。
Nacos 分為服務端和客戶端,這一點不要含糊。
Nacos Server
Nacos Server 使用 Java 語言編寫,提供了服務注冊發現和服務配置功能;對外提供了 SDK 接入以及HTTP RESTful 開放接口,SDK 接入和 RESTful 接口的功能是一致的。
Nacos Client
Nacos提供了官方的 SDK,遺憾的是只有 Java 版本,官方的 SDK 可以很方便與一些主流的框架進行集成,比如:Spring Cloud、Dubbo 等。
Nacos Client 主要的作用是訂閱獲取服務實例信息以及配置信息。
數據模型
在 Nacos中最重要的就是服務,為了方便管理還引入了數據模型這個概念,數據模型主要分為命名空間、集群、服務。
數據模型主要作用是給服務分類,方便維護管理。如果覺得抽象,簡單舉個例子:假如你叫張三,生活在武漢,國籍是中國,在其他城市或者省也有張三這個人。
Nacos 注冊中心原理
服務注冊成功后,為了向 Nacos Server 報告自己的健康狀態,客戶端每5秒向 Nacos server發送一次心跳,心跳帶上了服務名,服務ip,服務端口等信息。當然 Nacos server 也會向 client 主動發起健康檢查,支持tcp/http檢查。
如果15秒內無心跳且健康檢查失敗則會將該實例標記為不健康的狀態,如果30秒內健康檢查再次失敗則會直接剔除實例。
服務消費者訂閱成功后,如果服務提供者的實例不健康或者被剔除掉了,Nacos Server 會發送變更通知。
小試牛刀:Nacos 服務注冊發現功能體驗
對理論知識稍加理解后,我們可以動動小手,把 Nacos真正用起來吧。
搭建運行 Nacos Server
(1)下載 Nacos Server 安裝包,啟動 Nacos Server
進入 Github Nacos 下載主頁:
主頁鏈接:https://github.com/alibaba/nacos/releases
目前最新的穩定版本是 2.0.4,直接下載 zip 包或者 tar.gz包即可,windows 和 Linux 均可運行。
解壓完畢,如果是 Linux 系統,執行以下命令,以單實例的方式運行:
sh startup.sh -m standalone
如果是 windows 系統,執行以下命令:
startup.cmd -m standalone
(2)使用 Docker 啟動 Nacos Server
如果你電腦上已經裝了 Docker,建議你直接使用 Docker 來運行。
先拉取最新鏡像:
docker pull nacos/nacos-server
拉取成功后啟動實例:
docker run --name nacos-demo -e MODE=standalone -p 8848:8848 -p 9848:9848 -d nacos/nacos-server
這里有坑需要注意下,8848 是 Nacos Server 的主端口需要暴露出來,如果你安裝的是 Nacos 2.0 版本還需要將 9848 端口暴露出來,這里我含淚調試了一下午才知道的,哭暈……
為什么需要 9848 端口呢?因為 Nacos 2.0 版本之后默認將這個端口作為 grpc 的通信端口,官方提供的 Client SDK使用 grpc 來與 Nacos Server 進行通信,包括服務實例注冊、心跳檢查等功能。
這里需要說明下:grpc 的端口 = 主端口 + 偏移量1000,假如你的主端口是 8848,加上偏移量就是 9848。
熟悉 Nacos Server 控制臺界面
Nacos Server 運行成功后我們可以打開后臺管理界面,查看其運行狀態和管理信息。
本地訪問地址:http://127.0.0.1:8848/nacos。
第一次打開默認進入后臺登錄界面,默認用戶名和密碼都是:nacos。
登錄成功后可以看到左側的菜單欄,主要功能有:配置管理、服務管理、權限管理、命名空間、集群管理。
(1)服務管理
Nacos 的主要功能分為兩塊:配置管理和服務管理,這次主要展開講解服務管理。
展開菜單后,有服務列表和訂閱者列表兩塊,服務列表會顯示所有注冊到 Nacos Server 的服務,包括實例數、實例健康狀態等信息。
訂閱者列表會顯示某個服務下有哪些客戶端訂閱了,以及包括客戶端的版本信息等。
(2)權限控制
權限控制主要的作用是維護管理后臺系統的用戶角色和權限,一般的系統都有這個功能,這里不再贅述了。
(3)命名空間
命名空間比較好理解,比如同樣一個服務ServiceA可能會在研發環境、集成測試環境、生產環境各自部署一套,那如何區分它們呢?命名空間可以起這個作用,在下圖中,我新建了好幾個命名空間,用于將服務的注冊訂閱信息在邏輯上隔離開來。
(4)集群管理
Nacos Server可以是集群部署的也可以是單機部署,在實際生產環境中為了防止單點故障我們肯定不可能部署一個節點,為了方便測試演示,我在本地只啟動了一個節點,下圖中可以看到這個節點的ip、狀態等信息。
學習使用 Nacos Client SDK
目前官網只推出了 Java 版的 SDK,其他語言版本暫時靠社區自行貢獻。
我們拿 Java 版本 SDK 為例進行說明。
新建一個 Java Maven 工程,引入nacos-client 依賴:
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.0.3</version>
</dependency>
上面講過 Nacos 主要分為兩塊大的功能:配置中心、注冊中心,為了方便使用,Nacos-client 提供了三個工廠類:NacosFactory、ConfigFactory、NamingFactory,使用這些工廠類很容易生成對應實例對象。
NacosFactory 包含了 ConfigFactory 和 NamingFactory的所有功能,如果你想創建一個注冊中心功能的實例,你可以使用:
NacosFactory.createNamingService() 或者使用 NamingFactory.createNamingFactory()。
使用 Nacos Client 注冊實例
Nacos Client SDK 代碼非常簡單,基本一看就能學會怎么用,下面直接貼代碼,可以運行的那種代碼。
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
/**
* 模擬服務提供者注冊服務實例
*/
public class App {
public static void main(String[] args) throws NacosException {
// 使用工廠類創建注冊中心對象,構造參數為 Nacos Server 的 ip 地址,連接 Nacos 服務器
NamingService naming = NamingFactory.createNamingService("127.0.0.1:8848");
// 打印 Nacos Server 的運行狀態
System.out.println("server status: " + naming.getServerStatus());
// 模擬注冊當前服務實例,傳入參數:服務名、ip 地址、端口
naming.registerInstance("com.leixiaoshuai.rpc.provider", "11.11.11.11", 8888);
// 模擬當前進程不退出
while (true) {
}
}
}
看完 demo 之后有沒有同學比較好奇,Nacos Client 是通過什么協議與 Nacos Server通信的?簡單看下源碼就可以得到答案:Google grpc。
這里需要特別說明一下:在 Nacos 1.x 時代是使用 HTTP RESTful 接口與Nacos Server交互的,后面 2.x 時候為了提升效率改成了 grpc。
使用 Nacos Client 消費實例
假如服務 A 需要調用服務 B 的接口,首先得知道服務 B 實例的 ip 和端口,在這個場景下服務 A 就是服務消費者了,通過簡單的代碼很容易獲取到服務實例信息,為了方便感知服務實例變化,Nacos 還提供了事件通知能力。
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.listener.Event;
import com.alibaba.nacos.api.naming.listener.EventListener;
import com.alibaba.nacos.api.naming.listener.NamingEvent;
/**
* 模擬服務消費者訂閱服務實例
*/
public class App {
public static void main(String[] args) throws NacosException {
// 使用工廠類創建注冊中心對象,構造參數為 Nacos Server 的 ip 地址,連接 Nacos 服務器
NamingService naming = NamingFactory.createNamingService("127.0.0.1:8848");
// 打印 Nacos Server 的運行狀態
System.out.printf("server status: %s", naming.getServerStatus());
// 獲取指定服務所有的實例列表
System.out.println(naming.getAllInstances("com.leixiaoshuai.rpc.provider"));
// 訂閱指定服務,并注冊回調接口
naming.subscribe("com.leixiaoshuai.rpc.provider", new EventListener() {
@Override
public void onEvent(Event event) {
// 服務實例有變動就自動收到通知
System.out.println("~~event start");
System.out.println(((NamingEvent) event).getServiceName());
System.out.println(((NamingEvent) event).getInstances());
System.out.println("~~event end");
}
});
// 模擬當前進程不退出
while (true) {}
}
}
小結
Nacos 是阿里巴巴開源的一款中間件,常用于分布式微服務場景,主要功能包括兩大塊:服務注冊發現、服務配置。
Nacos 分為 server 和 client,可以在官網下載安裝包在本地運行,運行成功后通過后臺管理界面對 Nacos Server 進行管理和維護;
Client 端的接入方式有 SDK 和 HTTP RESTful 兩種方式,功能都是一樣的。