當前位置:首頁 » 編程語言 » nodejs調用python

nodejs調用python

發布時間: 2025-10-14 04:49:57

A. 微服務跨語言調用(摘選)

微服務架構已成為目前互聯網架構的趨勢,關於微服務的討論,幾乎占據了各種技術大會的絕大多數版面。國內使用最多的服務治理框架非阿里開源的 bbo 莫屬,千米網也選擇了 bbo 作為微服務治理框架。另一方面,和大多數互聯網公司一樣,千米的開發語言是多樣的,大多數後端業務由 java 支撐,而每個業務線有各自開發語言的選擇權,便出現了 nodejs,python,go 多語言調用的問題。

跨語言調用是一個很大的話題,也是一個很有挑戰的技術活,目前業界經常被提及的解決方案有如下幾種,不妨拿出來老生常談一番:

當我們再聊跨語言調用時我們在聊什麼?縱觀上述幾個較為通用,成熟的解決方案,可以得出結論:解決跨語言調用的思路無非是兩種:

如果一個新型的團隊面臨技術選型,我認為上述的方案都可以納入參考,可考慮到遺留系統的兼容性問題

舊系統的遷移成本

這也關鍵的選型因素。我們做出的第一個嘗試,便是在 RPC 協議上下功夫。

通用協議的跨語言支持

springmvc的美好時代

springmvc

springmvc

在沒有實現真正的跨語言調用之前,想要實現「跨語言」大多數方案是使用 http 協議做一層轉換,最常見的手段莫過於藉助 springmvc 提供的 controller/restController,間接調用 bbo provider。這種方案的優勢和劣勢顯而易見

通用協議的支持

事實上,大多數服務治理框架都支持多種協議,bbo 框架除默認的 bbo 協議之外,還有當當網擴展的 rest協議和千米網擴展的 json-rpc 協議可供選擇。這兩者都是通用的跨語言協議。

rest 協議為滿足 JAX-RS 2.0 標准規范,在開發過程中引入了 @Path,@POST,@GET 等註解,習慣於編寫傳統 rpc 介面的人可能不太習慣 rest 風格的 rpc 介面。一方面這樣會影響開發體驗,另一方面,獨樹一幟的介面風格使得它與其他協議不太兼容,舊介面的共生和遷移都無法實現。如果沒有遺留系統,rest 協議無疑是跨語言方案最簡易的實現,絕大多數語言支持 rest 協議。

和 rest 協議類似,json-rpc 的實現也是文本序列化&http 協議。bbox 在 restful 介面上已經做出了嘗試,但是 rest 架構和 bbo 原有的 rpc 架構是有區別的,rest 架構需要對資源(Resources)進行定義, 需要用到 http 協議的基本操作 GET、POST、PUT、DELETE。在我們看來,restful 更合適互聯網系統之間的調用,而 rpc 更適合一個系統內的調用。使用 json-rpc 協議使得舊介面得以兼顧,開發習慣仍舊保留,同時獲得了跨語言的能力。

千米網在早期實踐中採用了 json-rpc 作為 bbo 的跨語言協議實現,並開源了基於 json-rpc 協議下的 python 客戶端 bbo-client-py 和 node 客戶端 bbo-node-client,使用 python 和 nodejs 的小夥伴可以藉助於它們直接調用 bbo-provider-java 提供的 rpc 服務。系統中大多數 java 服務之間的互相調用還是以 bbo 協議為主,考慮到新舊協議的適配,在不影響原有服務的基礎上,我們配置了雙協議。

bbo 協議主要支持 java 間的相互調用,適配老介面;json-rpc 協議主要支持異構語言的調用。

定製協議的跨語言支持

微服務框架所謂的協議(protocol)可以簡單理解為:報文格式和序列化方案。服務治理框架一般都提供了眾多的協議配置項供使用者選擇,除去上述兩種通用協議,還存在一些定製化的協議,如 bbo 框架的默認協議:bbo 協議以及 motan 框架提供的跨語言協議:motan2。

motan2協議的跨語言支持

                                                                                                            motan2

motan2

motan2 協議被設計用來滿足跨語言的需求主要體現在兩個細節中—MetaData 和 motan-go。在最初的 motan 協議中,協議報文僅由 Header+Body 組成,這樣導致 path,param,group 等存儲在 Body 中的數據需要反序列得到,這對異構語言來說是很不友好的,所以在 motan2 中修改了協議的組成;weibo 開源了 motan-go ,motan-php ,motan-openresty ,並藉助於 motan-go 充當了 agent 這一翻譯官的角色,使用 simple 序列化方案來序列化協議報文的 Body 部分(simple 序列化是一種較弱的序列化方案)。

                                                                                                        agent

agent

仔細揣摩下可以發現這么做和雙協議的配置區別並不是大,只不過這里的 agent 是隱式存在的,與主服務共生。明顯的區別在於 agent 方案中異構語言並不直接交互。

bbo協議的跨語言支持

bbo 協議設計之初只考慮到了常規的 rpc 調用場景,它並不是為跨語言而設計,但跨語言支持從來不是只有支持、不支持兩種選擇,而是要按難易程度來劃分。是的,bbo 協議的跨語言調用可能並不好做,但並非無法實現。千米網便實現了這一點,nodejs 構建的前端業務是異構語言的主戰場,最終實現了 bbo2.js,打通了 nodejs 和原生 bbo 協議。作為本文第二部分的核心內容,重點介紹下我們使用 bbo2.js 幹了什麼事。

Dubbo協議報文格式

                                                                                                        bbo協議

bbo協議

bbo協議報文消息頭詳解:

magic:類似java位元組碼文件里的魔數,用來判斷是不是 bbo 協議的數據包。魔數是常量 0xdabb

flag:標志位, 一共8個地址位。低四位用來表示消息體數據用的序列化工具的類型(默認 hessian),高四位中,第一位為 1 表示是 request 請求,第二位為 1 表示雙向傳輸(即有返回 response),第三位為 1 表示是心跳 ping 事件。

status:狀態位, 設置請求響應狀態,bbo 定義了一些響應的類型。具體類型見com.alibaba.bbo.remoting.exchange.Response

invoke id:消息 id, long 類型。每一個請求的唯一識別 id(由於採用非同步通訊的方式,用來把請求 request 和返回的 response 對應上)

body length:消息體 body 長度, int 類型,即記錄 Body Content 有多少個位元組

body content:請求參數,響應參數的抽象序列化之後存儲於此。

協議報文最終都會變成位元組,使用 tcp 傳輸,任何語言只要支持網路模塊,有類似 Socket 之類的封裝,那麼通信就不成問題。那,跨語言難在哪兒?以其他語言調用 java 來說,主要有兩個難點:

ps:bbo 協議通訊demo( https://github.com/lexburner/Dubbojs-Learning )

B. Electron 框架中調用 Python 構建桌面應用

不同的語言、框架都有自己擅長的領域:Electron 基於 Chromium 和 Node.js 能以 Web 開發的模式打造桌面應用,開發用戶界面又快捷又簡單;Python 則在數據分析、自動化腳本等領域有非常多的應用。兩者的社區生態都十分強大,由兩者共同構建應用,在界面開發、功能、性能上能夠強強聯合;

為了簡單驗證技術可行性,我們來編寫一個 Demo:

目的:驗證 Electron 打造的桌面應用能夠調用 Python,思路是使用 RPC 或 HTTP 或 WebSocket 進行通信

Demo 功能:輸入 x、y 坐標,程序會移動滑鼠到屏幕的 x,y 位置(通過 python 庫 pyautogui 實現)

Demo 運行環境:MacOS、pyInstaller: 版本 4.5.1、python: 版本 3.9.7

源碼:-------- 項目源碼 --------

注意:移動滑鼠需要授予應用控制許可權,在 MacOS 下設置 偏好設置 -> 隱私 -> 輔助功能 -> 允許對應的應用。

技術棧:NodeJS、Electron、Python、aiohttp(HTTP、WebSocket)、pyautogui(控制滑鼠)

為了使 NodeJS 和 Python 能夠通信,Python 需要啟動一個本地通信服務,Demo 中 py/api.py 能夠啟動一個本地 HTTP 服務:

然後我們需要執行 Python 代碼以啟動服務,為了使 NodeJS 可以執行 Python,我們使用 pyinstaller 將 Python 打包成可執行文件:

Python 啟動了本地 HTTP 服務後,Chromium 和 Node.js 就可以通過請求的方式,與 python 連接通信了:

簡單來說三個步驟:

本項目只是一個驗證思路的 Demo,真的需要在項目上實踐,還需要考慮以下幾個點:

應該使用 RPC 通信而不是 HTTP 或者 WebSocket,Demo 使用 HTTP 只是搭建方便。實踐中在建立連接、保持連接、異常重連都需要編寫更多的邏輯來處理。為什麼 Demo 沒有使用 zerorpc? 這個庫已經 4 年沒有維護了,不兼容新版 NodeJS。

項目通過 pyinstaller 打包成可執行文件來調用 python。實際上其他能編譯為可執行文件的語言也一樣。還可以使用 WebAssembly 將其他語言編譯成 .wasm,在 NodeJS 中引入執行。

熱點內容
java返回this 發布:2025-10-20 08:28:16 瀏覽:710
製作腳本網站 發布:2025-10-20 08:17:34 瀏覽:972
python中的init方法 發布:2025-10-20 08:17:33 瀏覽:681
圖案密碼什麼意思 發布:2025-10-20 08:16:56 瀏覽:833
怎麼清理微信視頻緩存 發布:2025-10-20 08:12:37 瀏覽:741
c語言編譯器怎麼看執行過程 發布:2025-10-20 08:00:32 瀏覽:1081
郵箱如何填寫發信伺服器 發布:2025-10-20 07:45:27 瀏覽:312
shell腳本入門案例 發布:2025-10-20 07:44:45 瀏覽:192
怎麼上傳照片瀏覽上傳 發布:2025-10-20 07:44:03 瀏覽:879
python股票數據獲取 發布:2025-10-20 07:39:44 瀏覽:837