Nacos注册中心
(一)认识和安装Nacos
1、认识Nacos
2、安装nacos
这里下载1.4.1版本
默认端口是8848
下载解压后,终端进入到nacos/bin下,bash startup.sh -m standalone
然后查看start.out文件得到一个网址就可以查看nacos的服务列表,http://10.10.20.18:8848/nacos/index.html
(二)快速入门
1、服务注册到Nacos
在父工程中将springcloud-alibaba的管理依赖引入进来,以后它有关的所有版本都不用操心了
1、首先找到父工程的pom,已经有了springcloud的管理依赖,springcloudalibaba比较特殊,是后来才加入的,所以它没有在springcloud-dependencies中,需要单独去引入。所以直接将这个依赖放到springcloud-dependencies的下一个
<!-- springCloud -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope>
</dependency>
<!--nacos的管理依赖-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.5.RELEASE</version><type>pom</type><scope>import</scope>
</dependency>
2、接下来就可以改造服务了。
将userservice和orderservice的pom中的eureka的dependency注释掉,然后引入nacos客户端依赖包
<!--nacos客户端依赖包-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
3、修改yml文件
userservice和orderservice
将eureka的注释掉
往上找到spring这块,在spring的里面加上nacos的配置
userservice:
server:port: 8081
spring:datasource:url: jdbc:mysql://localhost:3306/cloud_user?useSSL=falseusername: rootpassword: root123456driver-class-name: com.mysql.jdbc.Driverapplication:name: userservice # user服务的服务名称cloud:nacos:server-addr: localhost:8848 # nacos服务端地址
mybatis:type-aliases-package: cn.itcast.user.pojoconfiguration:map-underscore-to-camel-case: true
logging:level:cn.itcast: debugpattern:dateformat: MM-dd HH:mm:ss:SSS
#eureka:
# client:
# service-url: # eureka的地址信息
# defaultZone: http://127.0.0.1:10086/eureka
orderservice
server:port: 8080
spring:datasource:url: jdbc:mysql://localhost:3306/cloud_order?useSSL=falseusername: rootpassword: root123456driver-class-name: com.mysql.jdbc.Driverapplication:name: orderservice # order服务的服务名称cloud:nacos:server-addr: localhost:8848 # nacos服务端地址
mybatis:type-aliases-package: cn.itcast.user.pojoconfiguration:map-underscore-to-camel-case: true
logging:level:cn.itcast: debugpattern:dateformat: MM-dd HH:mm:ss:SSS
#eureka:
# client:
# service-url: # eureka的地址信息
# defaultZone: http://127.0.0.1:10086/eureka
userservice:ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则
ribbon:eager-load:enabled: true # 开启饥饿加载clients: # 指定饥饿加载的服务名称- userservice
其他都不需要改,包括ribbon
启动两个userservice和一个orderservice:
点击userservice详情:
使用order/101、order/102、…测试,发现仍然是userservice轮询,因此负载均衡没有问题
2、总结
(三)服务多级存储模型
1、Nacos服务多级存储模型
之前是有两层概念,一层是服务,第二层就是实例。一个服务可以包含多个实例。
我们会将一个服务的多个实例部署到多个机房,就像把鸡蛋分散开了,这样就可以做到容灾
而Nacos服务多级存储模型就是引入了这样一个机房的概念,或者说地域的概念,它把存在一个机房的多个实例称为一个集群
2、服务跨集群调用问题
打开nacos中orderservice的详情,可以看到它集群名字为“DEFAULT”,也就是说没有集群。那下面我们就去学习如何配置实例的集群属性
3、服务集群属性
接下来我们要将UserApplication、UserApplication2放在hz集群,UserApplication3设置在sh集群
1、打开userservice的application.yml
spring:datasource:url: jdbc:mysql://localhost:3306/cloud_user?useSSL=falseusername: rootpassword: root123456driver-class-name: com.mysql.jdbc.Driverapplication:name: userservice # user服务的服务名称cloud:nacos:server-addr: localhost:8848 # nacos服务端地址discovery:cluster-name: HZ # 配置集群名称,也就是机房位置,例如:HZ,杭州
然后启动UserApplication和UserApplication2
那如果想要UserApplication3是SH集群,就是把userservice的application.yml中刚才那个cluster-name换成SH,然后再启动它。这个时候不要重启UserApplication和UserApplication2
4、总结
Nacos服务多级存储模型其实就是在原有分级上多做了一层,原来是两级,现在又把实例按照地域划分成了集群
(四)NacosRule负载均衡
1、服务集群属性
不过我们最终想要实现的是orderservice远程调用userserivce时优先选择本地集群,因此我们要给orderserivce也配置一个集群属性,
orderservice中的application.yml,给它也是HZ集群,然后重启orderservice
然后我们在浏览器中访问order/101、order/102、order/103
然后回到IDEA中看到UserApplication、UserApplication2、UserApplication3都有输出sql语句,说明它们都被访问了,也就是说orderservice发起远程调用时没有优先选择同集群,依然是采用轮询方案
我们知道服务在选择实例时,它的规则全都是由负载均衡的规则来决定的,也就是IRule。现在我们没有配置IRule,因此默认的规则就是轮询
2、根据集群负载均衡
修改负载均衡的规则同样是在yml里面。之前已经配置过orderservice的userservice的ribbon里负载均衡的规则了,不过配的是随机,现在只需要替换它
userservice:ribbon:NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
然后重启order服务
然后我们在浏览器中访问order/101、order/102、order/103、…、order/107,发现全部都在UserApplication和UserApplication2,UserApplication3一个都没有
nacos特点:优先选择本地集群,在本地集群内的多个服务当中再采用随机方式进行负载均衡
此时如果把8081和8082停掉会怎么样呢?
会发现本地集群没有服务时也能访问,
order中会出现一个警告信息
3、总结
(五)服务实例的权重设置
1、根据权重负载均衡
权重调为0时,就不会被访问!
2、总结
(六)环境隔离namespace
1、环境隔离
环境隔离就是在对服务service做隔离
那么我们来设置命名空间
那么怎么样去修改一个服务的命名空间呢?这个就不是在控制台修改的了,需要在代码区域了
就是添加了一个namespace,注意到填的不是名称是id
namespace: d2afdd92-4e10-47ee-be86-1b080c1ec582 # 命名空间,填id
然后重启orderservice
此时它们就是两个世界的人了,隔离,因此再访问就报错了:
2、总结
环境隔离是用namespace来做的
(七)Nacos和Eureka的对比
1、nacos注册中心细节分析
2、临时实例和非临时实例
将orderservice的修改:
spring:datasource:url: jdbc:mysql://localhost:3306/cloud_order?useSSL=falseusername: rootpassword: root123456driver-class-name: com.mysql.jdbc.Driverapplication:name: orderservice # order服务的服务名称cloud:nacos:server-addr: localhost:8848,localhost:8847,localhost:8849 # nacos服务端地址discovery:cluster-name: HZ # 配置集群名称,也就是机房位置,例如:HZ,杭州namespace: d2afdd92-4e10-47ee-be86-1b080c1ec582 # 命名空间,填idephemeral: false # 设置为非临时实例
此时先关闭orderservice,去nacos控制台,就没有了
再次启动orderservice
再在IDEA中关闭orderservice,nacos控制台中orderservice还在,只是红色了
再等很久这个服务也不会被剔除,除非手动删除它,否则永远都在
3、总结
(八)Nacos配置管理-Nacos实现配置管理
1、统一配置管理
打开nacos控制台,
点击加号,新建配置
切记这个配置内容不是把application.yml中一切内容都弄过来,只是有热更新需求的
(九)Nacos配置管理-微服务配置拉取
我们已经把部分配置放到nacos服务器上,下面我们的微服务就要想办法得到这些配置了
1、统一配置管理
与nacos地址和配置文件有关的所有信息都应该放到bootstrap.yml中
之前nacos-discovery是发现,这里config是配置
服务名称+开发环境+文件后缀名=控制台中配置的data id(userservice-dev.yaml),因此这个配置目的就是知道是哪个文件,而localhost:8848是nacos地址,就已经知道去哪读配置了,又知道了读取的配置叫什么名字
1、在userservice中引入nacos配置管理客户端依赖
<!--nacos的配置管理依赖-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2、bootstrap.yml
spring:application:name: userservice # 服务名称profiles:active: dev # 开发环境,这里是devcloud:nacos:server-addr: localhost:8848 # Nacos地址config:file-extension: yaml # 文件后缀名
application.yml中还有一些和它重复的地方,比如application:name:,cloud:nacos:,这些都删除,变成:
application.yml:
server:port: 8081
spring:datasource:url: jdbc:mysql://localhost:3306/cloud_user?useSSL=falseusername: rootpassword: root123456driver-class-name: com.mysql.jdbc.Driver
mybatis:type-aliases-package: cn.itcast.user.pojoconfiguration:map-underscore-to-camel-case: true
logging:level:cn.itcast: debugpattern:dateformat: MM-dd HH:mm:ss:SSS
好了,那如何证明我们已经从nacos拉到配置了呢?
那我们在UserController代码中试图读取这个配置
读取配置需要用**@Value注解**
@Value("${pattern.dateformat}")
private String dateformat;
如果这个dateformat能加载成功,就证明我们确实拿到了配置
@GetMapping("now")
public String now() {return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
}
这说明8081和8082这两个微服务都已经成功的从nacos控制台得到了这个配置信息
到这里,我们就实现微服务获取nacos中的配置信息了
2、总结
(十)Nacos配置管理-配置热更新
我们nacos控制中修改刚才那个配置模版
修改为:
我们希望改完以后http://127.0.0.1:8081/user/now微服务能立马变化,我们刷新,
虽然仍然显示当前时间,但没有根据配置变化。没有实现配置热更新
1、配置自动刷新
然后重启服务,
刷新页面,
没有重启微服务,因此实现了配置的热更新
这个方式二需要新建一个类,专门完成属性的加载
它采用的是约定大于配置的方式,只要前缀名和变量名两者拼接,与配置文件一致,就能完成属性的自动注入
为了让这个类可以被任何人使用,我们添加@Component注解,把它注册为Spring的一个Bean
然后在UserController中将@RefreshScope去掉,下面@Value的dateformat两个一起去掉。还要@Autowired注入PatternProperties
@Autowired
private PatternProperties properties;@GetMapping("now")
public String now() {return LocalDateTime.now().format(DateTimeFormatter.ofPattern(properties.getDateformat()));
}
重启,
更改配置,刷新,
2、总结
(十一)Nacos配置管理-多环境配置共享
1、多环境配置共享
比如有一个配置属性,在开发、生产、测试等环境下的值是一样的,那像这样的配置,在每个配置文件中都去写一份,是很浪费的;而且如果要改动,要在每个配置文件中都去改,这样显然是不合适的。我们想要找到一个地方,配一次以后,不管环境怎么变,这个配置都能被加载。这就是 多环境配置共享 的需求
现在我们有两个配置文件了,一个是第一个环境特有的,而另一个是多环境共享的
我们打开idea,要在userservice中读取刚才那个共享配置文件的属性,在PatternProperties增加一个,里面现在只有一个属性
private String envSharedValue;
然后为了展示,要在UserController中添加一个方法。注意因为UserController有一个@RestController注解,会将这个方法返回的PatternProperties自动转化成json字符串
@GetMapping("prop")
public PatternProperties properties() {return properties;
}
看userserivce的bootsrap.yml,看到它是dev环境,因此它可以同时读到userservice.yaml和userservice-dev.yaml
现在为了对比,再提供一个userserivce,把它的环境改一改,改成测试环境,只要将bootstrap.yml中dev改成test
!!但是如果这样改,将来重启又要改回来。这里有一种不需要更改代码的方法,右键UserService2,编辑配置,往下翻到最后,“有效配置文件“Active Profiles,这里就是激活的那个属性,跟在bootstrap.yml中配spring-profiles-active效果是完全一样的,填“test”即可,表示它是测试环境(虽然此时bootstrao.yml文件中仍然是dev但不影响)
然后重启它
这时8082的微服务是test环境,因此它不能读到userservice-dev.yaml,但它能读到共享的userserive.yaml文件
那如果userserive.yaml和userservice-dev.yaml中有一个相同的属性会以谁的为准呢?这其实考察的就是配置文件的优先级了;而且远端有配置,IDEA(application.yml)如果也有配置,那又以谁的优先级为准呢?
服务名-profile.yaml也就是带环境的;第二个是多环境共享
2、总结
(十二)Nacos配置管理-nacos集群搭建
1、Nacos集群搭建
之前我们一直使用的都是单点的nacos。但如果在企业中,更强调的是高可用,所以nacos一定要做成一个集群
条件有限,我们不会有三台电脑演示三个nacos,我们会在一台电脑上部署三个nacos结点
mysql理论上来说是集群,
(1)新建一个nacos数据库
新建查询:
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');