一代明君的小屋 - 学习笔记
type: channel
link: https://yidaimingjvn.xyz/index.php/category/学习/
description: 学习中的一些笔记
items: 基于mac的设备客户端任务队列调度服务 ——key设计
items: 基于mac的设备客户端任务队列调度服务
items: 分布式任务调度与资源管理系统设计
items: celery基于对象的逻辑栈分配设计
items: Captive Portal（强制门户认证）
items: Flex布局关于弹性约束的用法
items: swconfig 旧架构 (固件较旧/内核 4.x)调整VLAN
items: linux账号密码正确，ssh通过但无法远程问题解决
items: linux静态ip调整为dhcp指令
items: 关于鲁班猫rk3568适配的linux系统使用新版本python的情况

基于mac的设备客户端任务队列调度服务 ——key设计
type: item
date: 2026-06-22T14:54:00+08:00
description: 调度服务前文基于mac的设备客户端任务队列调度服务一、MAC 任务调度相关 Keysensitive:mac:queue:<mac> — List（每个 MAC 一个）每个设备的任务队列。入队时 RPUSH，消费时 RPOP（LIFO 栈行为）。过期检查、死信重投也在此操作。sensitive:mac:active:<mac> — String（SET NX EX）运行锁，防止同一 MAC 被多个 Worker 同时调度。NX 保证原子性获得锁，EX 自动过期（默认 900 秒）防止死锁，消费完成后手动 DELETE 释放。sensitive:mac:schedule — ZSet（全局唯一）调度有序集合，score = 老化等待秒数（封顶 600 秒 × 权重）。ZREVRANGE 按等待时间从高到低获取候选 MAC，实现 "等最久的先调度" 策略。sensitive:mac:meta:<mac> — Hash（每个 MAC 一个）元数据，包含以下字段：字段说明pending_count队列积压任务数oldest_created_at最旧任务的创建时间，用于计算老化分数updated_at最后更新时间unschedulable_until退避到期时间戳（defer 指数退避时设置）二、Worker 管理相关 Keysensitive:worker:<hostname>:<pid> — Hash（每个 Worker 进程一个）Worker 资源注册与心跳，包含 CPU/GPU/内存利用率、活跃任务数、最后心跳时间等。Worker 启动时 HSET 注册，每 15 秒 心跳更新，TTL 过期（默认 30 秒）后自动清理。三、全局监控与过载保护 Keysensitive:global_pending — String（计数器）全局待处理任务总数。入队 INCR，出队 DECR，用于快速判断系统整体负载。sensitive:overloaded_macs — Set过载 MAC 集合。当单个 MAC 积压超过阈值（默认 200）时 SADD，恢复后 SREM。与 global_pending 一起用于 is_queue_overloaded() 过载判断。sensitive:watermark — String（JSON）队列水位快照，每 15 秒 由 publish_watermark 定时任务更新，包含 total_pending、mac_count、active_workers，TTL 为发布间隔 + 5 秒。四、死信与异常 Keysensitive:dead_letter — List死信队列。OCR 任务 defer 超过最大次数（默认 5 次）后移入此处，保留最近 10000 条供人工排查。abnormal:parsed_queue — List异常数据解析队列。decter 路由收到的异常数据 RPUSH 入队，限制上限 5000 条，TTL 20 秒兜底。五、Celery Broker 队列（由 Celery 管理）队列名用途sensitive.dispatch调度器队列，运行 dispatch_next_mac_sensitive_tasks / process_mac_sensitive_taskssensitive.ocrOCR 敏感检测子任务队列sensitive.text文本敏感检测子任务队列Key 关系图 ┌─────────────────────┐ │ sensitive:schedule │ ← ZSet, 按等待时间排序 └──────────┬──────────┘ │ ┌─────────────────────┼─────────────────────┐ ▼ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ queue:<mac_A> │ │ queue:<mac_B> │ │ queue:<mac_C> │ ← List, 任务数据 │ active:<mac_A> │ │ active:<mac_B> │ │ active:<mac_C> │ ← String, 运行锁 │ meta:<mac_A> │ │ meta:<mac_B> │ │ meta:<mac_C> │ ← Hash, 元数据 └──────────────────┘ └──────────────────┘ └──────────────────┘ │ ┌─────────────┴─────────────┐ ▼ ▼ ┌──────────────────┐ ┌──────────────────────┐ │ global_p…

基于mac的设备客户端任务队列调度服务
type: item
date: 2026-06-18T17:39:19+08:00
description: 一、概述基于mac的设备客户端任务队列调度服务是一个基于 Redis 的、按设备标识（MAC）维度隔离的异步任务调度中间件，核心解决以下问题：多租户公平调度：大量设备共享有限的 Worker 资源，需保证各设备的任务都能被及时处理资源感知调度：不同任务对 CPU/GPU 资源需求不同，需感知 Worker 资源状况动态分配稳定性自保：防止某设备异常发量冲垮系统，也防止系统过载后雪崩该服务的核心思想是：为每个设备维护一个独立逻辑队列，通过老化优先级计算各设备的调度得分，结合分布式互斥锁实现多 Worker 安全的公平调度。二、数据模型整个调度系统的状态全部存储在 Redis 中，核心数据结构分为五类：┌─────────────────────────────────────────────────────────────────┐ │ MAC 队列调度系统 │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 设备逻辑队列 │ 元数据 │ 调度集 │ 全局计数器 │ │ │ │ (List) │ (Hash) │ (ZSET) │ (String) │ │ │ │ │ │ │ │ │ │ │ task_mac_q:m1 │ meta:m1 │ schedule │ global_pend │ │ │ │ task_mac_q:m2 │ meta:m2 │ [m1:15.2] │ → 128 │ │ │ │ task_mac_q:m3 │ meta:m3 │ [m2:42.5] │ │ │ │ │ ... │ ... │ [m3:8.1] │ │ │ │ └────────────────┴──────────────┴───────────┴─────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 运行锁 │ 过载集合 │ 死信队列 │ │ │ │ (String) │ (Set) │ (List) │ │ │ │ │ │ │ │ │ │ active:m1 → TTL │ overloaded: │ dead_letter │ │ │ │ active:m2 → TTL │ {m3, m7} │ [{task1}, ...] │ │ │ └──────────────────┴─────────────────┴──────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘2.1 数据结构详表用途Redis 类型键格式值说明设备队列Listsensitive:mac:queue:{mac}JSON 序列化的任务 payload，按入队顺序排列设备元数据Hashsensitive:mac:meta:{mac}字段：pending_count(积压数)、oldest_created_at(最早任务时间)、unschedulable_until(退避截止时间)、updated_at(更新时间)调度集合ZSetsensitive:mac:schedulemember = mac，score = 老化调度分数全局计数器Stringsensitive:global_pending所有设备积压任务总数（原子计数器）运行锁Stringsensitive:mac:active:{mac}SET NX + TTL，防止多 Worker 同时调度同一设备过载集合Setsensitive:overloaded_macs积压超过阈值的设备集合死信队列Listsensitive:dead_letter超过最大退避次数的任务记录水位快照Stringsensitive:watermark定期发布的系统运行状态 JSON三、核心操作3.1 入队流程（Enqueue）客户端请求 │ ▼ 检查全局过载 ──> 过载 ──> 拒绝入队，返回 503 │ ▼ (正常) 构建任务 payload (含 task_id, task_type, mac, created_at 等) │ ▼ Redis Pipeline: ├─ RPUSH queue_key, serialized_payload (追加到队列尾部) ├─ HINCRBY meta_key pending_count 1 (递增积压计数器) └─ INCR sensitive:global_pending (递增全局计数器) │ ▼ 如果是该设备的第一个任务 └─ HSET…

分布式任务调度与资源管理系统设计
type: item
date: 2026-06-18T17:37:04+08:00
description: 一、系统概述本系统是一个面向内容检测场景的分布式异步任务调度与资源管理平台，核心提供三方面能力：任务调度：基于设备维度的逻辑队列 + 老化优先级调度，实现多租户公平调度与饥饿感知资源调度：Worker 节点资源注册与心跳，CPU/GPU/内存感知的任务分发稳定性保障：过载保护、背压机制、指数退避、死信队列、任务 TTL 过期等多层可靠性策略系统基于 Flask + Celery + Redis + PostgreSQL 技术栈构建，采用三层架构（Web 路由层 → 业务服务层 → 异步任务层），所有异步任务通过 Celery 分发至专用队列，由 Worker 集群消费。二、整体架构┌─────────────────────────────────────────────────────────┐ │ Web 路由层 (Flask) │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ 检测结果上报 │ │ 图片处理任务 │ │ 文本处理任务 │ │ │ │ /api/decter │ │ /api/ocr/* │ │ /api/ocr/* │ │ │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ └─────────┼──────────────────┼──────────────────┼──────────┘ │ │ │ ▼ ▼ ▼ ┌─────────────────────────────────────────────────────────┐ │ 服务层 (Services) │ │ ┌────────────────┐ ┌──────────────────────────────┐ │ │ │ 检测结果处理服务 │ │ 任务处理服务 │ │ │ │ (同步处理) │ │ (异步入队 + 过载检查) │ │ │ └────────────────┘ └──────────┬───────────────────┘ │ │ │ │ │ ┌───────────────────────────────▼────────────────────┐ │ │ │ MAC 队列调度服务 │ │ │ │ 按设备维度逻辑队列 · 老化优先级排序 · 分布式互斥锁 │ │ │ │ 指数退避 · 死信 · 饥饿检测 · 动态批大小 │ │ │ └───────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ 异步任务层 (Celery + Redis) │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ 调度队列 │ │ 图片处理队列 │ │ 文本处理队列 │ │ │ │ dispatch │ │ ocr │ │ text │ │ │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ Worker 集群 │ │ │ │ GPU Worker (消费所有队列) · CPU Worker (消费部分) │ │ │ │ Worker 注册/心跳 · 过载自检 · 自适应 CPU/GPU │ │ │ └──────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ 数据持久层 (PostgreSQL) │ │ 任务记录 · 处理结果 · 统计报表 │ └─────────────────────────────────────────────────────────┘三、任务调度系统3.1 核心调度模型系统采用两级调度模型：第一级：全局调度器 (Celery Beat + dispatch Task) → 从 Sorted Set 中选取…

celery基于对象的逻辑栈分配设计
type: item
date: 2026-06-10T15:26:05+08:00
description: 运行逻辑图flowchart TD A[客户端请求 /text/handler 或 /calculate/handler] --> B[Router 参数校验/解密/取敏感词] B --> C[handlerService.text_handler / calculate_handler] C --> D[生成业务 task_id] D --> E[按 object 标准化 queue_object] E --> F[写入 Redis 逻辑队列 handler:object:queue:{queue_object}] F --> G{是否抢到该 object 的运行锁 handler:object:active:{queue_object}} G -- 否 --> H[结束提交 等待已有 dispatcher 继续消费] G -- 是 --> I[投递 Celery dispatcher 任务 dispatch_object_handler_tasks(object)] I --> J[Celery worker 固定消费 handler.dispatch] J --> K[dispatcher 启动] K --> L[循环处理最多 N 条 CELERY_object_DISPATCH_BATCH_SIZE] L --> M[从 Redis 队列 lpop 一条任务] M --> N{还有任务吗} N -- 否 --> O[释放 object 运行锁] O --> P[本轮 dispatcher 结束] N -- 是 --> Q{任务类型} Q -- text_handle --> R[_run_text_handler_job] Q -- calculate_handler --> S[_run_calculate_handler_job] R --> T[写 handlerDetectRecord processing] T --> U[执行敏感词匹配] U --> V{命中敏感词?} V -- 是 --> W[send_commend + write_log] V -- 否 --> X[正常结束] W --> Y[写 handlerDetectRecord success/failed] X --> Y S --> Z[写 calculateEngineRecord/handlerDetectRecord processing] Z --> AA[perform_calculate] AA --> AB{calculate 成功?} AB -- 否 --> AC[写 calculate failed + Detect failed] AB -- 是 --> AD[保存 calculate 成功结果] AD --> AE[执行敏感词匹配] AE --> AF{命中敏感词?} AF -- 是 --> AG[send_commend + write_log] AF -- 否 --> AH[正常结束] AG --> AI[写 handlerDetectRecord success/failed] AH --> AI Y --> AJ[刷新 object 锁 TTL] AI --> AJ AJ --> L L --> AK{本轮处理后 Redis 仍有剩余任务?} AK -- 否 --> O AK -- 是 --> AL[再次 apply_async 投递 dispatcher] AL --> P简化时序图sequenceDiagram participant Client as 客户端 participant Router as Router participant Service as handlerService participant Redis as Redis逻辑栈 participant Celery as Celery Dispatcher participant Job as 业务执行函数 participant DB as DB/日志/命令下发 Client->>Router: 提交 text/calculate 请求 Router->>Service: 调用 text_handler / calculate_handler Service->>Redis: rpush 到 object 对应逻辑队列 Service->>Redis: setnx active 锁 alt 抢锁成功 Service->>Celery: apply_async(dispatch_object_handler_tasks) else 抢锁失败 Service-->>Client: 返回 task_id，等待已有 dispatcher…

Captive Portal（强制门户认证）
type: item
date: 2026-06-08T18:35:18+08:00
description: 这就像连接酒店、机场Wi-Fi时，手机自动弹出登录页面的机制。它的工作流程大致是这样的：1. 持续“探路”：网络状态探测当你连接Wi-Fi或网线后，Windows系统会立刻在后台向微软预设的专用服务器（如 `http://www.msftconnecttest.com`）发送HTTP请求。这就像一个小程序在后台不断地询问：“我的网络通了吗？”。2. 意外“劫持”：路由器拦截并伪造回复关键是，未配置的路由器会利用 `dnsmasq` 这项技术，将这些探测请求的DNS解析结果劫持，指向自己本地Web服务器的IP地址。这相当于邮递员告诉Windows：“你要找的微软服务器就在这里（路由器）”。3. 自动“报到”：浏览器被唤起Windows的“网络位置感知服务（NLA）”发现响应内容异常（没有收到预期的成功报文），或收到“302重定向”指令。它会判定需要认证，于是调用系统API唤起默认浏览器，访问预设的网址。 本质上，这是网络设备利用网络协议特性，借助操作系统内置的自动探测服务，实现的一种“智能引导”机制。

Flex布局关于弹性约束的用法
type: item
date: 2026-05-27T14:15:19+08:00
description: 一、传统 Flex 布局的痛点：高度传递失效在传统布局中，为了让一个子元素填满父容器的高度，我们习惯使用 height: 100%。但在 Flex 布局中，这种用法经常失效，原因在于：Flex 容器的子元素默认高度由内容撑开（min-height: auto）。使用 height: 100% 需要父级明确指定高度，而 Flex 容器的交叉轴尺寸往往由内容决定（除非设置了固定高度）。多层嵌套时，height: 100% 需要每一层都显式设置高度，导致冗余且脆弱的代码。典型错误示例： 我想填满父容器高度 .flex-container { display: flex; height: 300px; /* 父级有明确高度 */ } .flex-item { flex: 1; /* 期望填满剩余空间 */ } .content { height: 100%; /* 试图填满 .flex-item 的高度 —— 可能失效 */ }当 .flex-item 本身没有显式高度时，height: 100% 会参照 auto，结果等于内容高度，无法拉伸。二、现代 Flex 的核心规则：min-height: 0 与 overflowFlex 布局中，子元素的默认最小尺寸（min-width: auto / min-height: auto）会阻止其收缩到小于内容尺寸。这是导致溢出、无法正确拉伸或滚动失效的根本原因。解决方案两步走：在 Flex 容器上设置 min-height: 0 允许子元素在交叉轴方向上收缩到比内容更小。配合 overflow: auto（或 hidden/scroll） 当内容超出约束尺寸时，提供滚动或裁剪，从而形成尺寸约束，使 flex 或绝对拉伸生效。核心原理：overflow 不为 visible 时，会改变元素的块级格式化上下文（BFC）并强制其尺寸受父级约束，不再被内部内容无限制撑开。三、现代最佳实践代码模板3.1 基础结构：让内容区域填满剩余高度并支持滚动 固定头部 固定底部 /* 全局 reset */ * { margin: 0; padding: 0; box-sizing: border-box; } /* 全屏布局 */ .app { display: flex; flex-direction: column; height: 100vh; /* 唯一显式高度，通常在根容器 */ } /* 主体区域：填满剩余空间 */ .flex-grow-container { flex: 1; /* 占据剩余高度 */ min-height: 0; /* 允许收缩，关键！ */ display: flex; /* 也可以是块级，但通常继续使用flex */ flex-direction: column; } /* 滚动内容区 */ .scroll-area { flex: 1; min-height: 0; /* 再次允许收缩 */ overflow-y: auto; /* 溢出时滚动，提供约束 */ }3.2 横向布局中避免宽度传递失效类似地，横向 Flex 需要 min-width: 0 + overflow-x: auto。.horizontal-flex { display: flex; min-width: 0; /* 防止溢出 */ } .scroll-x { flex: 1; min-width: 0; overflow-x: auto; }四、为什么 height: 100% 不再必要？现代 Flex 布局中，子元素的拉伸依靠：flex: 1 在主轴方向分配剩余空间（主轴为列时，分配高度）。align-self: stretch（默认）让子元素在交叉轴填满容器只要父容器有明确的约束尺寸（如 height: 100vh、flex: 1 配合 min-height: 0），子元素就能正确拉伸。不需要向上层层 height: 100%。对比两种写法：传统写法现代写法html, body, .parent, .child { height: 100%; }根容器设 height: 100vh，其余用 flex: 1 + min-height: 0脆弱，难以维护稳健，只依赖直接父级上下文内容溢出往往导致父级被撑开overflow 控制溢出，布局稳定五、深入原理解析5.1 默认 min-height: auto 的副作用在 Flex 布局中，子元素的默认 min-height: auto 意味着其高度不能小于内容的高度。例如：.flex-container { display: flex; flex-direction: column; height: 200px; } .item { flex: 1; /*…

swconfig 旧架构 (固件较旧/内核 4.x)调整VLAN
type: item
date: 2026-05-20T10:45:13+08:00
description: 情况：外壳上插 PC 的口 → 交换机逻辑端口 LAN2外壳上插上级路由器 LAN 口（即未来作为 WAN 的口） → 交换机逻辑端口 LAN1需要的方案：LAN1 作为 WAN 口，LAN2 作为 LAN 口 （其他不存在的物理口全部关闭）最终正确配置（交换机页面）VLAN IDCPU (eth0)LAN1LAN2LAN3LAN4WAN1不关联关不关联关关关2关联不关联关关关关解释：VLAN 1 = LAN 区域 → 只包含 CPU + LAN2（ PC 口）VLAN 2 = WAN 区域 → 只包含 CPU + LAN1（接上级路由器的口）具体操作步骤（Web 界面）编辑 VLAN 1点击 VLAN ID 1 后面的 编辑修改端口状态：CPU：不关联（不要选“关联”，但如果你只有“关联/关”选项，就选“关”？实际上 LEDE 中 CPU 一般为“关联”或“不关联”都行，我们选“不关联”更简单，但如果界面上只有“关联”和“关”，就选“关联”。建议你先选“不关联”，如果保存后不行再改回“关联”）鉴于你截图里 VLAN 1 CPU 显示“1000baseT”并不是一个可选项，实际编辑时 CPU 可能显示为“关联”（tagged）或“不关联”（untagged）。请选择 “不关联”。LAN1：关LAN2：不关联LAN3：关LAN4：关WAN：关点击 保存编辑 VLAN 2点击 VLAN ID 2 后面的 编辑修改端口状态：CPU：关联（必须，这样 CPU 才能处理 WAN 流量）LAN1：不关联LAN2：关LAN3：关LAN4：关WAN：关点击 保存保存并应用回到交换机主页面，点击 保存并应用最后配置接口配置完交换机后，需要让系统知道哪个 VLAN 是 WAN、哪个是 LAN。配置 WAN 接口进入 网络 → 接口找到 WAN（如果没有，可以新建；通常已有 WAN 接口）点击 编辑进入 物理设置 标签页在“接口”下拉框中，选择 “交换机 VLAN: eth0.2”（数字 2 对应 VLAN ID 2）协议 选择：如果你的上级路由器已经拨号，选 DHCP 客户端如果你要用这台设备拨号，选 PPPoE 并填写账号密码防火墙区域：确保是 wan点击 保存并应用配置 LAN 接口编辑 LAN 接口物理设置：选择 “交换机 VLAN: eth0.1”（数字 1 对应 VLAN ID 1）协议保持 静态地址（通常是 192.168.1.1/24）防火墙区域：lan保存并应用验证是否成功把 PC 插到 原来插着变成 LAN2 的那个口（外壳上你之前插 PC 的口）把上级路由器（或光猫）来的网线插到 原来插着变成 LAN1 的那个口（外壳上你插另一个路由器 LAN 的口）PC 应该能正常获取 IP（如 192.168.1.x）上级路由器应该能给这台设备分配 IP（如 192.168.0.x 或其他网段）此时 PC 应该能上网如果改完后连不上管理界面把 PC 插到 LAN2 对应的物理口如果获取不到 IP，手动设置：IP：192.168.1.2掩码：255.255.255.0网关：192.168.1.1访问 192.168.1.1如果仍然不行，说明你修改时可能把 CPU 端口配置错了。可以长按复位键恢复出厂，然后严格按照上面步骤再操作一次。一个小提醒你的设备交换机芯片是 rt305x-esw，这类芯片在 VLAN 配置时，CPU 端口必须在一个 VLAN 中设置为“关联”才能通信。在我们方案中：VLAN 1 的 CPU 我建议设为“不关联”，因为 LAN 流量不需要打标签；但如果这样 PC 无法上网，请改回“关联”。VLAN 2 的 CPU 必须“关联”。如果修改后 PC 无法上网但能获取 IP，大概率是 VLAN 1 的 CPU 端口设置问题，将其改为“关联”即可。

linux账号密码正确，ssh通过但无法远程问题解决
type: item
date: 2026-04-30T11:05:16+08:00
description: 1. 检查及调整主配置文件首先检查 /etc/ssh/sshd_config 中的关键配置，找到 PasswordAuthentication 和 PermitRootLogin（如果你用root登录）这两行：PasswordAuthentication: 请确保它的值是 yes。PermitRootLogin: 它是用来控制是否允许root用户登录的，选项包括 yes、no 或 prohibit-password。如果你用非root用户登录，可以先忽略此项。如果某行被注释（行首有#）或找不到，则代表使用默认值（PasswordAuthentication 的默认值通常是yes），可以不用修改。2. 检查所有相关配置文件Ubuntu 系统可能从 /etc/ssh/sshd_config.d/ 目录加载额外的配置文件。需要确保这些配置文件里没有 PasswordAuthentication no 或 PermitRootLogin no 的设置。需要注意：Match 语句块里的配置如果放在 sshd_config.d 的独立文件里，可能不会按预期生效。为了稳妥，建议把对特定用户的配置直接写到 /etc/ssh/sshd_config 文件的末尾。3. 重启并测试SSH服务配置修改完成后，需要重启SSH服务让配置生效：sudo systemctl restart sshd # 或使用传统的 service 命令 sudo service ssh restart重启后，新开一个终端窗口尝试SSH登录，检查问题是否解决。

linux静态ip调整为dhcp指令
type: item
date: 2026-04-30T09:09:39+08:00
description: ✅ 解决方案执行以下命令将 eth0 的连接配置从静态改为 DHCP：# 1. 修改方法为自动（DHCP） nmcli connection modify eth0 ipv4.method auto # 2. 清除之前设置的静态地址 nmcli connection modify eth0 ipv4.addresses "" # 3. （可选）增加 DHCP 超时时间，避免因网络慢导致获取失败 nmcli connection modify eth0 ipv4.dhcp-timeout 30 # 4. （可选）禁止 DHCP 失败后回退到其他地址 nmcli connection modify eth0 ipv4.may-fail no # 5. 确保开机自动连接 nmcli connection modify eth0 connection.autoconnect yes # 6. 重新激活连接以立即生效 nmcli connection down eth0 && nmcli connection up eth0修改完成后，检查是否成功获取到 DHCP 分配的 IP：ip addr show eth0如果没有立即获得，可以手动请求：sudo dhclient -v eth0最后重启测试：sudo reboot重启后用 ip addr show eth0 确认是否自动获得了正确的 DHCP 地址（不再是 192.168.100.100）。

关于鲁班猫rk3568适配的linux系统使用新版本python的情况
type: item
date: 2026-04-29T17:13:48+08:00
description: 前言开发了一些程序需要放到3568上运行。但是开发环境是python3.12，而最新版本的rk3568适配的系统是ubt20，系统默认的版本是python3.8其次，为了规避linux系统使用python安装依赖与系统依赖冲突的问题。需要采用python虚拟环境来运行情况1 默认版本是3.8需要编译3.12从源码编译（最通用、最干净）这是 ARM 开发板上安装新版 Python 的标准做法，虽然编译时间稍长，但兼容性最好，也不会破坏系统自带的 python3。1.安装编译依赖（已安装过的可跳过）sudo apt update sudo apt install -y wget build-essential libreadline-dev libncursesw5-dev \ libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev \ libffi-dev zlib1g-dev2.下载 Python 3.12 源码去 Python 官网 找最新的 3.12 版本链接（例如 3.12.4）：wget https://www.python.org/ftp/python/3.12.4/Python-3.12.4.tgz tar -xf Python-3.12.4.tgz cd Python-3.12.43.配置、编译、安装（使用 altinstall 避免覆盖系统 python3）# 配置（可选 --enable-optimizations 会提升性能但编译时间翻倍） ./configure --enable-optimizations # 使用全部CPU核心编译，RK3568大概需要30-60分钟 make -j$(nproc) # 关键：用 altinstall 而不是 install sudo make altinstall4.验证python3.12 --version你会看到 Python 3.12.x，同时系统默认的 python3 依然是 3.8.2，互不冲突。情况2 安装python3.12-venv报错这里的处理很简单，编译版本的python环境已经带了venv工具，直接使用python3.12 -m venv venv工具既可