跳转至

常见问题解答

此页面解答用户在使用 Pulsing 时遇到的常见问题和问题。

一般问题

什么是 Pulsing?

Pulsing 是分布式 AI 系统的通信骨干——一个用 Rust 构建、为 Python 设计的分布式 Actor 运行时。流式优先、零依赖、内置发现。无需 Redis、etcd 或 YAML,即可跨机器连接 AI Agent 和服务。

Pulsing 与 Ray 是什么关系?

Pulsing 和 Ray 是互补的。Ray 擅长分布式调度和资源管理。Pulsing 提供 Ray 没有内置的通信能力:

  • 流式:原生 async for 流式支持,适配 LLM token 生成
  • Actor 发现:内置 gossip 协议,跨节点命名 Actor 解析
  • 直接 Actor 通信:Actor 间直接调用,不经过对象存储
  • 零外部依赖:通信层不需要 GCS、Redis 或其他额外服务

如何在 Ray 中使用 Pulsing?

通过 pul.mount() 将 Ray Actor 接入 Pulsing 网络。Ray 负责调度,Pulsing 负责通信:

@ray.remote
class Worker:
    def __init__(self, name):
        pul.mount(self, name=name)  # 接入 Pulsing 网络

完整示例见 Ray + Pulsing 教程

何时应该独立使用 Pulsing(不搭配 Ray)?

当你需要以下特性时选择 Pulsing 独立使用:

  • 轻量级 Actor 通信,无需完整的集群管理器
  • 流式响应(LLM 应用)
  • 最小运维复杂度(零外部服务)
  • 通过内置 gossip 实现自包含集群

安装问题

ImportError: No module named 'pulsing'

问题:Pulsing 包未安装或不在 Python 路径中。

解决方案

  1. 安装 Pulsing

    pip install pulsing
    

  2. 开发环境

    git clone https://github.com/DeepLink-org/pulsing
    cd pulsing
    pip install -e .
    

  3. 检查 Python 路径

    import sys
    print(sys.path)
    

macOS/Linux 上的构建失败

问题:Rust 编译问题。

解决方案

  1. 安装 Rust

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    source ~/.cargo/env
    

  2. 安装系统依赖(Ubuntu/Debian):

    sudo apt-get install build-essential pkg-config libssl-dev
    

  3. 安装系统依赖(macOS):

    brew install openssl pkg-config
    

运行时问题

Actor 不响应消息

问题:Actor 似乎卡住或不处理消息。

可能原因

  1. 阻塞操作:Actor 在同步 I/O 上阻塞
  2. 无限循环:Actor 代码包含无限循环
  3. 死锁:Actor 正在等待永远不会到达的消息

解决方案

# ❌ 错误:在 actor 中使用阻塞 I/O
@pul.remote
class BadActor:
    def process(self, url):
        response = requests.get(url)  # 阻塞 actor!
        return response.text

# ✅ 正确:使用异步 I/O
@pul.remote
class GoodActor:
    async def process(self, url):
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                return await response.text()

连接拒绝错误

问题:无法连接到远程 actor。

可能原因

  1. 地址错误:Actor 系统监听不同的地址
  2. 防火墙:网络流量被阻塞
  3. TLS 问题:证书验证失败

解决方案

  1. 检查 actor 系统地址

    # 确保地址匹配
    system1 = await pul.actor_system(addr="0.0.0.0:8000")
    system2 = await pul.actor_system(addr="0.0.0.0:8001", seeds=["127.0.0.1:8000"])
    

  2. 测试时禁用 TLS

    # 仅用于开发环境
    system = await pul.actor_system(addr="0.0.0.0:8000", passphrase=None)
    

内存泄漏

问题:内存使用量随时间增长。

可能原因

  1. 消息积累:消息处理不够快
  2. 大型消息负载:消息包含大型数据结构
  3. Actor 泄漏:Actor 未正确清理

解决方案

  1. 监控邮箱大小

    # 检查 actor 邮箱大小
    mailbox_size = await system.get_mailbox_size("actor_name")
    

  2. 对大型数据使用流式处理

    @pul.remote
    class StreamingActor:
        async def process_large_data(self, data_stream):
            async for chunk in data_stream:
                # 分块处理
                yield self.process_chunk(chunk)
    

性能问题

高延迟

问题:消息往返耗时太长。

优化方案

  1. 尽可能使用本地 actor

    # 本地 actor(快速)
    local_actor = await MyActor.spawn()
    
    # 远程 actor(较慢)
    remote_actor = await MyActor.resolve("remote_actor")
    

  2. 批处理消息

    # 不要进行多次调用
    results = []
    for item in items:
        result = await actor.process(item)
        results.append(result)
    
    # 批处理
    results = await actor.process_batch(items)
    

  3. 对无需响应的操作使用 tell()

    # 如果不需要响应,不要等待
    await actor.log_event(event_data)  # 在内部使用 ask()
    await actor.tell({"action": "log", "data": event_data})  # 发射后不管
    

序列化开销

问题:消息序列化很慢。

解决方案

  1. 使用高效的数据格式

    # ✅ 良好:使用简单类型
    await actor.process({"numbers": [1, 2, 3], "text": "hello"})
    
    # ❌ 错误:复杂的嵌套对象
    await actor.process({"data": very_complex_nested_object})
    

  2. 避免发送大型负载

    # 发送引用而不是数据
    await actor.process_data(data_id)  # 发送 ID,而不是数据本身
    

部署问题

集群无法正常工作

问题:多个节点无法相互发现。

解决方案

  1. 检查种子节点配置

    # 节点 1(种子)
    system1 = await pul.actor_system(addr="192.168.1.100:8000")
    
    # 节点 2(加入集群)
    system2 = await pul.actor_system(
        addr="192.168.1.101:8000",
        seeds=["192.168.1.100:8000"]
    )
    

  2. 验证网络连接

    # 测试端口是否开放
    telnet 192.168.1.100 8000
    

  3. 检查防火墙设置

    # Linux
    sudo ufw status
    sudo ufw allow 8000
    
    # macOS
    sudo pfctl -s rules
    

负载均衡问题

问题:请求未在集群中均匀分布。

解决方案

  1. 使用轮询解析

    # 默认行为在实例间分布
    actor = await MyActor.resolve("service_name")
    

  2. 检查 actor 分布

    # 监控集群成员
    members = await system.members()
    print(f"Cluster has {len(members)} nodes")
    

Ray 集成问题

在 Ray 中使用 Pulsing

常见问题

  1. API 差异

    # Ray
    @ray.remote
    class MyActor:
        def __init__(self, value):
            self.value = value
    
    actor = MyActor.remote(42)
    result = ray.get(actor.method.remote())
    
    # Pulsing
    @pul.remote
    class MyActor:
        def __init__(self, value):
            self.value = value
    
    actor = await MyActor.spawn(value=42)
    result = await actor.method()
    

  2. 处处需要 async/await

    # Pulsing 需要 async/await
    async def main():
        await pul.init()
        actor = await MyActor.spawn()
        result = await actor.method()
        await pul.shutdown()
    
    asyncio.run(main())
    

获取帮助

如果在此处找不到答案:

  1. 查看文档用户指南API 参考
  2. 搜索现有问题GitHub Issues
  3. 咨询社区GitHub Discussions
  4. 提交错误报告:如果发现 bug,请创建 issue

贡献

发现此 FAQ 有问题?帮助改进它!