新闻详情

新闻详情

首页 / 资讯中心 / 详情

Kata Containers 中 dbs-upcall 详解:基于 VSOCK 的 VMM 与 Guest 直连热插拔通道

发布时间:2026/9/26 7:25:32来源:尧图网络
Kata Containers 中 dbs-upcall 详解:基于 VSOCK 的 VMM 与 Guest 直连热插拔通道
云原生容器运行时【免费下载链接】kata-containersKata Containers is an open source project and community working to build a standard implementation of lightweight Virtual Machines (VMs) that feel and perform like containers, but provide the workload isolation and security advantages of VMs. https://katacontainers.io/项目地址https://gitcode.com/gh_mirrors/ka/kata-containers点击查看免费下载dbs-upcall 是 DragonballKata Containers 内置的轻量级微虚拟机 VMM中一套基于 VSOCK 实现的 VMM 与 Guest 内核之间的直接通信通道其核心价值在于通过一条内核态 upcall 服务通道直接完成 CPU、virtio-mmio、PCI 设备的动态热插拔/热卸载从而完全绕开 ACPI 虚拟化显著降低虚拟机开销。本文将以 dbs-upcall 源码 为骨架结合仓库内的 Rust 实现、VMM 集成代码与内核补丁完整讲解 upcall 的架构设计、双端状态机、消息协议格式、内核补丁依赖以及它在 Dragonball 设备热插拔流程中的实际调用链。读完本文你将掌握 upcall 通道的工作原理能够读懂并上手扩展这套 VMM–Guest 直连通信机制。一、为什么需要 upcall直连通道的设计动机在传统虚拟化方案中设备热插拔如在线添加 CPU、插入 virtio 设备通常依赖 ACPI 机制VMM 通过 ACPI 表与 GPEGeneral Purpose Event向 Guest 通告设备状态变化Guest 内核解析 ACPI 事件后完成设备枚举与上线。这一过程链路长、开销大且需要在 VMM 与 Guest 两侧都实现完整的 ACPI 栈。Dragonball 采取的替代思路是建立一条 VMM 与 Guest 内核之间的直连通道upcall服务端Server位于 Guest 内核中是一个内核驱动。内核启动后会开启一个 VSOCK 监听服务专门响应来自 VMM 的请求客户端Client位于 VMM 侧由dbs-upcallcrate 抽象实现作为一个独立线程通过 UDSUnix Domain Socket与 VSOCK 通信。正如 README 所述We have accomplished device hotplug / hot-unplug directly through upcall in order to avoid virtualization of ACPI to minimize virtual machines overhead。也就是说ACPI 被整体移除设备热插拔事件通过这条高速、低开销的私有通道直接下发到 Guest 内核处理。README 同时指出除了设备热插拔there could be many other usage through this direct communication channel即该通道具备通用扩展能力未来可以承载更多 VMM–Guest 通信场景。二、整体架构服务端与客户端职责划分2.1 服务端设计Guest 内核侧服务端是 Guest 内核中的一个驱动其关键设计点如下VSOCK 端口固定为0xDB在 lib.rs 源码 中可见const SERVER_PORT: u32 0xDB;的定义。0xDB 即 DBDragonball的含义该端口是 VMM 客户端发起连接的目标端口VSOCK 连接建立后注册 upcall 服务服务端会注册对应服务并创建内核线程提供相应服务。以设备管理器device manager服务为例内核补丁 0001-upcall-establish-upcall-server.patch 中说明upcall 服务启动时创建名为db-vsock-srv的内核线程在该线程中基于端口 0xDB 建立 VSOCK listener接受来自客户端VMM的连接连接建立后客户端发送的 cmd 决定由哪个 upcall 服务处理请求同时提供register_db_vsock_service接口供各服务在初始化时注册到 service_entry 列表中服务线程连接流程upcall 服务线程首先发送消息类型为Connect的消息尝试与客户端VMM建立服务级连接连接成功后服务线程进入循环持续接收来自客户端的请求并处理直到服务停止。当前已支持的服务类型为device manager支持两类操作CPU 热插拔 / 热卸载hotplug / hot-unplugvirtio-mmio 设备热插拔 / 热卸载。从设备管理器服务源码 dev_mgr_service.rs 中可以看到完整的操作码枚举除了 README 提到的两类之外还包含内存与 PCI 相关操作码下文协议章节详述。2.2 客户端设计VMM 侧客户端位于 VMM 中其逻辑全部抽象在dbs-upcallcrate 内。客户端是一个 epoll 事件驱动的实现通过UpcallClient与UpcallEpollHandler两个核心结构配合完成与 VSOCK 的连接、事件监听、请求发送与响应回调。客户端整体状态机如 README 中的示意图所示客户端工作流对应 README 的三步流程与源码中的状态机一一对应WaitingServer状态检查与 VSOCK 服务器的连接即与 Guest 内核 upcall 驱动建立的 VSOCK 连接WaitingService状态检查与 Guest 内核中 upcall 服务如 device manager的连接——通过 Connect 消息与 magic version 校验确认服务可达ServiceConnected状态在此状态下可以正常通过 upcall 发送请求。若步骤 1、2 失败upcall 会自动尝试重连若步骤 3 中请求已发送但响应尚未返回客户端状态切换为ServiceBusy此状态下不会再处理其他请求保证通道单请求串行语义。三、客户端状态机与源码实现客户端状态机的完整定义位于 lib.rs共有五个状态状态含义WaitingServer服务器连接已断开等待重连或服务器连接请求已发出等待响应WaitingService服务连接请求已发出等待服务响应ServiceConnectedupcall 服务已连接可发送请求ServiceBusy通道繁忙请求已发出但响应未返回ReconnectError无法简单重连服务器的错误状态从源码注释看这里刻意没有设计ServerDisconnect状态因为客户端在构造连接或与服务器断开时总是立即发起连接。3.1 连接建立与检查UpcallEpollHandler::new在构造时会立刻调用server_connection_start()通过VsockInnerConnector建立 VSOCK 连接并将流设置为非阻塞然后写入CONNECT {SERVER_PORT}\n命令即CONNECT 0xDB\n。这一点在单元测试 test_upcall_client_connect 中有直接验证测试断言客户端发送的正是format!(CONNECT {SERVER_PORT}\n)这一字节序列。随后通过server_connection_check()读取服务器响应检查响应是否以OK开头源码中检查buffer[0..2] [bO, bK]若响应不是OK例如ERR则校验失败并进入重连流程。服务级连接由DevMgrService::connection_start完成客户端向流中写入单字节DEV_MGR_BYTE即bddevice manager 的标识字节见 dev_mgr_service.rs用于向服务端注册请求将交由 device manager 服务处理——这与内核补丁中register_db_vsock_service(DEVMGR_CMD_BYTE, db_devmgr_handler)的注册逻辑一一对应见 0002 补丁。DevMgrService::connection_check则读取完整的DEV_MGR_MSG_SIZE0x400即 1024 字节消息校验消息头四项magic_version DEV_MGR_MAGIC_VERSION、msg_size 0、msg_flags 0、msg_type Connect全部满足才算服务连接成功。3.2 请求发送与响应回调UpcallClient::send_request是公开的请求发送接口底层逻辑send_request_inner依据当前状态分派处于WaitingServer、WaitingService、ReconnectError返回UpcallIsNotConnected错误处于ServiceBusy返回UpcallIsBusy错误处于ServiceConnected发送请求状态切换为ServiceBusy并注册回调函数。响应到达后由handle_stream_event在ServiceBusy分支调用handle_response()成功后恢复ServiceConnected状态并通过consume_callback(response)触发用户注册的回调若响应处理失败则回到WaitingServer并进入重连流程。另外客户端还提供send_request_without_result只发请求、丢弃响应与is_ready()判断是否处于ServiceConnected等辅助接口。3.3 重连机制重连由set_reconnect()实现使用timerfdTimerFd作为重连定时器每次重连间隔SERVER_RECONNECT_DURATION_MS10ms最大重连次数SERVER_MAX_RECONNECT_TIME500 次。超过上限后记录错误日志并停止重连尝试。重连时会把旧的 stream 从 epoll 中移除并丢弃随后由handle_reconnect_event重新发起server_connection_start()并将新 stream 加入 epoll。值得强调的是重连前会先消费掉挂起的回调info.consume_callback(UpcallClientResponse::UpcallReset)即通知上层通道已断开、需要重连避免上层一直等待一个永远不会到达的响应——这是通道语义设计上的一个重要细节。四、消息协议设计请求与回复格式4.1 消息头Message Header请求消息由「消息头 消息负载」两部分组成回复消息由「消息头 result 消息负载」三部分组成。消息头在请求与回复中保持一致共四个字段均为 u32见 dev_mgr_service.rs 中的 DevMgrMsgHeader字段类型说明magic_versionu32标识 upcall 及服务类型的魔数版本msg_sizeu32消息负载msg_load的大小msg_typeu32消息类型标识用途如 ADD_CPUmsg_flagsu32保留字段device manager 服务使用的魔数版本为DEV_MGR_MAGIC_VERSION 0x444D0100DM 即 DevMgr 的 ASCII 含义单条消息固定缓冲大小DEV_MGR_MSG_SIZE 0x4001024 字节。消息类型操作码枚举定义如下操作码值用途Connect0x00000000服务连接AddCpu0x00000001CPU 热插拔DelCpu0x00000002CPU 热卸载AddMem0x00000003内存热插拔预留DelMem0x00000004内存热卸载预留AddMmio0x00000005virtio-mmio 设备热插拔DelMmio0x00000006virtio-mmio 设备热卸载AddPci0x00000007PCI 设备热插拔DelPci0x00000008PCI 设备热卸载对比 README 所述当前支持 CPU 与 virtio-mmio 热插拔源码枚举中还包含了内存与 PCI 的操作码PCI 热插拔由后续内核补丁 0008-upcall-add-pci-hotplug-hot-unplug-support.patch 提供支持说明协议在设计之初就为内存、PCI 等更多设备类型预留了扩展空间。4.2 请求负载msg_load请求消息的负载当前包含两种类型类型 1add_mmio_devMmioDevRequest——用于 virtio-mmio 设备热插拔/热卸载对应 Rust 结构体 MmioDevRequest字段类型说明mmio_baseu64virtio MMIO 配置窗口的基地址mmio_sizeu64virtio MMIO 配置窗口的大小mmio_irqu32分配给该 MMIO virtio 设备的中断号类型 2cpu_dev_infoCpuDevRequest——用于 CPU 热插拔/热卸载对应结构体 CpuDevRequest字段类型说明countu8热插拔/热卸载的 CPU 数量apic_veru8APIC 版本仅 x86_64 架构apic_ids[256]u8 数组APIC ID 数组仅 x86_64 架构从源码可见apic_ver与apic_ids都带有#[cfg(target_arch x86_64)]条件编译而 aarch64 架构下CpuDevRequest只包含count字段——这正对应内核补丁 0005-upcall-dragonball-devmgr-suppots-cpu-hotplug-on-arm64.patch 为 ARM64 增加的 CPU 热插拔支持ARM64 通过 CPU ID 而非 APIC ID 寻址。请求的字节序布局由DevMgrRequest::build()完成将DevMgrMsgHeader与负载结构体按#[repr(C)]布局写入 1024 字节缓冲区并设置对应的msg_type与msg_size负载结构体大小。DevMgrRequest枚举源码涵盖六种请求AddMmioDev / DelMmioDev / AddVcpu / DelVcpu / AddPciDev / DelPciDev其中 AddPciDev / DelPciDev 使用 PciDevRequestbusnoPCI 总线号devfn设备号与功能号组合。4.3 回复负载msg_load与结果语义回复消息在消息头之后紧跟着resulti32然后是消息负载。语义如下result 为 0操作成功result 非 0result 即错误码。回复负载同样有两种类型类型 1add_mmio_dev 回复——virtio-mmio 热插拔回复当前负载为空DevMgrResponse::AddMmioDev(DevMgrResponseInfo())见 dev_mgr_service.rs类型 2cpu_dev_reply_infoCpuDevResponse——CPU 热插拔/热卸载回复字段类型说明apic_indexx86_64u32最后一个激活 CPU 的 APIC ID 索引cpu_idaarch64u32最后一个激活 CPU 的 CPU ID回复解析由DevMgrResponse::make()完成根据msg_type区分 CPU 回复AddCpu/DelCpu、MMIO 回复AddMmio与未知消息类型归入Other。其中 CPU 回复还有一个重要的失败回滚语义内核补丁 0003 补丁 的注释说明Return the first failed hotplug index of the apic_ids to dragonball ... we will rollback the vcpus from apic_ids[0] to apic_ids[i-1] in dragonball——即批量 CPU 热插拔时若第 i 个 CPU 失败回复会携带失败索引VMM 侧据此回滚之前已插入的 CPU保证批量操作的一致性。五、设备热插拔从 VMM 请求到 Guest 内核动作的完整调用链5.1 VMM 侧的集成dbs-upcall在 Dragonball VMM 中的集成位于 src/dragonball/src/vm/mod.rs 与 src/dragonball/src/device_manager/mod.rs均以hotplugdbs-upcall两个 feature 同时开启为前提#[cfg(all(feature hotplug, feature dbs-upcall))]。Upcall 客户端初始化VM 启动流程中调用init_upcall()→new_upcall()从 VSOCK 后端获取 inner connector构造UpcallClient::new(connector, epoll_manager, DevMgrService::default())调用connect()将UpcallEpollHandler注册进 epoll manager开始与 Guest 内核 upcall 服务建链初始化成功后通过device_manager.set_upcall_channel(...)将ArcUpcallClientDevMgrService注入设备管理器供热插拔流程使用。VM 销毁时调用remove_upcall()清理 upcall 客户端见 vm/mod.rs。此外VM 还提供is_upcall_client_ready()查询通道就绪状态——这是热插拔请求发送的前置条件。热插拔请求下发设备管理器中的call_hotplug_device()封装了请求发送逻辑device_manager/mod.rs根据是否有回调选择send_request带回调或send_request_without_result不带回调请求类型统一为UpcallClientRequest::DevMgr(req)。具体的热插拔入口包括insert_hotplug_mmio_device/remove_hotplug_mmio_device构造DevMgrRequest::AddMmioDev/DelMmioDev含 mmio_base / mmio_size / mmio_irqinsert_hotplug_pci_device/remove_hotplug_pci_device构造DevMgrRequest::AddPciDev/DelPciDev含 busno / devfn且受pci_hotplug_enabled配置开关约束。5.2 内核侧的处理请求到达 Guest 内核后由注册的 device manager 服务处理。以内核补丁 0003 的 CPU 热插拔为例处理流程为解析请求负载中的cpu_dev_infocount、apic_ver、apic_ids[]ADD_CPU 操作遍历apic_ids逐个调用add_cpu_upcall(apic_id, apic_ver)通过generic_processor_info(apic_id, apic_ver)获取 CPU ID再调用add_cpu(cpu_id)完成 CPU 上线DEL_CPU 操作则遍历apic_ids通过get_cpu_id(apic_ids[i])定位后调用del_cpu_upcall完成 CPU 下线批量操作期间内核侧通过cpu event notification向 VMM 反馈当前处理到的 apic ids indexVMM 侧记录并在失败时据此回滚已生效的 CPU。virtio-mmio 热插拔0004 补丁与 PCI 热插拔0008 补丁采用类似的模式解析msg_load中的 MMIO 基址/大小/中断号或 PCI busno/devfn调用内核设备模型接口完成设备的添加或移除。六、内核补丁Guest 侧依赖dbs-upcall 的服务端是 Guest 内核驱动因此必须为 Guest 内核打上 upcall 系列补丁才能使用该功能。补丁位于 tools/packaging/kernel/patches/5.10.x/dragonball-experimental基于 5.10.x 内核共 8 个补丁按依赖顺序排列补丁内容0001-upcall-establish-upcall-server.patch建立 upcall 服务端框架db-vsock-srv内核线程、VSOCK 监听端口 0xDB、register_db_vsock_service服务注册机制0002-upcall-introduce-device-manager-upcall-service.patch引入 device manager upcall 服务定义消息头与 DEVMGR_MAGIC_VERSION 校验0003-upcall-add-cpu-hotplug-hot-unplug-into-device-manage.patchCPU 热插拔/热卸载add_cpu_dev/del_cpu_devAPIC ID 定位、失败索引回滚0004-upcall-add-virtio-mmio-hotplug-hot-unplug-into-devic.patchvirtio-mmio 设备热插拔/热卸载0005-upcall-dragonball-devmgr-suppots-cpu-hotplug-on-arm6.patchARM64 CPU 热插拔支持0006-msi-control-msi-irq-number-activated.patchMSI 中断号控制0007-smp-update-bringup_nonboot_cpus-parameters.patchSMPbringup_nonboot_cpus参数更新0008-upcall-add-pci-hotplug-hot-unplug-support.patchPCI 设备热插拔/热卸载支持其中 0001 补丁还包含drivers/misc/dragonball/Kconfig新增的DRAGONBALL_DRIVERS菜单配置项bool Alibaba Dragonball Secure Container Runtime Drivers依赖X86_64 || ARM64启用 upcall 内核驱动需要在内核配置中开启该选项。七、可测试性与扩展性dbs-upcall具备完整的单元测试覆盖测试代码直接位于两个源码文件的#[cfg(test)] mod tests中lib.rs 测试通过VsockInnerBackend构造内存中的 VSOCK 连接对get_vsock_inner_backend_stream_pair用FakeService模拟服务端覆盖服务器连接建立/检查、服务连接、请求/响应往返、状态切换、回调消费、重连定时器、以及send_request在各状态下的错误路径test_upcall_client_send_request_error验证了四种非ServiceConnected状态下发送请求均返回错误dev_mgr_service.rs 测试验证DevMgrRequest::build()的消息头字段与负载字节布局test_build_dev_mgr_request、DevMgrResponse::make()对 CPU / MMIO / 未知类型回复的解析test_make_dev_mgr_response以及DevMgrService各方法的真实字节流行为connection_start写入bd、send_request写入完整 1024 字节消息等。这套测试模式用 VSOCK 内存后端模拟 Guest 内核、用 trait 泛型注入 FakeService也体现了UpcallClientServicetrait 的设计价值任何新服务只需要实现 UpcallClientService trait 的四个方法connection_start/connection_check/send_request/handle_response即可复用完整的连接管理、状态机与重连逻辑接入新的 VMM–Guest 通信场景。八、使用前提与限制必须使用打过 upcall 补丁的 Guest 内核未打补丁的内核没有 0xDB 端口的 VSOCK 服务与 device manager 服务upcall 客户端将一直处于重连状态热插拔不可用依赖 virtio-vsock 设备dbs-upcall依赖dbs-virtio-devices的virtio-vsockfeature见 Cargo.toml并通过 VSOCK 的 UDS 通道通信因此 VMM 配置中必须包含 vsock 设备需要同时开启hotplug与dbs-upcallfeatureVMM 集成代码以这两个 feature 为编译前提与之对应vm/mod.rs 中not(feature dbs-upcall)分支的注释明确写着 We will support hotplug without upcall in future stages即当前热插拔能力依赖 upcall 通道架构差异CPU 热插拔请求在 x86_64 与 aarch64 下负载结构不同APIC ID 数组 vs 仅 count协议解析与内核处理均按架构条件编译单请求串行语义同一时刻通道只允许一个在途请求ServiceBusy状态需要并发热插拔多个设备时应串行下发或自行在上层做队列控制版本信息crate 版本为 0.3.0采用 Apache-2.0 许可证由 Alibaba Dragonball Team 维护见 Cargo.toml。九、总结dbs-upcall 是 Dragonball 在去 ACPI 化方向上的一项关键实现它用一条基于 VSOCK端口 0xDB的 VMM–Guest 内核直连通道替代传统 ACPI 事件链路完成 CPU、virtio-mmio 与 PCI 设备的热插拔/热卸载从而降低虚拟机运行开销。其客户端状态机WaitingServer → WaitingService → ServiceConnected ↔ ServiceBusy、紧凑的#[repr(C)]二进制消息协议magic_version / msg_size / msg_type / msg_flags 消息头 类型化负载 result 结果码、以及可插拔的UpcallClientServicetrait 设计使得该通道既稳定可靠又易于扩展。对于希望深入理解 Kata Containers / Dragonball 热插拔机制或在 VMM 与 Guest 之间建立自定义高速通信通道的开发者dbs-upcall 源码、设备管理服务实现 与 内核补丁集 是三个最佳的研读入口。赞分享云原生容器运行时【免费下载链接】kata-containersKata Containers is an open source project and community working to build a standard implementation of lightweight Virtual Machines (VMs) that feel and perform like containers, but provide the workload isolation and security advantages of VMs. https://katacontainers.io/项目地址https://gitcode.com/gh_mirrors/ka/kata-containers点击查看免费下载相关推荐Kata Containers Dragonball VMM 设备模型深解析dbs-device 的 MMIO/PIO 陷阱处理、IO 分发与热插拔机制Kata Containers Dragonball VMM 设备模型深解析dbs device 的 MMIO/PIO 陷阱处理、IO 分发与热插拔机制 本篇云原生容器运行时终极Switch游戏文件管理工具NSC_BUILDER完整使用指南终极Switch游戏文件管理工具NSC_BUILDER完整使用指南 如果你正在寻找一款功能强大的Nintendo Switch游戏文件管理工具NSC_BUI云原生容器运行时Kata Containers Dragonball 的 dbs-allocator基于区间树的 VMM 资源分配器设计与实践Kata Containers Dragonball 的 dbs allocator基于区间树的 VMM 资源分配器设计与实践 本文以 Dragonball云原生容器运行时上一篇Reddit AI Trends与MongoDB集成趋势数据持久化与历史分析指南下一篇如何轻松实现微信聊天记录永久保存你的个人数据守护指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

OpenWAM世界动作模型:七校联合开源,破解机器人sim-to-real难题 2026/9/26 8:16:40

OpenWAM世界动作模型:七校联合开源,破解机器人sim-to-real难题

1. 这个「世界模拟器」到底在解决什么问题机器人圈子里有个老生常谈的尴尬:真机上跑一个抓取策略,调参调到怀疑人生,一天下来机械臂没动几次,日志倒是刷了几百兆。强化学习在仿真里能飞檐走壁,一上真机就变成「人工智障…

阅读更多 →
金融数据服务架构设计与工程实践:模块化分层、数据模型与实时推送 2026/9/26 8:16:33

金融数据服务架构设计与工程实践:模块化分层、数据模型与实时推送

1. 金融数据服务项目的整体架构设计思路1.1 为什么选择模块化分层架构做金融数据服务这些年,我最大的体会就是:千万别把数据采集、清洗、存储、接口这四件事揉在一起写。早期我接手过一个项目,所有逻辑塞在一个脚本里,行情数据拉取…

阅读更多 →
AI Agent开发利器:BrowserSkill本地桥如何接管真实浏览器 2026/9/26 8:16:33

AI Agent开发利器:BrowserSkill本地桥如何接管真实浏览器

刚接触 AI Agent 开发那阵子,最容易困惑的一件事就是:Agent 到底长什么样?很多人的第一反应是“Agent 就是调用大模型 API,让它说一段话”,后来发现还要接工具(Tool Use)、接记忆、接流程编排。…

阅读更多 →
nRF54LC10A休眠电流实测:从50nA到整板低功耗设计 2026/9/26 8:16:32

nRF54LC10A休眠电流实测:从50nA到整板低功耗设计

1. 这颗芯片到底在卷什么:从休眠电流到电池寿命的账 第一次看到“休眠电流不到 50 nA”这个数字,我的反应是——这基本等于把“待机耗电”这件事按在地上摩擦了。做过低功耗产品的人都知道,nA 级别的休眠电流不是随便标标的,它背后…

阅读更多 →
Atlas 300V 24G推理加速卡部署YOLO全流程解析与踩坑指南 2026/9/26 8:16:26

Atlas 300V 24G推理加速卡部署YOLO全流程解析与踩坑指南

手头正好在研究 Atlas 相关的东西,最近搜“atlas 部署 YOLO”的朋友明显变多了。我在实际项目里踩过不少 Atlas 系列的坑,尤其是 Atlas 300V 24G 这块卡,很多人一上来就问同一个问题:这玩意儿到底是不是运算加速卡?它能…

阅读更多 →
基于WiFi与RS485的园区有氧健身设备物联网监测系统设计与落地 2026/9/26 8:16:26

基于WiFi与RS485的园区有氧健身设备物联网监测系统设计与落地

1. 项目缘起与整体设计思路1.1 这个项目到底在做什么科技园区里配几台有氧健身设备,跑步机、椭圆机、动感单车,这事儿不新鲜。但设备装完之后,使用率怎么样、有没有人用、设备是不是坏了、耗材什么时候该换,这些数据如果全靠人工去…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉