提示:以下是本篇文章正文内容,SpringCloud Alibaba 系列学习将会持续更新
Nacos 更加全能的注册中心
Nacos
(Naming Configuration Service)是一款阿里巴巴开源的服务注册与发现、配置管理的组件,相当于是 Eureka + Config 的组合形态。
一、安装与部署 (服务端)
🍇1.1 下载服务端程序
Nacos 服务器是需要独立安装部署的,官方下载地址:https://github.com/alibaba/nacos
下载好的压缩包如下:
我们可以看看解压后的内容:
🍇1.2 部署和配置
方案一:在IDEA中配置,直接将解压后的Nacos文件夹拖到项目工程下,然后进行如下配置:
①其中 -m standalone
表示单节点模式。
②Mac 和 Linux 下记得将 解释器路径 Interpreter path 设定为 /bin/bash
。
③Nacos 在 Windows 下只能前台执行。而在 Mac/Linux 默认是后台启动模式,我们修改一下它的 startup.sh
文件,让它变成前台启动,这样 IDEA 关闭了 Nacos 就自动关闭了,否则开发环境下很容易忘记关。
# 注释掉最后两行
# nohup "$JAVA" "$JAVA_OPT_EXT_FIX" ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
# echo "nacos is starting,you can check the ${BASE_DIR}/logs/start.out"
# 替换成下面的
$JAVA ${JAVA_OPT} nacos.nacos
方案二:更推荐的方式是在外部部署。我们可以创建一个 startup.bat 作为启动程序,编辑指令为 startup.cmd -m standalone
🍇1.3 启动 Nacos
OK,启动成功。访问地址:http://localhost:8848/nacos/index.html
默认的用户名 和 管理员密码都是 nacos
,直接登陆即可,可以看到进入管理页面之后功能也是相当丰富.
至此,Nacos 的安装与部署完成。
二、服务注册与发现 (客户端)
🍬2.1 引入依赖
现在我们要实现基于 Nacos 的服务注册与发现,还是用之前的 脚手架项目,那么就需要导入 SpringCloudAlibaba 相关的依赖,我们在父工程将依赖进行管理:
<dependencyManagement>
<dependencies>
<!-- 这里引入最新的 SpringCloud 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 这里引入最新的 SpringCloudAlibaba 依赖,2021.0.1.0 版本支持 SpringBoot2.6.X -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.0.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
客户端:接着我们就可以在子项目中添加服务发现依赖了,比如我们以图书服务为例:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
🍬2.2 启动类注解
我们需要用 @EnableDiscoveryClient
注解修饰所有服务启动类,这一步也可以省略。
@EnableDiscoveryClient
@SpringBootApplication
public class BookApplication {
public static void main(String[] args) {
SpringApplication.run(BookApplication.class, args);
}
}
🍬2.3 配置文件
和注册到 Eureka 一样,我们也需要在服务们的配置文件中配置 Nacos 注册中心的地址:
spring:
application:
name: bookservice
cloud:
nacos:
discovery:
# 配置 Nacos注册中心地址
server-addr: localhost:8848
接着启动我们的图书服务,可以在 Nacos 的服务列表中找到:
我们可以将其它两个服务也注册到 Nacos 中
🍬2.4 OpenFeign 远程调用
例如,我们的 borrowervice 服务需要远程调用另外两个服务,那么我们需要使用 OpenFeign,实现服务发现远程调用以及负载均衡。
①先在我们的 borrowservice 消费端导入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 这里需要单独导入 LoadBalancer 依赖 -->
<!-- 否则会报错: No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalancer? -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
②消费端的启动类添加 @EnableFeignClients
注解:
@EnableFeignClients
@SpringBootApplication
public class BorrowApplication {
public static void main(String[] args) {
SpringApplication.run(BorrowApplication.class, args);
}
}
③编写远程接口:
- 可以选择把接口创建到本系统模块的某个包下,但该接口仅能被该服务模块调用,这种方式仅适用于学习阶段。
- 也可以创建 API 模块,将所有的远程接口放在该模块下。这样远程接口就可以被其它微服务共用了,这是分布式开发的推荐模式。
@FeignClient("bookservice")
public interface BookClient {
@RequestMapping("/book/{bid}")
Book getBookById(@PathVariable("bid") int bid);
}
④借阅服务中,调用接口 (远程调用):
@Service
public class BorrowServiceImpl implements BorrowService{
@Resource
BorrowMapper mapper;
@Resource
UserClient userClient;
@Resource
BookClient bookClient;
@Override
public UserBorrowDetail getUserBorrowDetailByUid(int uid) {
List<Borrow> borrow = mapper.getBorrowsByUid(uid);
User user = userClient.getUserById(uid);
List<Book> bookList = borrow
.stream()
.map(b -> bookClient.getBookById(b.getBid()))
.collect(Collectors.toList());
return new UserBorrowDetail(user, bookList);
}
}
启动,发现可以实现远程调用了!
🍬2.5 OpenFeign 负载均衡
测试正常,可以自动发现服务,接着我们来多配置几个实例:
然后我们在图书服务和用户服务中添加日志打印方便之后查看:
@Slf4j
@Service
public class BookServiceImpl implements BookService {
@Resource
private BookMapper bookMapper;
@Resource
private Environment environment;
@SneakyThrows
@Override
public Book getBookById(int bid) {
String hostIp = InetAddress.getLocalHost().getHostAddress();
String port = environment.getProperty("server.port");
log.info(hostIp + ":" + port + " 的findBookById()被访问了!");
return bookMapper.getBookById(bid);
}
}
现在将全部服务启动:
可以看到 Nacos 中的实例数量已经显示为 2:
接着我们多次访问 http://localhost:8082/borrow/2
,调用借阅服务,看看能否负载均衡远程调用:
OK,负载均衡远程调用没有问题,这样我们就实现了基于 Nacos 的服务的注册与发现,实际上大致流程与 Eureka 一致。
🍬2.6 临时实例和非临时实例
值得注意的是,Nacos 区分了临时实例和非临时实例:
那么临时和非临时有什么区别呢?
- 临时实例:和 Eureka 一样,采用心跳机制向 Nacos 发送请求保持在线状态,一旦心跳停止,代表实例下线,不保留实例信息。(当然现在 Eureka 有了自动保护机制)
- 非临时实例:由 Nacos 主动进行联系,如果连接失败,那么不会移除实例信息,而是将健康状态设定为 false,相当于会对某个实例状态持续地进行监控。
我们可以通过配置文件进行修改临时实例:
spring:
application:
name: bookservice
cloud:
nacos:
discovery:
server-addr: localhost:8848
# 将 ephemeral 修改为false,表示非临时实例
ephemeral: false
接着我们在 Nacos 中查看,可以发现实例已经不是临时的了:可能需要重启 Nacos-Server
如果这时我们关闭一个实例,那么会变成这样:
只是将健康状态变为 false,而不会删除实例的信息。
三、集群分区
我们之前已经做过的 Eureka 集群,是这样配置的:没有做分区
server:
port: 8802
spring:
application:
name: eurekaserver
eureka:
instance:
hostname: eureka02
client:
fetch-registry: false
service-url:
defaultZone: http://eureka01:8801/eureka
# 这个defaultZone是个啥玩意,为什么要用这个名称?为什么要要用这样的形式来声明注册中心?
在一个分布式应用中,相同服务的实例可能会在不同的机器、位置上启动,比如我们的用户管理服务,可能在成都有1台服务器部署、重庆有一台服务器部署,而这时,我们在成都的服务器上启动了借阅服务,那么如果我们的借阅服务现在要调用用户服务,就应该优先选择同一个区域的用户服务进行调用,这样会使得响应速度更快。
因此,我们可以对部署在不同机房的服务进行分区,可以看到实例的默认集群分区: DEFAULT
🍌3.1 开启集群分区
我们可以直接在配置文件中进行修改:
spring:
application:
name: borrowservice
cloud:
nacos:
discovery:
server-addr: localhost:8848
# 修改为重庆地区的集群
cluster-name: Chongqing
当然,如果我们需要不同的启动配置,也可以直接在启动配置项中添加环境变量-Dspring.cloud.nacos.discovery.cluster-name
这里我们将 用户服务 的两个实例分配到不同的区域:重庆、成都
修改完成之后,我们来尝试重新启动一下(Nacos也要重启),观察 Nacos 中集群分布情况:
可以看到现在有两个集群,并且都有一个实例正在运行。我们接着去调用借阅服务,但是发现并没有按照区域进行优先调用,而依然使用的是 轮询模式 的负载均衡调用。
🍌3.2 开启区域优先调用机制
我们必须要提供 Nacos 的负载均衡实现才能开启区域优先调用机制,只需要在 borrowservice
的配制文件中进行修改:
spring:
application:
name: borrowservice
cloud:
nacos:
discovery:
server-addr: localhost:8848
cluster-name: Chongqing
# 将 loadbalancer 的 nacos 支持开启,集成 Nacos 负载均衡
loadbalancer:
nacos:
enabled: true
现在我们重启借阅服务,会发现优先调用的是同区域的用户服务:
如果我们把同区域的用户服务下线,那么借阅服务就只能调用其它区域的用户服务了。
🍌3.3 开启权重优先调用机制
除了根据区域优先调用之外,同一个区域内的实例也可以单独设置权重值,Nacos 会优先选择权重更大的实例进行调用,我们可以直接在管理页面中进行配置:
或是在配置文件中进行配置:
spring:
application:
name: bookservice
cloud:
nacos:
discovery:
server-addr: localhost:8848
cluster-name: Chengdu
# 权重大小,越大越优先调用,默认为 1
weight: 0.5
通过配置权重,某些性能不太好的机器就能够更少地被使用,而更多的使用那些网络良好性能更高的主机上的实例。
回到目录…
四、配置中心
前面我们学习了 SpringCloud Config,我们可以通过配置服务来加载远程配置,这样我们就可以在远端集中管理配置文件。
我们可以在 bootstrap.yml
中配置远程配置文件获取,然后再进入到配置文件加载环节,而 Nacos 也支持这样的操作。
🍓4.1 Nacos 配置管理
①比如我们现在想要将图书服务的配置文件放到 Nacos 进行管理,那么这个时候就需要在 Nacos 中创建配置文件:
注意: Data ID 的格式跟我们之前一样,应用名称-环境.yml
,如果只编写应用名称,那么代表此配置文件无论在什么环境下都会使用,然后每个配置文件都可以进行分组,也算是一种分类方式:
完成之后点击发布即可:
②然后在图书服务模块中导入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
③接着我们在图书服务中添加 bootstrap.yml 文件: 原本的 application.yml 想删就删了
server:
port: 8081
spring:
application:
name: bookservice # 服务名称和配置文件保持一致
profiles:
active: dev # 环境也是和配置文件保持一致
cloud:
nacos:
config:
file-extension: yml # 配置文件后缀名
# 配置中心服务器地址,也就是 Nacos 地址
server-addr: localhost:8848
现在我们启动服务试试看:
可以看到成功读取配置文件并启动了,实际上使用上来说跟之前的 Config 是基本一致的。
🍓4.2 配置文件热更新
Nacos 还支持配置文件的热更新: 比如我们在配置文件中新增/更改了一个属性,我们后端就可以收到信息并实时更新。
①比如:我们在配置文件新增一个属性。
当我们发布修改后的配置文件,后端立刻发现了。
②我们可以再创建一个 Controller 进行接收属性,来观察现象:需要用 @RefreshScope
注解修饰,以即时刷新接收到的信息。
@RestController
@RefreshScope
public class TestController {
@Value("${my.name}") // org.springframework.beans.factory.annotation.Value
private String name;
@GetMapping("/name")
public String getName() {
return name;
}
}
③现象: 访问获取的属性值。
我们修改一下配置文件:不需要重启
后端已经发现,配置文件中的属性值改变了。
再次访问,发现拿到新的数据了。
回到目录…
五、命名空间
我们还可以将配置文件或是服务实例划分到不同的命名空间中,其实就是区分开发、生产环境或是引用归属之类的:
这里我们创建一个新的命名空间:ID 可以自动生成
可以看到在 dev 命名空间下,没有任何配置文件和服务:
我们在不同的命名空间下,实例和配置都是相互之间隔离的。我们也可以在配置文件中指定当前的命名空间:
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: 空间ID
![](https://i-blog.csdnimg.cn/blog_migrate/7d12c98dbf430340e3ae64e72a87e741.gif)
六、实现可用性
本小节我们用 Linux 云服务器(Nacos 比较吃内存,2个Nacos服务器集群,至少2G内存)。
通过前面的学习,我们已经了解了如何使用 Nacos 以及 Nacos 的功能等,最后我们来看看,如果像之前 Eureka 一样,搭建 Nacos 集群,实现高可用。
官方部署说明:https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html
集群部署架构图:
因此开源的时候推荐用户把所有服务列表放到一个vip下面,然后挂到一个域名下面
- http://ip1:port/openAPI 直连 ip 模式,机器挂则需要修改 ip 才可以使用。
- http://SLB:port/openAPI 挂载 SLB 模式 (内网 SLB,不可暴露到公网,以免带来安全风险),直连SLB 即可,下面挂server 真实ip,可读性不好。
- http://nacos.com:port/openAPI 域名 + SLB模式 (内网SLB,不可暴露到公网,以免带来安全风险),可读性好,而且换ip方便,推荐模式
我们来看看它的架构设计,它推荐我们在所有的 Nacos 服务端之前建立一个负载均衡,我们通过访问负载均衡服务器来间接访问到各个 Nacos 服务器。实际上就,是比如有三个 Nacos 服务器做集群,但是每个服务不可能把每个 Nacos 都去访问一次进行注册,实际上只需要在任意一台 Nacos 服务器上注册即可,Nacos 服务器之间会自动同步信息,实现了整个集群高可用的状态。
-
所以这里就需要在所有 Nacos 服务器之前搭建一个
SLB
(服务器负载均衡),这样就可以避免上面的问题了。但是我们知道,如果要实现外界对服务访问的负载均衡,我们就得用比如之前说到的Gateway
来实现,而这里实际上我们可以用一个更加方便的工具:Nginx
来实现。 -
关于 SLB 最上方还有一个 DNS,这个是因为 SLB 是裸 IP,如果 SLB 服务器修改了地址,那么所有微服务注册的地址也得改,所以这里是通过加域名,通过域名来访问,让 DNS 去解析真实 IP,这样就算改变 IP,只需要修改域名解析记录即可,域名地址是不会变化的。(由于成本高,这里我们就不搞了)
🍡6.1 云服务环境准备
①云服务器:64 bit OS Linux/Unix/Mac,推荐使用 Linux 系统。
②下载安装 64 bit JDK 1.8+
③下载安装 MariaDB (MySQL):参考文章 - Linux下安装MariaDB
# 启动数据库
systemctl start mariadb
④下载 nacos-server-2.0.3.zip 安装包,并解压到云服务器。
unzip nacos-server-2.0.3.zip
🍡6.2 配置外置数据源
- 使用内置数据源:单节点 Nacos,无需进行任何配置。
- 使用外置数据源:Nacos 集群模式,生产使用建议至少主备模式,或者采用高可用数据库。
初始化 MySQL 数据库:根据 nacos/conf/nacos-mysql.sql
文件建库建表
CREATE SCHEMA `nacos_config` DEFAULT CHARACTER SET utf8mb4 ;
use nacos_config;
/*
* 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 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');
🍡6.3 配置集群配置文件
①修改:application.properties
,包括 MySQL 服务器的信息:
### Default web server port:
server.port=8848
#*************** 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://localhost:3306/nacos_config?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
db.user.0=root
db.password.0=123456
②修改:cluster.conf.example
-> cluster.conf
,重命名并修改
mv cluster.conf.example cluster.conf
每行配置成 ip:port
,两台做集群的 nacos 服务器的IP (内网IP,使用 ifconfig
查看;端口号不能连号,否则会报错)
# ip:port
10.0.4.12:8848
10.0.4.12:8850
③ Nacos 的内存分配以及前台启动,直接修改nacos/bin/startup.sh
文件
④将整个 nacos 文件夹复制 n 份,用于做集群的节点
cp -r nacos nacos2
仅仅更改 application.properties
中的 端口号 即可,其余配置不变。
🍡6.4 启动 nacos 集群
分别在两个 nacos 目录下,启动 nacos 服务
sh bin/startup.sh
然后我们直接通过云服务器的外网来访问 http://1.15.76.95:8848/nacos ,注意一定要设置云服务器防火墙,允许访问端口。
打开管理面板,可以看到两个节点都已经启动了:
当有一个 Nacos 宕机后:
🍡6.5 Nginx 反向代理
当我们的 Nacos 集群搭建好时,我们还需要做到服务器之间的负载均衡。此时我们需要添加一个 SLB,这里用 Nginx 做反向代理:
Nginx (engine x) 是一个高性能的 HTTP 和反向代理 web 服务器,同时也提供了 IMAP/POP3/SMTP 服务。它相当于在内网与外网之间形成一个网关,所有的请求都可以由 Nginx 服务器转交给内网的其他服务器。
①首先我们要在云服务器上安装 nginx,参考往期文章:Linux 安装 nginx 详细步骤
启动 nginx 后,直接访问云服务器的外网IP就行,http://1.15.76.95,默认 80 端口,可省略。
②现在我们需要让其代理我们刚刚启动的两个 Nacos 服务器,我们需要对其进行一些配置。配置文件位于/etc/nginx/nginx.conf
,添加以下内容:
http {
......
# 添加两个 nacos 服务器
upstream nacos-server {
server 10.0.4.12:8848;
server 10.0.4.12:8850;
}
server {
listen 80;
server_name localhost;
# 添加需要转发的路径
location /nacos {
proxy_pass http://nacos-server;
}
......
}
}
重启 Nginx 服务器,访问地址:http://1.15.76.95/nacos,成功连接到 Nacos 服务器上。
③然后我们将所有的服务全部修改为云服务器上 Nacos 的地址,启动试试看。
spring:
cloud:
nacos:
discovery:
# 配置到云服务器上的 Nacos 注册中心,因为有 nginx 代理,所以地址直接写云服务器的外网IP,端口也不用加
server-addr: 1.15.76.95
这样,我们就搭建好了 Nacos 集群。
总结:
提示:这里对文章进行总结:
本文是对Nacos的学习,学习了更加全能的注册中心,不仅仅有服务的注册与发现,还具有配置中心的作用。也可以做集群分区和命名空间,最后也在Linux环境下搭建了Nacos集群,并且使用 Nginx 代理转发,实现了 nacos 之间的负载均衡。