Nacos实现配置管理
统一配置管理
- 配置更新热更新
统一配置的创建是在UI界面中完成的:
首先我们点击【配置管理】然后点击【配置列表】:
然后我们就看到了配置管理界面,但是此时这里是空的,我们可以创建一些配置文件:
点击这个加号:
然后就看到了配置的编写界面:
其中比较重要的就是配置的名称和配置内容。Data ID就是配置文件的名称,配置文件的名称的命名规范是:【服务名-环境名.后缀名】,比如我要创建一个userserver在dev环境下的统一配置管理,那么我的配置文件名就可以叫做:【userserver-dev.yaml】。描述指的就是你的配置文件的描述信息,也就是介绍一下你的配置文件是干什么用的。配置格式我们一般选择YAML,剩下的就是最重要的配置内容部分。
配置内容并不是将我们之前写的所有的内容直接粘贴进去,在这里面写的,主要是一些经常变动的部分,以及一些true和false产生不同效果的部分,比如我们的数据库的内容,我们并不需要变更他们,写一次就可以了,这种的我们就不会写在这里。我们以时间的格式化模板作为案例:
都写好之后,我们就可以点击【发布】按钮,将内容发布出去:
然后就可以看到我们刚才编写的配置文件了。
微服务配置拉取
配置获取的步骤如下:
项目启动之后,要优先读取nacos中的配置文件,然后再次读取本地的配置文件,但是要读取nacos的配置文件之前,要先知道nacos的地址,而nacos的地址存在于本地的application.yml文件中,所以,这里要使用另一个配置文件叫做:bootstrap.yml文件,这个文件的优先级要比application.yml文件的优先级要高很多,所以我们要把关于nacos的配置都写在这个里面。
- 1.引入Nacos配置管理客户端依赖:
<!-- Nacos的配置管理客户端依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
- 2.在userserver中的resource目录添加一个bootstrap.tml文件,这个文件是引导文件,优先级高于application.yml文件:
spring:
application:
name: userserver # 服务的名称
profiles:
active: dev # 环境
cloud:
nacos:
server-addr: localhost:8848 # 服务器的地址
config:
file-extension: yaml # 文件的后缀名
在这个文件中配置的东西,其中【服务名称】,【环境】,【文件的后缀名】这三个设置,就决定了在Nacos中配置的Data ID的内容,也是根据这三个内容能找到在Nacos中的对应的配置。
然后将之前在application.yml中的相同的配置注释掉。
之后就可以测试一下我们是否拉取到了在微服务中的配置,我们直接使用变量去注入我们在微服务中配置的配置项的内容,然后在Controller中创建一个方法,输出这个变量就知道我们是否拉取到了配置:
@Value("${pattern.dateformat}")
private String dataformat;
@GetMapping("data")
public String getDataformat(){
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dataformat));
}
其实我们并没有必要去访问方法,如果你的配置错误,那么在重启服务的时候你就已经无法重启了,会报出一个错误:
意思就是说,无法读取到你想要注入到变量中的配置项,所以说如果你的项目能启动起来,那么就说明你的配置是正确的。
我们也可以执行一下方法,也就是我们访问一下刚才在Controller中写入的方法对应的地址:
之前我们在微服务中配置的是一个日期格式化形式的参数,现在输入的跟我们在微服务中配置的形式一样。
这就说明,我们现在已经完成了配置的统一管理。
将配置交给Nacos管理的步骤:
- 在Nacos中添加配置文件
- 在微服务中引入nacos的config依赖
- 在微服务中添加bootstrap.yml,配置nacos地址,当前环境,服务名称,文件后缀名。这些决定了程序启动时去nacos读取那个文件。
配置热更新
Nacos中的配置文件变更后,微服务无需重启就可以感知。不过需要通过下面两种配置实现:
- 方式一:【在@Value注入的变量所在类上添加注解@RefreshScope】
package cn.itcast.user.web;
import cn.itcast.user.pojo.User;
import cn.itcast.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Slf4j
@RestController
@RequestMapping("/user")
@RefreshScope
public class UserController {
@Autowired
private UserService userService;
@Value("${pattern.dateformat}")
private String dataformat;
/**
* 路径: /user/110
*
* @param id 用户id
* @return 用户
*/
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id) {
return userService.queryById(id);
}
@GetMapping("data")
public String getDataformat(){
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dataformat));
}
}
这样就完成了第一种方式的配置,然后我们看一下当前的显示效果:
然后我们来到Nacos的配置管理界面:
将这里的配置修改一下,修改成其他样式都可以,然后我们点击【发布】:
出现这个确认界面,然后点击【确认发布】,之后我们重新访问刚才的Controller:
然后就看到,我们在没有重启服务的情况下,显示的效果就发生了改变,同时,在你的服务日志中,关于这次的配置文件修改也产生了对应的日志:
他会告诉你,dataId就是发生变化的配置文件,通知这些服务去更新一下。
- 方式二:使用@ConfigurationProperties注解
我们创建一个配置类,专门用来读取配置文件中的内容:
package cn.itcast.user.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "pattern")
@Component
@Data
public class PatternProperties {
private String dataformat;
}
在之前学习SpringBoot的时候,我们知道,这种@ConfigurationProperties的方式是一种约定大于规则的方式,也就是说,我们配上一个配置的前缀,这个前缀后面的所有的配置项都会自动注入到类中的与配置名相同的变量中。
然后我们使用这个类中的变量去代替之前使用@Value注入的变量:
package cn.itcast.user.web;
import cn.itcast.user.config.PatternProperties;
import cn.itcast.user.pojo.User;
import cn.itcast.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Slf4j
@RestController
@RequestMapping("/user")
@RefreshScope
public class UserController {
@Autowired
private UserService userService;
// @Value("${pattern.dateformat}")
// private String dataformat;
@Autowired
private PatternProperties patternProperties;
/**
* 路径: /user/110
*
* @param id 用户id
* @return 用户
*/
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id) {
return userService.queryById(id);
}
@GetMapping("data")
public String getDataformat(){
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(patternProperties.getDataformat()));
}
}
然后我们重启项目,将服务日志清空:
然后我们访问一下现在的显示方式:
然后我们去修改一下Nacos的配置:
修改之后发布,那么现在我们再次刷新页面,此时的显示方式应该是将年月日按照斜杠分割开的显示方式:
现在看到确实是这样的,并且我们看到服务的更新日志也提示我们有对应的配置更新:
并且最重要的是,我们并没有做其他的多余的配置,这些都是跟我们之前学习使用@ConfigurationProperties的过程是一样,没有多余的配置,也就是没有之前我们的RefreshScope,这就表示,他推荐我们使用@ConfigurationProperties的方式读取配置,以及做自动注入的配置。
总结:
Nacos配置更改后,微服务可以实现热更新,方式:
- 通过@Value注解注入,结合@RefreshScope来刷新
- 通过@ConfigurationProperties注入,自动刷新
注意事项:
- 不是所有的配置都适合放到配置中心,维护起来比较麻烦
- 建议将一些关键参数,需要运行时调整的参数放到nacos配置中心,一般都是自定义配置
微服务配置共享
当多环境中的某个配置的值是一样的,不管环境怎么变,都去这个配置中读取配置值。
微服务启动时会从nacos中读取多个配置文件:
- [spring.application.name]-[spring.profiles.active].yaml,例如:userserver-dev.yaml
- [spring.application.name].yaml,例如:userserver.yaml
无论profile如何变化,[spring.application.name].yaml这个文件一定会被加载,因此多环境共享配置可以写入这个文件。
然后我们来到Nacos的配置管理界面,我们新建一个配置文件,这个配置文件的文件名就叫做【userserver.yaml】,然后写入一些配置,至于配置的内容并不是很重要:
写好之后,我们发布出去:
然后就是来到读取配置的配置类中,添加一个新的变量:
package cn.itcast.user.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "pattern")
@Component
@Data
public class PatternProperties {
private String dateformat;
private String envSharedValue;
}
然后我们来到user服务的Controller中,添加一个方法,直接将读取配置信息的类返回出去即可,如果对应的变量有内容,则说明成功的读取到了:
@GetMapping("prop")
public PatternProperties patternProperties(){
return patternProperties;
}
然后就是,重启服务,访问Controller:
发现已经成功的读取到了两个配置文件,分别是dev环境的配置文件和环境共享配置文件,然后我们再次拷贝一个服务,这次我们将服务的环境改变,然后再次启动这个服务:
首先我们打开环境的编辑页面:
有一个配置项叫做【有效配置文件】,对应的英文名叫做【Active profiles】,在这里就可以不修改代码,而改变服务的运行环境,然后我们输入【test】,表示这个服务在测试环境中运行,启动之后,我们访问这个环境下的Controller:
此时启动了一个其他环境中的服务,就无法读取到dev服务中的变量了,但是依然能够读取到共享环境变量中中的属性值,这就是最基本的微服务的配置共享,就是不同环境之间的属性共享。
并且,每个服务所读取的配置文件名字,我们可以在运行日志中,看到服务所读取的内容是什么:
可以看到,这里就是读取了对应的环境配置文件,以及对应的环境共享配置文件。
属性冲突
当环境配置文件与环境共享配置文件中有属性冲突,会应用哪一个属性?又或者,我的云端配置属性与我的本地配置属性有冲突,会应用那个属性?这就是一个属性的优先级的问题。
其实我们可以在不同的配置文件中配置相同的属性,然后在Controller中读取,看最终是谁的值被读取了即可:
我们在三个地方分别配置同一个属性值:pattern.name
- 本地配置:
- 环境配置文件:
- 环境共享配置文件:
然后修改一下配置读取类:
package cn.itcast.user.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "pattern")
@Component
@Data
public class PatternProperties {
private String dateformat;
private String envSharedValue;
private String name;
}
然后我们重启服务,看一下最终是谁的配置文件被读取:
这一次是环境配置文件被读取,也就是说,当本地配置文件与云端配置文件冲突的时候,是以云端配置文件为准,并且都是云端配置文件,这里显示的是环境配置文件,而不是环境共享配置文件,那么也就说明,是环境配置文件大于环境共享配置文件,那么最终的配置文件优先级就是:
环境配置文件 > 环境共享配置文件 > 本地配置文件
Nacos集群搭建
Nacos生产环境下一定要部署为集群状态,部署方式如下:
首先看一下官方给出的Nacos集群图:
黑马的Nacos集群搭建:
搭建集群步骤:
- 搭建数据库,初始化数据库表结构
- 下载nacos安装包
- 配置nacos
- 启动nacos集群
- nginx反向代理
初始化数据库
Nacos默认数据存储在内嵌数据库Derdy中,不属于生产可用的数据库
官方推荐的最佳实践是使用带有逐层的高可用的数据库集群。
使用单点模式的数据库进行模拟:
初始化数据库语句:
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 database if not exists nacos;
use 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', '$2a10EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');
这里有一个小小的坑,就是如果你去官网复制,那么你大概率复制的就是2.1版本之后的数据库初始SQL语句,但是如果你的安装包用的不是2.1之后的版本,那么在最后的时候,你在新建配置文件的时候会报错,就是提示你【发布失败 请检查参数是否正确】,这时候你就要去检查你的SQL使用的是不是和你的Nacos版本不一致,区别就在于2.1版本之后在第一张表,也就是config_info这张表中多加个一个字段:
而这张表也就是我们写入配置文件的表,而这个字段是非空的,也就是说在早先的版本是没有这个字段的,所以就会报错,如果你报错了,改成早期版本的初始化SQL语句,也就是我上面的语句即可。
执行完成之后,可以看到在nacos中出现了12张表:
这样就完成了数据库的初始化。
下载Nacos
就使用之前下载的Nacos即可
配置Nacos
之前我们基本没有做任何的配置就可以直接使用Nacos,但是对于集群的搭建,我们需要做一些比较复杂的配置。
我们修改配置文件:
在conf文件夹中找到cluster.conf.example文件,并复制一份,将后缀名的example去掉,然后打开这个文件:
在这个文件中,我们主要配置的就是服务的节点信息,由于我们是本机启动,所以我们的ip地址都是127.0.0.1,而端口号就根据自己的机器,选择任意三个没有被占用的端口号即可:
127.0.0.1:8845
127.0.0.1:8846
127.0.0.1:8847
然后来到同一个文件夹下的另一个配置文件:application.properties配置文件,在这里,我们要配置MySQL的相关信息,因为我们的Nacos要将数据存储到MySQL中:
然后打开文件进行配置:
首先打开数据源信息,这一条之前是被注释掉的,现在打开它:
这就表示要使用MySQL数据源。
然后就是修改对应的信息:
#*************** Config Module Related Configurations ***************#
If use MySQL as datasource:
表示使用MySQL数据源
spring.datasource.platform=mysql
Count of DB:
MySQK数据库的数量
db.num=1
Connect URL of DB:
MySQL数据库的连接信息
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=@Gaoyang1
修改好之后,保存关闭即可
在WIndows中单点启动三台相同的服务,可以将安装包复制三份,然后将服务的端口号修改成三个不同的端口号,然后分别在不同的端口中启动相同的服务即可:
现在三个服务的端口号还没有修改,我们依次修改对应的端口号即可。
修改完成之后就可以启动服务,之前的启动方式我们是在启动程序后面加上了-m参数然后跟上单点启动的参数,但是现在我们用集群启动,就不需要加上参数,直接使用程序驱动即可:
出现这个语句,就表示集群已经启动成功了
Nginx反向代理
Nginx主要是做反向代理和负载均衡,也就是使用Nginx去管理这三台Nacos实例,我们首先拿到Nginx的安装压缩包:
然后解压到相关目录:
我们依然是来到conf目录,对Nginx做相关的配置:
修改nginx.conf:
打开之后,找到http节点,然后将下面的内容粘贴到http节点中任意一个位置即可:
修改内容如下:
upstream nacos-cluster {
server 127.0.0.1:8845;
server 127.0.0.1:8846;
server 127.0.0.1:8847;
}
server {
listen 1111;
server_name localhost;
location /nacos {
proxy_pass http://nacos-cluster
}
}
这段配置的意思就是说,upstream中配置的是要做代理的三个节点列表,然后server代理的相关配置,当我们访问localhost的80端口的时候,就相当于是访问上面的三个节点,并且当我们访问/nacos时,就相当于是访问下面的网址,打开nacos的UI管理界面,然后保存退出。
然后我们来到Nginx的主目录中,在这里打开一个黑窗口,输入命令启动Nginx:
start ./nginx.exe
输入之后不会有任何的回应,然后我们来到浏览器输入以下网址
localhost
如果你看到是这个界面:
开错啦哈哈,你的Nginx并没有运行。因为Nginx的默认端口是80端口,而现在的情况就是你的80端口被占用了,你需要去修改Nginx的默认端口,我改成了81,所以我需要访问下面的网址:
localhost:81
这个界面才是Nginx的正常登录界面,这个坑是因为我按照正常配置并没有看到对应的界面,我就去找找后台的进程去看看Nginx没有启动,但是我启动单点的Nacos能启动,我就想可能是Nginx没启动,没启动的原因是因为端口占用,大部分的服务一开始无法启动就是这个原因,确实是被占用了,就换个端口就行了,然后继续打开Nginx代理的Nacos界面:
只要你通过之前在Nginx中配置的地址和端口进入到Nacos,就表示已经进入了集群的Nacos中。
这里集群的端口号改了,那么在代码那边,之前写的nacos单点的地址就要改成现在的端口,也很简单,就是改成你现在启动的端口号就行,就是你在Nginx中配置的端口号:
之前这里是8848,现在改成1111即可,因为我在Nginx中配置的代理端口号就是1111,然后我们重启这个服务:
在新的界面,就可以看到我们刚才改配置之后重启的服务器就已经转移过来了。
然后我们可以像之前一样写一个统一配置:
这次写完之后就不一样了,我们在使用了MySQL的集群之后,这里的配置信息就会写入到MySQL中,我们可以看一下配置信息的写入位置:
这里,配置文件的名称和内容就都有了。
总结
集群搭建步骤:
- 搭建MySQL集群并初始化数据库表
- 下载解压nacos
- 修改集群配置(节点信息)、数据库配置
- 分别启动多个nacos节点
- nginx反向代理
坑:
- 一个坑就是Nacos的2.1版本之前和之后的初始化数据库的SQL语句不一样
- 一个坑就是Nginx启动成功与失败没有提示,你只能自己看是否启动成功,并且如果端口占用就需要去修改默认的启动端口号。
- 在使用IP地址的时候,我非常的建议是使用真实的IP,别用127.0.0.1,有时候可能会在连接集群的时候报错,但是你就是不知道怎么回事,就是因为IP地址导致的无法找到对应的服务,所以还是用你的IP代替127.0.0.1吧。