python xmlrpc踩坑记录及解决方案

 更新时间:2025年11月18日 09:57:16   作者:cheniie  
这篇文章主要介绍了python xmlrpc踩坑记录及解决方案,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

最近用 Python 写了一个 RPC 服务,之前在 Ubuntu 上跑,换到 Windows 上之后突然发现一个神奇的问题。我的目的是在一个循环里定时获取设备状态,然后广播给订阅的客户端。获取设备状态是一个 RPC 接口。大致结构如下:

proxy = xmlrpc.client.ServerProxy(f"http://localhost:8080/", allow_none=True)
subscribers = [] # 客户端连接
running = True
async def periodic_pusher():
    while running:
        await asyncio.sleep(0.05)
        if subscribers:
            data = proxy.get_data()
            payload = json.dumps(data)
            # 将 payload 广播给客户端
async def main(port):
    asyncio.create_task(periodic_pusher())
    async with websockets.serve(handler, "0.0.0.0", port):
        await asyncio.Future()

任务很简单,客户端通过 websocket 连接上来,然后订阅数据,这里为了照护客户端的实现者,所以转了一手。

因为配环境还挺麻烦的,而且我的数据并不复杂,所以选了 python 标准库自带的 xmlrpc 作为 rpc 库。换到 Windows 上以后,客户端突然变得异常卡顿,打印日志后发现差不多两秒多才能从服务的收到一个条数据,不管循环里 sleep 的时间调的多小都没用。

开始怀疑是异步任务调度的问题,试了纯 sleepprint,还是飕飕的。然后是排查服务端响应,还真有问题。

def rpc_get_xxx():
     data = None
     while data is None:
         data = robot.get_xxx()
         time.sleep(0.01)
     return data

因为获取数据 API 可能会返回 None,所以用了循环来保证一定能获取到数据,data=None 导致一定会进入循环,也就导致 sleep 一定至少会执行一次,带来不必要的延时。知错就改,只要把 data=None 改成 data=robot.get_xxx() 就可以了。

再次测试,但是问题依然存在,rpc 服务端的延时顶多几十毫秒,websocket 客户端那边是一两秒的问题。没别的办法加日志吧,在 rpc 调用前后加上日志,发现一次 rpc 调用就要两秒多,为进一步定位问题,在 rpc 服务端也加上日志。试了几次,结果如下:

before rpc: 1763365566.3031723
before get: 1763365568.3533354
after  get: 1763365568.3543353
after  rpc: 1763365568.3543353
before rpc: 1763367026.1716492
before get: 1763367028.228031
after  get: 1763367028.228031
after  rpc: 1763367028.228031
before rpc: 1763367290.863952
before get: 1763367292.9115446
after  get: 1763367292.9115446
after  rpc: 1763367292.9135447

rpc 客户端发起请求到服务端收到请求居然花了两秒多?这也太离谱了。。。

正当我怀疑 xmlrpc 库到底靠不靠谱的时候,找到看一篇帖子:

真是救命稻草,当我把 rpc 客户端的 ip 地址换成 127.0.0.1 之后,还真就解决了。一次调用几十毫秒就完成了:

before rpc: 1763367422.9848952
before get: 1763367422.9868922
after  get: 1763367422.9868922
after  rpc: 1763367422.9880338

这才正常嘛,不过这个坑是真坑爹啊。

其实这个问题也问过 AI,它坚持说是 getfqdn 反解 DNS 的问题,还给了一段测试代码:

import socket, time
t0 = time.perf_counter()
socket.getfqdn('localhost')   # 模拟 xmlrpc 内部调用
print("getfqdn 耗时:", time.perf_counter() - t0)

但是实际上这段代码运行起来非常快:

getfqdn 耗时: 0.012044099974445999

帖子里也说了跳过 getfqdn 并没有用,所以应该不是它的问题。

到此这篇关于python xmlrpc踩坑记录及解决方案的文章就介绍到这了,更多相关python xmlrpc内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Pytorch自定义Dataset和DataLoader去除不存在和空数据的操作

    Pytorch自定义Dataset和DataLoader去除不存在和空数据的操作

    这篇文章主要介绍了Pytorch自定义Dataset和DataLoader去除不存在和空数据的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • 利用pyinstaller打包exe文件的基本教程

    利用pyinstaller打包exe文件的基本教程

    这篇文章主要给大家介绍了关于利用pyinstaller打包exe文件的基本方法,文中通过示例代码介绍的非常详细,对大家学习或者使用pyinstaller具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • NLTK 3.2.4 环境搭建教程

    NLTK 3.2.4 环境搭建教程

    这篇文章主要为大家详细介绍了NLTK 3.2.4 环境搭建教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-09-09
  • pandas如何解决excel科学计数法问题

    pandas如何解决excel科学计数法问题

    这篇文章主要介绍了pandas如何解决excel科学计数法问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Python动刷新12306火车票的代码(附源码)

    Python动刷新12306火车票的代码(附源码)

    这篇文章主要介绍了Python动刷新12306火车票的完整代码,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2018-01-01
  • python 字符串格式化代码

    python 字符串格式化代码

    python 字符串格式化代码,需要的朋友可以参考一下
    2013-03-03
  • 利用Python如何将数据写到CSV文件中

    利用Python如何将数据写到CSV文件中

    在数据分析中经常需要从csv格式的文件中存取数据以及将数据写书到csv文件中。下面这篇文章主要给大家介绍了关于利用Python如何将数据写到CSV文件中的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-06-06
  • Django多层嵌套ManyToMany字段ORM操作详解

    Django多层嵌套ManyToMany字段ORM操作详解

    这篇文章主要介绍了Django多层嵌套ManyToMany字段ORM操作详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05
  • Python实现多张图片合成文字的效果

    Python实现多张图片合成文字的效果

    前段时间看到有人问如何使用Python实现多张图片组成文字的效果?觉得还挺有意思,于是尝试做了一下,刚好赶上端午节,所以打算从网上下载1000张王心凌的照片,组成端午安康的字样,感兴趣的可以了解一下
    2022-06-06
  • 基于Python实现一键群发邮件并自动收发附件功能

    基于Python实现一键群发邮件并自动收发附件功能

    在职场中,邮件是主要的沟通工具,但你有没有被它拖垮过效率?每月需要向几百个客户邮件群发促销信息,手动一封封发送,耗时巨大,需要定期发送提醒或通知,却总是忘记定时邮件,导致工作延误,将手把手教你如何基于Python实现一键群发邮件并自动收发附件功能
    2025-11-11

最新评论