nacos1.4.1升级到2.1.2方案

2,200 阅读12分钟

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、配置文件全部先导出

登录对应的环境,先导出全部的配置文件

image.png

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

image.png

3、创建对应环境数据库

  • 创建数据库
  • 获取表结构,进入服务器的nacos\config目录下,下载nacos-mysql.sql,将文件中的表结构导入到数据库中

image.png

  • 将表结构数据导入到库中

/* * 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 ( 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 );

INSERT INTO users (username, password, enabled) VALUES ('nacos', '2a2a10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);

INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');

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', '2a2a10$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、访问页面

image.png

升级过程

1. 停止旧节点

使用Nacos目录下nacos/bin/shutdown.sh进行停止。

2. 替换文件

下载并解压缩nacos-server-2.1.2.tar.gz,将其下的binconftarget目录覆盖原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_key text NOT NULL COMMENT '秘钥';

ALTER TABLE config_info_beta ADD COLUMN encrypted_data_key text NOT NULL COMMENT '秘钥';

ALTER TABLE his_config_info ADD COLUMN encrypted_data_key text NOT NULL COMMENT '秘钥';

4、启动服务

单机启动命令(standalone代表着单机模式运行):

sh startup.sh -m standalone

集群启动(使用置数据库):

bash startup.sh

5. 观察是否启动成功

首先查看nacos目录下 logs/start.outlogs/nacos.log 观察到nacos启动成功的日志,如 Nacos started successfully in cluster mode. use xxx storage 说明程序已启动成功。

6、导入配置数据

image.png

  • 查看数据是否持久化到mysql中

image.png

线上集群升级步骤

升级前请先备份原先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_key text NOT NULL COMMENT '秘钥';

ALTER TABLE config_info_beta ADD COLUMN encrypted_data_key text NOT NULL COMMENT '秘钥';

ALTER TABLE his_config_info ADD COLUMN encrypted_data_key text NOT NULL COMMENT '秘钥';

2、停止旧节点

选择集群中一台Nacos1.X节点,使用Nacos目录下nacos/bin/shutdown.sh进行停止。

3、替换文件

下载并解压缩nacos-server-2.0.2.tar.gz,将其下的binconftarget目录覆盖原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

image.png

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.outlogs/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 trueUpgrade to 2.0.X

image.png

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字样。说明关闭双写。

image.png

10、需要注意点

Nacos2.0版本相比1.X新增了gRPC的通信方式,新增端口是在配置的主端口(server.port)基础上,进行一定偏移量自动生成。

98481000客户端gRPC请求服务端端口,用于客户端向服务端发起连接和请求
98491001服务端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发生了变化

image.png

image.png

  • 升级后为某个组件新增配置信息,代码中通过@Value是否能取得到

答:可以

  • 升级后为某个组件动态修改配置文件信息,代码中通过@Value是否能取得到新值

答:可以

  • 升级后在控制台将某个服务给手动下线,某个服务通过rpc是否还能调用的到该服务

答:不可以