一、Nacos 簡介
Nacos 致力于幫助您發(fā)現(xiàn)、配置和管理微服務(wù)。Nacos 提供了一組簡單易用的特性集,幫助您快速實現(xiàn)動態(tài)服務(wù)發(fā)現(xiàn)、服務(wù)配置、服務(wù)元數(shù)據(jù)及流量管理。Nacos 幫助您更敏捷和容易地構(gòu)建、交付和管理微服務(wù)平臺。 Nacos 是構(gòu)建以“服務(wù)”為中心的現(xiàn)代應(yīng)用架構(gòu) (例如微服務(wù)范式、云原生范式) 的服務(wù)基礎(chǔ)設(shè)施。
nacos官網(wǎng):https://nacos.io/zh-cn/docs/what-is-nacos.html
二、Nacos 安裝
2.1、Nacos 環(huán)境依賴
Nacos 基于 java 開發(fā)的,運行依賴于64 bit JDK 1.8+環(huán)境。
前往官網(wǎng)下載JDK: Java Downloads | Oracle
2.2、Nacos 服務(wù)端安裝
由于Nacos是開源的,可以從github下載源碼編譯后安裝,也可以直接從github下載官方編譯好的安裝包進行安裝,本文直接使用官方編譯好的包進行安裝,基于目前官方最新release2.0.3版本。請勿使用2.x以下的版本,之前爆出過漏洞。2.x版本相對于1.x版本,性能也提升了10倍。
下載地址:https://github.com/alibaba/nacos/releases
三、Nacos 部署
3.1、單實例部署
單實例部署不適合生產(chǎn)環(huán)境,單點故障是致命的。
Linux 單實例非集群模式啟動命令:
startup.sh -m standalone
Linux 單實例非集群模式關(guān)閉命令:
shutdown.sh
訪問 nacos 管理頁面,初始化用戶名密碼均為 nacos
訪問地址:http://127.0.0.1:8848/nacos/index.html
端口默認為8848,ip需要替換為部署服務(wù)器實例的ip
3.2、 集群部署
3.2.1、集群架構(gòu)
- 高可用 Nginx 集群
- Nacos 集群(至少三個實例)
- 高可用數(shù)據(jù)庫集群(取代 Nacos 內(nèi)嵌數(shù)據(jù)庫)
3.2.2、模擬部署
環(huán)境信息:
系統(tǒng)版本 | 機器IP | 部署應(yīng)用 | 應(yīng)用版本 |
---|---|---|---|
CentOS8.5 | 192.168.230.1 | Nginx | nginx-1.18.0 |
CentOS8.5 | 192.168.230.129 | Nacos | 2.0.3 |
CentOS8.5 | 192.168.230.130 | Nacos | 2.0.3 |
CentOS8.5 | 192.168.230.131 | Nacos | 2.0.3 |
CentOS8.5 | 192.168.230.1 | MySQL | 5.7.32 |
使用vmware虛擬機模擬以上不同機器環(huán)境。
搭建步驟:
- 初始化 nacos數(shù)據(jù)庫
解壓下載的安裝包nacos-server-2.0.3.tar.gz至/usr/local目錄,找到/nacos/conf下的nacos-mysql.sql腳本
在MySQL實例創(chuàng)建 nacos庫并執(zhí)行sql腳本
修改修改 Nacos 配置文件,指向MySQL實例,替換其內(nèi)嵌數(shù)據(jù)庫
在application.properties中找到如下配置,該配置默認為注釋掉的,取消注釋即可,修改數(shù)據(jù)庫信息為實際的數(shù)據(jù)庫信息后保存。其他nacos服務(wù)實例也需要做同樣的修改
為了達到高可用,通常會有多個MySQL數(shù)據(jù)庫實例,nacos的配置文件也需要指定每一個MySQL實例的信息,例如:
- 集群配置
在/nacos/conf下找到cluster.conf.example文件,將其重命名為cluster.conf
修改cluster.conf文件,將其中的默認的ip信息刪除,將nacos集群中每一臺nacos實例的ip添加進去。集群中所有nacos實例都需要做以上集群配置,至此關(guān)于 nacos 的配置結(jié)束了,可以嘗試以集群模式啟動三個nacos實例了。
切換到/nacos/bin目錄下,執(zhí)行./startup.sh & tail -f /usr/local/nacos/logs/start.out
啟動nacos,并查看啟動日志,出現(xiàn)下面提示說明啟動成功
此時可以通過瀏覽器訪問每個nacos實例的控制臺,例如:http://192.168.230.131:8848/nacos
說明:如果三個實例以集群模式正常啟動,那么分別訪問三個實例的管理頁就是展示以上登錄頁了。如果不能訪問,則可能防火墻未開放 nacos 服務(wù)的端口,可執(zhí)行如下命令。
[root@localhost bin]# firewall-cmd --add-port=8848/tcp --permanent
success
[root@localhost bin]# firewall-cmd --reload
success
如果nacos啟動時報已下異常,有以下三種原因:
原因一:連不上MySQL數(shù)據(jù)庫,通常是由于MySQL數(shù)據(jù)庫所在的宿主機沒有開放3306端口導(dǎo)致的,在MySQL宿主機執(zhí)行以下命令即可
[root@localhost bin]# firewall-cmd --add-port=3306/tcp --permanent
success
[root@localhost bin]# firewall-cmd --reload
Success
原因二:由于nacos配置文件application.properties中默認的數(shù)據(jù)庫連接超時時間設(shè)置較短,如下圖,因為網(wǎng)絡(luò)延時等原因,MySQL可能會連接超時導(dǎo)致nacos啟動報錯,因此只需要將超時時間適當(dāng)設(shè)置長一些即可
原因三:虛擬機內(nèi)存不足,由于在vmvare創(chuàng)建虛擬機時,只給每個虛擬分配了1G的內(nèi)存,從nacos的啟動腳本startup.sh中可知,nacos以集群模式啟動時,默認分配的java堆內(nèi)存空間為2G,因此可判斷是由于虛擬機內(nèi)存不足導(dǎo)致nacos啟動報錯,修改虛擬機內(nèi)存為2G后可以正常啟動。
- Nginx 配置
修改 Nginx 配置文件 nginx.conf如下:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#nacos集群負載均衡
upstream nacos-cluster {
server 192.168.230.129:8848;
server 192.168.230.130:8848;
server 192.168.230.131:8848;
}
server {
listen 80;
server_name 192.168.230.1;
location / {
#root html;
#index index.html index.htm;
proxy_pass http://nacos-cluster;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
- 訪問控制臺
在瀏覽器輸入Nginx服務(wù)所在宿主機的ip即可訪問:
http://192.168.230.1/nacos/#/login
默認用戶名/密碼:nacos/nacos
切換至【集群管理】-【節(jié)點列表】,可查看nacos集群節(jié)點信息:
四、微服務(wù)集成Nacos
4.1、依賴組件版本選型
由于Spring Cloud Alibaba與Spring Boot 及Spring Cloud版本的兼容性要求非常嚴格,如果依賴選錯版本,很可能會導(dǎo)致服務(wù)啟動報錯從而導(dǎo)致啟動失敗。不過alibaba官方已經(jīng)給我們整理出了推薦的版本依賴關(guān)系:
由于我們使用的nacos是最新的2.0.3版本,從以上表格可以查詢到依賴的Spring Cloud Alibaba的版本為2.2.7.RELEASE。繼續(xù)根據(jù)Spring Cloud Alibaba的版本查詢畢業(yè)版本依賴關(guān)系表,如下圖,可以找到依賴的Spring Cloud版本為Hoxton.SR12,依賴的Spring Boot版本為2.3.12.RELEASE
因此,通過上述查詢,最終確定微服務(wù)依賴版本選型如下:
Spring Cloud Version | Spring Cloud Alibaba Version | Spring Boot Version | Nacos Version |
---|---|---|---|
Hoxton.SR12 | 2.2.7.RELEASE | 2.3.12.RELEASE | 2.0.3 |
官方版本說明:https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
4.2、注冊中心
首先新建demo-project-parent父工程,根據(jù)4.1 依賴組件版本選型選型確定的版本,在父pom文件統(tǒng)一定義好依賴的組件以及版本,如下:
<properties>
<java.version>1.8</java.version>
<spring-boot.version>2.3.12.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR12</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.7.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- spring boot 依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud 依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud alibaba 依賴 -->
<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>
4.2.1、服務(wù)提供者
在父工程下新建服務(wù)提供者子模塊micro-service-provider,并在pom文件引入依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
修改provider配置文件application.yml:
server:
port: 8081
spring:
application:
name: service-provider
cloud:
nacos:
discovery:
#nacos集群配置(Nginx)
server-addr: 192.168.230.1:80
provider啟動類:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
Provider測試Controller類:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProviderController {
@Value("${server.port}")
String port;
@GetMapping("/hi")
public String hi(@RequestParam(value = "name", defaultValue = "zmx",required = false) String name) {
return "hello " + name + ", i'm provider, my port:" + port;
}
}
4.2.2、服務(wù)消費者
在父工程下新建服務(wù)消費者子模塊micro-service-consumer,并在pom文件引入以下依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 需要注意的是引入openfeign,必須要引入loadbalancer,否則無法啟動。-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
修改consumer配置文件:
server:
port: 8082
spring:
application:
name: service-consumer
cloud:
nacos:
discovery:
#nacos集群配置(Nginx)
server-addr: 192.168.230.1:80
在工程的啟動類加上@EnableFeignClient注解,以開啟FeignClient的功能:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
寫一個feign客戶端FeignClient,去調(diào)用provider服務(wù)的接口:
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
//此處的value值對應(yīng)于provider服務(wù)application配置文件中的spring.application.name
@FeignClient(value = "service-provider" )
public interface ProviderClient {
@GetMapping("/hi")
String hi(@RequestParam(value = "name", defaultValue = "zmx", required = false) String name);
}
寫一個測試接口,讓consumer去調(diào)用provider服務(wù)的接口:
import net.myibc.client.ProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConsumerController {
@Autowired
ProviderClient providerClient;
@GetMapping("/hi-feign")
public String hiFeign(){
return providerClient.hi("feign");
}
}
啟動provider和consumer兩個工程,在nacos的【服務(wù)管理】-【服務(wù)列表】頁面查看,可見2個服務(wù)都已經(jīng)注冊成功:
注意:這里啟動所有服務(wù)后,可能在控制臺只能查看到某一個服務(wù),或者查不到注冊的服務(wù),查看nacos.log日志,發(fā)現(xiàn)報如下異常:
出現(xiàn)該異常的原因:當(dāng)nacos客戶端升級為2.x版本后,新增了gRPC的通信方式,新增了兩個端口。這兩個端口在nacos原先的端口上(默認8848),進行一定偏移量自動生成。
端口與主端口的偏移量描述:
9848:客戶端gRPC請求服務(wù)端端口,用于客戶端向服務(wù)端發(fā)起連接和請求
9849:服務(wù)端gRPC請求服務(wù)端端口,用于服務(wù)間同步等
7848:Nacos 集群通信端口,用于Nacos 集群間進行選舉,檢測等
因此,不難猜出,出現(xiàn)該問題的原因是由于nacos2.x版本新增的這兩個端口沒有在宿主機開啟防火墻白名單,導(dǎo)致nacos實例之間無法進行服務(wù)間數(shù)據(jù)同步,因而在控制臺無法查看到所有的服務(wù)注冊實例信息。只需要在nacos宿主機執(zhí)行以下命令即可:
[root@localhost bin]# firewall-cmd --add-port=9848/tcp --permanent
success
[root@localhost bin]# firewall-cmd --add-port=9849/tcp --permanent
success
[root@localhost bin]# firewall-cmd --add-port=7848/tcp --permanent
success
[root@localhost bin]# firewall-cmd --reload
Success
注意:如果是采用VIP/nginx代理集群的話,需要在nginx配置9848和9849這兩個端口的TCP請求轉(zhuǎn)發(fā),否則客戶端服務(wù)在啟動時因為無法連接到服務(wù)端這兩個端口,從而導(dǎo)致啟動失敗。如果不使用任何代理,在宿主機執(zhí)行以上開啟端口白名單命令后,只需要在客戶端服務(wù)application配置文件里配置naocs集群的節(jié)點的ip和端口即可,配置如下:
Nginx配置nacos TCP轉(zhuǎn)發(fā)配置:
#配置nacos TCP轉(zhuǎn)發(fā)
stream {
upstream nacos1 {
server 192.168.230.129:9848;
server 192.168.230.130:9848;
server 192.168.230.131:9848;
}
server {
listen 9848;
proxy_pass nacos1;
}
upstream nacos2 {
server 192.168.230.129:9849;
server 192.168.230.130:9849;
server 192.168.230.131:9849;
}
server {
listen 9849;
proxy_pass nacos2;
}
}
4.2.3、服務(wù)調(diào)用
在瀏覽器上輸入http://127.0.0.1:8082/hi-feign,瀏覽器返回響應(yīng):
hello feign, i'm provider ,my port:8081
可見瀏覽器的請求成功調(diào)用了consumer服務(wù)的接口,consumer服務(wù)也成功地通過feign成功的調(diào)用了provider服務(wù)的接口。
4.2.4、負載均衡
Feign使用了Spring Cloud Loadbanlancer作為負載均衡器??梢酝ㄟ^修改provider的端口,再在本地啟動一個新的provider服務(wù),那么本地有2個provider 服務(wù),端口分別為8081 和8083。在瀏覽器上多次調(diào)用http://127.0.0.1:8082/hi-feign,瀏覽器會交替顯示:
hello feign, i’m provider ,my port:8081
hello feign, i’m provider ,my port:8083
此時控制臺provider的實例數(shù)會變?yōu)?:
4.3、配置中心
4.3.1、配置中心客戶端
在父工程下新建nacos配置客戶端子模塊nacos-config-client,并在pom文件引入以下依賴:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
在bootstrap.yml(一定是bootstrap.yml文件,不是application.yml文件)文件配置以下內(nèi)容:
spring:
application:
name: nacos-config-client
cloud:
nacos:
config:
server-addr: 192.168.230.1:80
file-extension: yaml
prefix: nacos-config-client
profiles:
active: dev
在上面的配置中,配置了nacos config server的地址,配置的擴展名是ymal(目前僅支持ymal和properties)。注意是沒有配置server.port的,sever.port的屬性在nacos中配置。上面的配置是和Nacos中的dataId 的格式是對應(yīng)的,nacos的完整格式如下:
${prefix}-${spring.profile.active}.${file-extension}
- prefix 默認為 spring.application.name 的值,也可以通過配置項 spring.cloud.nacos.config.prefix來配置。
- spring.profile.active 即為當(dāng)前環(huán)境對應(yīng)的 profile,詳情可以參考 Spring Boot文檔。 注意:當(dāng) spring.profile.active 為空時,對應(yīng)的連接符 - 也將不存在,dataId 的拼接格式變成 p r e f i x . {prefix}. prefix.{file-extension}
- file-exetension 為配置內(nèi)容的數(shù)據(jù)格式,可以通過配置項 spring.cloud.nacos.config.file-extension 來配置。目前只支持 properties 和 yaml 類型。
啟動nacos,登陸控制臺http://192.168.230.1/nacos,創(chuàng)建一個Data ID ,完整的配置如圖所示:
寫一個RestController,在Controller上添加@RefreshScope注解實現(xiàn)配置的熱加載。該注解只有加載需要動態(tài)更新配置的類上才會生效,如果將該注解加在啟動類上,其他類中的動態(tài)更新是不會生效的,代碼如下:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RefreshScope
public class ConfigController {
@Value("${username:lily}")
private String username;
@RequestMapping("/username")
public String get() {
return username;
}
}
啟動工程nacos-provider,在瀏覽器上訪問http://127.0.0.1:8084/username,可以返回在nacos控制臺上配置的username的值zhangsan3。在nacos 控制臺上更改username的配置為lisi,在不重啟nacos-provider工程的情況下,重新訪問http://127.0.0.1:8084/username,返回的是修改后的值lisi,可見nacos作為配置中心實現(xiàn)了熱加載功能。
修改nacos中username配置前返回:
將nacos中username的值修改為lisi后重新請求返回:
注意:使用某些高版本的SpringCloud組件時,在啟動nacos配置客戶端服務(wù)的時候,可能會找不到bootstrap.yml配置文件,會報如下錯誤,只需要在系統(tǒng)環(huán)境變量中配置一下環(huán)境變量即可:spring.cloud.bootstrap.enabled=true
4.3.2、開啟權(quán)限認證
通常情況下,為了安全起見,客戶端服務(wù)在訪問nacos的時候都需要通過用戶名和密碼認證,nacos默認是沒有開啟認證的,如果需要開啟認證,首先需要編輯/nacos/conf/application.properties配置文件,找到nacos.core.auth.enabled=false配置項,如下圖,默認是false,表示權(quán)限認證是關(guān)閉的,修改為true即可開啟認證。修改完成后需要重啟所有nacos實例。
在application配置文件中配置nacos的用戶名和密碼,如下圖,首先將服務(wù)用戶名和密碼配置為一個不存在的用戶,啟動服務(wù)驗證權(quán)限配置是否生效:
啟動服務(wù),發(fā)現(xiàn)報了以下異常,code=403和unknown user,說明權(quán)限驗證失?。?/p>
將用戶名和密碼修改為正確的之后,再次啟動服務(wù),可發(fā)現(xiàn)服務(wù)啟動正常:
文章來源:http://www.zghlxwxcb.cn/news/detail-651976.html
至此,說明nacos的權(quán)限認證配置已生效。文章來源地址http://www.zghlxwxcb.cn/news/detail-651976.html
到了這里,關(guān)于【Spring Clound】Nacos高可用集群搭建與使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!