第二篇:Nacos服务注册与发现原理

news2026/5/12 16:52:49
第二篇Nacos服务注册与发现原理关键词Nacos、服务注册、服务发现、心跳机制、健康检查、Distro协议、Spring Cloud、负载均衡、长连接、gRPC摘要服务注册与发现是微服务架构的神经系统它决定了服务之间能否高效、可靠地找到彼此。Nacos 作为国产注册中心的佼佼者其服务注册与发现机制经历了从 1.x 到 2.x 的重大演进。本文将深入剖析 Nacos 服务注册的完整链路、服务发现的双模式运作原理、健康检查的底层实现以及 Spring Cloud 集成中的自动装配机制。通过源码级别的解读和实际项目中的踩坑经验帮助读者不仅知其然更知其所以然。文章标签Nacos服务注册服务发现源码分析Spring Cloud心跳机制健康检查微服务一、服务注册流程从客户端发起请求到服务端落盘1.1 注册流程全景图当一个 Spring Boot 应用引入spring-cloud-starter-alibaba-nacos-discovery依赖后服务启动时会自动向 Nacos Server 发起注册。这个看似简单的操作背后涉及客户端 SDK、网络传输、服务端处理、数据同步等多个环节。在 Nacos 1.x 版本中客户端通过 HTTP 协议向服务端发送注册请求请求体中包含服务名、分组名、IP、端口、权重、元数据等信息。服务端接收到请求后将实例数据写入内存注册表并根据实例类型决定是否需要持久化。对于临时实例数据仅保存在内存中通过 Distro 协议异步同步给其他节点对于永久实例则需要通过 Raft 协议写入到文件系统或数据库中。到了 Nacos 2.x 版本通信协议从 HTTP 升级到了 gRPC 长连接整个注册流程发生了显著变化。客户端启动时会与服务端建立一个 gRPC 连接后续的注册、心跳、订阅等操作都复用这条连接。这种长连接模型避免了频繁的 TCP 握手开销据官方压测数据2.x 版本的吞吐量相比 1.x 提升了近 10 倍。------------------------------------------------------------------ | Nacos 2.x 服务注册流程 | ------------------------------------------------------------------ | | | Client Side Server Side | | ------------------ ------------------ | | | Application | | Nacos Server | | | | (Spring Boot) | | | | | ----------------- ----------------- | | | | | | | 1. 建立 gRPC 长连接 | | | |------------------------------------| | | | | | | | 2. 发送 InstanceRequest | | | | (serviceName, ip, port...) | | | |------------------------------------| | | | | | | | | 3. 写入 Client | | | | 对象和索引 | | | | | | | | 4. Distro 同步 | | | | 给其他节点 | | | | | | | | 5. 触发 Push | | | | 给订阅者 | | | | | | | 6. 返回注册成功响应 | | | |------------------------------------| | | | ------------------------------------------------------------------1.2 客户端注册源码解析在客户端NacosNamingService是服务注册的核心入口。当调用registerInstance方法时SDK 首先会检查实例的合法性然后构建心跳信息如果是临时实例最后通过 gRPC 客户端发送InstanceRequest。OverridepublicvoidregisterInstance(StringserviceName,StringgroupName,Instanceinstance)throwsNacosException{NamingUtils.checkInstanceIsLegal(instance);StringgroupedServiceNameNamingUtils.getGroupedName(serviceName,groupName);// 临时实例需要构建心跳任务if(instance.isEphemeral()){BeatInfobeatInfobeatReactor.buildBeatInfo(groupedServiceName,instance);beatReactor.addBeatInfo(groupedServiceName,beatInfo);}// 发送 gRPC 注册请求redoService.cacheInstanceForRedo(serviceName,groupName,instance);doRegisterService(serviceName,groupName,instance);}privatevoiddoRegisterService(StringserviceName,StringgroupName,Instanceinstance)throwsNacosException{InstanceRequestrequestnewInstanceRequest(namespaceId,serviceName,groupName,NamingRemoteConstants.REGISTER_INSTANCE,instance);requestToServer(request,Response.class);redoService.instanceRegistered(serviceName,groupName);}值得注意的是 Nacos 2.x 引入的Redo 机制。由于客户端与服务端之间是长连接一旦连接断开或服务端重启客户端需要通过 Redo 机制自动重新注册之前注册过的实例和订阅关系。RedoService会缓存所有注册和订阅操作在连接恢复后自动重放确保客户端状态与服务端最终一致。这种设计在实际生产环境中非常关键因为网络闪断或服务端滚动升级是常态如果没有自动恢复机制运维压力将难以想象。1.3 服务端处理流程服务端接收到注册请求后InstanceRequestHandler会委托给ClientOperationService处理。对于临时实例服务端会创建一个IpPortBasedClient对象如果是 2.x 的 gRPC 连接则创建ConnectionBasedClient将实例信息关联到该 Client 对象下然后更新发布者索引publisherIndexes。------------------------------------------------------------------ | 服务端注册处理内部流程 | ------------------------------------------------------------------ | | | InstanceRequestHandler | | | | | v | | ClientOperationService.registerInstance() | | | | | v | | ------------------- ------------------- | | | 创建/更新 Client |-----| 更新 publisherIndexes | | | 对象 | | (服务 - 客户端列表映射) | | ------------------- ------------------- | | | | | v | | ------------------- ------------------- | | | 触发 ClientChange |-----| DistroProtocol.sync() | | | Event | | (异步同步给其他节点) | | ------------------- ------------------- | | | | | v | | ------------------- | | | PushService | | | | (推送变更给订阅者) | | | ------------------- | | | ------------------------------------------------------------------服务端注册完成后会触发两个关键动作一是通过 Distro 协议将 Client 对象同步给其他 Nacos 节点保证集群数据最终一致二是通过 Push Service 将服务变更推送给所有订阅了该服务的客户端。这两个动作都是异步执行的避免了同步等待对注册接口性能的影响。二、服务发现机制Pull 与 Push 的双模式运作2.1 客户端本地缓存与定时拉取Pull 模式Nacos 客户端不会每次服务调用都直接请求服务端获取实例列表而是在本地维护了一份服务实例的缓存。这种设计的考量非常实际如果每次 RPC 调用前都要先查询注册中心不仅会增加网络开销还会使 Nacos 成为整个系统的性能瓶颈。客户端启动时会通过HostReactor向服务端查询订阅服务的实例列表并将结果缓存在serviceInfoMap中。同时会启动一个定时任务默认每隔 5 秒向服务端拉取一次最新数据与本地缓存进行比对。如果数据发生变化则更新本地缓存并通知监听器。publicclassHostReactor{privatefinalMapString,ServiceInfoserviceInfoMapnewConcurrentHashMap();publicServiceInfogetServiceInfo(StringserviceName,Stringclusters){StringkeyServiceInfo.getKey(serviceName,clusters);ServiceInfoserviceInfoserviceInfoMap.get(key);if(serviceInfonull||isExpired(serviceInfo)){// 本地缓存不存在或已过期从服务端拉取serviceInfoupdateServiceNow(serviceName,clusters);}returnserviceInfo;}// 定时更新任务默认 5 秒间隔privateclassUpdateTaskimplementsRunnable{Overridepublicvoidrun(){ServiceInfoserviceInfoserviceInfoMap.get(serviceName);// 向服务端发起查询ServiceInfonewInfoqueryServer(serviceName,clusters);if(!newInfo.getChecksum().equals(serviceInfo.getChecksum())){// 数据发生变更更新缓存serviceInfoMap.put(serviceName,newInfo);notifyListeners(serviceName,newInfo);}// 继续下一次定时任务executor.schedule(this,5,TimeUnit.SECONDS);}}}2.2 服务端主动推送Push 模式仅靠客户端定时拉取存在一个明显的缺陷数据变更的感知存在延迟最长 5 秒。对于某些对实时性要求极高的场景这种延迟是不可接受的。因此Nacos 还提供了服务端主动推送的机制。在 Nacos 1.x 中推送通道基于 UDP 实现。当服务端检测到服务实例发生变化时会遍历该服务的所有订阅者通过 UDP 将最新的实例列表推送给客户端。UDP 虽然速度快但存在丢包风险因此客户端仍需依赖定时拉取作为兜底。在 Nacos 2.x 中得益于 gRPC 长连接推送机制变得更加可靠和高效。服务端维护着 subscriberIndexes 索引当服务实例发生变更时能够快速定位到所有订阅该服务的客户端连接然后通过对应的 gRPC Stream 将变更数据推送过去。这种基于长连接的流式推送既保证了实时性又避免了 UDP 的不可靠问题。------------------------------------------------------------------ | Nacos 服务发现双模式对比 | ------------------------------------------------------------------ | | | Pull 模式 (客户端轮询) Push 模式 (服务端推送) | | -------------------- -------------------- | | | 客户端定时任务 | | 服务端检测数据变更 | | | | (默认 5s 间隔) | | | | | ------------------- ------------------- | | | | | | v v | | -------------------- -------------------- | | | 向服务端查询列表 | | 遍历 subscriberIndexes | | | 比对本地缓存 | | 找到订阅该服务的客户端 | | ------------------- ------------------- | | | | | | v v | | -------------------- -------------------- | | | 如数据变化则更新 | | 通过 gRPC Stream | | | | 本地缓存 | | 推送新实例列表 | | | -------------------- -------------------- | | | | 特点可靠但有一定延迟 特点实时性高依赖长连接 | | 作用兜底机制 作用加速变更感知 | | | ------------------------------------------------------------------2.3 服务发现的性能优化实践在实际项目中我发现很多团队对服务发现的性能调优存在误区。以下是我在生产环境中总结的几条经验缓存过期时间的合理设置默认 5 秒的定时拉取间隔在大多数场景下是合适的但如果集群规模非常大数千个服务实例可以适当放宽到 10 秒减少对 Nacos 服务器的查询压力。避免过度订阅有些应用会订阅大量无关的服务导致客户端内存占用过高也加重了服务端推送的负担。应当只订阅实际需要调用的服务。本地缓存的文件化Nacos 客户端支持将服务列表缓存到本地文件即使应用重启后 Nacos 服务端暂时不可用也能基于本地快照启动。这在灾备场景下尤为重要。三、健康检查确保注册表中的实例真实可用健康检查是注册中心的核心能力之一。如果注册表中充斥着大量不可用的僵尸实例服务调用方就会频繁遭遇调用失败严重影响系统稳定性。Nacos 提供了两套互补的健康检查机制。3.1 临时实例客户端主动心跳上报对于临时实例健康检查采用客户端主动上报的方式。Nacos 1.x 通过 HTTP 心跳实现2.x 则复用 gRPC 长连接的保活机制。在 1.x 版本中客户端注册实例后会启动一个定时任务BeatReactor默认每隔 5 秒向服务端发送一次心跳请求PUT /nacos/v1/ns/instance/beat。服务端接收到心跳后更新对应实例的lastBeat时间戳。服务端同时运行着一个健康检查任务ClientBeatCheckTask默认每隔 5 秒扫描一次所有临时实例如果当前时间 - lastBeat 15 秒将实例标记为不健康healthy false并触发服务变更事件通知订阅者。如果当前时间 - lastBeat 30 秒直接将实例从注册表中摘除。publicclassClientBeatCheckTaskimplementsRunnable{Overridepublicvoidrun(){try{ListInstanceinstancesservice.allIPs(true);// 获取所有临时实例// 第一遍标记不健康实例for(Instanceinstance:instances){if(System.currentTimeMillis()-instance.getLastBeat()instance.getInstanceHeartBeatTimeOut()){if(instance.isHealthy()){instance.setHealthy(false);getPushService().serviceChanged(service);}}}// 第二遍摘除过期实例for(Instanceinstance:instances){if(System.currentTimeMillis()-instance.getLastBeat()instance.getIpDeleteTimeout()){deleteIp(instance);// 直接删除}}}catch(Exceptione){Loggers.SRV_LOG.warn(Exception while processing client beat time out.,e);}}}在 2.x 版本中由于采用了 gRPC 长连接心跳机制被大大简化。客户端不再需要定时发送专门的心跳包只需要保持 gRPC 连接的存活即可。服务端通过监听连接断开事件ClientDisconnectEvent在检测到连接断开后立即摘除该客户端注册的所有实例。这种基于连接状态的健康检查相比定时心跳更加实时和高效。3.2 永久实例服务端反向探测对于永久实例Nacos 采用服务端主动探测的方式。服务端会定期向实例发起 TCP 端口探测、HTTP 接口探测或 MySQL 连接探测根据探测结果判断实例的健康状态。TCP 探测尝试与实例的指定端口建立 TCP 连接连接成功则认为健康。HTTP 探测向实例的指定 URL 发送 HTTP 请求根据返回的状态码判断健康状态默认期望 200。MySQL 探测尝试连接实例上的 MySQL 端口验证数据库服务的可用性。需要注意的是永久实例即使被判定为不健康也不会被自动删除只是标记健康状态为 false。这是因为永久实例通常对应着相对固定的资源如物理机、数据库代理其生命周期不由 Nacos 控制。只有当管理员主动发起注销请求时永久实例才会从注册表中移除。------------------------------------------------------------------ | Nacos 健康检查机制对比 | ------------------------------------------------------------------ | | | 维度 临时实例 永久实例 | | ------------------------------------------------ | | | 检查方式 | 客户端心跳/长连接 | 服务端主动探测 | | | ------------------------------------------------ | | | 默认周期 | 5 秒 | 20 秒 | | | ------------------------------------------------ | | | 不健康阈值 | 15 秒无心跳 | 探测失败 | | | ------------------------------------------------ | | | 摘除阈值 | 30 秒无心跳 | 不自动摘除 | | | ------------------------------------------------ | | | 数据一致性协议 | Distro (AP) | Raft (CP) | | | ------------------------------------------------ | | | 是否持久化 | 否仅内存 | 是持久化存储 | | | ------------------------------------------------ | | | ------------------------------------------------------------------3.3 健康检查的实战经验在某次线上故障排查中我遇到过一个典型案例一个服务实例因为 JVM Full GC 导致长达 40 秒的业务线程停顿但由于心跳线程是独立的仍然正常向 Nacos 发送心跳所以 Nacos 认为该实例是健康的继续将流量导向它导致大量请求超时。这个案例暴露了一个问题单纯的心跳保活无法反映业务的实际健康状态。解决方案有两个一是将关键业务健康检查嵌入到心跳 payload 中只有业务健康时才发送正常心跳二是在服务端配置 HTTP 健康检查接口让 Nacos 探测业务层面的可用性而不仅仅是网络连通性。对于核心业务我强烈建议两种机制并用。四、Spring Cloud 集成自动装配原理揭秘4.1 自动装配的核心类Spring Cloud Alibaba Nacos Discovery 的自动装配入口是NacosServiceRegistryAutoConfiguration。这个配置类会在满足条件时类路径下存在NacosDiscoveryProperties自动向 Spring 容器注入三个核心 BeanNacosServiceRegistry实现了ServiceRegistry接口负责服务注册的增删改操作。NacosRegistration封装了当前应用的注册信息服务名、IP、端口、元数据等。NacosAutoServiceRegistration实现了ApplicationListenerWebServerInitializedEvent在 Web 服务器启动完成后自动触发服务注册。Configuration(proxyBeanMethodsfalse)EnableConfigurationProperties(NacosDiscoveryProperties.class)ConditionalOnNacosDiscoveryEnabledpublicclassNacosServiceRegistryAutoConfiguration{BeanpublicNacosServiceRegistrynacosServiceRegistry(NacosDiscoveryPropertiesnacosDiscoveryProperties){returnnewNacosServiceRegistry(nacosDiscoveryProperties);}BeanConditionalOnBean(AutoServiceRegistrationProperties.class)publicNacosRegistrationnacosRegistration(NacosDiscoveryPropertiesnacosDiscoveryProperties){returnnewNacosRegistration(null,nacosDiscoveryProperties);}BeanConditionalOnBean(AutoServiceRegistrationProperties.class)publicNacosAutoServiceRegistrationnacosAutoServiceRegistration(NacosServiceRegistryregistry,NacosRegistrationregistration){returnnewNacosAutoServiceRegistration(registry,registration);}}4.2 服务自动注册与注销NacosAutoServiceRegistration继承自AbstractAutoServiceRegistration后者实现了ApplicationListenerWebServerInitializedEvent接口。当 Spring Boot 应用的 Web 服务器Tomcat/Jetty/Netty启动完成后会发布WebServerInitializedEvent监听器收到事件后调用start()方法最终通过NacosServiceRegistry.register()完成服务注册。------------------------------------------------------------------ | Spring Boot 启动触发 Nacos 注册流程 | ------------------------------------------------------------------ | | | SpringApplication.run() | | | | | v | | WebServer 启动完成 | | | | | v | | 发布 WebServerInitializedEvent | | | | | v | | NacosAutoServiceRegistration | | (onApplicationEvent) | | | | | v | | AbstractAutoServiceRegistration.start() | | | | | v | | NacosServiceRegistry.register(NacosRegistration) | | | | | v | | NacosNamingService.registerInstance() | | | | | v | | gRPC 请求发送到 Nacos Server | | | ------------------------------------------------------------------服务注销则通过PreDestroy注解实现。AbstractAutoServiceRegistration中定义了destroy()方法当 Spring 容器关闭时会触发该方法进而调用NacosServiceRegistry.deregister()完成优雅下线。这一过程确保了在应用停止、滚动升级或容器缩容时实例能够及时从注册表中摘除避免调用方访问到已下线的节点。4.3 NacosDiscoveryProperties 的配置绑定NacosDiscoveryProperties是 Spring Cloud Alibaba Nacos Discovery 的核心属性类它通过ConfigurationProperties(spring.cloud.nacos.discovery)将 YAML/Properties 中的配置绑定到 Java 对象。关键的配置项包括spring:cloud:nacos:discovery:server-addr:127.0.0.1:8848# Nacos 服务端地址namespace:dev# 命名空间 IDgroup:DEFAULT_GROUP# 服务所属分组cluster-name:HZ# 集群名称用于同集群优先路由ephemeral:true# 是否为临时实例weight:1.0# 实例权重metadata:# 自定义元数据region:hangzhouversion:v2heart-beat-interval:5000# 心跳间隔毫秒heart-beat-timeout:15000# 心跳超时时间毫秒ip-delete-timeout:30000# 实例摘除时间毫秒这些配置项直接影响服务注册的行为和健康检查的参数。在生产环境中我通常会根据业务的敏感度调整心跳参数。对于核心链路的服务我会将心跳间隔缩短到 3 秒超时时间缩短到 9 秒以便更快地感知故障而对于一些非核心服务则可以适当放宽减少对 Nacos 服务器的压力。五、负载均衡与 Spring Cloud LoadBalancer 的深度集成5.1 从 Ribbon 到 Spring Cloud LoadBalancer在早期的 Spring Cloud Netflix 生态中Ribbon 是默认的客户端负载均衡器。Nacos Discovery 通过实现RibbonNacosAutoConfiguration将 Nacos 的服务列表与 Ribbon 的ServerList对接起来。Ribbon 会定期从 Nacos 获取服务实例列表然后根据配置的负载均衡策略轮询、随机、权重等选择目标实例。随着 Spring Cloud Netflix 进入维护模式Spring Cloud 官方推出了新一代的负载均衡组件Spring Cloud LoadBalancer。Nacos Discovery 也提供了对应的适配NacosLoadBalancer。与 Ribbon 相比Spring Cloud LoadBalancer 的优势在于反应式编程模型的支持、更轻量的依赖以及与 Spring Cloud 生态更紧密的整合。5.2 基于权重的负载均衡Nacos 的实例模型中包含weight属性取值范围 1-100这个权重会被负载均衡器识别并参与路由决策。在NacosLoadBalancer中默认的权重策略是如果所有实例权重相同则采用轮询如果权重不同则按权重比例分配流量。这一特性在生产发布中非常实用。例如当新版本上线时可以先将小部分实例的权重调高或保持默认将大部分旧版本实例的权重降低实现金丝雀发布。如果发现新版本异常可以立即将权重调整回来实现快速回滚。// Nacos 权重负载均衡核心逻辑简化版publicclassNacosLoadBalancerimplementsReactorServiceInstanceLoadBalancer{OverridepublicMonoResponseServiceInstancechoose(Requestrequest){ServiceInstanceListSuppliersupplierinstanceSupplier.getInstance(serviceId);returnsupplier.get(request).next().map(instances-{// 基于 Nacos 权重选择实例returngetInstanceResponse(instances);});}privateResponseServiceInstancegetInstanceResponse(ListServiceInstanceinstances){if(instances.isEmpty()){returnnewEmptyResponse();}// 按权重随机选择inttotalWeightinstances.stream().mapToInt(inst-Integer.parseInt(inst.getMetadata().get(nacos.weight))).sum();intrandomWeightThreadLocalRandom.current().nextInt(totalWeight);for(ServiceInstanceinstance:instances){randomWeight-Integer.parseInt(instance.getMetadata().get(nacos.weight));if(randomWeight0){returnnewDefaultResponse(instance);}}returnnewDefaultResponse(instances.get(0));}}5.3 同集群优先路由在多机房部署的场景下跨机房调用会带来明显的网络延迟。Nacos 提供了cluster-name属性来实现同集群优先路由。当调用方和服务提供方都配置了相同的cluster-name时负载均衡器会优先选择同集群的实例只有同集群实例全部不可用时才会_fallback_到跨集群实例。在我主导的一个异地多活项目中我们在杭州、上海、北京各部署了一套服务集群通过给每个机房的实例打上不同的cluster-name配合 Nacos 的集群优先策略成功将跨机房调用比例从 30% 降低到 5% 以下整体接口平均耗时下降了 15ms。六、总结Nacos 的服务注册与发现机制是一个将分布式系统理论与工程实践完美结合的典范。从 1.x 到 2.x 的演进中我们看到了 HTTP 短连接向 gRPC 长连接的升级看到了 UDP 推送向可靠流式推送的进化也看到了无状态服务向有状态连接模型的转变。这些变化背后是 Nacos 社区对性能、可靠性和易用性的不懈追求。对于开发者而言理解服务注册的完整链路有助于在遇到注册失败、服务发现延迟等问题时快速定位根因理解健康检查的双轨机制有助于设计出更加健壮的微服务理解 Spring Cloud 的自动装配原理有助于在框架层面进行二次开发和定制。在下一篇文章中我们将把目光转向 Nacos 的另一大核心能力——配置中心深入剖析长轮询机制、本地快照容灾、版本管理等底层原理。文章声明本文仅供学习参考请勿用于商业用途。

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…