【SpringCloud】注册中心的其他实现 - Nacos

目录

  • 注册中心的其他实现-Nacos
    • Nacos简介
    • Nacos安装
      • 下载安装包
      • Windows
        • 解压
        • 修改单机模式
        • 启动Nacos
        • 常见问题
      • Linux
        • 准备安装包
        • 单机模式启动
        • 常见问题
    • Nacos快速上手
      • 服务注册/服务发现
        • 引入Spring Cloud Alibaba依赖
        • 引入Nacos 依赖
        • 引入Load Balance依赖
      • 配置Nacos地址
      • 远程调用
      • 启动服务
      • 启动多个服务, 测试负载均衡
      • 常见问题
    • Nacos负载均衡
      • 服务下线
      • 权重配置
        • 配置权重
        • 开启Nacos负载均衡策略
        • 测试权重配置
        • 常见问题
      • 同集群优先访问
        • 给实例配置集群名称
        • 开启Nacos负载均衡策略
        • 测试
    • Nacos 健康检查
      • 两种健康检查机制
      • Nacos服务实例类型
      • 常见问题
        • Nacos服务实例类型不允许改变
        • 服务正常, Nacos健康检查失败
    • Nacos环境隔离
      • 创建Namespace
      • 配置namespace
      • 测试远程调用
    • Nacos配置中心
      • 为什么需要配置中心
      • 快速上手
        • 添加配置
        • 获取配置
        • 常见问题
      • 配置中心详解
        • 设置命名空间
        • Data Id
    • 服务部署
    • Nacos与Eureka的区别


注册中心的其他实现-Nacos

Nacos简介

2018年6月,Eureka 2.0宣布闭源(但是1.X版本仍然为活跃项目),同年7月份,阿里Nacos宣布开源,并快速成为国内最受关注的开源产品。作为Eureka的替代,Nacos已经成为了国内开发者的首选,目前Nacos Star已经突破28K(Eureka 12K)。

Nacos

Nacos (Dynamic Naming and Configuration Service)

在最初开源时,Nacos选择进行内部三个产品合并统一开源(Configserver非持久注册中心,VIPServer持久化注册中心,Diamond配置中心)。定位为:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。所以Nacos是一个注册中心组件,但它又不仅仅是注册中心组件。

截至目前,Nacos几乎支持了所有的主流语言,比如 Java, Go, C++, Nodejs, Python, Scala等。

Nacos支持的语言

官方网站:https://nacos.io/

仓库:https://github.com/alibaba/nacos

Nacos安装

学习阶段采⽤单机安装即可. 以下内容都是单机版

下载安装包

⽬前官⽅推荐的稳定版本为2.2.3, 我们也是⽤2.2.3

下载地址 https://github.com/alibaba/nacos/releases/tag/2.2.3

其他版本下载链接: 下载链接: https://github.com/alibaba/nacos/releases

Windows

解压

把压缩包解压到任意⾮中⽂的⽬录下

⽬录介绍:

bin: Nacos启停脚本

  • startup.cmd :windows平台的启动脚本
  • startup.sh :Linux平台的启动脚本
  • shutdown.cmd : windows平台的停⽌脚本
  • shutdown.sh : Linux平台的停⽌脚本

conf: Nacos配置⽂件

target: 存放 Nacos 应⽤的 jar 包

修改单机模式

Nacos 默认启动⽅式为集群, 启动前需要修改配置为单机模式.

  1. 使⽤记事本打开 startup.cmd
  2. Line 26左右, 修改启动模式
set MODE="cluster"

改为

set MODE="standalone"

如下图所⽰:

启动Nacos

启动⾮常简单, 进⼊bin⽬录下, 双击 startup.cmd 即可

访问Nacos主⻚, 出现以下界⾯, 表⽰Nacos启动成功

http://127.0.0.1:8848/nacos

常见问题

Nacos启动后, ⽬录下会多⼀个logs的⽂件夹

报错⽇志在: logs/nacos.log

集群模式启动

报错⽇志

Caused by: java.net.UnknownHostException: jmenv.tbsite.netat java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:572)at java.base/java.net.Socket.connect(Socket.java:633)at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:178)at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:534)at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:639)at java.base/sun.net.www.http.HttpClient.<init>(HttpClient.java:282)at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:387)at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:409)at java.base/sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1309)at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1242)at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1128)at java.base/sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:1057)at com.alibaba.nacos.common.http.client.request.JdkHttpClientRequest.execute(JdkHttpClientRequest.java:114)at com.alibaba.nacos.common.http.client.NacosRestTemplate.execute(NacosRestTemplate.java:482)at com.alibaba.nacos.common.http.client.NacosRestTemplate.get(NacosRestTemplate.java:72)at com.alibaba.nacos.core.cluster.lookup.AddressServerMemberLookup.syncFromAddressUrl(AddressServerMemberLookup.java:175)at com.alibaba.nacos.core.cluster.lookup.AddressServerMemberLookup.run(AddressServerMemberLookup.java:143)... 126 common frames omitted
2023-12-25 12:14:54,260 WARN [HttpClientBeanHolder] Start destroying common HttpClient
2023-12-25 12:14:54,260 WARN [ThreadPoolManager] Start destroying ThreadPool

Nacos默认是集群(cluster)启动,将其设置为单机(standalone), 设置⽅式参考之前的笔记

端⼝号冲突

Nacos 默认端⼝号是8848, 如果该端⼝号被其他应⽤占⽤, 启动会报错:

Caused by: java.net.BindException: Address already in use: bindat java.base/sun.nio.ch.Net.bind0(Native Method)at java.base/sun.nio.ch.Net.bind(Net.java:555)at java.base/sun.nio.ch.ServerSocketChannelImpl.netBind(ServerSocketChannelImpl.java:337)at java.base/sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:294)at io.grpc.netty.shaded.io.netty.channel.socket.nio.NioServerSocketChannel.doBind(NioServerSocketChannel.java:141)at io.grpc.netty.shaded.io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:562)at io.grpc.netty.shaded.io.netty.channel.DefaultChannelPipeline$HeadContext.bind(DefaultChannelPipeline.java:1334)at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeBind(AbstractChannelHandlerContext.java:506)at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.bind(AbstractChannelHandlerContext.java:491)at io.grpc.netty.shaded.io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:973)at io.grpc.netty.shaded.io.netty.channel.AbstractChannel.bind(AbstractChannel.java:260)at io.grpc.netty.shaded.io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:356)at io.grpc.netty.shaded.io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)at io.grpc.netty.shaded.io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)at io.grpc.netty.shaded.io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)at io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:503)at io.grpc.netty.shaded.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)at io.grpc.netty.shaded.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)at io.grpc.netty.shaded.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)at java.base/java.lang.Thread.run(Thread.java:842)
2023-12-25 12:22:05,267 WARN [HttpClientBeanHolder] Start destroying common HttpClient

解决⽅式有以下两种, 任选其⼀:

  1. 关闭该进程

    1. 打开cmd

      Win + R, 弹出命令提⽰符, 输⼊cmd

    2. 查找进程

      输⼊命令

      netstat -ano|findstr "8848"
      

    3. 杀掉进程

      taskkill /pid 4968 -f
      

  2. 修改Nacos端⼝号

    修改⽂件: ${Nacos⽬录}/conf/application.properties

    23⾏左右

    修改8848为期望的端⼝号即可.

Linux

准备安装包

上传提前下载好的安装包到服务器上某个⽬录, ⽐如 /usr/local/src

解压安装包

unzip nacos-server-2.2.3.zip

如果第⼀次使⽤, 未安装unzip命令, 需要安装⼀下

apt-get install unzip

解压后⽬录如下:

root@hcss-ecs-0bb1:/usr/local/src/nacos# pwd
/usr/local/src/nacos
root@hcss-ecs-0bb1:/usr/local/src/nacos# ll
total 44
drwxr-xr-x 5 root root 4096 May 25 2023 ./
drwxr-xr-x 3 root root 4096 Dec 25 15:07 ../
drwxr-xr-x 2 root root 4096 May 25 2023 bin/
drwxr-xr-x 2 root root 4096 May 25 2023 conf/
-rw-r--r-- 1 root root 16583 Mar 6 2023 LICENSE
-rw-r--r-- 1 root root 1305 May 14 2020 NOTICE
drwxr-xr-x 2 root root 4096 May 25 2023 target/

和windows⼀样

单机模式启动

进⼊nacos/bin⽬录, 输⼊命令:

bash startup.sh -m standalone

上述命令为Ubuntu系统的命令

nacos安装前需要先安装JDK

CenterOS使⽤: sh startup.sh -m standalone

root@hcss-ecs-0bb1:/usr/local/src/nacos/bin# bash startup.sh -m standalone/usr/lib/jvm/java-17-openjdk-amd64/bin/java \-Xms512m -Xmx512m -Xmn256m \-Dnacos.standalone=true \-Dnacos.member.list= \-Xlog:gc*:file=/usr/local/src/nacos/logs/nacos_gc.log:time,tags:filecount=10,filesize=100m \-Dloader.path=/usr/local/src/nacos/plugins,/usr/local/src/nacos/plugins/health,/usr/local/src/nacos/plugins/cmdb,/usr/local/src/nacos/plugins/selector \-Dnacos.home=/usr/local/src/nacos \-jar /usr/local/src/nacos/target/nacos-server.jar \--spring.config.additional-location=file:/usr/local/src/nacos/conf/ \--logging.config=/usr/local/src/nacos/conf/nacos-logback.xml \--server.max-http-header-size=524288nacos is starting with standalone
nacos is starting, you can check the /usr/local/src/nacos/logs/start.out

启动成功后, 访问Nacos链接: http://IP:port/nacos

10020为修改后的端⼝号, 需要在服务器上开放对应的端⼝号

常见问题

参考Windows常⻅问题

Nacos快速上手

Nacos是Spring Cloud Alibaba的组件, Spring Cloud Alibaba遵循Spring Cloud中定义的服务注册, 服务发现规范. 因此使⽤Nacos和使⽤Eureka对于微服务来说,并没有太⼤区别.

主要差异在于:

  • Eureka需要⾃⼰搭建⼀个服务, Nacos不⽤⾃⼰搭建服务, 组件已经准备好了, 只需启动即可.
  • 对应依赖和配置不同

操作参考: https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-discovery

服务注册/服务发现

Nacos的服务注册和服务发现代码⼀样

同 Eureka 时的学习一样,我们复制 spring-cloud-demo 项目为新的 spring-cloud-nacos,修改对应的 pom.xml 文件

引入Spring Cloud Alibaba依赖

在⽗⼯程的pom⽂件中的 <dependencyManagement> 中引⼊Spring Cloud Alibaba的依赖:

<properties><spring-cloud-alibaba.version>2022.0.0.0-RC2</spring-cloud-alibaba.version>
</properties><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope>
</dependency>

注意: Spring Boot 和Spring Cloud的版本是有⼀定对应关系的. Spring Cloud Alibaba也遵循Spring Cloud 的标准, 在引⼊依赖时, ⼀定要确认各个版本的对应关系.

Spring Cloud Alibaba 和Spring Cloud版本对应关系, 参考官⽅⽂档:

https://sca.aliyun.com/zh-cn/docs/2022.0.0.0/overview/version-explain/

版本在⼀定范围内可以⾃由选择.

引入Nacos 依赖

在order-service和product-service中引⼊nacos依赖

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
引入Load Balance依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>

配置Nacos地址

学习时直接使⽤服务器Nacos地址

配置项Key默认值说明
服务端地址spring.cloud.nacos.discovery.server-addrNacos Server 启动监听的 IP 地址和端口
spring:application:name: order-servicecloud:nacos:discovery:server-addr: 110.41.51.65:10020 # (自己云服务器的地址)

也可以改成本地Nacos的IP: 127.0.0.1:8848

远程调用

  1. 修改IP为项⽬名
public OrderInfo selectOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectOrderById(orderId);String url = "http://product-service/product/" + orderInfo.getProductId();ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;
}
  1. 为restTemplate添加负载均衡注解 @LoadBalanced
@Configuration
public class BeanConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}

启动服务

启动两个服务(记得要先启动 nacos), 访问 http://127.0.0.1:8848/nacos, 观察Nacos的管理界⾯, 发现order-service 和product-service 都注册在Nacos上了

测试接⼝: http://127.0.0.1:8080/order/1

启动多个服务, 测试负载均衡

启动三个product-service服务

观察Nacos控制台

多次访问接⼝, 观察⽇志

http://127.0.0.1:8080/order/1

常见问题

java.net.UnknownHostException

java.net.UnknownHostException
2023-12-25T19:04:23.803+08:00 ERROR 25892 --- [nio-8080-exec-1] o.a.c.c.C.[.[. [/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] 
in context with path [] threw exception [Request processing failed: 
org.springframework.web.client.ResourceAccessException: I/O error on GET 
request for "http://product-service/product/1001": product-service] with root 
causejava.net.UnknownHostException: product-serviceat java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:572) ~[na:na]at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]at java.base/java.net.Socket.connect(Socket.java:583) ~[na:na]at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:183) ~[na:na]at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:534) ~[na:na]
// ... 

检查是否添加 LoadBalance 依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>

服务注册失败

可能没有报错⽇志, 或者报错⽇志如下(与版本有关)

Parameter 0 of method inetIPv6Utils in
com.alibaba.cloud.nacos.util.UtilIPv6AutoConfiguration required a bean of type 
'org.springframework.cloud.commons.util.InetUtilsProperties' that could not be 
found.The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)Action:Consider defining a bean of type 
'org.springframework.cloud.commons.util.InetUtilsProperties' in your 
configuration.

检查Spring Cloud Alibaba版本是否正确

参考: 版本发布说明 | Spring Cloud Alibaba

Nacos负载均衡

生产环境相对比较恶劣,我们需要对服务的流量进行更加精细的控制。Nacos支持多种负载均衡策略,包括权重、同机房、同地域、同环境等。

服务下线

当某一个节点上接口的性能较差时,我们可以第一时间对该节点进行下线。

操作步骤: 服务详情 -> 下线

服务下线

点击下线后,再次请求接口,会发现该服务没有请求进来了。

再次单击上线,该节点会继续收到请求。

权重配置

除了下线之外,我们也可以配置这个节点的流量权重。

配置权重

操作步骤: 找到对应节点 -> 编辑 -> 在弹出的窗口修改权重值

配置权重

每个节点默认权重为1,修改为0.1。但暂时不会有效果,原因在下面。

开启Nacos负载均衡策略

由于Spring Cloud LoadBalance组件自身有负载均衡配置方式,所以不支持Nacos的权重属性配置。

我们需要开启Nacos的负载均衡策略,让权重配置生效。

参考: 如何解决MSE Nacos上修改服务实例的权重不生效问题

修改 order-service 的配置文件,因为是 order-service 决定调用哪一个 product-service,这是一个客户端负载均衡

spring:cloud:loadbalancer:nacos:enabled: true
测试权重配置

启动服务,访问多次接口,观察结果,会发现9091端口号(权重较低的那个)的实例接收的请求明显比另外两个实例少。

整体流量生效,局部流量不是严格按照设置的比例进行分配的。

常见问题

修改权重时,可能会报错:

报错信息

报错信息: caused: errCode: 500, errMsg: do metadata operation failed ;caused: com.alibaba.nacos.consistency.exception.ConsistencyException: The Raft Group [naming_instance_metadata] did not find the Leader node;caused: The Raft Group [naming_instance_metadata] did not find the Leader node;

原因: Nacos采用Raft算法来计算Leader,并且会记录前一次启动的集群地址,当服务器IP改变时会导致Raft记录的集群地址失效,导致选Leader出现问题。(网络环境发生变化时,IP地址也会发生变化)

解决办法: 删除Nacos根目录下data文件夹下的protocol文件夹即可。

同集群优先访问

Nacos把同一个机房内的实例,划分为一个集群。所以同集群优先访问,在一定程度上也可以理解为同机房优先访问。

微服务架构中,一个服务通常有多个实例共同提供服务,这些实例可以部署在不同的机器上,这些机器可以分布在不同的机房,比如product-service:

实例1: 分布在上海机房
实例2: 分布在上海机房
实例3: 分布在北京机房
实例4: 分布在北京机房

同集群优先访问

微服务访问时,应尽量访问同机房的实例。当本机房内实例不可用时,才访问其他机房的实例。

比如order-service在上海机房,product-service在北京和上海机房都有实例,那我们希望可以优先访问上海机房,如果上海机房没有实例,或者实例不可用,再访问北京机房的实例。通常情况下,因为同一个机房的机器属于一个局域网,局域网访问速度更快一点。

同机房优先访问

给实例配置集群名称
  1. 为product-service配置集群名称
spring:cloud:nacos:discovery:server-addr: 110.41.51.65:10020cluster-name: SH # 集群名称: 上海集群

重启服务,观察Nacos控制台,SH集群下多了一个实例。

SH集群

复制product-service启动配置,添加VM Option

设置9091端⼝号的实例,机房为BJ

-Dserver.port=9091 -Dspring.cloud.nacos.discovery.cluster-name=BJ

设置9092端⼝号的实例,机房为BJ

-Dserver.port=9092 -Dspring.cloud.nacos.discovery.cluster-name=BJ

观察Nacos,BJ集群下多了⼀个实例

BJ集群

  1. 为order-service配置集群名称: SH
spring:cloud:nacos:discovery:server-addr: 110.41.51.65:10020cluster-name: SH # 集群名称: 上海集群
开启Nacos负载均衡策略

同权重配置,还是给 order-service 配置

spring:cloud:loadbalancer:nacos:enabled: true
测试

启动服务

  1. 对接口 http://127.0.0.1:8080/order/1 访问多次,观察日志,会发现只有9090端口的实例收到了请求(同集群)。
  2. 把9090端口的实例进行下线(SH集群),再次访问接口,观察日志,发现9091端口和9092端口的实例收到了请求。

Nacos负载均衡

  1. 支持服务上下线
  2. 服务配置权重(非严格)
  3. 同集群优先访问

Nacos 健康检查

两种健康检查机制

Nacos作为注册中⼼, 需要感知服务的健康状态, 才能为服务调⽤⽅提供良好的服务.

Nacos 中提供了两种健康检查机制:

客⼾端主动上报机制

  • 客⼾端通过⼼跳上报⽅式告知服务端(nacos注册中⼼)健康状态, 默认⼼跳间隔5秒;
  • nacos会在超过15秒未收到⼼跳后将实例设置为不健康状态, 超过30秒将实例删除

服务器端反向探测机制

  • nacos主动探知客⼾端健康状态, 默认间隔为20秒.
  • 健康检查失败后实例会被标记为不健康, 不会被⽴即删除.

⽐如领导管理员⼯的⼯作

  1. 员⼯主动汇报: 员⼯每天主动汇报⾃⼰⼯作进度
  2. 领导主动问询: 领导每周向员⼯了解⼯作进度

Nacos 中的健康检查机制不能主动设置,健康检查机制是和 Nacos 的服务实例类型强相关的.

Nacos服务实例类型

Nacos的服务实例(注册的节点)分为临时实例和⾮临时实例.

  • 临时实例: 如果实例宕机超过⼀定时间, 会从服务列表剔除, 默认类型.
  • 非临时实例: 如果实例宕机, 不会从服务列表剔除, 也可以叫永久实例

Nacos对临时实例, 采取的是 客⼾端主动上报机制, 对⾮临时实例, 采取服务器端反向探测机制.

配置⼀个服务实例为永久实例

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

重启服务, 观察Nacos控制台

停⽌服务, 再观察控制台

节点依然不会消失.

常见问题

Nacos服务实例类型不允许改变

设置服务实例类型, 重新启动Nacos可能会报错

即修改了服务实例类型,都要进行下面的解决方法

报错信息参考:

Caused by: com.alibaba.nacos.api.exception.NacosException: failed to req API:/nacos/v1/ns/instance after all servers([110.41.51.65:10020]) tried: caused: errCode: 400, errMsg: Current service DEFAULT_GROUP@@product-service is ephemeral service, can't register persistent instance. ;at com.alibaba.nacos.client.naming.remote.http.NamingHttpClientProxy.reqApi(NamingHttpClientProxy.java:410) ~[nacos-client-2.2.1.jar:na]at com.alibaba.nacos.client.naming.remote.http.NamingHttpClientProxy.reqApi(NamingHttpClientProxy.java:351) ~[nacos-client-2.2.1.jar:na]at com.alibaba.nacos.client.naming.remote.http.NamingHttpClientProxy.reqApi(NamingHttpClientProxy.java:346) ~[nacos-client-2.2.1.jar:na]// ...

原因: Nacos会记录每个服务实例的IP和端⼝号, 当发现IP和端⼝都没有发⽣变化时, Nacos不允许⼀个服务实例类型发⽣变化, ⽐如从临时实例,变为⾮临时实例, 或者从⾮临时实例, 变成临时实例.

解决办法:

  1. 停掉nacos
  2. 删除nacos ⽬录下 /data/protocol/raft 信息, ⾥⾯会保存应⽤实例的元数据信息.
服务正常, Nacos健康检查失败

现象:

服务正常, 但是Nacos显⽰健康状态为false

原因和解决办法:

参考:

如何解决Nacos持久化实例HTTP/TCP的健康检查不通过问题_微服务引擎(MSE)-阿⾥云帮助中⼼

Nacos环境隔离

企业开发中, ⼀个服务会分为开发环境, 测试环境和⽣产环境.

  1. 开发环境:开发⼈员⽤于开发的服务器, 是最基础的环境. ⼀般⽇志级别设置较低, 可能会开启⼀些调试信息.
  2. 测试环境:测试⼈员⽤来进⾏测试的服务器, 是开发环境到⽣产环境的过渡环境.
  3. ⽣产环境:正式提供对外服务的环境, 通常关掉调试信息.

通常情况下, 这⼏个环境是不能互相通信的. Nacos提供了namespace(命名空间)来实现环境的隔离. 不同的namaspace的服务不可⻅.

创建Namespace

默认情况下,所有服务都在同⼀个namespace,名为public

点击左侧命名空间, 可以对namespace进⾏操作

新增命名空间

配置namespace

namespace创建完成后, 对服务进⾏配置

这是配置项的表格,包括默认值和说明:

配置项Key默认值说明
命名空间spring.cloud.nacos.discovery.namespace常见的使用场景之一是不同环境中的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。

如果还有其他需要帮助的,请告诉我。

修改order-service的命名空间

spring:cloud:nacos:discovery:namespace: 4f597670-0ef8-4450-89e3-044371222220 # 服务管理的命名空间

测试远程调用

  1. 启动服务, 观察Nacos控制台

public 命名空间下只有product-service服务

order-service在dev命名空间下

  1. 访问接⼝, 测试远程调⽤

发现服务报错:

2023-12-27T18:23:27.058+08:00 ERROR 30408 --- [nio-8080-exec-1] o.a.c.c.C.[.[. [/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.IllegalStateException: No instances available for product-service] with root causejava.lang.IllegalStateException: No instances available for product-service
at org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient.execute(BlockingLoadBalancerClient.java:78) ~[spring-cloud-loadbalancer-4.0.3.jar:4.0.3]
at org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor.intercept(LoadBalancerInterceptor.java:56) ~[spring-cloud-commons-4.0.3.jar:4.0.3]
at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:87) ~[spring-web-6.0.14.jar:6.0.14]
at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:71) ~[spring-web-6.0.14.jar:6.0.14]
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48) ~[spring-web-6.0.14.jar:6.0.14]
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66) ~[spring-web-6.0.14.jar:6.0.14]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:862) ~[spring-web-6.0.14.jar:6.0.14]
// ...
  1. 修改product-service的其中⼀个实例, 命名空间改为dev
spring:cloud:nacos:discovery:namespace: 4f597670-0ef8-4450-89e3-044371222220 # 服务管理的命名空间
  1. 启动服务

观察Nacos控制台

再次访问接⼝ http://127.0.0.1:8080/order/3, 发现远程调⽤成功

Nacos配置中心

除了注册中⼼和负载均衡之外, Nacos还是⼀个配置中⼼, 具备配置管理的功能.

Namespace 的常⽤场景之⼀是不同环境的配置区分隔离. 例如开发测试环境和⽣产环境的配置隔离.

为什么需要配置中心

当前项⽬的配置都在代码中, 会存在以下问题:

  1. 配置⽂件修改时, 服务需要重新部署. 微服务架构中, ⼀个服务可能有成百个实例, 挨个部署⽐较⿇烦, 且容易出错.

  2. 多⼈开发时, 配置⽂件可能需要经常修改, 使⽤同⼀个配置⽂件容易冲突.

配置中⼼就是对这些配置项进⾏统⼀管理. 通过配置中⼼, 可以集中查看, 修改和删除配置, ⽆需再逐个修改配置⽂件. 提⾼效率的同时, 也降低了出错的⻛险.

  1. 服务启动时, 从配置中⼼读取配置项的内容, 进⾏初始化.
  2. 配置项修改时, 通知微服务, 实现配置的更新加载.

快速上手

通过以下操作, 我们先来感受下Nacos 配置中⼼的使⽤

参考⽂档: Nacos Spring Cloud 快速开始 Nacos config

添加配置

在Nacos控制台添加配置项

注意: 配置管理的命名空间和服务列表的命名空间是隔离的, 两个是分别设置的. 默认是public

也就是服务管理命名空间配置 ≠ 配置管理的命名空间

新建配置项

配置内容:

nacos.test.num=5

说明:

  1. Data ID 设置为项⽬名称
  2. 配置内容的数据格式, ⽬前只⽀持 properties 和 yaml 类型
  3. 设置配置内容
获取配置
  1. 引入Nacos Config依赖
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency><!-- Spring Cloud 2020.*之后版本需要引入bootstrap -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
  1. 配置bootstrap.properties

微服务启动前, 需要先获取nacos中配置, 并与application.yml配置合并. 在微服务运⾏之前, Nacos要求必须使⽤ bootstrap.properties 配置⽂件来配置Nacos Server 地址.

spring.application.name=product-service
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

或者使⽤bootstrap.yml

spring:application:name: product-servicecloud:nacos:config:server-addr: 127.0.0.1:8848

spring.application.name 需要和nacos配置管理的Data ID⼀致

spring.cloud.nacos.config.server-addr 为Nacos Server的地址

配置中⼼和注册中⼼的配置是隔离的

Nacos 配置中⼼: spring.cloud.nacos.config.server-addr

Nacos 注册中⼼: spring.cloud.nacos.discovery.server-addr

  1. 编写程序
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RequestMapping("/config")
@RefreshScope
@RestController
public class NacosController {@Value("${nacos.test.num:0}")private Integer nacosNum;@RequestMapping("/get")public Integer get() {return nacosNum;}
}
  • @Value 读取配置
  • @RefreshScope 配置进⾏热更新
  1. 测试

启动程序, 访问接⼝: http://127.0.0.1:9090/config/get

在Nacos控制台修改 nacos.test.num

再次访问接⼝:

常见问题
  1. 读取不到配置项

    可能原因:

    • 配置错误: 检查配置Data ID, 配置格式, 配置空间等
    • 未引⼊依赖
  2. No spring.config.import property has been defined

    启动报错⽇志:

    ***************************
    APPLICATION FAILED TO START
    ***************************Description:No spring.config.import property has been definedAction:Add a spring.config.import=nacos: property to your configuration.
    If configuration is not required add spring.config.import=optional:nacos: instead.
    To disable this check, set spring.cloud.nacos.config.import-check.enabled=false.
    

    原因: bootstrap.properties 是系统级的资源配置⽂件, ⽤于程序执⾏更加早期配置信息读取. 但是SpringCloud 2020.* 之后的版本把bootstrap禁⽤了, 导致在读取⽂件的时候读取不到⽽报错, 所以需要重新导⼊bootstrap 包进来就可以了

  3. Nacos Server地址配置错误

    报错信息如下:

    2023-12-28T17:12:53.070+08:00 ERROR 14356 --- [t.remote.worker] c.a.n.c.remote.client.grpc.GrpcClient : Server check fail, please check server 127.0.0.1, port 11020 is available, error ={}java.util.concurrent.ExecutionException: com.alibaba.nacos.shaded.io.grpc.StatusRuntimeException: UNAVAILABLE: io exceptionat com.alibaba.nacos.shaded.com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:566) ~[nacos-client-2.2.1.jar:na]at com.alibaba.nacos.shaded.com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:445) ~[nacos-client-2.2.1.jar:na]// ...
    Caused by: com.alibaba.nacos.shaded.io.grpc.StatusRuntimeException: UNAVAILABLE: io exceptionat com.alibaba.nacos.shaded.io.grpc.Status.asRuntimeException(Status.java:539) ~[nacos-client-2.2.1.jar:na]at com.alibaba.nacos.shaded.io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:544) ~[nacos-client-2.2.1.jar:na]at com.alibaba.nacos.shaded.io.grpc.internal.DelayedClientCall$DelayedListener$3.run(DelayedClientCall.java:471) ~[nacos-client-2.2.1.jar:na]// ...
    Caused by: com.alibaba.nacos.shaded.io.grpc.netty.shaded.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /127.0.0.1:11020Caused by: java.net.ConnectException: Connection refused: no further informationat java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:946) ~[na:na]// ...
    

配置中心详解

设置命名空间

Nacos配置管理的命名空间和服务列表的命名空间是分别设置的. 默认是public

配置管理的配置项都是在 bootstrap 配置的,服务启动的配置项是在 application 配置的

Nacos命名空间配置依然在bootstrap.properties中进⾏配置

spring.cloud.nacos.config.namespace=4f597670-0ef8-4450-89e3-044371222220

对应bootstrap.yml配置

spring:cloud:nacos:config:namespace: 4f597670-0ef8-4450-89e3-044371222220

value对应 命名空间的ID, 如下图所⽰:

如果设置命名空间后, 项⽬启动时, 会从该命名空间下找对应的配置项.

重新访问接⼝, 观察结果:

http://127.0.0.1:9090/config/get

Data Id

Data Id 格式介绍

在 Nacos Spring Cloud 中, dataId 的完整格式如下:

${prefix}-${spring.profiles.active}.${file-extension}
  • prefix 默认为 spring.application.name 的值(我们上面填的就是 product-service), 也可以通过配置项 spring.cloud.nacos.config.prefix 来配置.
  • spring.profiles.active 即为当前环境对应的 profile(即 public 还是 dev 之类的). 当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
  • file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。⽬前只⽀持 propertiesyaml 类型. 默认为 properties.

微服务启动时, 会从Nacos读取多个配置⽂件:

  1. ${prefix}-${spring.profiles.active}.${file-extension} 如: product-service-dev.properties

  2. ${prefix}.${file-extension} , 如: product-service.properties

  3. ${prefix} 如product-service

${spring.application.name}, ${spring.profiles.active} 等通过配置⽂件来指定时, 必须放在 bootstrap.properties ⽂件中

观察⽇志

在bootstrap.yml中添加 spring.profiles.active

spring:profiles:active: dev

注意,这里如果配置了 dev 环境,而且 Nacos 中也配置了 dev,那么这些配置就会被加载

启动服务, 观察⽇志

1 2023-12-28T18:48:08.614+08:00 INFO 36672 --- [ main] c.a.n.client.config.impl.ClientWorker : [fixed-51152a13-7911-49e3-bbdc-16fd5670a257-110.41.51.65_10020] [subscribe] product-service-dev.properties+DEFAULT_GROUP+51152a13-7911-49e3-bbdc-16fd5670a257
2 2023-12-28T18:48:08.624+08:00 INFO 36672 --- [ main] c.a.nacos.client.config.impl.CacheData : [fixed-51152a13-7911-49e3-bbdc-16fd5670a257-110.41.51.65_10020] [add-listener] ok, tenant=51152a13-7911-49e3-bbdc-16fd5670a257, dataId=product-service-dev.properties, group=DEFAULT_GROUP, cnt=1
3 2023-12-28T18:48:08.624+08:00 INFO 36672 --- [ main] c.a.c.n.refresh.NacosContextRefresher : [Nacos Config] Listening config: dataId=product-service-dev.properties, group=DEFAULT_GROUP
4 2023-12-28T18:48:08.625+08:00 INFO 36672 --- [ main] c.a.n.client.config.impl.ClientWorker : [fixed-51152a13-7911-49e3-bbdc-16fd5670a257-110.41.51.65_10020] [subscribe] product-service.properties+DEFAULT_GROUP+51152a13-7911-49e3-bbdc-16fd5670a257
5 2023-12-28T18:48:08.625+08:00 INFO 36672 --- [ main] c.a.nacos.client.config.impl.CacheData : [fixed-51152a13-7911-49e3-bbdc-16fd5670a257-110.41.51.65_10020] [add-listener] ok, tenant=51152a13-7911-49e3-bbdc-16fd5670a257, dataId=product-service.properties, group=DEFAULT_GROUP, cnt=1
6 2023-12-28T18:48:08.625+08:00 INFO 36672 --- [ main] c.a.c.n.refresh.NacosContextRefresher : [Nacos Config] Listening config: dataId=product-service.properties, group=DEFAULT_GROUP
7 2023-12-28T18:48:08.626+08:00 INFO 36672 --- [ main] c.a.n.client.config.impl.ClientWorker : [fixed-51152a13-7911-49e3-bbdc-16fd5670a257-110.41.51.65_10020] [subscribe] product-service+DEFAULT_GROUP+51152a13-7911-49e3-bbdc-16fd5670a257
8 2023-12-28T18:48:08.627+08:00 INFO 36672 --- [ main] c.a.nacos.client.config.impl.CacheData : [fixed-51152a13-7911-49e3-bbdc-16fd5670a257-110.41.51.65_10020] [add-listener] ok, tenant=51152a13-7911-49e3-bbdc-16fd5670a257, dataId=product-service, group=DEFAULT_GROUP, cnt=1
9 2023-12-28T18:48:08.627+08:00 INFO 36672 --- [ main] c.a.c.n.refresh.NacosContextRefresher : [Nacos Config] Listening config: dataId=product-service, group=DEFAULT_GROUP

配置文件的优先级顺序如下:

  1. ${prefix}-${spring.profiles.active}.${file-extension}:例如 product-service-dev.properties
  2. ${prefix}.${file-extension}:例如 product-service.properties
  3. ${prefix}:例如 product-service

优先级顺序为:product-service-dev.properties > product-service.properties > product-service

这样可以确保在有特定环境配置时,优先使用特定环境的配置,而没有特定环境配置时,使用默认的配置。

测试

bootstrap.yml配置如下:

spring:application:name: product-serviceprofiles:active: devcloud:nacos:config:server-addr: 127.0.0.1:8848namespace: 4f597670-0ef8-4450-89e3-044371222220

配置项如下:

访问接⼝: http://127.0.0.1:9090/config/get

服务获取到了 product-service-dev.properties 的值

删除 product-service-dev.properties 配置, 再次访问接⼝

注意:

  1. bootstrap.yml 设置的配置格式必须和nacos控制台配置的数据格式保持⼀致.
  2. 不设置配置格式(spring.cloud.nacos.config.file-extension)时, 默认为properties

虽然我们在 bootstrap.yml 文件格式是 yml,而在 Nacos 中的配置文件格式是 properties,只要配置的内容格式正确,Spring Cloud 会自动解析并加载这些配置。

服务部署

  1. 修改数据库, Nacos等相关配置

    在这里bootstrap.yml中设置动态的 profile.name 时 Maven 不能直接读取,需要额外在pom.xml 加点东西

    <profiles><profile><id>dev</id><properties><profile.name>dev</profile.name></properties></profile><profile><id>prod</id><properties><profile.name>prod</profile.name></properties></profile>
    </profiles><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins><resources><resource><directory>src/main/resources</directory><filtering>true</filtering><includes><include>**/**</include></includes></resource></resources>
    </build>
    

    product-service 的 application-dev.yml、application-prod.yml、bootstrap.yml

    server:
    port: 9090spring:
    datasource:url: jdbc:mysql://127.0.0.1:3306/cloud_product?characterEncoding=utf8&useSSL=falseusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver
    cloud:nacos:discovery:server-addr: 127.0.0.1:8848 # (或自己云服务器的地址)
    #        cluster-name: SH
    #        namespace: 4f597670-0ef8-4450-89e3-044371222220 # 服务管理的命名空间mybatis:
    configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true
    
    server:
    port: 9090spring:
    datasource:url: jdbc:mysql://127.0.0.1:3306/cloud_product?characterEncoding=utf8&useSSL=falseusername: rootpassword: # 云服务器的数据库密码driver-class-name: com.mysql.cj.jdbc.Driver
    cloud:nacos:discovery:server-addr: 127.0.0.1:8848 # (或自己云服务器的地址)
    #        cluster-name: SH
    #        namespace: 4f597670-0ef8-4450-89e3-044371222220 # 服务管理的命名空间mybatis:
    configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true
    
    spring:
    application:name: product-service
    profiles:active: @profile.name@
    cloud:nacos:config:server-addr: 127.0.0.1:8848
    #        namespace: 4f597670-0ef8-4450-89e3-044371222220
    

    order-service 的 application.yml、application-dev.yml、application-prod.yml

    server:
    port: 8080spring:
    application:name: order-service
    profiles:active: @profile.name@
    cloud:nacos:discovery:server-addr: 127.0.0.1:8848 # (或自己云服务器的地址)
    #        namespace: 4f597670-0ef8-4450-89e3-044371222220 # 服务管理的命名空间
    #        cluster-name: BJ
    #        ephemeral: false # 设置为非临时实例loadbalancer:nacos:enabled: truemybatis:
    configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true # 配置驼峰自动转换
    
    spring:
    datasource:url: jdbc:mysql://127.0.0.1:3306/cloud_order?characterEncoding=utf8&useSSL=falseusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver
    
    spring:
    datasource:url: jdbc:mysql://127.0.0.1:3306/cloud_order?characterEncoding=utf8&useSSL=falseusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver
    

    如果出现类似Caused by: org.yaml.snakeyaml.scanner.ScannerException: while scanning for the next token found character '@' that cannot start any token.这样的报错

    可能需要重新导入 maven

  2. 对两个服务进⾏打包

  3. 上传jar到Linux服务器

  4. 启动Nacos

    启动前最好把data数据删除掉.

  5. 启动服务

# 后台启动 order-service,并设置输出日志到 logs/order.log
nohup java -jar order-service.jar > logs/order.log &# 后台启动 product-service,并设置输出日志到 logs/product-9090.log
nohup java -jar product-service.jar > logs/product-9090.log &# 启动实例,指定端口号为 9091,日志输出到 logs/product-9091.log
nohup java -jar product-service.jar --server.port=9091 > logs/product-9091.log &

观察Nacos控制台

  1. 测试

    访问接⼝: http://110.41.51.65:8080/order/1

    观察远程调⽤的结果:

Nacos与Eureka的区别

共同点:

  • 都⽀持服务注册和服务拉取

区别:

  1. 功能

Nacos除了服务发现和注册之外, 还提供了配置中⼼, 流量管理和DNS服务等功能.

  1. CAP理论

Eureka遵循AP原则, Nacos可以切换AP和CP模式,默认AP.

Nacos 根据配置识别CP或者AP模式. 如果注册Nacos的Client的节点是临时节点, 那么Nacos对这个Client节点的效果就是AP, 反之是CP. AP和CP可以同时混合存在.

  1. 服务发现

Eureka:基于拉模式. Eureka Client会定期从Server拉取服务信息, 有缓存, 默认每30秒拉取⼀次.

Nacos:基于推送模式. 服务列表有变化时实时推送给订阅者, 服务端和客⼾端保持⼼跳连接.

服务启动:

11:02:05.685+08:00 INFO 3544 --- [110.41.51.65-45] com.alibaba.nacos.common.remote.client : 
[e41cbcc4-e986-428c-bd30-f1e4820e4084] Receive server push request, request = NotifySubscriberRequest, requestId = 211:02:05.686+08:00 INFO 3544 --- [110.41.51.65-45] com.alibaba.nacos.client.naming : 
new ips(1) service: DEFAULT_GROUP@@product-service -> 
[{"ip": "192.168.31.107","port": 9092,"weight": 1.0,"healthy": true,"enabled": true,"ephemeral": true,"clusterName": "BJ","serviceName": "DEFAULT_GROUP@@product-service","metadata": {"preserved.register.source": "SPRING_CLOUD"},"instanceHeartBeatTimeOut": 15000,"instanceHeartBeatInterval": 5000,"ipDeleteTimeout": 30000
}]11:02:05.687+08:00 INFO 3544 --- [110.41.51.65-45] com.alibaba.nacos.client.naming : 
current ips:(2) service: DEFAULT_GROUP@@product-service -> 
[{"ip": "192.168.31.107","port": 9090,"weight": 1.0,"healthy": true,"enabled": true,"ephemeral": true,"clusterName": "SH","serviceName": "DEFAULT_GROUP@@product-service","metadata": {"preserved.register.source": "SPRING_CLOUD"},"instanceHeartBeatTimeOut": 15000,"instanceHeartBeatInterval": 5000,"ipDeleteTimeout": 30000
},
{"ip": "192.168.31.107","port": 9092,"weight": 1.0,"healthy": true,"enabled": true,"ephemeral": true,"clusterName": "BJ","serviceName": "DEFAULT_GROUP@@product-service","metadata": {"preserved.register.source": "SPRING_CLOUD"},"instanceHeartBeatTimeOut": 15000,"instanceHeartBeatInterval": 5000,"ipDeleteTimeout": 30000
}]11:02:05.724+08:00 INFO 3544 --- [110.41.51.65-45] com.alibaba.nacos.common.remote.client : 
[e41cbcc4-e986-428c-bd30-f1e4820e4084] Ack server push request, request = NotifySubscriberRequest, requestId = 2

服务停⽌:

2023-12-29T11:02:58.839+08:00 INFO 3544 --- [110.41.51.65-59] com.alibaba.nacos.common.remote.client : 
[e41cbcc4-e986-428c-bd30-f1e4820e4084] Receive server push request, request = NotifySubscriberRequest, requestId = 32023-12-29T11:02:58.839+08:00 INFO 3544 --- [110.41.51.65-59] com.alibaba.nacos.client.naming : 
removed ips(1) service: DEFAULT_GROUP@@product-service -> 
[{"ip": "192.168.31.107","port": 9092,"weight": 1.0,"healthy": true,"enabled": true,"ephemeral": true,"clusterName": "BJ","serviceName": "DEFAULT_GROUP@@product-service","metadata": {"preserved.register.source": "SPRING_CLOUD"},"instanceHeartBeatTimeOut": 15000,"instanceHeartBeatInterval": 5000,"ipDeleteTimeout": 30000
}]2023-12-29T11:02:58.840+08:00 INFO 3544 --- [110.41.51.65-59] com.alibaba.nacos.client.naming : 
current ips:(1) service: DEFAULT_GROUP@@product-service -> 
[{"ip": "192.168.31.107","port": 9090,"weight": 1.0,"healthy": true,"enabled": true,"ephemeral": true,"clusterName": "SH","serviceName": "DEFAULT_GROUP@@product-service","metadata": {"preserved.register.source": "SPRING_CLOUD"},"instanceHeartBeatTimeOut": 15000,"instanceHeartBeatInterval": 5000,"ipDeleteTimeout": 30000
}]2023-12-29T11:02:58.842+08:00 INFO 3544 --- [110.41.51.65-59] com.alibaba.nacos.common.remote.client : 
[e41cbcc4-e986-428c-bd30-f1e4820e4084] Ack server push request, request = NotifySubscriberRequest, requestId = 3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/145682.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

SpringCloud微服务实现服务熔断的实践指南

Spring Cloud是一套分布式系统的微服务框架&#xff0c;它提供了一系列的组件和工具&#xff0c;能够使我们更容易地构建和管理微服务架构。在实际开发中&#xff0c;由于各个服务之间的通信依赖&#xff0c;一旦某个服务出现故障或负载过高&#xff0c;可能会导致整个系统的性…

百度飞浆Paddle OCR检测和识别【OCR数据收集、标注、数据集划分、检测识别模型训练、导出模型】

文章目录 前言一、OCR数据集采集二、OCR数据标注三、划分数据集四、数据训练五、导出模型 前言 1、我的电脑没有GPU&#xff0c;如果不使用AI Studio训练的话&#xff0c;第一遍我是按照CPU进行环境配置和训练的&#xff0c;可以参考这篇文章&#xff0c;我按着弄了一遍&#…

深度学习(一)——CMC特刊推荐

点击蓝字 关注我们 特刊征稿 01 期刊名称&#xff1a; Multimedia Security in Deep Learning 截止时间&#xff1a; 提交截止日期:2024年9月30日 目标及范围&#xff1a; 题为“深度学习中的多媒体安全”的特刊是一个平台&#xff0c;旨在推动深度学习在多媒体安全领域的创…

山体滑坡检测系统源码分享

山体滑坡检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

(黑马点评)八、实现签到统计和uv统计

8.1 签到统计系列功能 8.1.1 认识BitMap结构 BitMap是Redis基于String实现的一种高效的二进制数位的数据结构。因此一个BItMap的最大上线为512M&#xff0c;转为bit位可表示 2^32位 常见命令 SETBIT&#xff1a;向指定位置&#xff08;offset&#xff09;存入一个0或1 GETBIT …

CST软件超表面---电容或变容二极管调焦反射镜

可变焦的超表面&#xff08;focus tunable metasurface&#xff09;类型反射镜具有超薄、智能可控等特点&#xff0c;可用于成像、显微等应用。而且经常有朋友问如何用电容或二极管调控超材料&#xff0c;这期我们就用个简单的案例看看调控效果。 1. 单元仿真 单元尺寸我们用1…

【原创教程】电气电工20:一文弄透电气电工辅材

电气电工这些知识点,我们描述的比较细,虽然看起来比较简单,但是它是后面我们技能提升的基础,如果我们后面学电气工程师相关知识,这些都属于基本功。 接着我们来看一下电气辅材。 电气辅材定义: 电气辅材是指与电气设备固有的元器件配套使用的配件和器具。常见的电气辅…

Python “函数” ——Python面试100道实战题目练习,巩固知识、检查技术、成功就业

本文主要是作为Python中函数的一些题目&#xff0c;方便学习完Python的函数之后进行一些知识检验&#xff0c;感兴趣的小伙伴可以试一试&#xff0c;含选择题、判断题、实战题、填空题&#xff0c;答案在第五章。 在做题之前可以先学习或者温习一下Python的函数&#xff0c;推荐…

构建高效用户中心的技术方案

一、架构设计 在设计用户中心时&#xff0c;首先要考虑其架构。推荐采用微服务架构&#xff0c;这样可以将不同功能模块独立开来&#xff0c;便于后期维护和扩展。例如&#xff0c;可以将用户注册、登录、信息管理、权限控制等功能分为不同的服务模块。 二、前端开发 前端是…

【2022工业图像异常检测文献】PatchCore

Towards Total Recall in Industrial Anomaly Detection 1、Background 工业图像异常检测主要解决 冷启动问题 &#xff0c;即仅使用正常&#xff08;无缺陷&#xff09;样本图像来训练模型。 现有的关于冷启动工业视觉异常检测的工作依赖于通过自编码方法、生成对抗网络或其…

高速CT滑环的特点分析

高速CT滑环在现代成像技术中发挥着至关重要的作用&#xff0c;尤其是在医学成像设备和工业检测系统中。这种滑环不仅满足高速旋转的需求&#xff0c;还确保了信号和电力的稳定传输。本文将详细分析高速CT滑环的主要特点及其应用优势。 高速CT滑环的第一个特点是其高传输速率。…

101. 对称二叉树【同时遍历两棵树】【C++】

题目描述 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false 提示&#xff1a; …

Flet内置图标库ft.icons的图标如何使用庖丁解牛深度解读讲解,源代码IDE运行和调试通过

序言 Flet内置图标库图标丰富多彩、包罗万象。flet内置图标库指ft.icons图标库。使用Flet框架编写程序和项目&#xff0c;就要使用 Flet 内置图标库图标。使用 Flet 内置图标库的图标好处很多。 具体说有以下好处&#xff1a; 便捷性&#xff1a;无需额外寻找和下载图标资源&…

「OC」present和push操作区别以及混合推出的实现

「OC」present和push操作区别以及混合推出的实现 文章目录 「OC」present和push操作区别以及混合推出的实现前言present用途while循环越级返回通知越级返回添加present动画 push模态视图和push视图混合跳转操作一&#xff1a;控制器Apresent控制器B&#xff0c;控制器B再将控制…

影视会员充值api?接口对接需要做哪些准备工作?

影视会员充值 API 接口对接主要有以下步骤&#xff1a; 1.前期准备 明确自身需求&#xff1a;确定你希望通过 API 接口实现的功能&#xff0c;例如支持哪些影视平台的会员充值、是否需要获取会员信息、是否需要订单查询功能等。选择合适的 API 提供商&#xff1a;官方视频平台…

中国电子学会202312青少年软件编程(Python)等级考试试卷(三级)真题

2023年12月青少年软件编程Python等级考试(三级)真题试卷 题目总数:38 总分数:100 一、选择题 第 1 题 单选题 一个非零的二进制正整数,在其末尾添加两个“0”,则该新数将是原数的?( ) A.10倍 B.2倍 C.4倍 D.8倍 第 2 题 单选题 2023年亚运会将在杭…

分步指南:如何使用 ChatGPT 撰写文献综述

撰写文献综述对于研究人员和学生来说,往往是一项既耗时又复杂的任务。这一过程不仅要求对所选主题的现有研究进行全面的了解和掌握,还需要学术严谨性。然而,随着像 ChatGPT 这样的高级语言模型的广泛应用,撰写文献综述的过程变得更加高效和简化。通过合理利用 ChatGPT,研究…

跨国公司决策的影响与中国IT产业的应对

跨国公司在华研发中心的调整是一个复杂的现象&#xff0c;它可能受到多种因素的影响&#xff0c;包括全球经济环境的变化、成本考量、战略重心的转移以及地缘政治因素等。IBM中国研发中心的撤出可能会对中国IT行业造成短期的就业压力&#xff0c;加速人才流动&#xff0c;并促使…

【LeetCode】每日一题 2024_9_20 统计特殊整数(数位 DP)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;统计特殊整数 代码与解题思路 func countSpecialNumbers(n int) int { // 今天的题目是数位 DP&#xff0c;我不会做&#xff0c;所以现场学习了一下灵神的数位 DP 模版s : strconv.Itoa…

轻松打造:用Python实现手机与电脑间的简易消息系统

展示&#x1f3a5; 观看视频&#xff1a;&#x1f440;&#xff0c;这是之前完成的一个项目&#xff0c;但今天我们的重点不是这个哦。 告别往昔&#xff0c;启航新篇章 现象&#x1f31f; 智能互动&#xff1a;&#x1f4f1; 我们每天都在享受与智能设备的互动&#xff0c;…