nacos1.4.1升级到2.1.2方案
兼容性
Nacos2.0的服务端完全兼容1.X客户端。Nacos2.0客户端由于使用了gRPC,无法兼容Nacos1.X服务端,请勿使用2.0以上版本客户端连接Nacos1.X服务端。
配置中心
JAVA SDK
- 完全兼容1.X客户端所有API接口方法;
- 完全实现2.0客户端所有API接口方法。
服务发现
JAVA SDK
- 完全兼容1.X客户端所有API接口方法;
- 完全兼容2.0客户端所有API接口方法;
能否支持Nacos旧版本客户端?
配置中心兼容支持Nacos1.0起的所有版本客户端,服务发现兼容Nacos1.2起所有版本客户端。 因此建议使用Nacos1.2.0之后版本客户端。 但nacos1.X的客户端不具有长连接能力,因此仍然建议使用Nacos2.0客户端。
单节点升级步骤(持久化采用内置数据库的升级步骤)
由于我们的开发、测试、预生产环境,nacos采用的是单节点部署方式,且各个服务的配置信息是保存到内置数据库中。nacos 2.x版本之后数据库表 config_info、config_info_beta、his_config_info中需要新增字段 encrypted_data_key ,用来存储每一个配置项加密使用的秘钥 。而内置数据库无法直接添加表字段。因此需要将各个服务的配置信息保存的方式由内置数据库迁移到外部数据库mysql中才能进行升级
升级前提
1、配置文件全部先导出
登录对应的环境,先导出全部的配置文件
2、修改数据持久化方式
将原先使用内置数据库改为使用外部数据库(mysql)
- 登录服务器,进入nacos的conf文件夹,编辑application.properties配置文件,添加mysql相关信息
vim application.properties
添加mysql相关信息
spring.datasource.platform=mysql
### Count of DB: db.num=1
### Connect URL of DB: db.url.0=jdbc:mysql://10.160.0.41:3306/nacos-1.4.1?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC db.user.0=leelendb db.password.0=leelendb
3、创建对应环境数据库
- 创建数据库
- 获取表结构,进入服务器的nacos\config目录下,下载nacos-mysql.sql,将文件中的表结构导入到数据库中
- 将表结构数据导入到库中
/* * Copyright 1999-2018 Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LI… * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
// / 数据库全名 = nacos_config / / 表名称 = config_info / // CREATE TABLE
config_info(idbigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',data_idvarchar(255) NOT NULL COMMENT 'data_id',group_idvarchar(255) DEFAULT NULL,contentlongtext NOT NULL COMMENT 'content',md5varchar(32) DEFAULT NULL COMMENT 'md5',gmt_createdatetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',gmt_modifieddatetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',src_usertext COMMENT 'source user',src_ipvarchar(50) DEFAULT NULL COMMENT 'source ip',app_namevarchar(128) DEFAULT NULL,tenant_idvarchar(128) DEFAULT '' COMMENT '租户字段',c_descvarchar(256) DEFAULT NULL,c_usevarchar(64) DEFAULT NULL,effectvarchar(64) DEFAULT NULL,typevarchar(64) DEFAULT NULL,c_schematext, PRIMARY KEY (id), UNIQUE KEYuk_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(idbigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',data_idvarchar(255) NOT NULL COMMENT 'data_id',group_idvarchar(255) NOT NULL COMMENT 'group_id',datum_idvarchar(255) NOT NULL COMMENT 'datum_id',contentlongtext NOT NULL COMMENT '内容',gmt_modifieddatetime NOT NULL COMMENT '修改时间',app_namevarchar(128) DEFAULT NULL,tenant_idvarchar(128) DEFAULT '' COMMENT '租户字段', PRIMARY KEY (id), UNIQUE KEYuk_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(idbigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',data_idvarchar(255) NOT NULL COMMENT 'data_id',group_idvarchar(128) NOT NULL COMMENT 'group_id',app_namevarchar(128) DEFAULT NULL COMMENT 'app_name',contentlongtext NOT NULL COMMENT 'content',beta_ipsvarchar(1024) DEFAULT NULL COMMENT 'betaIps',md5varchar(32) DEFAULT NULL COMMENT 'md5',gmt_createdatetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',gmt_modifieddatetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',src_usertext COMMENT 'source user',src_ipvarchar(50) DEFAULT NULL COMMENT 'source ip',tenant_idvarchar(128) DEFAULT '' COMMENT '租户字段', PRIMARY KEY (id), UNIQUE KEYuk_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(idbigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',data_idvarchar(255) NOT NULL COMMENT 'data_id',group_idvarchar(128) NOT NULL COMMENT 'group_id',tenant_idvarchar(128) DEFAULT '' COMMENT 'tenant_id',tag_idvarchar(128) NOT NULL COMMENT 'tag_id',app_namevarchar(128) DEFAULT NULL COMMENT 'app_name',contentlongtext NOT NULL COMMENT 'content',md5varchar(32) DEFAULT NULL COMMENT 'md5',gmt_createdatetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',gmt_modifieddatetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',src_usertext COMMENT 'source user',src_ipvarchar(50) DEFAULT NULL COMMENT 'source ip', PRIMARY KEY (id), UNIQUE KEYuk_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(idbigint(20) NOT NULL COMMENT 'id',tag_namevarchar(128) NOT NULL COMMENT 'tag_name',tag_typevarchar(64) DEFAULT NULL COMMENT 'tag_type',data_idvarchar(255) NOT NULL COMMENT 'data_id',group_idvarchar(128) NOT NULL COMMENT 'group_id',tenant_idvarchar(128) DEFAULT '' COMMENT 'tenant_id',nidbigint(20) NOT NULL AUTO_INCREMENT, PRIMARY KEY (nid), UNIQUE KEYuk_configtagrelation_configidtag(id,tag_name,tag_type), KEYidx_tenant_id(tenant_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';// / 数据库全名 = nacos_config / / 表名称 = group_capacity / // CREATE TABLE
group_capacity(idbigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',group_idvarchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',quotaint(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',usageint(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',max_sizeint(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',max_aggr_countint(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',max_aggr_sizeint(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',max_history_countint(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',gmt_createdatetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',gmt_modifieddatetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (id), UNIQUE KEYuk_group_id(group_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';// / 数据库全名 = nacos_config / / 表名称 = his_config_info / // CREATE TABLE
his_config_info(idbigint(64) unsigned NOT NULL,nidbigint(20) unsigned NOT NULL AUTO_INCREMENT,data_idvarchar(255) NOT NULL,group_idvarchar(128) NOT NULL,app_namevarchar(128) DEFAULT NULL COMMENT 'app_name',contentlongtext NOT NULL,md5varchar(32) DEFAULT NULL,gmt_createdatetime NOT NULL DEFAULT CURRENT_TIMESTAMP,gmt_modifieddatetime NOT NULL DEFAULT CURRENT_TIMESTAMP,src_usertext,src_ipvarchar(50) DEFAULT NULL,op_typechar(10) DEFAULT NULL,tenant_idvarchar(128) DEFAULT '' COMMENT '租户字段', PRIMARY KEY (nid), KEYidx_gmt_create(gmt_create), KEYidx_gmt_modified(gmt_modified), KEYidx_did(data_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';// / 数据库全名 = nacos_config / / 表名称 = tenant_capacity / // CREATE TABLE
tenant_capacity(idbigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',tenant_idvarchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',quotaint(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',usageint(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',max_sizeint(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',max_aggr_countint(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',max_aggr_sizeint(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',max_history_countint(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',gmt_createdatetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',gmt_modifieddatetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (id), UNIQUE KEYuk_tenant_id(tenant_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';CREATE TABLE
tenant_info(idbigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',kpvarchar(128) NOT NULL COMMENT 'kp',tenant_idvarchar(128) default '' COMMENT 'tenant_id',tenant_namevarchar(128) default '' COMMENT 'tenant_name',tenant_descvarchar(256) DEFAULT NULL COMMENT 'tenant_desc',create_sourcevarchar(32) DEFAULT NULL COMMENT 'create_source',gmt_createbigint(20) NOT NULL COMMENT '创建时间',gmt_modifiedbigint(20) NOT NULL COMMENT '修改时间', PRIMARY KEY (id), UNIQUE KEYuk_tenant_info_kptenantid(kp,tenant_id), KEYidx_tenant_id(tenant_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';CREATE TABLE
users(usernamevarchar(50) NOT NULL PRIMARY KEY,passwordvarchar(500) NOT NULL,enabledboolean NOT NULL );CREATE TABLE
roles(usernamevarchar(50) NOT NULL,rolevarchar(50) NOT NULL, UNIQUE INDEXidx_user_role(usernameASC,roleASC) USING BTREE );INSERT INTO users (username, password, enabled) VALUES ('nacos', '10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');
CREATE TABLE
permissions(rolevarchar(50) NOT NULL,resourcevarchar(255) NOT NULL,actionvarchar(8) NOT NULL, UNIQUE INDEXuk_role_permission(role,resource,action) USING BTREE );
导入表结构时默认会插入两条数据,即为登录账号和密码
INSERT INTO users (username, password, enabled) VALUES ('nacos', '10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');
4、导入表结构可能出现的问题
当mysql的版本**<5.7**时会出现下方问题
添加表结构时会出现Specified key was too long; max key length is 767 bytes
CREATE TABLE permissions (
role varchar(50) NOT NULL,
resource varchar(512) NOT NULL,
action varchar(8) NOT NULL,
constraint uk_role_permission UNIQUE (role,resource,action)
)
1071 - Specified key was too long; max key length is 767 bytes 时间: 0s
这是MySQL在大字段上创建索引时,偶尔可能会遇到如下错误:
ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes.
可能原因
由于MySQL5,7之前的版本InnoDB引擎表索引字段长度的限制为767字节,因此对于多字节字符集的大字段或者多字段组合,创建索引时会出现该问题。
5、访问页面
- 重启nacos服务,访问http://ip:8848/nacos,看是否能正常进入nacos首页
升级过程
1. 停止旧节点
使用Nacos目录下nacos/bin/shutdown.sh进行停止。
2. 替换文件
下载并解压缩nacos-server-2.1.2.tar.gz,将其下的bin,conf,target目录覆盖原Nacos1.X的安装目录下。
3、数据库新增表字段
数据库表 config_info、config_info_beta、his_config_info中需要新增字段 encrypted_data_key ,用来存储每一个配置项加密使用的秘钥。新版本的默认创建表的sql中已经添加该字段。 对于目前已经搭建好的 Nacos 使用以下 sql 将字段添加到对应的表中:
ALTER TABLE config_info ADD COLUMN
encrypted_data_keytext NOT NULL COMMENT '秘钥';ALTER TABLE config_info_beta ADD COLUMN
encrypted_data_keytext NOT NULL COMMENT '秘钥';ALTER TABLE his_config_info ADD COLUMN
encrypted_data_keytext NOT NULL COMMENT '秘钥';
4、启动服务
单机启动命令(standalone代表着单机模式运行):
sh startup.sh -m standalone
集群启动(使用外置数据库):
bash startup.sh
5. 观察是否启动成功
首先查看nacos目录下 logs/start.out或logs/nacos.log 观察到nacos启动成功的日志,如 Nacos started successfully in cluster mode. use xxx storage 说明程序已启动成功。
6、导入配置数据
- 访问nacos-2.1.2控制台,http://ip:8848/nacos
- 导入先前从1.4.1版本导出的配置文件
- 查看数据是否持久化到mysql中
线上集群升级步骤
升级前请先备份原先nacos,升级前请先备份原先nacos,升级前请先备份原先nacos
1、数据库新增表字段
由于2.x版本的nacos数据库表 config_info、config_info_beta、his_config_info中需要新增字段 encrypted_data_key ,用来存储每一个配置项加密使用的秘钥, 对于目前已经搭建好的 Nacos 使用以下 sql 将字段添加到对应的表中:
ALTER TABLE config_info ADD COLUMN
encrypted_data_keytext NOT NULL COMMENT '秘钥';ALTER TABLE config_info_beta ADD COLUMN
encrypted_data_keytext NOT NULL COMMENT '秘钥';ALTER TABLE his_config_info ADD COLUMN
encrypted_data_keytext NOT NULL COMMENT '秘钥';
2、停止旧节点
选择集群中一台Nacos1.X节点,使用Nacos目录下nacos/bin/shutdown.sh进行停止。
3、替换文件
下载并解压缩nacos-server-2.0.2.tar.gz,将其下的bin,conf,target目录覆盖原Nacos1.X的安装目录下
4、 修改配置
4.1、数据库修改
在替换后的nacos的conf文件夹下编辑application.properties将数据库信息改为原先的信息,例如下方所示
vim application.properties
spring.datasource.platform=mysql
### Count of DB: db.num=1
### Connect URL of DB: db.url.0=jdbc:mysql://10.160.0.41:3306/nacos-cluster?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC db.user.0=leelendb db.password.0=leelendb
### Connection pool configuration: hikariCP db.pool.config.connectionTimeout=30000 db.pool.config.validationTimeout=10000 db.pool.config.maximumPoolSize=20 db.pool.config.minimumIdle=2
4.2、开启nacos数据双写
由于Nacos1.X和Nacos2.0的数据结构发生了变化,为了能够完成平滑升降级,需要将数据进行双写,分别生成Nacos1和Nacos2的数据结构进行存储。因此会对性能有一定影响。当集群升级并稳定运行后,可以关闭双写,关闭双写后将会失去平滑降级的功能。
在Nacos2.1.0版本后,默认关闭了双写能力,因此无法支持从Nacos1.X版本平滑升级到2.1.0的能力,若需要使用平滑升级能力,从Nacos1.X直接升级到Nacos2.1.0版本,需要在application.properties文件中设置配置nacos.core.support.upgrade.from.1x=true.
- 添加双写配置
在替换后的nacos的conf文件夹下编辑application.properties新增双写配置
vim application.properties
# 添加双写配置
nacos.core.support.upgrade.from.1x=true
4.3、集群列表
在替换后的nacos的conf文件夹下编辑cluster.conf
- 若conf文件夹下没有cluster,可以先克隆一份
cp cluster.conf.example cluster.conf
- 修改cluster.conf,增加各个nacos集群节点,例如下方
10.173.173.XX:8848
10.173.173.XX:8848
10.173.173.XX:8848
5、启动Nacos2.0
使用nacos目录下nacos/bin/startup.sh启动nacos2.0
6、观察是否启动成功
首先查看nacos目录下 logs/start.out或logs/nacos.log 观察到nacos启动成功的日志,如 Nacos started successfully in cluster mode. use xxx storage 说明程序已启动成功。
之后在观察 logs/naming-server.log 中,可以看到有upgrade check result false 以及 Check whether close double write等日志信息。
属于正常现象。
7、升级其他节点
待该节点的服务及实例信息已经同步完毕后(可从控制台进行确认)。重复1~6步骤,将其他的nacos节点也进行升级。
8. 确认升级完成
当集群中最后一个节点也升级到2.0.X版本时,集群会开始进行升级检测。每个节点会对该节点的服务信息和实例信息进行校验,并检测是否还有未完成的双写任务。
当集群中所有节点均判定为准备完毕时。Nacos集群中的节点会进行升级切换,自动升级到Nacos2.0的处理逻辑。
可以从logs/naming-server.log日志中观察到upgrade check result true及Upgrade to 2.0.X。
9 、关闭双写
当集群升级完成后,可以先观察一段时间运行情况,当确认无误后,可以关闭双写,从而释放性能,具体的关闭方式是通过API进行:
选择一台服务器进行关闭就可以
curl -X PUT 'localhost:8848/nacos/v1/ns/operator/switches entry=doubleWriteEnabled&value=false'
关闭后可以从logs/naming-server.log日志中观察到Disable Double write, stop and clean v1.x cache and features字样。说明关闭双写。
10、需要注意点
Nacos2.0版本相比1.X新增了gRPC的通信方式,新增端口是在配置的主端口(server.port)基础上,进行一定偏移量自动生成。
| 9848 | 1000 | 客户端gRPC请求服务端端口,用于客户端向服务端发起连接和请求 |
|---|---|---|
| 9849 | 1001 | 服务端gRPC请求服务端端口,用于服务间同步等 |
- 如果是采用VIP/nginx代理集群的话,需要在nginx配置9848和9849这两个端口的TCP请求转发,否则客户端服务在启动时因为无法连接到服务端这两个端口,从而导致启动失败。
- 如果不使用任何代理,在宿主机执行以上开启端口白名单
Nginx配置nacos TCP转发配置:例如
stream {
upstream nacos1 {
server 10.173.173.71:9848;
server 10.173.173.72:9848;
server 10.173.173.73:9848;
}
server {
listen 9848;
proxy_pass nacos1;
}
upstream nacos2 {
server 10.173.173.71:9849;
server 10.173.173.72:9849;
server 10.173.173.73:9849;
}
server {
listen 9849;
proxy_pass nacos2;
}
}
}
升级后的测试结论
- 升级后所有服务组件,在引入客户端依赖nacos-client为1.4.1不变的前提下,服务是否可以正常注册到nacos中,并正确调用服务
答:可以
- 升级后个别服务组件,在引入客户端依赖nacos-client为2.1.2的前提下,服务是否可以正常启动注册到nacos中?
答:可能服务没法正常启动,有些工具类包在2.2.1发生了变化
- 升级后为某个组件新增配置信息,代码中通过@Value是否能取得到
答:可以
- 升级后为某个组件动态修改配置文件信息,代码中通过@Value是否能取得到新值
答:可以
- 升级后在控制台将某个服务给手动下线,某个服务通过rpc是否还能调用的到该服务
答:不可以