欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > nacos注册中心配置中心集群搭建

nacos注册中心配置中心集群搭建

2024/10/24 5:15:40 来源:https://blog.csdn.net/qq_16992475/article/details/139665322  浏览:    关键词:nacos注册中心配置中心集群搭建

文章目录

  • 学习连接
  • 1.Nacos安装与简单使用
    • 1.1. Nacos安装指南
      • Windows安装
        • 下载安装包
        • 解压
        • 端口配置
        • 启动
        • 访问
      • Linux安装
        • 安装JDK
        • 上传安装包
        • 解压
        • 端口配置
        • 启动
    • 1.2.服务注册到nacos
      • 使用步骤
        • 引入依赖
        • 配置nacos地址
        • 重启
      • 示例
        • 父工程pom.xml
        • user-service
          • pom.xml
          • application.yml
          • UserApplication
          • UserController
          • UserService
        • order-service
          • pom.xml
          • application.yml
          • UserApplication
          • OrderService
          • UserClient
        • 访问nacos
  • 2.服务分级存储模型
    • 集群介绍
    • 服务跨集群调用问题
    • 服务集群属性
    • 同集群优先的负载均衡
      • 给user-service配置集群
        • 修改user-service的yml配置文件
        • 访问nacos
      • 给order-service配置集群
        • 修改order-service的yml配置文件
        • 访问nacos
      • 测试
    • 权重负载均衡
      • 测试
    • 环境隔离
      • Nacos环境隔离
      • 测试
  • 3. Nacos注册中心原理
    • nacos注册中心细节分析
      • nacos与eureka区别
        • nacos的 临时实例&非临时实例
        • 主动推送变更消息
        • 总结
        • 测试
  • 4. Nacos配置管理
    • 统一配置管理
      • 在nacos中添加配置文件
      • 从微服务拉取配置
        • 示例
        • 总结
    • 配置热更新
      • 方式一:@RefreshScope
      • 方式二:@ConfigurationProperties
      • 测试
    • 多环境配置共享
      • 优先级
      • 测试一
        • 添加一个环境共享配置
        • 在user-service中读取共享配置
        • 运行两个UserApplication,使用不同的profile
      • 测试二
        • 添加一个redis.yml
        • 修改UserApplication1的bootstrap.yaml
        • 修改redis.yml,并发布,再次访问测试
  • 5. Nacos集群
    • 集群结构图
    • 搭建集群
      • 初始化数据库
      • 下载nacos
      • 配置nacos
      • 启动
      • nginx反向代理
      • 项目配置
        • 依赖
        • bootstrap.yaml
        • application.yml
        • UserApplication
        • UserController2
      • 测试

学习连接

SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

nacos官网

nacos github地址

【微服务】Nacos注册中心

nacos核心源码深度剖析

国内公司一般都推崇阿里巴巴的技术,比如注册中心,SpringCloudAlibaba也推出了一个名为Nacos的注册中心。

1.Nacos安装与简单使用

在这里插入图片描述

1.1. Nacos安装指南

Windows安装

开发阶段采用单机安装即可。

下载安装包

在Nacos的GitHub页面,提供有下载链接,可以下载编译好的Nacos服务端或者源代码:

GitHub主页:https://github.com/alibaba/nacos

GitHub的Release下载页:https://github.com/alibaba/nacos/releases

如图:

在这里插入图片描述

本课程采用1.4.1.版本的Nacos,课前资料已经准备了安装包:

在这里插入图片描述

windows版本使用nacos-server-1.4.1.zip包即可。

解压

将这个包解压到任意非中文目录下,如图:

在这里插入图片描述

目录说明:

  • bin:启动脚本
  • conf:配置文件
端口配置

Nacos的默认端口是8848,如果你电脑上的其它进程占用了8848端口,请先尝试关闭该进程。

如果无法关闭占用8848端口的进程,也可以进入nacos的conf目录,修改配置文件中的端口:

在这里插入图片描述

修改其中的内容:
在这里插入图片描述

启动

启动非常简单,进入bin目录,结构如下:

在这里插入图片描述

然后执行命令即可:

  • windows命令:

    ## 此时由于没有修改配置文件, 默认将数据持久化到与bin文件夹同级目录data文件夹中
    startup.cmd -m standalone
    

执行后的效果如图:

在这里插入图片描述

访问

在浏览器输入地址:http://127.0.0.1:8848/nacos即可:

在这里插入图片描述

默认的账号和密码都是nacos,进入后:

在这里插入图片描述

Linux安装

Linux或者Mac安装方式与Windows类似。

安装JDK

Nacos依赖于JDK运行,索引Linux上也需要安装JDK才行。

上传jdk安装包:

在这里插入图片描述

上传到某个目录,例如:/usr/local/
在这里插入图片描述

然后解压缩:

tar -xvf jdk-8u144-linux-x64.tar.gz

然后重命名为java

配置环境变量:

export JAVA_HOME=/usr/local/java
export PATH=$PATH:$JAVA_HOME/bin

设置环境变量:

source /etc/profile
上传安装包

如图:
在这里插入图片描述

也可以直接使用课前资料中的tar.gz:

上传到Linux服务器的某个目录,例如/usr/local/src目录下:

在这里插入图片描述

解压

命令解压缩安装包:

tar -xvf nacos-server-1.4.1.tar.gz

然后删除安装包:

rm -rf nacos-server-1.4.1.tar.gz

目录中最终样式:

在这里插入图片描述

目录内部:
在这里插入图片描述

端口配置

与windows中类似

启动

在nacos/bin目录中,输入命令启动Nacos:

sh startup.sh -m standalone

1.2.服务注册到nacos

Nacos是SpringCloudAlibaba的组件,而SpringCloudAlibaba也遵循SpringCloud中定义的服务注册、服务发现规范。因此使用Nacos和使用Eureka对于微服务来说,并没有太大区别。

主要差异在于:

  • 依赖不同
  • 服务地址不同

使用步骤

引入依赖

在cloud-demo父工程的pom文件中的<dependencyManagement>中引入SpringCloudAlibaba的依赖:

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.6.RELEASE</version><type>pom</type><scope>import</scope>
</dependency>

然后在user-service和order-service中的pom文件中引入nacos-discovery依赖:

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

注意:不要忘了注释掉eureka的依赖。

配置nacos地址

在user-service和order-service的application.yml中添加nacos地址:

spring:cloud:nacos:server-addr: localhost:8848

注意:不要忘了注释掉eureka的地址

重启

重启微服务后,登录nacos管理页面,可以看到微服务信息:

在这里插入图片描述

示例

父工程pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.itcast.demo</groupId><artifactId>cloud-demo</artifactId><version>1.0</version><modules><module>user-service</module><module>order-service</module></modules><packaging>pom</packaging><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.9.RELEASE</version><relativePath/></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><spring-cloud.version>Hoxton.SR10</spring-cloud.version><mysql.version>5.1.47</mysql.version><mybatis.version>2.1.1</mybatis.version></properties><dependencyManagement><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><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><!-- mysql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.version}</version></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>
</project>
user-service
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>cloud-demo</artifactId><groupId>cn.itcast.demo</groupId><version>1.0</version></parent><modelVersion>4.0.0</modelVersion><artifactId>user-service</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency></dependencies><build><finalName>app</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
application.yml
server:port: 8081
spring:application:name: user-servicecloud:nacos:server-addr: localhost:8848datasource:url: jdbc:mysql://localhost:3306/cloud-user?useSSL=falseusername: rootpassword: rootdriver-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
UserApplication
@MapperScan("cn.itcast.user.mapper")
@SpringBootApplication
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class, args);}
}
UserController
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;/*** 路径: /user/110** @param id 用户id* @return 用户*/@GetMapping("/{id}")public User queryById(@PathVariable("id") Long id) {return userService.queryById(id);}
}
UserService
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public User queryById(Long id) {return userMapper.findById(id);}
}
order-service
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>cloud-demo</artifactId><groupId>cn.itcast.demo</groupId><version>1.0</version></parent><modelVersion>4.0.0</modelVersion><artifactId>order-service</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--feign客户端依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--引入HttpClient依赖--><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
application.yml
server:port: 8080
spring:application:name: order-servicecloud:nacos:server-addr: localhost:8848datasource:url: jdbc:mysql://localhost:3306/cloud-order?useSSL=falseusername: rootpassword: rootdriver-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
UserApplication
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
@EnableFeignClients("cn.itcast.order.feign")
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}}
OrderService
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate UserClient userClient;public Order queryOrderById(Long orderId) {// 1.查询订单Order order = orderMapper.findById(orderId);// 2.用Feign远程调用User user = userClient.findById(order.getUserId());// 3.封装user到Orderorder.setUser(user);// 4.返回return order;}
}
UserClient
@FeignClient(value = "user-service")
public interface UserClient {@GetMapping("/user/{id}")User findById(@PathVariable("id") Long id);
}
访问nacos

将user-service分别以8081和8082启动,order以8080启动。

效果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.服务分级存储模型

集群介绍

一个服务可以有多个实例,例如我们的user-service,可以有:

  • 127.0.0.1:8081
  • 127.0.0.1:8082
  • 127.0.0.1:8083

假如这些实例分布于全国各地的不同机房,例如:

  • 127.0.0.1:8081,在上海机房
  • 127.0.0.1:8082,在上海机房
  • 127.0.0.1:8083,在杭州机房

Nacos就将同一机房内的实例 划分为一个集群

也就是说,user-service是服务,一个服务可以包含多个集群,如杭州、上海,每个集群下可以有多个实例(按地域划分集群),形成分级模型,如图:

在这里插入图片描述

服务跨集群调用问题

微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集群内不可用时,才访问其它集群。例如:

在这里插入图片描述
杭州机房内的order-service应该优先访问同机房的user-service。

服务集群属性

Nacos服务分级存储模型

  • 一级是服务,例如userservice
  • 二级是集群,例如杭州或上海
  • 三级是实例,例如杭州机房的某台部署了userservice的服务器

如何设置实例的集群属性

  • 修改application.yml文件,添加spring.cloud.nacos.discovery.cluster-name属性即可

同集群优先的负载均衡

默认的ZoneAvoidanceRule并不能实现根据同集群优先来实现负载均衡。
因此Nacos中提供了一个NacosRule的实现,可以优先从同集群中挑选实例。

NacosRule负载均衡策略

  • 优先选择同集群服务实例列表
  • 本地集群找不到提供者,才去其它集群寻找,并且会报警告
  • 确定了可用实例列表后,再采用随机负载均衡挑选实例

下面通过1个示例来演示

给user-service配置集群

修改user-service的yml配置文件

在前面最基础的示例上,仅修改user-service的yml配置文件,启动3个user-service实例,分别占用8081,8082,8083端口,其中8081,8082的集群名称使用HZ,8083的集群名称使用SH

server:port: 8081
spring:application:name: user-servicecloud:nacos:server-addr: localhost:8848 # nacos服务地址discovery:cluster-name: HZ          # 配置集群名称,也就是机房位置,例如:HZ代指杭州datasource:url: jdbc:mysql://localhost:3306/cloud_user?useSSL=falseusername: rootpassword: rootdriver-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

在这里插入图片描述
点击详情进去查看
在这里插入图片描述

给order-service配置集群

修改order-service的yml配置文件

在前面最基础的示例上,仅修改order-service的yml配置文件

server:port: 8080
spring:application:name: order-servicecloud:nacos:server-addr: localhost:8848  # nacos服务地址discovery:cluster-name: HZ           # 设置当前服务实例所属集群名称datasource:url: jdbc:mysql://localhost:3306/cloud-order?useSSL=falseusername: rootpassword: rootdriver-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

在这里插入图片描述
在这里插入图片描述

测试

现在我们多次调用:http://localhost:8080/order/103,发现:order-service会轮询调用这3个实例。可是,我们知道order-service服务是在HZ这个集群的,它应当要优先选择HZ集群下的user-service服务,当HZ集群下的user-service服务不可用时,再去选择其它集群下的user-service服务实例。

为了解决上面这个问题,我们在order-service中设置负载均衡的IRule为NacosRule(如下配置),这个规则优先会寻找与自己同集群的服务,重启order-service后,多次调用:http://localhost:8080/order/103发现:order-service会去HZ集群中随机选择1个user-service实例,而SH集群的user-service实例没有被选择。此时,把HZ集群下的user-service实例全部关掉,多次调用:http://localhost:8080/order/103发现:刚开始报错几次之后,就选择到了SH集群下的user-service实例,并且此时order-service下会有WARN级别的日志:[nio-8080-exec-3] c.alibaba.cloud.nacos.ribbon.NacosRule : A cross-cluster call occurs,当查看到这个日志时,就知道发生了跨集群调用了。

server:port: 8080
spring:application:name: order-servicecloud:nacos:server-addr: localhost:8848discovery:cluster-name: HZdatasource:url: jdbc:mysql://localhost:3306/cloud-order?useSSL=falseusername: rootpassword: rootdriver-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
userservice:ribbon:NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule  # 负载均衡规则

权重负载均衡

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

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

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

实例的权重控制

  • Nacos控制台可以设置实例的权重值,0~1之间
  • 同集群内的多个实例,权重越高被访问的频率越高
  • 权重设置为0则完全不会被访问(可以用作平滑升级:当某个服务需要升级时,先把权重调的很低,先放部分用户过来,当没有问题时,再提高权重)

测试

如下修改8082的权重为0.1,现在我们调用:http://localhost:8080/order/103 20次,发现:18次都在8081上,有2次再8082上,说明权重设置是生效的。

在这里插入图片描述
可以看到8082的权重改为了0.1,而8081的权重仍然为1
在这里插入图片描述

再尝试把8081的权重设置为0,8082的权重恢复为1,发现:8081没有被访问,全都到了8082上。在这里插入图片描述

环境隔离

Nacos提供了namespace来实现环境隔离功能。Nacos中服务存储数据存储最外层都是一个名为namespace的东西,用来做最外层隔离

  • nacos中可以有多个namespace
  • namespace下可以有group、service等(而服务由下分为:服务-集群-实例)
  • 不同namespace之间相互隔离,例如不同namespace的服务互相不可见(不同namespace下的各服务完全隔离,互相之间完全看不见对方)

在这里插入图片描述

Nacos环境隔离

  • 每个namespace都有唯一id
  • 服务设置namespace时要写id而不是名称
  • 不同namespace下的服务互相不可见(如果要让2个服务之间能调用,那么它们必须在同1个namespace下)

测试

最初的默认配置如下:在这里插入图片描述
在这里插入图片描述
创建1个dev的命名空间:
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
修改order-service的application.yml,添加namespace(注意是命名空间id),重启order-service,发现:order-service已经从public命名空间下移除掉了,并且注册到了dev命名空间下,此时访问:http://localhost:8080/order/103,就会报错:com.netflix.client.ClientException: Load balancer does not have available server for client: user-service负载均衡已经找不到user-service
服务

server:port: 8080
spring:application:name: order-servicecloud:nacos:server-addr: localhost:8848discovery:cluster-name: HZnamespace: 7fe7efeb-e4a4-4cd1-82f4-46d46c6f7bba # 填命名空间IDdatasource:url: jdbc:mysql://localhost:3306/cloud-order?useSSL=falseusername: rootpassword: rootdriver-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
user-service:ribbon:NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule  # 负载均衡规则

在这里插入图片描述
在这里插入图片描述

3. Nacos注册中心原理

nacos注册中心细节分析

服务提供者在启动时,都会把自己的信息提交给注册中心,注册中心就会把服务提供者的信息保存下来。当消费者需要消费时,就会从注册中心拉取服务提供者的信息(或者叫作服务发现),缓存到本地服务列表中,这样当下一次需要获取服务信息时,就不用从注册中心拉取了,而是使用缓存的服务列表信息。

当注册中心的服务列表变化时,就需要消费者定时从注册中心拉取服务信息缓存到本地,其中,eureka就每隔默认30s从注册中心拉取服务信息。当消费者获取到服务后,从提供的服务中根据负载均衡策略挑选服务发起远程调用。
在这里插入图片描述

nacos与eureka区别

nacos的 临时实例&非临时实例

Nacos的服务实例分为两种类型:

  • 临时实例:如果实例宕机超过一定时间,会从服务列表剔除,默认的类型(如果不作任何配置,默认就是临时实例;临时实例每隔一段时间,定时向注册中心发送1次心跳报告健康状态,这一点与eureka相同;超过一定时间未收到心跳,将会从服务列表中剔除)。
  • 非临时实例:如果实例宕机,不会从服务列表剔除,也可以叫永久实例。(非临时实例不会向注册中心发送心跳请求,而是由注册中心主动询问健康状态;nacos主动发请求询问,如果检测不到,也不会清除这个服务,而是会一直等待这个非临时实例好为止)
主动推送变更消息

当服务提供者信息发生变化,而服务消费者由于采用的是定时拉取,未能及时更新本地缓存服务列表,此时发起远程调用会发生问题。eureka采取的是pull定时拉取方案,因此更新的不够及时,服务列表更新效率差,而nacos采取的是pull定时拉取 + 主动推送变更消息,如果服务提供信息发生变化时,会立即将此变更消息推送到消费者。

总结
  • Nacos与eureka的共同点
    • 都支持服务注册和服务拉取
    • 都支持服务提供者心跳方式做健康检测
  • Nacos与Eureka的区别
    • Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
    • 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
    • Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
    • Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式
测试

修改order-service的application.yml配置文件,将order-service注册为非临时实例

server:port: 8080
spring:application:name: order-servicecloud:nacos:server-addr: localhost:8848discovery:cluster-name: HZnamespace: 7fe7efeb-e4a4-4cd1-82f4-46d46c6f7bba # 填命名空间IDephemeral: false  # 是否临时实例datasource:url: jdbc:mysql://localhost:3306/cloud-order?useSSL=falseusername: rootpassword: rootdriver-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
user-service:ribbon:NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule  # 负载均衡规则

从中可以看到order-service注册为非临时实例了,这与之前的注册为临时实例是不同的在这里插入图片描述在这里插入图片描述

当关闭order-service,发现order-service仍然还在列表中(如果是临时实例,会直接在列表中被移除掉。因此,只能手动移除它。)
在这里插入图片描述
在这里插入图片描述
当order-service重新上线,就恢复了

4. Nacos配置管理

Nacos除了可以做注册中心,同样可以做配置管理来使用。

统一配置管理

当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错。我们需要一种统一配置管理方案,可以集中管理所有实例的配置。
在这里插入图片描述
Nacos一方面可以将配置集中管理,另一方可以在配置变更时,及时通知微服务,实现配置的热更新
在这里插入图片描述

在nacos中添加配置文件

在Nacos中添加配置信息,点击“+”号:

在这里插入图片描述
然后在弹出的表单中,填写配置信息(注意:项目的核心配置,需要热更新的配置才有放到nacos管理的必要。基本不会变更的一些配置还是保存在微服务本地比较好。):

在这里插入图片描述
在这里插入图片描述

从微服务拉取配置

微服务要拉取nacos中管理的配置,并且与本地的application.yml配置合并,才能完成项目启动。

但如果尚未读取application.yml,又如何得知nacos地址呢?

因此spring cloud引入了一种新的配置文件:bootstrap.yaml文件,会在application.yml之前被读取,流程如下:
在这里插入图片描述

示例

第一步:给user-service 引入Nacos的配置管理客户端依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>cloud-demo</artifactId><groupId>cn.itcast.demo</groupId><version>1.0</version></parent><modelVersion>4.0.0</modelVersion><artifactId>user-service</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><!--nacos服务发现--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--nacos配置管理依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency></dependencies><build><finalName>app</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

第二步:添加bootstrap.yaml
然后,在user-service中添加一个bootstrap.yaml文件,内容如下:

spring:application:name: user-service # 服务名称profiles:active: dev # 开发环境,这里是devcloud:nacos:server-addr: localhost:8848 # nacos地址config:file-extension: yaml # 文件后缀名

这里会根据spring.cloud.nacos.server-addr获取nacos地址,再根据
${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}作为文件id,来读取配置。本例中,就是去读取user-service-dev.yaml

此时的application.yml配置如下:

server:port: 8081
spring:cloud:nacos:discovery:cluster-name: HZ # 配置集群名称,也就是机房位置,例如:HZ代指杭州datasource:url: jdbc:mysql://localhost:3306/cloud-user?useSSL=falseusername: rootpassword: rootdriver-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

第三步:修改UserController,注入nacos配置文件的配置,测试是否生效

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {// ... 省略其它代码/* 注入nacos配置文件的配置 */@Value("${pattern.dataFormat}")private String dataFormat;@GetMapping("now")public String now(){return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dataFormat));}
}

第四步:以8081端口,重启user-service服务,发现user-service已成功注册到了nacos,并且是在HZ集群。此时访问:http://localhost:8081/user/now,返回如下
在这里插入图片描述

总结

将配置交给Nacos管理的步骤

  • 在Nacos中添加配置文件
  • 在微服务中引入nacos的config依赖
  • 在微服务中添加bootstrap.yml,配置nacos地址、当前环境、服务名称、文件后缀名。这些决定了程序启动时去nacos读取哪个文件

配置热更新

我们最终的目的,是修改nacos中的配置后,微服务中无需重启即可让配置生效,也就是配置热更新

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

方式一:@RefreshScope

在@Value注入的变量所在类上添加注解@RefreshScope
在这里插入图片描述

方式二:@ConfigurationProperties

使用@ConfigurationProperties注解,此时无需使用@RefreshScope注解

在这里插入图片描述

测试

修改UserController,如下:

@Slf4j
@RestController
@RequestMapping("/user")
@RefreshScope // 添加@RefreshScope注解
public class UserController {// ...省略其它代码@Value("${pattern.dataFormat}")private String dataFormat;@GetMapping("now")public String now(){return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dataFormat));}
}

创建UserController2,如下:

@Slf4j
@RestController
@RequestMapping("/user2")
@RefreshScope
public class UserController2 {@Autowiredprivate PatternProperties properties;@GetMapping("now")public String now(){return LocalDateTime.now().format(DateTimeFormatter.ofPattern(properties.getDataFormat()));}}
@Data
@Component
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {private String dataFormat;private String envSharedValue;private String name;
}

重启user-service,访问如下:
在这里插入图片描述
此时修改nacos中的配置,如下:
在这里插入图片描述
此时,可以看到user-service日志输出如下:

06-15 16:27:23:837  INFO 15636 --- [-localhost_8848] c.a.n.client.config.impl.ClientWorker    : [fixed-localhost_8848] [polling-resp] config changed. dataId=user-service-dev.yaml, group=DEFAULT_GROUP
06-15 16:27:23:837  INFO 15636 --- [-localhost_8848] c.a.n.client.config.impl.ClientWorker    : get changedGroupKeys:[user-service-dev.yaml+DEFAULT_GROUP]
06-15 16:27:23:840  INFO 15636 --- [-localhost_8848] c.a.n.client.config.impl.ClientWorker    : [fixed-localhost_8848] [data-received] dataId=user-service-dev.yaml, group=DEFAULT_GROUP, tenant=null, md5=a64c8b4c6e466eaa891f821c40ee71c1, content=pattern:dataFormat: yyyy-MM-dd, type=yaml
06-15 16:27:23:840  INFO 15636 --- [-localhost_8848] c.a.nacos.client.config.impl.CacheData   : [fixed-localhost_8848] [notify-context] dataId=user-service-dev.yaml, group=DEFAULT_GROUP, md5=a64c8b4c6e466eaa891f821c40ee71c1
06-15 16:27:25:999  WARN 15636 --- [-localhost_8848] c.a.c.n.c.NacosPropertySourceBuilder     : Ignore the empty nacos configuration and get it based on dataId[user-service] & group[DEFAULT_GROUP]
06-15 16:27:26:002  WARN 15636 --- [-localhost_8848] c.a.c.n.c.NacosPropertySourceBuilder     : Ignore the empty nacos configuration and get it based on dataId[user-service.yaml] & group[DEFAULT_GROUP]
06-15 16:27:26:005  INFO 15636 --- [-localhost_8848] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-user-service-dev.yaml,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-user-service.yaml,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-user-service,DEFAULT_GROUP'}]
06-15 16:27:26:009  INFO 15636 --- [-localhost_8848] o.s.boot.SpringApplication               : The following profiles are active: dev
06-15 16:27:26:014  INFO 15636 --- [-localhost_8848] o.s.boot.SpringApplication               : Started application in 2.173 seconds (JVM running for 313.295)
06-15 16:27:26:044  INFO 15636 --- [-localhost_8848] o.s.c.e.event.RefreshEventListener       : Refresh keys changed: [pattern.dataFormat]
06-15 16:27:26:044  INFO 15636 --- [-localhost_8848] c.a.nacos.client.config.impl.CacheData   : [fixed-localhost_8848] [notify-ok] dataId=user-service-dev.yaml, group=DEFAULT_GROUP, md5=a64c8b4c6e466eaa891f821c40ee71c1, listener=com.alibaba.cloud.nacos.refresh.NacosContextRefresher$1@22606caa 
06-15 16:27:26:044  INFO 15636 --- [-localhost_8848] c.a.nacos.client.config.impl.CacheData   : [fixed-localhost_8848] [notify-listener] time cost=2204ms in ClientWorker, dataId=user-service-dev.yaml, group=DEFAULT_GROUP, md5=a64c8b4c6e466eaa891f821c40ee71c1, listener=com.alibaba.cloud.nacos.refresh.NacosContextRefresher$1@22606caa 

此时,再次访问如下,发现,在未重启user-service的情况下,对配置的修改已生效
在这里插入图片描述

多环境配置共享

其实微服务启动时,会去nacos读取多个配置文件,例如:

  • [spring.application.name]-[spring.profiles.active].yaml,例如:user-service-dev.yaml

  • [spring.application.name].yaml,例如:user-service.yaml

[spring.application.name].yaml不包含环境,因此会被多个环境共享(也就是user-service.yaml这个配置文件会被所有的spring.application.name为user-service的服务所共享)。

即:无论profile如何变化,[spring.application.name].yaml这个文件一定会加载,因此多环境共享配置可以写入这个文件,如果不同的配置文件的配置了相同的属性,那么优先级是:[服务名]-[环境].yaml >[服务名].yaml > 本地配置

优先级

在这里插入图片描述

微服务默认读取的配置文件:

  • [服务名]-[spring.profile.active].yaml,默认配置
  • [服务名].yaml,多环境共享

不同微服务共享的配置文件:

  • 通过shared-configs指定
  • 通过extension-configs指定

优先级:

  • 环境配置 >服务名.yaml > extension-config > extension-configs > shared-configs > 本地配置

测试一

添加一个环境共享配置

我们在nacos中添加一个userservice.yaml文件:

在这里插入图片描述
此时配置如下:
在这里插入图片描述

在user-service中读取共享配置

在user-service服务中,修改PatternProperties类,读取新添加的属性:

@Data
@Component
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {private String dataFormat;// 读取定义在user-service.yaml中的配置private String envSharedValue;private String name;
}

UserController2,如下

@Slf4j
@RestController
@RequestMapping("/user2")
@RefreshScope
public class UserController2 {@Autowiredprivate PatternProperties properties;@GetMapping("props")public PatternProperties props(){return properties;}}
运行两个UserApplication,使用不同的profile

user-service的配置同:统一配置管理中的示例。在此配置的基础上,作如下修改:

修改UserApplication2这个启动项,改变其profile值为test(等价于修改spring.profile.active的值)
在这里插入图片描述

这样,UserApplication(8081)使用的profile是dev,UserApplication2(8082)使用的profile是test。

启动UserApplication和UserApplication2(启动UserApplication2,此时日志会输出:The following profiles are active: test

访问http://localhost:8081/user2/props,结果:
在这里插入图片描述
访问http://localhost:8082/user2/props,结果:
在这里插入图片描述
可以看出来,不管是dev,还是test环境,都读取到了envSharedValue这个属性的值,而dev还读取到了自己的user-service-dev.yaml中配置的pattern.dataFormat的值。

可以看出,每个服务实例不仅会加载当前所设置的profile配置(user-service-dev.yaml),还会默认加载上不带profile的公共配置(user-service.yaml)

测试二

有的时候,某个服务实例,需要加载自己所需要的配置,这些配置被某些服务实例所共享,但其它服务却是不需要的。此时,可以用到nacos提供的扩展配置

添加一个redis.yml

在这里插入图片描述
此时配置如下:
在这里插入图片描述

修改UserApplication1的bootstrap.yaml

添加 spring.cloud.nacos.config.extension-configs 配置

spring:application:name: user-service # 服务名称profiles:active: dev # 开发环境,这里是devcloud:nacos:server-addr: localhost:8848 # nacos地址config:file-extension: yaml # 文件后缀名extension-configs:- data-id: redis.ymlgroup: commonrefresh: true

此时的application.yml配置文件(未作任何修改)

server:port: 8081
spring:cloud:nacos:discovery:cluster-name: HZ # 配置集群名称,也就是机房位置,例如:HZ代指杭州datasource:url: jdbc:mysql://localhost:3306/cloud-user?useSSL=falseusername: rootpassword: rootdriver-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

重启UserApplication1,访问测试,发现读取到了redis.yml中的配置
在这里插入图片描述

修改redis.yml,并发布,再次访问测试

在这里插入图片描述
可以看到,redis.port的值 热更新了
在这里插入图片描述

5. Nacos集群

Nacos生产环境下一定要部署为集群状态

集群结构图

官方给出的Nacos集群图
在这里插入图片描述
其中包含3个nacos节点,然后一个负载均衡器代理3个Nacos。这里负载均衡器可以使用nginx。

我们计划的集群结构,Nginx做负载均衡,MySQL集群做数据共享

在这里插入图片描述
三个Nacos节点的地址

节点ipport
nacos1192.168.134.58845
nacos2192.168.134.58846
nacos3192.168.134.58847

搭建集群

搭建集群的基本步骤

  • 搭建数据库,初始化数据库表结构
  • 下载nacos安装包
  • 配置nacos
  • 启动nacos集群
  • nginx反向代理

初始化数据库

Nacos默认数据存储在内嵌数据库Derby中,不属于生产可用的数据库。

官方推荐的最佳实践是使用带有主从模式的高可用数据库集群,这里我们以单点的数据库为例来讲解

首先新建一个数据库,命名为nacos,而后导入下面的SQL:

/******************************************/
/*   数据库全名 = 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');

下载nacos

nacos在GitHub上有下载地址: https://github.com/alibaba/nacos/tags,可以选择任意版本下载。

本例中采用1.4.1版本
在这里插入图片描述

配置nacos

将这个包解压到任意非中文目录下,如图:
在这里插入图片描述
目录说明

  • bin:启动脚本
  • conf:配置文件

进入nacos的conf目录,修改配置文件cluster.conf.example,重命名为cluster.conf,然后添加每个nacos节点的ip和端口,内容如下:
在这里插入图片描述
然后,修改application.properties文件,修改数据库配置:

### 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=root

启动

将nacos文件夹复制三份,分别命名为: nacos1、nacos2、nacos3
在这里插入图片描述
然后分别修改三个文件夹中的application.properties

nacos1:

server.port=8845

nacos2:

server.port=8846

nacos3:

server.port=8847

然后分别启动三个nacos节点:双击 startup.cmd 以集群模式启动即可
在这里插入图片描述

nginx反向代理

解压nginx-1.18.0.zip压缩包,如下:
在这里插入图片描述
将如下内容,添加到http块中,以实现nginx对nacos集群的负载均衡

	upstream nacos-cluster {server 192.168.134.5:8845;server 192.168.134.5:8846;server 192.168.134.5:8847;}server {listen 80;server_name 192.168.134.5;location /nacos {proxy_pass http://nacos-cluster;}}

此时访问nacos就不用带端口号了:http://192.168.134.5/nacos
在这里插入图片描述
添加user-service-dev.yaml配置文件
在这里插入图片描述

在这里插入图片描述

项目配置

仅修改了user-service的bootstrap.yaml配置文件的spring.cloud.nacos.server-addr配置,其它未动,这里将user-service的重要配置列出来

依赖
<!--nacos服务发现-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency><!--nacos配置管理依赖-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
bootstrap.yaml

仅修改了spring.cloud.nacos.server-addr=192.168.134.5:80

spring:application:name: user-service # 服务名称profiles:active: dev # 开发环境,这里是devcloud:nacos:server-addr: 192.168.134.5:80 # nacos集群地址(就是nginx作负载均衡的地址)config:file-extension: yaml # 文件后缀名extension-configs:- data-id: redis.ymlgroup: commonrefresh: true
application.yml
server:port: 8081
spring:cloud:nacos:discovery:cluster-name: HZ # 配置集群名称,也就是机房位置,例如:HZ代指杭州datasource:url: jdbc:mysql://localhost:3306/cloud-user?useSSL=falseusername: rootpassword: rootdriver-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
UserApplication
@MapperScan("cn.itcast.user.mapper")
@SpringBootApplication
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class, args);}
}
UserController2

此处使用@RefreshScope的方式来热更新

@Slf4j
@RestController
@RequestMapping("/user2")
@RefreshScope 
public class UserController2 {@Autowiredprivate PatternProperties properties;@GetMapping("props")public PatternProperties props(){return properties;}
}

测试

访问http://localhost:8081/user2/props
在这里插入图片描述
在这里插入图片描述
如上修改配置后,再次访问http://localhost:8081/user2/props
在这里插入图片描述
说明集群搭建成功

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com