python xmlrpc踩坑記錄及解決方案
最近用 Python 寫了一個 RPC 服務(wù),之前在 Ubuntu 上跑,換到 Windows 上之后突然發(fā)現(xiàn)一個神奇的問題。我的目的是在一個循環(huán)里定時獲取設(shè)備狀態(tài),然后廣播給訂閱的客戶端。獲取設(shè)備狀態(tài)是一個 RPC 接口。大致結(jié)構(gòu)如下:
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()任務(wù)很簡單,客戶端通過 websocket 連接上來,然后訂閱數(shù)據(jù),這里為了照護(hù)客戶端的實(shí)現(xiàn)者,所以轉(zhuǎn)了一手。
因?yàn)榕洵h(huán)境還挺麻煩的,而且我的數(shù)據(jù)并不復(fù)雜,所以選了 python 標(biāo)準(zhǔn)庫自帶的 xmlrpc 作為 rpc 庫。換到 Windows 上以后,客戶端突然變得異??D,打印日志后發(fā)現(xiàn)差不多兩秒多才能從服務(wù)的收到一個條數(shù)據(jù),不管循環(huán)里 sleep 的時間調(diào)的多小都沒用。
開始懷疑是異步任務(wù)調(diào)度的問題,試了純 sleep 加 print,還是颼颼的。然后是排查服務(wù)端響應(yīng),還真有問題。
def rpc_get_xxx():
data = None
while data is None:
data = robot.get_xxx()
time.sleep(0.01)
return data因?yàn)楂@取數(shù)據(jù) API 可能會返回 None,所以用了循環(huán)來保證一定能獲取到數(shù)據(jù),data=None 導(dǎo)致一定會進(jìn)入循環(huán),也就導(dǎo)致 sleep 一定至少會執(zhí)行一次,帶來不必要的延時。知錯就改,只要把 data=None 改成 data=robot.get_xxx() 就可以了。
再次測試,但是問題依然存在,rpc 服務(wù)端的延時頂多幾十毫秒,websocket 客戶端那邊是一兩秒的問題。沒別的辦法加日志吧,在 rpc 調(diào)用前后加上日志,發(fā)現(xiàn)一次 rpc 調(diào)用就要兩秒多,為進(jìn)一步定位問題,在 rpc 服務(wù)端也加上日志。試了幾次,結(jié)果如下:
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 客戶端發(fā)起請求到服務(wù)端收到請求居然花了兩秒多?這也太離譜了。。。
正當(dāng)我懷疑 xmlrpc 庫到底靠不靠譜的時候,找到看一篇帖子:
真是救命稻草,當(dāng)我把 rpc 客戶端的 ip 地址換成 127.0.0.1 之后,還真就解決了。一次調(diào)用幾十毫秒就完成了:
before rpc: 1763367422.9848952 before get: 1763367422.9868922 after get: 1763367422.9868922 after rpc: 1763367422.9880338
這才正常嘛,不過這個坑是真坑爹啊。
其實(shí)這個問題也問過 AI,它堅持說是 getfqdn 反解 DNS 的問題,還給了一段測試代碼:
import socket, time
t0 = time.perf_counter()
socket.getfqdn('localhost') # 模擬 xmlrpc 內(nèi)部調(diào)用
print("getfqdn 耗時:", time.perf_counter() - t0)但是實(shí)際上這段代碼運(yùn)行起來非??欤?/p>
getfqdn 耗時: 0.012044099974445999
帖子里也說了跳過 getfqdn 并沒有用,所以應(yīng)該不是它的問題。
到此這篇關(guān)于python xmlrpc踩坑記錄及解決方案的文章就介紹到這了,更多相關(guān)python xmlrpc內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Pytorch自定義Dataset和DataLoader去除不存在和空數(shù)據(jù)的操作
這篇文章主要介紹了Pytorch自定義Dataset和DataLoader去除不存在和空數(shù)據(jù)的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03
pandas如何解決excel科學(xué)計數(shù)法問題
這篇文章主要介紹了pandas如何解決excel科學(xué)計數(shù)法問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11
利用Python如何將數(shù)據(jù)寫到CSV文件中
在數(shù)據(jù)分析中經(jīng)常需要從csv格式的文件中存取數(shù)據(jù)以及將數(shù)據(jù)寫書到csv文件中。下面這篇文章主要給大家介紹了關(guān)于利用Python如何將數(shù)據(jù)寫到CSV文件中的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-06-06
Python實(shí)現(xiàn)多張圖片合成文字的效果
前段時間看到有人問如何使用Python實(shí)現(xiàn)多張圖片組成文字的效果?覺得還挺有意思,于是嘗試做了一下,剛好趕上端午節(jié),所以打算從網(wǎng)上下載1000張王心凌的照片,組成端午安康的字樣,感興趣的可以了解一下2022-06-06
基于Python實(shí)現(xiàn)一鍵群發(fā)郵件并自動收發(fā)附件功能
在職場中,郵件是主要的溝通工具,但你有沒有被它拖垮過效率?每月需要向幾百個客戶郵件群發(fā)促銷信息,手動一封封發(fā)送,耗時巨大,需要定期發(fā)送提醒或通知,卻總是忘記定時郵件,導(dǎo)致工作延誤,將手把手教你如何基于Python實(shí)現(xiàn)一鍵群發(fā)郵件并自動收發(fā)附件功能2025-11-11

