一、Nacos的安裝
Nacos是阿里推出的一種注冊中心組件,并且已經開源,目前是國內最為流行的注冊中心組件。下面我們來了解一下如何安裝并啟動Nacos。
Nacos是一個獨立的項目,我們可以去GitHub上下載其壓縮包來使用,地址如下:
https://github.com/alibaba/nacos/releases/tag/2.2.3
下載完成之后解壓縮,打開Nacos下的bin文件夾,我們可以看到下面這四個文件?
我們可以依據自己機器的環境選擇要運行哪個啟動腳本,但需要注意的是,Nacos默認是集群啟動,如果你當前是單機環境進行啟動,運行腳本會閃退。如果我們想進行單機啟動,需要修改一下相關配置。下面,我們來了解一下Windows環境下修改的方式:
首先我們用記事本打開start.cmd文件,找到下面這行配置
將cluster改為standalone后保存退出,此時再運行啟動腳本,就能正常啟動Nacos了
并且nacos默認是使用Nacos端口,如果我們想修改這個端口,需要打開{Nacos文件夾所在目錄}/conf/applictaion.preperties文件,并將下面這行配置代碼的端口改為自己想要設置的端口
?需要注意的是端口號必須是未被使用的,否則啟動時會因為端口已被占用而啟動失敗。
成功啟動Nacos后,我們可以通過瀏覽器來訪問{Nacos所在機器Ip} :{Nacos端口號}/nacos,用來獲取一個nacos的可視化管理頁面。
Widows
在命令提示符中輸入netstat -ano | findstr :<端口號>
LInux?
netstat -ano | grep 端口號
成功啟動Nacos后,我們可以通過瀏覽器來訪問{Nacos所在機器Ip} :{Nacos端口號}/nacos,用來獲取一個nacos的可視化管理頁面。
二、Nacos的使用
下面我們來了解一下如何使用Nacos。
服務注冊
將服務注冊到Nacos,我們需要在各服務父工程中的pom文件中的<DependeceMannager>中聲明Spring Cloud Alibaba的相關依賴, 需要注意的是其版本需要與你當前的spring boot版本進行兼容,兩者之間的兼容關系大家可以去官網上查詢。然后在各服務的pom文件中引入Nacos的相關依賴,具體可以參考下面的代碼
父工程里面引入
<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>
子工程中引入
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
然后我們需要去設置Nacos的相關配置
cloud:nacos:discovery:server-addr: 182.92.242.181:8848
配置好之后我們就可以啟動服務了,成功啟動后就能在前面的Nacos的服務列表中看到我們注冊的服務了
咱們這里直接使用linux云服務器上面搭建Nacos
Nacos對比Eureka,Nacos的功能要更為豐富,下面我們來具體一下。
權重
Nacos可以為服務分配權重,權重越高的服務,在進行負載均衡時被選中的概率就越大。在Nacos提供的網頁中,我們可以去設置服務的權重。這里我們先啟動三個product-service服務(由于機器不足,都部署到一臺機器的不同端口上了),并注冊到Nacos中
點開服務最右邊的詳情頁,可以看到具體的三個服務實例,然后在點擊實例右邊的編輯按鈕
在彈出的頁面里我們就可以自己去編輯權重的大小了.這里我們把9092端口的服務權重設置成1,其它的設置為0.1
設置完成之后,權重并不會立馬生效,因為這里權重的配置可以說算是一種負載均衡策略,而我們本地服務的負載均衡策略使用的是LoadBalance默認的輪詢策略,因此要想讓權重生效,我們需要通過修改配置文件將負載均衡策略調整為Nacos的負載均衡策略,具體配置參考下面的代碼:
spring:cloud:loadbalancer:nacos:enabled: true
配置完成后,Nacos的負載均衡策略就生效了,我們剛才配置的權重也隨之生效了。
下面 我們來訪問一下order-service的接口(這個接口會遠程調用product-service,并在調用的服務中打印一條信息)。
打印的結果如下:
可以發現9092端口的product-service服務被調用的次數要遠遠多于另外兩個服務。
服務下線
在Nacos中可以讓一個服務下線,一個服務下線后,在其它服務進行服務發現時,就不會在獲取這個已下線服務的信息,也就不再會被遠程調用到。在Nacos中下線一個服務非常簡單,只需要在Nacos網頁服務列表中找到要下線的服務,打開詳情頁,選擇要下線是實例進行下線即可
?在這里,我們下線9092端口的服務,此時我們再多次訪問order-service的接口
可以發現9092端口的服務一次都沒有被調用了。然后我們再讓其上線看看,還是再剛剛下線的地方上線,再進行幾次接口訪問,可以發現,9092端口的服務又被調用到了
同集群優先
?在進行服務調用時,服務的提供者和服務的調用者如果在同一個機房或者同一個地區會比在不同機房不同地區受到網絡的影響要小很多,因為網絡的延遲通常是與距離成正比的。因此Nacos提供了一種同集群優先的負載均衡策略,在這種策略下,Nacos會把不同服務按地區分為不同集群,并在進行服務調用時,優先調用同一集群的服務,例如上海集群中的服務在進行服務調用時,會優先調用上海集群中的服務。下面我們來具體了解一下如何使用同集群由先:
首先我們需要在服務的配置文件中設置服務集群名稱,具體可以參考下面的代碼:
然后啟動服務,當前服務就被設置為在上海集群中了。
?接下來我們通過添加VM opition的方式將我們的9091.9092端口的product-service的服務設置為在上海集群,將9090設置為在北京集群,具體的設置方式可以參考下圖一個一個設置
此時我們再多次訪問order-service的接口(SH集群),控制臺的信息如下:
9091(SH集群)9092(SH)
9090(BJ)
可以發現與order-service在同一集群中的9091.9092服務都有被調用,而不同集群中的9090則一次沒有被調用。 但也并不是說完全不會調用其它集群中 的服務,如果調用的服務在當前集群中沒有,也是會去調用其它集群中的服務的。例如,我們把9091.9092下線,再訪問幾次接口
通過控制臺可以發現9090也被調用到了
健康檢查
Nacos會對注冊的服務進行健康檢查,具體來說就是去檢查看看服務還能不能被訪問到。Nacos健康檢查的機制有兩種,具體如下:
- 客戶端主動上報:服務主動向Nacos發送心跳來告知健康狀態,一般5s上報一次,如果超過15s未上報,該服務會被標記為不健康狀態,超過30s則會被直接刪除。
- 服務端反向探測?:Nacos主動探知服務進行健康檢查,間隔20s探測一次,如果檢查失敗,則會被標記為不健康狀態,并不會直接刪除
Nacos具體使用哪種機制依據當前服務實例的類型。下面 ,我們來了解一下服務實例的類型。
服務實例類型
在Nacos中,服務實例有兩種類型,一種是臨時實例,一種是非臨時實例。臨時實例在處于非健康狀態時,會被刪除,而非臨時實例在非健康狀態時則不會被刪除,而是會被標記為非健康。因此,臨時實例使用客戶端主動上報的健康檢查機制,而非臨時實例則是使用服務端反向探側。
我們可以在服務的配置文件中來配置當前服務是臨時實例還是非臨時實例,具體配置參考下面的代碼
spring:cloud:nacos:discovery:ephemeral: false # 設置為?臨時實例
需要注意的是Nacos服務實例的類型一旦確定就不能再更改了,因為Nacos會保存每一個服務對應的實例類型,如果服務以不同于先前的實例類型啟動(修改了ephemeral配置再啟動),就會報錯,解決辦法有兩種,一種是直接重啟Nacos,一種則則是刪除nacos目錄下/data/protocol/raft這個文夾這里面報存的服務的元數據。
否則會報錯
注意:在刪除raft/之前需要停止nacos,kill掉nacos進程
接下來我們將product-service全設置成臨時實例,oreder-servie設為非臨時實例,Nacos網頁中的顯示如下:
此時,如果我們終止一個product-service,再次查看Nacos網頁可以發現,product-service只剩下兩個了
而我們終止order-service,再次查看網頁,可以發現order-service仍然還在,只是健康狀態為false了
環境隔離
在企業中,一個服務的開發通常會經歷三個環境,開發環境(dev) ,測試環境(test),生產環境(prod)。處于不同環境下的服務之間是不能夠進行調用的,因此要對不同環境下的服務進行環境隔離。
在Nacos中通過Namespace(命名空間)來實現環境隔離,默認情況下所有注冊的服務都位于public命名空間中,我們可以自己創建一個命名空間,具體流程如下:
打開Nacos網頁,選擇命名空間
點擊新建命名空間
在彈出來的頁面就可以自定義創建我們的命名空間了
這里我們創建兩個命名空間,一個dev,一個prod?
接下來我們需要將我們的服務分配到這些命名空間中,具體為設置以下配置:
spring:cloud:nacos:discovery:namespace: 51152a13-7911-49e3-bbdc-16fd5670a257
?這里namespace的值為Nacos自動生成的命名空間id,可以去前面的命名空間頁面查看。
接下來我們將9091.9092的product-service服務和order-service放到dev命名空間中,剩下的9090端口的product-service放到prod服務中
此時再多次調用order-service的接口,可以發現和order-service 同樣位于dev命名空間中的9091.9092端口的product-service服務被調用到,而位于不同命名空間的9090則一次都沒用被調用到。
配置中心
Nacos除了上面的功能以外,還能作為配置中心進行使用。什么是配置中心呢?我們來了解一下。
在微服務項目中,同一個服務通常會采取集群模式部署到多臺主機上,當服務的配置需要修改時,如果一臺一臺機器去修改,就會顯得十分的麻煩,如果有一個統一的組件能夠讓我們在組件上修改配置,并將修改的配置信息推送到各個相關的服務主機上,那就會高效很多,而配置中心就是這樣一個組件。Nacos中就提供了配置中心的功能。
我們可以在Nacos中添加配置,添加的具體步驟如下
打開Nacos中的配置列表頁,點擊創建配置
這里的DataId暫且設置為服務名稱,配置格式選擇為properties,命名空間為我們前面的dev
?設置完成后點擊發布,就能看到我們剛才設置的配置了。
下面我們來看一下如何在服務端獲取Nacos中的配置。
首先我們需要在服務中引入Nacos配置中心的依賴,具體如下:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud 2020.*之后版本需要引?bootstrap-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
然后我們需要再創建一個bootstrap配置文件,這個文件會在appliaction前綴的配置文件被加載之前被加載,在這個文件中,我們需要去配置Nacos作為配置中心的相關信息。在服務啟動前,會先去讀取bootstrap前綴的配置文件,然后根據里面的配置內容去Nacos中獲取Nacos中的配置并整合到我們的application前綴的配置文件中。
spring:application:name: product-servicecloud:nacos:config:server-addr: 182.92.242.181:8848
這里主要配置了兩個信息一個是服務名稱,一個則是Nacos配置中心地址,這個地址與Nacos注冊中心的地址配置是隔離的。
下面我們通過@Value去獲取一下這個配置信息,代碼如下
@RestController
public class NacosController {@Value("${nacos.conf}")private String nacosConfg;@RequestMapping("/getConf")public String getConfig(){return "從Nacos獲取配置項nacos.config:"+nacosConfg;}
}
在Nacos中配置中心也是有命名空間的,在前面創建配置時也能看到當前創建的配置位于哪個命名空間中,因此我們在去獲取配置時,需要去指定命名空間,如果不指定,就只能從默認的命名空間(public)中去獲取配置。指定命名空間的配置如下(在bootstrap中配置):
spring:application:name: product-servicecloud:nacos:config:server-addr: 182.92.242.181:8848namespace: 8ac80256-2b42-4e3a-b085-b4cb8dcca495
當我們修改Nacos配置時候,按理說應該是實時更新的,但是我們發現沒有,這是因為我們得添加一個注解
在獲取配置時,并不是命名空間中創建的所有配置文件都會去獲取,只會去獲取對應DataId的配置,這個Dataid有固定的格式
${prefix}-${spring.profiles.active}.${file-extension}
- 其中prefix默認為服務名稱,也可以通過 spring.cloud.nacos.config.prefix來配置。
- spring.profiles.active為服務當前所處環境,可以通過spring.profiles.active配置項配置,這部分內容可以為空,為空時前面的‘-’會消除
- file-extension為讀取的配置格式,可以不設置,不設置為默認的properties,可以通過spring.cloud.nacos.config.file-extension配置項來配置,不過只支持yaml何properties兩種
需要注意的是上面的配置項在設置時,只能在bootstrap前綴的配置文件中設置
服務在去Nacos中獲取配置時,會獲取下面這三種DataId的配置內容