node.js와 Python의 결합
Node.js는 우리의 웹 프로젝트와 완벽하게 일치하지만 Python을 선호하는 계산 작업은 거의 없습니다.우리는 그들을 위한 파이썬 코드도 이미 가지고 있습니다.속도에 대해 매우 우려하고 있습니다. 비동기식 논블로킹 방식으로 node.js에서 파이썬을 "worker"라고 부르는 가장 우아한 방법은 무엇입니까?
이것은 0MQ가 적합한 시나리오처럼 들립니다.TCP나 유닉스 소켓을 사용하는 것과 유사한 메시징 프레임워크이지만 훨씬 강력합니다(http://zguide.zeromq.org/py:all) .
제로MQ를 사용하여 꽤 잘 작동하는 RPC 프레임워크를 제공하는 라이브러리가 있습니다.제로RPC(http://www.zerorpc.io/) )라고 합니다.안녕하세요 세상입니다.
Python "Hello x" 서버:
import zerorpc
class HelloRPC(object):
'''pass the method a name, it replies "Hello name!"'''
def hello(self, name):
return "Hello, {0}!".format(name)
def main():
s = zerorpc.Server(HelloRPC())
s.bind("tcp://*:4242")
s.run()
if __name__ == "__main__" : main()
node.js 클라이언트:
var zerorpc = require("zerorpc");
var client = new zerorpc.Client();
client.connect("tcp://127.0.0.1:4242");
//calls the method on the python object
client.invoke("hello", "World", function(error, reply, streaming) {
if(error){
console.log("ERROR: ", error);
}
console.log(reply);
});
또는 그 반대의 node.js 서버:
var zerorpc = require("zerorpc");
var server = new zerorpc.Server({
hello: function(name, reply) {
reply(null, "Hello, " + name, false);
}
});
server.bind("tcp://0.0.0.0:4242");
그리고 파이썬 클라이언트는
import zerorpc, sys
c = zerorpc.Client()
c.connect("tcp://127.0.0.1:4242")
name = sys.argv[1] if len(sys.argv) > 1 else "dude"
print c.hello(name)
node.js와 Python 서버 간의 통신을 위해 두 프로세스가 동일한 서버에서 실행되는 경우 Unix 소켓을 사용하고 그렇지 않은 경우 TCP/IP 소켓을 사용합니다.마샬링 프로토콜의 경우 JSON 또는 프로토콜 버퍼를 사용합니다.스레드된 Python이 병목 현상으로 나타나는 경우 do node.js와 동일한 이벤트 기반 동시성을 제공하는 Twisted Python을 사용하는 것을 고려하십시오.
모험심이 강하다면 클로저(클로저스크립트, 클로저-파이)를 배우면 Java, JavaScript(node.js 포함), CLR 및 Python에서 기존 코드와 실행되고 상호 운용되는 동일한 언어를 얻을 수 있습니다.또한 클로저 데이터 구조를 사용하면 우수한 마샬링 프로토콜을 얻을 수 있습니다.
Python 작업자를 별도의 프로세스(장기 실행 중인 서버 유형 프로세스 또는 요청 시 생성된 하위 프로세스)에 배치하면 node.js 측에서 Python 작업자와의 통신이 비동기화됩니다.UNIX/TCP 소켓 및 stdin/out/err 통신은 본질적으로 비동기 노드입니다.
저는 think.js를 thoonk.py 과 함께 사용하여 많은 성공을 거두었습니다.Thunk는 Redis(메모리 내 키 값 저장소)를 활용하여 커뮤니케이션을 위한 피드(게시/구독), 대기열 및 작업 패턴을 제공합니다.
유닉스 소켓이나 직접 tcp 소켓보다 더 나은 이유는 무엇입니까?전체적인 성능은 다소 저하될 수 있지만 Thoonk는 소켓을 수동으로 처리하는 것을 단순화하는 매우 간단한 API를 제공합니다.Thunk는 또한 Python 작업자의 새 인스턴스를 스핀업하여 동일한 redis 서버에 연결하기 때문에 성능을 향상시키기 위해 Python 작업자를 확장할 수 있는 분산 컴퓨팅 모델을 구현하는 것을 매우 단순하게 만듭니다.
Apache Respret http://thrift.apache.org/ 도 고려해 보겠습니다.
여러 프로그래밍 언어를 연결할 수 있으며, 효율성이 높고 비동기 또는 동기 호출을 지원합니다.여기에서 전체 기능 보기 http://thrift.apache.org/docs/features/
다중 언어는 향후 계획에 유용할 수 있습니다. 예를 들어 나중에 C++에서 계산 작업의 일부를 수행하려면 Surgeft를 사용하여 혼합에 추가하는 것이 매우 쉽습니다.
예를 들어, 백그라운드 작업을 발송하고 처리된 후 비동기식으로 결과를 얻을 수 있는 훌륭한 방법을 제공하는 우수한 기어맨을 사용하여 작업 대기열을 사용하는 것이 좋습니다.
Digg(다른 많은 제품 중에서도)에서 많이 사용되는 이점은 모든 언어의 근로자가 모든 언어의 고객과 대화할 수 있는 강력하고 확장 가능하며 강력한 방법을 제공한다는 것입니다.
2019년 업데이트
이를 달성하기 위한 몇 가지 방법이 있으며, 복잡성이 증가하는 순서대로 나열하면 다음과 같습니다.
- 파이썬 셸, 당신은 파이썬 콘솔에 스트림을 쓰고 그것은 당신에게 답장을 쓸 것입니다.
- Redis Pub Sub, 노드 js 게시자가 데이터를 푸시하는 동안 Python에서 채널 수신을 할 수 있습니다.
- 노드가 클라이언트 역할을 하고 Python이 서버 역할을 하는 웹 소켓 연결 또는 그 반대의 경우
- Express/Flask/Tornado 등과의 API 연결은 상대방이 쿼리할 수 있도록 노출된 API 끝점과 별도로 작동합니다.
접근법 1 Python Shell 가장 간단한 접근법
source.js 파일
const ps = require('python-shell')
// very important to add -u option since our python script runs infinitely
var options = {
pythonPath: '/Users/zup/.local/share/virtualenvs/python_shell_test-TJN5lQez/bin/python',
pythonOptions: ['-u'], // get print results in real-time
// make sure you use an absolute path for scriptPath
scriptPath: "./subscriber/",
// args: ['value1', 'value2', 'value3'],
mode: 'json'
};
const shell = new ps.PythonShell("destination.py", options);
function generateArray() {
const list = []
for (let i = 0; i < 1000; i++) {
list.push(Math.random() * 1000)
}
return list
}
setInterval(() => {
shell.send(generateArray())
}, 1000);
shell.on("message", message => {
console.log(message);
})
destination.py 파일
import datetime
import sys
import time
import numpy
import talib
import timeit
import json
import logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
size = 1000
p = 100
o = numpy.random.random(size)
h = numpy.random.random(size)
l = numpy.random.random(size)
c = numpy.random.random(size)
v = numpy.random.random(size)
def get_indicators(values):
# Return the RSI of the values sent from node.js
numpy_values = numpy.array(values, dtype=numpy.double)
return talib.func.RSI(numpy_values, 14)
for line in sys.stdin:
l = json.loads(line)
print(get_indicators(l))
# Without this step the output may not be immediately available in node
sys.stdout.flush()
참고: source.js 파일과 동일한 수준의 subscriber라는 폴더를 만들고 그 안에 destination.py 을 넣습니다.가상 환경을 변경하는 것을 잊지 마십시오.
2023년 업데이트
python을 nodejs와 함께 사용할 수 있는 라이브러리를 만듭니다.
Javascript 라이브러리: https://github.com/7HR4IZ3/js_bridge
파이썬 라이브러리: https://github.com/7HR4IZ3/py_bridge
Javascript에서 예제
const { python } = require("js_bridge");
const py = python();
async function myPythonFunction() {
let math = await py.import("math");
let result = await math.sqrt(16);
console.log(result);
}
myPythonFunction();
Python의 예
from py_bridge import nodejs
node1 = nodejs(port=7000)
node2 = nodejs(port-7001)
node1.setup(name="my_node")
node2.setup(name="nodejs2") # name parameter is for imports
node1.console.log("Hello from node1")
node2.console.log("Hello from node2")
fs = node1.require("fs") # also supports 'from my_node import fs'
print(fs.readSync("./mytext.txt"))
언급URL : https://stackoverflow.com/questions/10775351/combining-node-js-and-python
'programing' 카테고리의 다른 글
다국어 데이터베이스 설계를 위한 모범 사례는 무엇입니까? (0) | 2023.07.26 |
---|---|
표에 날짜 열이 없는 경우 MariaDB에서 최근 30일 레코드 양식 표를 찾는 방법 (0) | 2023.07.26 |
중요 종속성: require 함수는 종속성을 정적으로 추출할 수 없는 방식으로 사용됩니다. (0) | 2023.07.26 |
jQuery에서 입력[type=text]의 값 변경 감지 (0) | 2023.07.26 |
jQuery에서 지정된 클래스 없이 모든 요소를 선택하려면 어떻게 해야 합니까? (0) | 2023.07.26 |