RocketMQ 源码解析——Controller 高可用切换架构

news2026/5/22 3:58:58
延伸阅读「RocketMQ 中文社区」 持续更新源码解析/最佳实践提供 RocketMQ 专家 AI 答疑服务一、原理及核心概念浅述1.1 核心架构1.2 核心概念controller负责管理broker间的主备关系可以挂在namesrv中不影响namesrv能力支持独立部署。master/slave主备身份。syncStateSet字面意思为“同步状态集合”。当备节点能够及时跟上主节点则会纳入syncStateSet。epoch用于记录每一次主备切换时的状态避免切换后产生数据丢失或者不一致的情况。为方便理解在某些过程中可以把controller当作班主任master作为小组长slave作为小组成员。同步过程是各位同学向小组长抄作业的过程位于syncStateSet中的是优秀作业。二、相关代码文件及说明核心是“controllerbroker复制过程”因此分三块进行叙述。2.1 Controller该部分代码主要集中在rocketmq-controller模块下主要有如下代码文件ControllerManager:负责管理controller其中存储了许多controller相关配置并负责了心跳管理等核心功能。(班主任管理条例)DLederController:Controller的DLedger实现。包含了controller的基本功能。在其中实现了副本信息管理、broker存活情况探测、选举Master等核心功能。某种班主任DefaultBrokerHeartbeatManager:负责管理broker心跳其中包含了broker存活情况表以及在broker下线时的listeners当副本掉线时触发重新选举。点名册ReplicasInfoManager:负责controller中事件的处理。即各种选举事件、更换SyncStateSet事件等等。小组登记册ControllerRequestProcessor:处理向controller发送的requests例如让controller选举、向controller注册broker、心跳、更换SyncStateSet等等。班主任信箱DefaultElectPolicy:选举Master的策略。可以选择从sync状态的副本中选也可以支持从所有副本中无论是否同步的unclean选举。班规......2.2 Broker该部分代码主要集中在rocketmq-broker模块中可进入org/apache/rocketmq/broker/controller进行查看ReplicasManager: 完成自己作为一个replica的使命——找controller角色管理Master更新(Expand/Shrink)SyncStateSet等等。2.3 复制模块该部分代码主要集中在rocketmq-store模块中的ha文件夹下HAService:每个Replica必备的的service负责管理作为主、备的同步任务。HAClient:每个Slave 的HAService中必备的client负责管理同步任务中的读、写操作。HAConnection:代表在Master中的HA连接每个connection理论上对应一个slave。在该connection类中存储了传输过程中的诸多内容包括channel、传输状态、当前传输位点等等信息。三、核心流程3.1 心跳核心CODEBROKER_HEARTBEATBroker端该部分较简单带上code向controller发request不再赘述BrokerController.sendHeartbeat() - brokerOuterAPI.sendHeartbeat()Controller端1. 首先由ControllerRequestProcessor接收到code进入处理逻辑private RemotingCommand handleBrokerHeartbeat(ChannelHandlerContext ctx, RemotingCommand request) throws Exception { final BrokerHeartbeatRequestHeader requestHeader (BrokerHeartbeatRequestHeader) request.decodeCommandCustomHeader(BrokerHeartbeatRequestHeader.class); if (requestHeader.getBrokerId() null) { return RemotingCommand.createResponseCommand(ResponseCode.CONTROLLER_INVALID_REQUEST, Heart beat with empty brokerId); } this.heartbeatManager.onBrokerHeartbeat(requestHeader.getClusterName(), requestHeader.getBrokerName(), requestHeader.getBrokerAddr(), requestHeader.getBrokerId(), requestHeader.getHeartbeatTimeoutMills(), ctx.channel(), requestHeader.getEpoch(), requestHeader.getMaxOffset(), requestHeader.getConfirmOffset(), requestHeader.getElectionPriority()); return RemotingCommand.createResponseCommand(ResponseCode.SUCCESS, Heart beat success); }之后在onBrokerHeartbeat()中主要更新controller brokerHeartbeatManager中的brokerLiveTablepublic void onBrokerHeartbeat(String clusterName, String brokerName, String brokerAddr, Long brokerId, Long timeoutMillis, Channel channel, Integer epoch, Long maxOffset, Long confirmOffset, Integer electionPriority) { BrokerIdentityInfo brokerIdentityInfo new BrokerIdentityInfo(clusterName, brokerName, brokerId); BrokerLiveInfo prev this.brokerLiveTable.get(brokerIdentityInfo); ...... if (null prev) { this.brokerLiveTable.put(...); log.info(new broker registered, {}, brokerId:{}, brokerIdentityInfo, realBrokerId); } else { prev.setXXX(......) } }3.2 选举相关CODE: CONTROLLER_ELECT_MASTER有如下几种情形可能触发选举1.controller主动发起通过triggerElectMaster()a.HeartbeatManager监听到有broker心跳失效。 (班主任发现有小组同学退学了)b.Controller检测到有一组Replica Set不存在master。班主任发现有组长虽然在名册里但是挂了2.broker发起将自己选为master通过ReplicaManager.brokerElect()a.Broker向controller查metadata时没找到master信息。同学定期检查小组情况问班主任为啥没小组长b.Broker向controller注册完后仍未从controller获取到master信息。同学报道后发现没小组长汇报3.通过tools发起:a.通过选举命令ReElectMasterSubCommand发起。校长直接任命上述所有过程最终均触发:controller.electMaster() - replicasInfoManager.electMaster()// 即所有小组长必须通过班主任任命public ControllerResultElectMasterResponseHeader electMaster(final ElectMasterRequestHeader request, final ElectPolicy electPolicy) { ... // 从request中取信息 ... if (syncStateInfo.isFirstTimeForElect()) { // 从未注册直接任命 newMaster brokerId; } // 按选举政策选主 if (newMaster null) { // we should assign this assignedBrokerId when the brokerAddress need to be elected by force Long assignedBrokerId request.getDesignateElect() ? brokerId : null; newMaster electPolicy.elect(brokerReplicaInfo.getClusterName(), brokerReplicaInfo.getBrokerName(), syncStateSet, allReplicaBrokers, oldMaster, assignedBrokerId); } if (newMaster ! null newMaster.equals(oldMaster)) { // 老主 新主 // old master still valid, change nothing String err String.format(The old master %s is still alive, not need to elect new master for broker %s, oldMaster, brokerReplicaInfo.getBrokerName()); LOGGER.warn({}, err); // the master still exist response.setXXX() result.setBody(new ElectMasterResponseBody(syncStateSet).encode()); result.setCodeAndRemark(ResponseCode.CONTROLLER_MASTER_STILL_EXIST, err); return result; } // a new master is elected if (newMaster ! null) { // 出现不一样的新主 final int masterEpoch syncStateInfo.getMasterEpoch(); final int syncStateSetEpoch syncStateInfo.getSyncStateSetEpoch(); final HashSetLong newSyncStateSet new HashSet(); //设置新的syncStateSet newSyncStateSet.add(newMaster); response.setXXX()... ElectMasterResponseBody responseBody new ElectMasterResponseBody(newSyncStateSet); } result.setBody(responseBody.encode()); final ElectMasterEvent event new ElectMasterEvent(brokerName, newMaster); result.addEvent(event); return result; } // 走到这里说明没有主选举失败 // If elect failed and the electMaster is triggered by controller (we can figure it out by brokerAddress), // we still need to apply an ElectMasterEvent to tell the statemachine // that the master was shutdown and no new master was elected. if (request.getBrokerId() null) { final ElectMasterEvent event new ElectMasterEvent(false, brokerName); result.addEvent(event); result.setCodeAndRemark(ResponseCode.CONTROLLER_MASTER_NOT_AVAILABLE, Old master has down and failed to elect a new broker master); } else { result.setCodeAndRemark(ResponseCode.CONTROLLER_ELECT_MASTER_FAILED, Failed to elect a new master); } return result; }3.3 更新SyncStateSet核心CODE CONTROLLER_ALTER_SYNC_STATE_SET1.由master发起主动向controller更换syncStateSet等价于小组长汇报优秀作业2.controllerRequestProcessor接收更换syncStateSet的请求进入handleAlterSyncStateSet()方法private RemotingCommand handleAlterSyncStateSet(ChannelHandlerContext ctx, RemotingCommand request) throws Exception { final AlterSyncStateSetRequestHeader controllerRequest (AlterSyncStateSetRequestHeader) request.decodeCommandCustomHeader(AlterSyncStateSetRequestHeader.class); final SyncStateSet syncStateSet RemotingSerializable.decode(request.getBody(), SyncStateSet.class); final CompletableFutureRemotingCommand future this.controllerManager.getController().alterSyncStateSet(controllerRequest, syncStateSet); if (future ! null) { return future.get(WAIT_TIMEOUT_OUT, TimeUnit.SECONDS); } return RemotingCommand.createResponseCommand(null); }3. 之后进入Controller.alterSyncStateSet() - replicasInfoManager.alterSyncStateSet()方法public ControllerResultAlterSyncStateSetResponseHeader alterSyncStateSet( final AlterSyncStateSetRequestHeader request, final SyncStateSet syncStateSet, final BrokerValidPredicate brokerAlivePredicate) { final String brokerName request.getBrokerName(); ... final SetLong newSyncStateSet syncStateSet.getSyncStateSet(); final SyncStateInfo syncStateInfo this.syncStateSetInfoTable.get(brokerName); final BrokerReplicaInfo brokerReplicaInfo this.replicaInfoTable.get(brokerName); // 检查syncStateSet是否有变化 final SetLong oldSyncStateSet syncStateInfo.getSyncStateSet(); if (oldSyncStateSet.size() newSyncStateSet.size() oldSyncStateSet.containsAll(newSyncStateSet)) { String err The newSyncStateSet is equal with oldSyncStateSet, no needed to update syncStateSet; ... } // 检查是否是master发起的 if (!syncStateInfo.getMasterBrokerId().equals(request.getMasterBrokerId())) { String err String.format(Rejecting alter syncStateSet request because the current leader is:{%s}, not {%s}, syncStateInfo.getMasterBrokerId(), request.getMasterBrokerId()); ... } // 检查master的任期epoch是否一致 if (request.getMasterEpoch() ! syncStateInfo.getMasterEpoch()) { String err String.format(Rejecting alter syncStateSet request because the current master epoch is:{%d}, not {%d}, syncStateInfo.getMasterEpoch(), request.getMasterEpoch()); ... } // 检查syncStateSet的epoch if (syncStateSet.getSyncStateSetEpoch() ! syncStateInfo.getSyncStateSetEpoch()) { String err String.format(Rejecting alter syncStateSet request because the current syncStateSet epoch is:{%d}, not {%d}, syncStateInfo.getSyncStateSetEpoch(), syncStateSet.getSyncStateSetEpoch()); ... } // 检查新的syncStateSet的合理性 for (Long replica : newSyncStateSet) { // 检查replica是否存在 if (!brokerReplicaInfo.isBrokerExist(replica)) { String err String.format(Rejecting alter syncStateSet request because the replicas {%s} dont exist, replica); ... } // 检查broker是否存活 if (!brokerAlivePredicate.check(brokerReplicaInfo.getClusterName(), brokerReplicaInfo.getBrokerName(), replica)) { String err String.format(Rejecting alter syncStateSet request because the replicas {%s} dont alive, replica); ... } } // 检查是否包含master if (!newSyncStateSet.contains(syncStateInfo.getMasterBrokerId())) { String err String.format(Rejecting alter syncStateSet request because the newSyncStateSet dont contains origin leader {%s}, syncStateInfo.getMasterBrokerId()); ... } // 更新epoch int epoch syncStateInfo.getSyncStateSetEpoch() 1; ... // 生成事件替换syncStateSet final AlterSyncStateSetEvent event new AlterSyncStateSetEvent(brokerName, newSyncStateSet); ... }4.最后通过syncStateInfo.updateSyncStateSetInfo()更新syncStateSetInfoTable.get(brokerName)得到的syncStateInfo信息该过程可以理解为班主任在班级分组册上找到了组长的名字拿出组员名单更新。3.4 复制该部分较复杂其中HAService/HAClient/HAConnection以及其中的各种Service/Reader/Writer容易产生混淆对阅读造成阻碍。因此绘制本图帮助理解可在粗读源码后回头理解下面对HA复制过程作拆解分别讲解在各个replica的DefaultMessageStore中均注册了HAService负责管理HA的复制。在Master的 HAService中有一个AcceptSocketService, 负责自动接收各个slave的连接protected abstract class AcceptSocketService extends ServiceThread { ... /** * Starts listening to slave connections. * * throws Exception If fails. */ public void beginAccept() throws Exception { ... } Override public void shutdown(final boolean interrupt) { ... } Override public void run() { log.info(this.getServiceName() service started); while (!this.isStopped()) { try { this.selector.select(1000); SetSelectionKey selected this.selector.selectedKeys(); if (selected ! null) { for (SelectionKey k : selected) { if (k.isAcceptable()) { SocketChannel sc ((ServerSocketChannel) k.channel()).accept(); if (sc ! null) { DefaultHAService.log.info(HAService receive new connection, sc.socket().getRemoteSocketAddress()); try { HAConnection conn createConnection(sc); conn.start(); DefaultHAService.this.addConnection(conn); } catch (Exception e) { log.error(new HAConnection exception, e); sc.close(); } } } ... } }3.在各个Slave 的HAService中存在一个HAClient负责向master发起连接、传输请求。public class AutoSwitchHAClient extends ServiceThread implements HAClient { ... } public interface HAClient { void start(); void shutdown(); void wakeup(); void updateMasterAddress(String newAddress); void updateHaMasterAddress(String newAddress); String getMasterAddress(); String getHaMasterAddress(); long getLastReadTimestamp(); long getLastWriteTimestamp(); HAConnectionState getCurrentState(); void changeCurrentState(HAConnectionState haConnectionState); void closeMaster(); long getTransferredByteInSecond(); }4.当master收到slave的连接请求后将会创建一个HAConnection负责收发内容。public interface HAConnection { void start(); void shutdown(); void close(); SocketChannel getSocketChannel(); HAConnectionState getCurrentState(); String getClientAddress(); long getTransferredByteInSecond(); long getTransferFromWhere(); long getSlaveAckOffset(); }5.Master的HAConnection会与Slave的HAClient建立连接二者均通过HAWriter较简单不解读位于HAWriter类往socket中写内容再通过HAReader读取socket中的内容。只不过一个是HAServerReader一个是HAClientReaderpublic abstract class AbstractHAReader { private static final Logger LOGGER LoggerFactory.getLogger(LoggerName.STORE_LOGGER_NAME); protected final ListHAReadHook readHookList new ArrayList(); public boolean read(SocketChannel socketChannel, ByteBuffer byteBufferRead) { int readSizeZeroTimes 0; while (byteBufferRead.hasRemaining()) { ... boolean result processReadResult(byteBufferRead); ... } } ... protected abstract boolean processReadResult(ByteBuffer byteBufferRead); }6.两种HAReader均实现了processReadResult()方法负责处理从socket中得到的数据。client需要详细阐述该方法因为涉及到如何将读进来的数据写入commitlogclient的processReadResult():Override protected boolean processReadResult(ByteBuffer byteBufferRead) { int readSocketPos byteBufferRead.position(); try { while (true) { ... switch (AutoSwitchHAClient.this.currentState) { case HANDSHAKE: { ... // 握手阶段先检查commitlog完整性截断 } break; case TRANSFER: { // 传输阶段将body写入commitlog ... byte[] bodyData new byte[bodySize]; ... if (bodySize 0) { // 传输阶段将body写入commitlog AutoSwitchHAClient.this.messageStore.appendToCommitLog(masterOffset, bodyData, 0, bodyData.length); } haService.updateConfirmOffset(Math.min(confirmOffset, messageStore.getMaxPhyOffset())); ... break; } default: break; } if (isComplete) { continue; } } // 检查buffer中是否还有数据, 如果有, compact() ... break; } } ... }7.server的processReadResult()主要用于接收client的握手等请求较简单。更需要解释其WriteSocketService如何向socket中调用HAwriter去写数据abstract class AbstractWriteSocketService extends ServiceThread { ... private void transferToSlave() throws Exception { ... int size this.getNextTransferDataSize(); if (size 0) { ... buildTransferHeaderBuffer(this.transferOffset, size); this.lastWriteOver this.transferData(size); } else { // 无需传输直接更新caught up的时间 AutoSwitchHAConnection.this.haService.updateConnectionLastCaughtUpTime(AutoSwitchHAConnection.this.slaveId, System.currentTimeMillis()); haService.getWaitNotifyObject().allWaitForRunning(100); } } Override public void run() { AutoSwitchHAConnection.LOGGER.info(this.getServiceName() service started); while (!this.isStopped()) { try { this.selector.select(1000); switch (currentState) { case HANDSHAKE: // Wait until the slave send it handshake msg to master. // 等待slave的握手请求并进行回复 break; case TRANSFER: ... transferToSlave(); break; default: ... } } catch (Exception e) { ... } } ... // 在service结束后的一些事情 } ... }此处同样附上server实现processReadResult()读socket中数据的代码Override protected boolean processReadResult(ByteBuffer byteBufferRead) { while (true) { ... HAConnectionState slaveState HAConnectionState.values()[byteBufferRead.getInt(readPosition)]; switch (slaveState) { case HANDSHAKE: // 收到了client的握手 ... LOGGER.info(Receive slave handshake, slaveBrokerId:{}, isSyncFromLastFile:{}, isAsyncLearner:{}, AutoSwitchHAConnection.this.slaveId, AutoSwitchHAConnection.this.isSyncFromLastFile, AutoSwitchHAConnection.this.isAsyncLearner); break; case TRANSFER: // 收到了client的transfer状态 ... // 更新client状态信息 break; default: ... } ... }3.5 Active Controller的选举该选举主要通过DLedger实现在DLedgerController中通过RoleChangeHandler.handle()更新自身身份class RoleChangeHandler implements DLedgerLeaderElector.RoleChangeHandler { private final String selfId; private final ExecutorService executorService Executors.newSingleThreadExecutor(new ThreadFactoryImpl(DLedgerControllerRoleChangeHandler_)); private volatile MemberState.Role currentRole MemberState.Role.FOLLOWER; public RoleChangeHandler(final String selfId) { this.selfId selfId; } Override public void handle(long term, MemberState.Role role) { Runnable runnable () - { switch (role) { case CANDIDATE: this.currentRole MemberState.Role.CANDIDATE; // 停止扫描inactive broker任务 ... case FOLLOWER: this.currentRole MemberState.Role.FOLLOWER; // 停止扫描inactive broker任务 ... case LEADER: { log.info(Controller {} change role to leader, try process a initial proposal, this.selfId); int tryTimes 0; while (true) { // 将会开始扫描inactive brokers ... break; } } }; this.executorService.submit(runnable); } ... }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2624009.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;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…