Nacos是阿里巴巴的产品,相比Eureka功能更加丰富。

Nacos安装链接

Nacos安装包 提取码: 63wx ,将zip包解压出来即可

在bin目录中有的是Nacos的执行文件,在conf目录中有的是Nacos的配置文件,其中applcation.properties文件可以查看Nacos的启动端口

Nacos启动

进入Nacos的解压目录的bin中,其目录结构如下

nacos连接redis集群配置 nacos集群启动命令_spring

然后执行启动命令即可,其中windows命令如下

startup.cmd -m standalone

启动页面如下

nacos连接redis集群配置 nacos集群启动命令_spring cloud_02

在浏览器输入Console的链接即可登录,默认账号密码为Nacos

服务注册到Nacos

1、在cloud-demo父工程中添加spring-cloud-alibaba的管理依赖

<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>

注意:如果你的子工程有Eureka的依赖需要注释掉

2、添加nacos客户端依赖

<dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

3、修改user-service&order-service中的application.yml文件,添加nacos地址

spring:
   cloud:
     nacos:
       server-addr: localhost:8848 # nacos服务端地址

4、服务注册成功,在nacos服务页面可以看到,如下

nacos连接redis集群配置 nacos集群启动命令_spring cloud_03

Nacos服务分级存储模型

Nacos服务分级存储模型,第一级是服务、第二级是集群、第三级是服务的实例,如图所示

nacos连接redis集群配置 nacos集群启动命令_nacos连接redis集群配置_04

服务跨集群调用问题

如果集群之间的物理距离越大延迟就越高,为此服务跨集群调用的时候尽可能的去选择本地集群的服务,跨集群调用延迟较高,但本地集群不可访问时才访问其他集群

服务集群属性

1、修改application.yml文件,添加内容如下

spring:
  cloud:
    nacos:
      server-addr: localhost:8848 #nacos服务端地址
      discovery:
         cluster-name: HZ #配置集群名称,也就是机房的位置

2、在Nacos页面中就可以看到你配置的集群名称

nacos连接redis集群配置 nacos集群启动命令_java_05

NacosRule负载均衡

NacosRule的默认负载均衡是轮询

修改集群负载均衡

1、修改order-service中的application.yml,设置集群为HZ:

spring:
  cloud:
    nacos:
     server-addr: localhost:8848 #nacos服务端地址
     discovery:
      cluster-name: HZ #配置集群名称

2、然后在order-service中设置负载均衡的IRule为NacosRule,这个规则优先会寻找与自己同集群的服务

userservice:
  ribbon:
   NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule #负载均衡规则

NacosRule会优先访问本地集群,本地集群内的多个服务采用随机策略来进行负载均衡

Nacos权重负载均衡

在实际部署中会出现这个的场景:

1、服务器设备性能差异较大,部分实例所在的机器性能较好,另一些性能较差,我们希望性能较好的机器承担更多的用户请求。

Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高

1、在Nacos控制台可以设置实例权重值,首先选中实例后面的编辑按钮

nacos连接redis集群配置 nacos集群启动命令_java_06

2、将权重设置为0.1(0~1之间),测试可以发现8081被访问到的频率大大降低

nacos连接redis集群配置 nacos集群启动命令_nacos连接redis集群配置_07

如果权重改为0,则说明这个服务实例不会被访问,则用于服务的版本的升级

Nacos环境隔离

Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离

nacos连接redis集群配置 nacos集群启动命令_spring cloud_08

创建namespace

1、在nacos控制台创建namespace

nacos连接redis集群配置 nacos集群启动命令_java_09

2、修改order-service的applicaion.yml,添加namespace

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos服务端地址
      discovery:
        cluster-name: HZ
        namespace: c0ae74d4-276e-449d-9bd4-055fef48bf86 #命名空间id

3、如图服务设置namespace成功

nacos连接redis集群配置 nacos集群启动命令_spring_10

服务不能跨namespace访问其他服务

Nacos注册中心流程

nacos连接redis集群配置 nacos集群启动命令_spring cloud_11

临时实例与非临时实例

服务注册到nacos时,可以选择注册为临时实例或非临时实例,通过下面配置信息来设置

spring:
  cloud:
     nacos:
       discovery:
         ephemeral: false #设置为非临时实例

Nacos配置管理

统一配置管理

1、在nacos控制台中的配置列表进行添加配置

nacos连接redis集群配置 nacos集群启动命令_nacos_12

nacos发布的配置如下:

nacos连接redis集群配置 nacos集群启动命令_java_13

2、服务读取nacos发布的配置文件

引入nacos的配置管理客户端依赖:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

在userservice中的resource目录添加一个bootstrap.yml文件,这个文件是引导文件,优先级高于application.yml

spring:
  application:
    name: userservice #服务名称
  profiles:
    active: dev  #开发环境
  cloud:
    nacos:
      server-addr: localhost:8848
      config:
        file-extension: yaml #文件后缀名
# application.name、profiles.active和cloud.nacos.config.file-extension
# 组成了nacos的DataID,注意application.yml有重复的配置需要删除掉

在代码中读取配置

@RestController
@RequestMapping("order")
public class OrderController {

   @Value("${pattern.dateformat}")
   private String dateformat;

    @GetMapping("/query")
    public String query() {
        return dateformat;
    }
}

Nacos配置的热更新

nacos的配置文件变更后,微服务无需重启就可以感知,不过需要通过下面两种配置实现:

1、方式1:在@Value注入的变量所在的类上添加注解@RefreshScope

@RestController
@RequestMapping("order")
@RefreshScope
public class OrderController {

   @Value("${pattern.dateformat}")
   private String dateformat;

    @GetMapping("/query")
    public String query() {
        return dateformat;
    }
}

2、方式二:使用@ConfigurationProperties注解

创建一个配置类

@Data
@Component
@ConfigurationProperties(prefix = "pattern") //配置的前缀
public class PatternProperties {
    /** 前缀和变量名拼接成nacos发布的配置文件的配置属性 */
    private String dateformat;
}

在业务逻辑中使用

@RestController
@RequestMapping("order")
public class OrderController {
   @Autowired
   private PatternProperties properties;

    @GetMapping("/query")
    public String query() {
        return properties.getDateformat();
    }
}

这样即可实现nacos配置管理的热更新

Nacos多环境配置共享

微服务启动时会从nacos读取多个配置文件

[spring.application.name]-[spring.profiles.active].yaml,例如userservice-dev.yaml

[spring.application.name].yaml,例如userservice.yaml

无论profiles如何改变,[spring.application.name].yaml这个文件一定会加载,因此多环境共享配置可以写入这个文件

在@ConfigurationProperties注解的配置类中添加共享属性

@Data
@Component
@ConfigurationProperties(prefix = "pattern") //配置的前缀
public class PatternProperties {
    /** 前缀和变量名拼接成nacos发布的配置文件的配置属性 */
    private String dateformat;
    private String envSharedValue;
}

在Nacos的控制台中创建一个userservice.yaml的配置文件

nacos连接redis集群配置 nacos集群启动命令_nacos_14

注意:其中的userservice就是你服务中spring.application.name中的属性

多环境配置共享的优先级

[spring.application.name]-[spring.profiles.active].yaml>[spring.application.name].yaml>本地的yaml文件

Nacos集群搭建

Nacos集群搭建示意图

nacos连接redis集群配置 nacos集群启动命令_spring cloud_15

1、搭建数据库集群,在MySQL数据库中创建一个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、将nacos解压文件夹,复制三份来搭建集群

nacos连接redis集群配置 nacos集群启动命令_spring_16

进入到nacos/conf文件夹中,修改cluster.conf.example为cluster.conf

3、在cluster.conf文件中添加如下内容

#it is ip
#example
127.0.0.1:8845
127.0.0.1:8846
127.0.0.1:8847

4、配置Nacos的数据库信息,在/conf/application.properties文件中

#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
spring.datasource.platform=mysql

### Count of DB:
db.num=1

### Connect URL of DB:
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=123456

5、同时在application.properties文件中修改对应的端口,分别改成8845、8846、8847

### Default web context path:
server.servlet.contextPath=/nacos
### Default web server port:
server.port=8845

6、启动nacos集群,在对应的Nacos的bin目录中运行以下命令即可

startup.cmd

注意:Nacos的解压目录中不能有中文!!!

7、使用Nginx做集群的负载均衡,在conf/nginx.conf文件中配置如下信息

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
	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;
		}
	}
}

注意:要将原来的server配置给注释或者修改掉,点击nginx.exe即可

8、修改bootstrap.yml或者application.yml的配置,如下

spring:
  application:
    name: userservice #服务名称
  profiles:
    active: dev  #开发环境
  cloud:
    nacos:
      server-addr: localhost:80
      config:
        file-extension: yaml #文件后缀名

注册成功,在Nacos控制台可以看到,如下

nacos连接redis集群配置 nacos集群启动命令_java_17

在集群情况下配置和单体Nacos的情况一致