Nacos配置中心
當微服務部署的例項越來越多,達到數十、數百時,逐個修改微服務配置就會讓人抓狂,而且很容易出錯。我們需要一種統一配置管理方案,可以集中管理所有例項的配置。
Nacos一方面可以將配置集中管理,另一方可以在配置變更時,及時通知微服務,實現配置的熱更新。
啟動微服務時的流程:如圖
微服務要拉取nacos中管理的配置,並且與本地的application.yml配置合併,才能完成專案啟動。
但如果尚未讀取application.yml,又如何得知nacos地址呢?
因此spring引入了一種新的配置檔案:bootstrap.yaml檔案,會在application.yml之前被讀取,流程如下:
bootstrap.yaml檔案的優先順序高於application.yaml
設定配置中心
1、設定Nacos配置檔案
注意:專案的核心配置,需要熱更新的配置才有放到nacos管理的必要。基本不會變更的一些配置還是儲存在微服務本地比較好。
然後在彈出的表單中,填寫配置資訊:
Data Id命名規則:[服務名稱]-[profile].[字尾名] 如:userservice-dev.yaml 一定要遵守
2、配置微服務
①微服務都要匯入依賴
<!--nacos配置管理依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
②新增bootstrap.yaml
這裡的取名一定要和nacos配置的一樣
spring:
application:
name: userservice # 服務名稱
profiles:
active: dev #開發環境,這裡是dev
cloud:
nacos:
server-addr: localhost:8848 # Nacos地址
config:
file-extension: yaml # 檔案字尾名
這裡會根據spring.cloud.nacos.server-addr獲取nacos地址,再根據
${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
作為檔案id,來讀取配置。
本例中,就是去讀取userservice-dev.yaml
:
③業務中讀取nacos配置中心的配置
這裡的讀取都實現了配置熱更新,即更新nacos配置檔案無需重啟服務
有兩種方式,二選一即可。
-
方式一:@RefreshScope
- 使用@Value註解得到nacos配置檔案資訊
- 在@Value注入的變數所在類上新增註解@RefreshScope
- 使用nacos配置檔案資訊完成業務
-
方式二:@ConfigurationProperties註解代替@Value註解【推薦】
-
建立一個配置類,在類上面加入@Component @Data @ConfigurationProperties
!!!注意:這裡的prefix="變數是配置檔案中的字首名",String dateformat需要取名和配置檔案中一致
nacos配置檔案:
-
配置類:
```java
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component //作用:講從nacos中讀取到的資訊寫成物件並注入到spring容器
@Data //作用:在業務類注入該類即可呼叫其中的資訊
@ConfigurationProperties(prefix = "pattern") //讀取Nacos配置檔案的patterrn.dateformat屬性
public class PatternProperties {
private String dateformat;
}
```
-
業務中注入nacos配置檔案類,並呼叫配置資訊完成業務
@Slf4j @RestController @RequestMapping("/user") public class UserController { @Autowired private PatternProperties patternProperties; @GetMapping("now") public String now(){ return LocalDateTime.now().format(DateTimeFormatter.ofPattern(patternProperties.getDateformat())); } }
設定配置共享
引入:有些配置在開發和測試環境都是一樣的就可以使用配置共享
其實微服務啟動時,會去nacos讀取多個配置檔案,例如:
-
[spring.application.name]-[spring.profiles.active].yaml
,例如:userservice-dev.yaml -
[spring.application.name].yaml
,例如:userservice.yaml
而[spring.application.name].yaml
不包含環境,因此可以被多個環境共享。(即[spring.application.name]這個名字下的所有環境都會讀取到該配置檔案)
舉例:有兩個服務分別配置在userservice的dev和test環境執行;此時在nacos配置了一個userservice.yaml 和 userservice-dev.yaml;
結果:兩個服務都能讀到userservice.yaml、但只有dev環境的才可以讀到userservice-dev.yaml
1. 配置共享的優先順序
當nacos、服務本地同時出現相同屬性時,優先順序有高低之分:nacos的區域性 > nacos全域性 > 服務本地
【當有相同配置的時候優先順序高的覆蓋低的】
搭建Nacos叢集
注意:搭建叢集后,服務訪問的nacos介面就改成訪問nginx的介面。 如nginx是80介面,那服務的bootstrap.yaml配置檔案訪問nacos的介面改成80
1.叢集結構圖
官方給出的Nacos叢集圖:
其中包含3個nacos節點,然後一個負載均衡器代理3個Nacos。這裡負載均衡器可以使用nginx。
我們計劃的叢集結構:
三個nacos節點的地址:
節點 | ip | port |
---|---|---|
nacos1 | 192.168.150.1 | 8845 |
nacos2 | 192.168.150.1 | 8846 |
nacos3 | 192.168.150.1 | 8847 |
2.搭建叢集
搭建叢集的基本步驟:
- 搭建資料庫,初始化資料庫表結構
- 下載nacos安裝包
- 配置nacos
- 啟動nacos叢集
- nginx反向代理
2.1.初始化資料庫
Nacos預設資料儲存在內嵌資料庫Derby中,不屬於生產可用的資料庫。
官方推薦的最佳實踐是使用帶有主從的高可用資料庫叢集,主從模式的高可用資料庫可以參考傳智教育的後續高手課程。
這裡我們以單點的資料庫為例來講解。
首先新建一個資料庫,命名為nacos,而後匯入下面的SQL:
CREATE TABLE `config_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(255) DEFAULT NULL,
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改時間',
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
`app_name` varchar(128) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租戶欄位',
`c_desc` varchar(256) DEFAULT NULL,
`c_use` varchar(64) DEFAULT NULL,
`effect` varchar(64) DEFAULT NULL,
`type` varchar(64) DEFAULT NULL,
`c_schema` text,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';
/******************************************/
/* 資料庫全名 = nacos_config */
/* 表名稱 = config_info_aggr */
/******************************************/
CREATE TABLE `config_info_aggr` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(255) NOT NULL COMMENT 'group_id',
`datum_id` varchar(255) NOT NULL COMMENT 'datum_id',
`content` longtext NOT NULL COMMENT '內容',
`gmt_modified` datetime NOT NULL COMMENT '修改時間',
`app_name` varchar(128) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租戶欄位',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租戶欄位';
/******************************************/
/* 資料庫全名 = nacos_config */
/* 表名稱 = config_info_beta */
/******************************************/
CREATE TABLE `config_info_beta` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL COMMENT 'content',
`beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改時間',
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
`tenant_id` varchar(128) DEFAULT '' COMMENT '租戶欄位',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';
/******************************************/
/* 資料庫全名 = nacos_config */
/* 表名稱 = config_info_tag */
/******************************************/
CREATE TABLE `config_info_tag` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
`tag_id` varchar(128) NOT NULL COMMENT 'tag_id',
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL COMMENT 'content',
`md5` varchar(32) DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改時間',
`src_user` text COMMENT 'source user',
`src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';
/******************************************/
/* 資料庫全名 = nacos_config */
/* 表名稱 = config_tags_relation */
/******************************************/
CREATE TABLE `config_tags_relation` (
`id` bigint(20) NOT NULL COMMENT 'id',
`tag_name` varchar(128) NOT NULL COMMENT 'tag_name',
`tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',
`data_id` varchar(255) NOT NULL COMMENT 'data_id',
`group_id` varchar(128) NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
`nid` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`nid`),
UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';
/******************************************/
/* 資料庫全名 = nacos_config */
/* 表名稱 = group_capacity */
/******************************************/
CREATE TABLE `group_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字元表示整個叢集',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配額,0表示使用預設值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '單個配置大小上限,單位為位元組,0表示使用預設值',
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大個數,,0表示使用預設值',
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '單個聚合資料的子配置大小上限,單位為位元組,0表示使用預設值',
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大變更歷史數量',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改時間',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='叢集、各Group容量資訊表';
/******************************************/
/* 資料庫全名 = nacos_config */
/* 表名稱 = his_config_info */
/******************************************/
CREATE TABLE `his_config_info` (
`id` bigint(64) unsigned NOT NULL,
`nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`data_id` varchar(255) NOT NULL,
`group_id` varchar(128) NOT NULL,
`app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
`content` longtext NOT NULL,
`md5` varchar(32) DEFAULT NULL,
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`src_user` text,
`src_ip` varchar(50) DEFAULT NULL,
`op_type` char(10) DEFAULT NULL,
`tenant_id` varchar(128) DEFAULT '' COMMENT '租戶欄位',
PRIMARY KEY (`nid`),
KEY `idx_gmt_create` (`gmt_create`),
KEY `idx_gmt_modified` (`gmt_modified`),
KEY `idx_did` (`data_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租戶改造';
/******************************************/
/* 資料庫全名 = nacos_config */
/* 表名稱 = tenant_capacity */
/******************************************/
CREATE TABLE `tenant_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配額,0表示使用預設值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '單個配置大小上限,單位為位元組,0表示使用預設值',
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大個數',
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '單個聚合資料的子配置大小上限,單位為位元組,0表示使用預設值',
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大變更歷史數量',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改時間',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租戶容量資訊表';
CREATE TABLE `tenant_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`kp` varchar(128) NOT NULL COMMENT 'kp',
`tenant_id` varchar(128) default '' COMMENT 'tenant_id',
`tenant_name` varchar(128) default '' COMMENT 'tenant_name',
`tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc',
`create_source` varchar(32) DEFAULT NULL COMMENT 'create_source',
`gmt_create` bigint(20) NOT NULL COMMENT '建立時間',
`gmt_modified` bigint(20) NOT NULL COMMENT '修改時間',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';
CREATE TABLE `users` (
`username` varchar(50) NOT NULL PRIMARY KEY,
`password` varchar(500) NOT NULL,
`enabled` boolean NOT NULL
);
CREATE TABLE `roles` (
`username` varchar(50) NOT NULL,
`role` varchar(50) NOT NULL,
UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
);
CREATE TABLE `permissions` (
`role` varchar(50) NOT NULL,
`resource` varchar(255) NOT NULL,
`action` varchar(8) NOT NULL,
UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);
INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');
2.2.下載nacos
nacos在GitHub上有下載地址:https://github.com/alibaba/nacos/tags,可以選擇任意版本下載。
本例中才用1.4.1版本:
2.3.配置Nacos
將這個包解壓到任意非中文目錄下,如圖:
目錄說明:
- bin:啟動指令碼
- conf:配置檔案
進入nacos的conf目錄,修改配置檔案cluster.conf.example,重新命名為cluster.conf:
然後新增內容:如果裡面有ip地址就刪除換成如下(在生產環境就需要改成伺服器地址)
127.0.0.1:8845
127.0.0.1.8846
127.0.0.1.8847
然後修改application.properties檔案,新增資料庫配置
spring.datasource.platform=mysql
db.num=1
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=root
db.password.0=123
2.4.啟動
將nacos資料夾複製三份,分別命名為:nacos1、nacos2、nacos3
然後分別修改三個資料夾中的application.properties,
nacos1:
server.port=8845
nacos2:
server.port=8846
nacos3:
server.port=8847
然後分別啟動三個nacos節點:
startup.cmd
2.5.nginx反向代理
找到課前資料提供的nginx安裝包:
解壓到任意非中文目錄下:
修改conf/nginx.conf檔案,新增配置如下:新增到http內部
upstream nacos-cluster {
server 127.0.0.1:8845;
server 127.0.0.1:8846;
server 127.0.0.1:8847;
}
server {
listen 80;
server_name localhost;
location /nacos {
proxy_pass http://nacos-cluster;
}
}
在nginx.exe的目錄下開啟cmd啟動nginx:start nginx.exe
;而後在瀏覽器訪問:http://localhost/nacos即可。
2.6 服務端該埠
所有服務的程式碼中bootstrap.yaml/application.yml檔案配置如下:
spring:
cloud:
nacos:
server-addr: localhost:80 # Nacos地址
2.7.最佳化
-
實際部署時,需要給做反向代理的nginx伺服器設定一個域名,這樣後續如果有伺服器遷移nacos的客戶端也無需更改配置.
-
Nacos的各個節點應該部署到多個不同伺服器,做好容災和隔離