Nacos配置中心 (介紹與配置)

不吃紫菜發表於2023-02-09

Nacos配置中心

當微服務部署的例項越來越多,達到數十、數百時,逐個修改微服務配置就會讓人抓狂,而且很容易出錯。我們需要一種統一配置管理方案,可以集中管理所有例項的配置。image

Nacos一方面可以將配置集中管理,另一方可以在配置變更時,及時通知微服務,實現配置的熱更新。

啟動微服務時的流程:如圖

微服務要拉取nacos中管理的配置,並且與本地的application.yml配置合併,才能完成專案啟動。

但如果尚未讀取application.yml,又如何得知nacos地址呢?

因此spring引入了一種新的配置檔案:bootstrap.yaml檔案,會在application.yml之前被讀取,流程如下:

bootstrap.yaml檔案的優先順序高於application.yaml

image

設定配置中心

1、設定Nacos配置檔案

注意:專案的核心配置,需要熱更新的配置才有放到nacos管理的必要。基本不會變更的一些配置還是儲存在微服務本地比較好。

image

然後在彈出的表單中,填寫配置資訊:

Data Id命名規則:[服務名稱]-[profile].[字尾名] 如:userservice-dev.yaml 一定要遵守

image

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

image

③業務中讀取nacos配置中心的配置

這裡的讀取都實現了配置熱更新,即更新nacos配置檔案無需重啟服務

有兩種方式,二選一即可。

  • 方式一:@RefreshScope

    1. 使用@Value註解得到nacos配置檔案資訊
    2. 在@Value注入的變數所在類上新增註解@RefreshScope
    3. 使用nacos配置檔案資訊完成業務

image

  • 方式二:@ConfigurationProperties註解代替@Value註解【推薦】

    1. 建立一個配置類,在類上面加入@Component @Data @ConfigurationProperties

      !!!注意:這裡的prefix="變數是配置檔案中的字首名",String dateformat需要取名和配置檔案中一致

      nacos配置檔案:

image

 配置類:

 ```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;
 }
 ```
  1. 業務中注入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全域性 > 服務本地
【當有相同配置的時候優先順序高的覆蓋低的】

image

搭建Nacos叢集

注意:搭建叢集后,服務訪問的nacos介面就改成訪問nginx的介面。 如nginx是80介面,那服務的bootstrap.yaml配置檔案訪問nacos的介面改成80

1.叢集結構圖

官方給出的Nacos叢集圖:
image

其中包含3個nacos節點,然後一個負載均衡器代理3個Nacos。這裡負載均衡器可以使用nginx。

我們計劃的叢集結構:
image

三個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版本:

image

2.3.配置Nacos

將這個包解壓到任意非中文目錄下,如圖:

image

目錄說明:

  • bin:啟動指令碼
  • conf:配置檔案

進入nacos的conf目錄,修改配置檔案cluster.conf.example,重新命名為cluster.conf:

image

然後新增內容:如果裡面有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

image

然後分別修改三個資料夾中的application.properties,

nacos1:

server.port=8845

nacos2:

server.port=8846

nacos3:

server.port=8847

然後分別啟動三個nacos節點:

startup.cmd

2.5.nginx反向代理

找到課前資料提供的nginx安裝包:

image

解壓到任意非中文目錄下:

image

修改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的各個節點應該部署到多個不同伺服器,做好容災和隔離

相關文章