您好,登錄后才能下訂單哦!
這篇文章主要講解了“如何實現Nacos注冊中心”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“如何實現Nacos注冊中心”吧!
一個更易于構建云原生應用的動態服務發現、配置管理和服務管理平臺。
通俗解釋就是:Nacos是一個注冊中心&配置中心
服務發現和服務健康監測
動態配置服務
動態 DNS 服務
服務及其元數據管理
更多詳細內容請關注Nacos官方文檔
我們說Nacos是一個注冊中心,那么,什么是注冊中心呢?通過上面的關鍵特性不難發現,注冊中心提供了服務注冊,服務發現,服務健康檢查等基礎能力,使開發者能夠輕松地管理服務,在Spring Cloud家族中,代表性的有Spring Cloud Eureka, Spring Cloud Consul,以及早期Apache的Zookeeper, 這些都能稱之為注冊中心,如果之前沒有接觸過微服務的小伙伴可能有疑問,為什么需要注冊中心呢?
我們先來看看最原始的服務與服務之間的調用方式
相信這是最簡單的也是大家最熟悉的調用方式,在同一個公司中,A項目組(簡稱訂單服務)想要使用B項目組(簡稱商品服務)提供的能力時,往往就會采用這樣的方式,只需簡單的發送一個Http請求,即能獲取到對方的能力。
這樣的方式比較簡單,但同樣有一些問題,比如:
商品服務做服務遷移時,訂單服務將不得不跟隨著修改請求地址,然后重啟服務
商品服務做了集群時,訂單服務需要有負載均衡策略,不然就會造成商品服務單節點壓力過大
這時,有開發經驗的小伙伴就會說:搞個Nginx做負載均衡不就好啦!沒錯,當服務上到生產環境時,我們都會改成這樣的方式。
基于Http請求直接調用的問題,我們只需稍稍改變一下調用策略:中間增加一個Nginx,訂單服務不再直接調用商品服務,而且訪問Nginx,由Nginx進行轉發到商品服務上,此時,
如果商品服務ip地址發生變更:改動Nginx的代理配置即可
如果商品服務發生擴縮容:改動Nginx的負載均衡配置即可
完美解決Http請求直接調用的問題
一般來說,尋常的項目到這里就可以了,但是隨著業務的不斷迭代,需要的能力也逐漸增多,此時不僅僅只有訂單和商品服務,還出現了物流,積分,庫存,支付等等服務,不僅如此,這些服務與服務之間還會發生相互調用的情況,訂單調積分,物流調庫存,訂單調支付....此時服務與服務之間的調用情況就會像下面這樣:
不難想象,此時的Nginx配置將會打動每一位運維小哥。后續每一個服務配置發生改動,或者增加一個服務,運維小哥的心都將顫一顫。
直到有一天,開發:今天再加一個服務。
阿鑒在之前的公司就有幸目睹過運維小哥配置服務時nginx的樣子,三臺nginx的配置滿滿當當,令人頭皮發麻,不知道有沒有小伙伴遇到過這種情況呢
使用Nginx負載的方式確實是一個比較好的方式,但就是有些費運維小哥,我們不妨思考一下,除了運維小哥知道服務的地址信息,還有誰知道呢?
沒錯,就是服務本身!
我們將運維小哥配置服務地址的動作轉化成:服務啟動時向MySQL中插入一條數據。
Nginx路由轉發的動作改為:訂單服務到數據庫中查詢商品服務的地址,再發起調用。
Nginx負載均衡改為:訂單服務查詢出商品服務列表,自己選擇其中一個地址。
改變為的方式如下圖:
表結構中有個server_name字段,調用商品服務時使用server_name='goods-server'為條件查詢即可。
這樣子,我們就可以把運維小哥解放(kaichu)了。
善于思考的小伙伴不難看出其中帶來的問題:
所有的服務都需要連接這個MySQL,一但MySQL跪了,那咱也跪了。
每次服務發起調用時都需要查詢一次MySQL。
服務如果掛了,MySQL中的記錄仍舊存在。
那么我們現在就來著手解決這些問題吧
既然MySQL不行,我們就把它換成Redis,所有服務連一個MySQL不太現實,連Redis總行吧
每次調用前都要查詢一次,改成查詢后緩存到服務本地,同時啟動定時任務,每30秒更新緩存,服務調用時從緩存中獲取地址信息。
服務如果掛了,MySQL中的記錄仍舊存在:插入到Redis的數據有過期時間,而且服務啟動后開啟定時任務,每30秒就更新緩存,如果服務掛了,緩存自動過期。
嘿,現在在看這個方案,是不是比較完美了呢~
偷偷告訴小伙伴,Dubbo使用Redis做注冊中心時,就是這么玩的
雖然看起來完美,但是第二和第三點在真正使用時,產生的問題產生的足以讓人自閉,現在阿鑒給大家模擬一下自閉場景。
環境:訂單服務:一個實例,商品服務,兩個實例,A和B。
時間:1分00秒
訂單服務調用商品服務,正常。
A商品服務緩存過期時間剩余:29S
時間:1分01秒
A商品服務同步Redis緩存信息,Redis剩余過期時間:30S。
同時,A商品服務下線(掛了)
時間:1分02秒
訂單服務調用商品服務,由于A商品服務已下線,此時的調用時好時壞(調用B時正常)。
A商品服務在本地緩存過期時間剩余:28S
A商品服務Redis剩余過期時間: 29S
時間:1分29秒
本地緩存更新,刷新A商品服務緩存時間:30S
A商品服務Redis剩余過期時間: 1S,下一秒過期
時間:1分59秒
本地緩存更新,刷新A商品服務緩存:此時Redis緩存中已沒有A商品服務信息,所以本地緩存也將不再存在A商品服務信息。
訂單服務調用商品服務,正常(此時緩存里只有B商品服務信息)
模擬完畢
大家可以看到,在1分01秒時,A商品服務已經下線了,但是直到1分59秒時,訂單服務才能反應過來,這其中的58秒的服務調用時好時壞,怎么樣,要是在生產環境足夠讓人自閉了吧。
當然,如果在訂單服務上加上一個重試策略:在調用A商品服務失敗后,重試,調用B商品服務,就能較好的解決這個問題,但是假設A商品服務沒掛,它只是抖了一下,訂單服務又去調用了B商品服務,這等于一個接口同時調了兩次,這時又要考慮接口冪等性的問題了。
這時可能有小伙伴會說:冪等性的問題有啥的,Easy! 但一個項目的開發人員水平參差不齊,要求人人都做到這是不太現實的,不說了,說多了該被噴了。
這個問題的關鍵在于:被調用的服務掛了,調用方能不能及時感知到這個變化。
嘿,最早的Zookeeper(簡稱zk)就是來干這活的~ zk的臨時節點機制能使服務下線后,zk能夠立即感知,watch機制能夠使其他服務立即收到所監聽數據的變化。過多內容阿鑒這里就不再展開說了,有興趣的小伙伴可以自己研究一下,Zookeeper官網
聊了那么多,相信小伙伴已經有些感覺什么是注冊中心了哈,沒錯,以上都是注冊中心的能力,當我們把這些能力進行抽象,做成了一個服務時,那么這個服務,就叫做注冊中心!
下面這張阿鑒畫的圖還是有些好看哈
可以看到,注冊中心的基礎接口有4個:服務注冊,服務發現(獲取),心跳檢測,服務注銷
以下為使用注冊中心時服務的調用過程
訂單服務|商品服務啟動時,調用服務注冊接口,將自己的地址信息發送給注冊中心
訂單服務調用商品服務時,調用服務獲取接口,獲取到商品服務的地址信息,放入緩存
使用調用組件進行負載均衡,發起調用
商品服務下線,調用服務注銷接口,注冊中心剔除商品服務信息
當然,這樣的方式還是沒能解決
被調用的服務掛了,調用方能不能及時感知到這個變化
這個問題,到底該如何解決,我們放到后面再聊~
相信小伙伴已經明白了注冊中心的原理,那么現在我們就來手寫一個注冊中心吧,開始使用Nacos吧。
Nacos支持三種部署模式
單機模式 - 用于測試和單機試用。
集群模式 - 用于生產環境,確保高可用。
多集群模式 - 用于多數據中心場景。
環境:Ubuntu 18.04 LTS 一臺
Releases notes
這里選擇版本1.4.2
wget https://github.wuyanzheshui.workers.dev/alibaba/nacos/releases/download/1.4.2/nacos-server-1.4.2.tar.gz tar -xf nacos-server-1.4.2.tar.gz
Nacos支持兩種數據存儲方式
使用內置數據源實現數據的存儲,使用這種方式直接啟動Nacos即可
使用MySQL進行數據存儲,這種方式需要先有個MySQL
為了方便觀察數據存儲的基本情況,這里我們使用MySQL的存儲方式。
變變變,變出一臺MySQL,沒有MySQL的小伙伴可以參考安裝MySQL
執行初始化SQL腳本
腳本地址
修改配置文件
vim nacos/conf/application.properties
spring.datasource.platform=mysql ### Count of DB: db.num=1 ### Connect URL of DB: db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC db.user.0=nacos db.password.0=nacos nacos.core.auth.enabled=true nacos.core.auth.enable.userAgentAuthWhite=false nacos.core.auth.server.identity.key=abcd nacos.core.auth.server.identity.value=123456
其中db相關配置修改為自己的MySQL配置,
nacos.core.auth.server.identity.key
和nacos.core.auth.server.identity.value
自行定義
bash nacos/bin/startup.sh -m standalone
ubuntu系統需要使用bash命令,其他系統使用sh命令即可
此時在瀏覽器中輸入以下地址即可打開Nacos控制臺
127.0.0.1:8848/nacos/index.html
初始賬號密碼為:nacos | nacos
環境:Ubuntu 18.04 LTS 三臺,地址分別為:
192.168.2.11:8848
192.168.2.12:8848
192.168.2.13:8848
沒有三臺的小伙伴可以搭建一個偽集群用于測試,如127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850
集群模式搭建十分簡單,具體步驟如下:
將單機模式的配置復制三份到每個節點中
在每個節點的conf文件夾下新建cluster.conf
,配置如下
192.168.2.11:8848 192.168.2.12:8848 192.168.2.13:8848
依次啟動各個節點
bash startup.sh
這樣子nacos集群就搭建好了,但是在瀏覽器訪問時我們還需要一個nginx做負載均衡
變變變,變成一個nginx,如果沒有nginx的小伙伴可以參考安裝Nginx
配置反向代理
server { listen 8850; server_name _; location / { proxy_pass http://nacos-server; } } upstream nacos-server { server 192.168.2.13:8848 weight=5; server 192.168.2.12:8848 weight=5; server 192.168.2.11:8848 weight=5; }
訪問
由于我的Nginx在192.168.2.11上,所以我的訪問地址為:192.168.2.11:8848/nacos,初始賬號密碼同單機模式:nacos | nacos
Nacos已經搭建好了,接下來就是使用了。
下面阿鑒給大家介紹一下如何在Spring Cloud項目中使用Nacos
新建一個my-micro-service-demo
項目,并在pom.xml
中增加Spring Cloud相關依賴
<properties> <java.version>1.8</java.version> <spring.cloud-version>Hoxton.SR8</spring.cloud-version> <spring.cloud.alibaba-version>2.2.5.RELEASE</spring.cloud.alibaba-version> </properties> <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> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring.cloud.alibaba-version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
在項目中增加兩個子模塊,分別為my-order
和my-goods
, 并引入Nacos的依賴
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
編寫bootstrap.yaml
配置文件
server: port: 8080 spring: application: name: my-order main: allow-bean-definition-overriding: true cloud: nacos: discovery: server-addr: 192.168.2.11:8850 username: nacos password: nacos management: endpoints: web: exposure: include: "*"
商品服務修改一下服務名和端口號即可
編寫啟動類
package com.my.micro.service.order; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author Zijian Liao * @since 1.0.0 */ @SpringBootApplication public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
啟動項目,查看Nacos控制臺
服務注冊成功
服務已經注冊到Nacos上了,接下來,我們嘗試使用訂單服務調用商品服務吧
在畫的原理圖中,訂單服務是使用的一個調用組件
調用商品服務,大家先不必關心這個調用組件是什么,關于這部分內容,阿鑒會在后續的文章中詳解介紹。
在商品服務中編寫一個接口
@RestController @RequestMapping("/goods") public class GoodsController { @GetMapping("/get") public String get(){ return "商品服務響應了一個蘋果"; } }
在訂單服務中注入調用組件
@LoadBalanced @Bean public RestTemplate restTemplate(){ return new RestTemplate(); }
增加@LoadBalanced注解會使RestTemplate增加基于服務名進行調用的功能
發起調用
@RestController @RequestMapping("/order") public class OrderController { @Resource private RestTemplate restTemplate; @GetMapping("/get") public String get(){ // 舊方式:restTemplate.getForObject("http://127.0.0.1:8081/goods/get", String.class) // 現在直接使用服務名即可發起調用 return restTemplate.getForObject("http://my-goods/goods/get", String.class); } }
測試
Nacos還提供服務實例的上下線操作,在服務詳情頁面,可以點擊實例的上線
或者下線
按鈕,被下線的實例,將不會再被服務所獲取。
當然,前面也提到了,由于緩存的原因,服務下線后,調用方并不能立即感知到,需要等待一定的時間。
那么,這個功能可以用來做什么呢?
假設商品服務需要升級
運行版本:v1.0.0
升級版本:v1.1.0
我們先將v1.1.0部署到生產環境中,此時商品服務便有了兩個實例v1.0.0和v1.1.0,緊接著我們需要將舊版本下線
如果我們直接停止服務,此時商品服務正在處理業務,業務被中斷,造成的后果不可估摸。
如果我們先將v1.0.0下線,等待一段時間,此時便不會有服務再訪問v1.0.0了,便可以安全停止服務了。
在以往的注冊中心里,一般都是一個注冊中心只對應一整個微服務系統,這是因為只要有服務注冊到了注冊中心上,那么只要在這個注冊中心上的服務,都是可以相互訪問的,這樣就造成了每一個微服務系統,都要有一個自己的注冊中心,比如Eureka。
這就會造成一個資源浪費的問題,因為一個注冊中心明明是可以注冊成千上萬的實例的(Nacos服務發現性能測試報告),所以,Nacos還給我們提供了命名空間的功能,這使得服務與服務之間擁有了隔離機制(同一個命名空間下的服務才能相互訪問),這樣,每個命名空間便可以對應一個微服務系統。
新增命名空間
新增一個dev
命名空間與test
命名空間
修改服務配置
修改my-goods, 讓my-goods處于dev命名空間下
server: port: 8081 spring: application: name: my-goods main: allow-bean-definition-overriding: true cloud: nacos: discovery: server-addr: 192.168.2.11:8850 namespace: dev username: nacos password: nacos
修改my-order, 讓my-order處于test命名空間下
server: port: 8080 spring: application: name: my-order main: allow-bean-definition-overriding: true cloud: nacos: discovery: server-addr: 192.168.2.11:8850 namespace: test username: nacos password: nacos
重啟服務
查看Nacos控制臺
my-goods
my-order
測試
此時服務已經隔離了
感謝各位的閱讀,以上就是“如何實現Nacos注冊中心”的內容了,經過本文的學習后,相信大家對如何實現Nacos注冊中心這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。