重い処理タスクをワーカー サーバーに送信する Web サイトがあります。現在、ワーカー サーバーは 1 つだけですが、将来的にはさらに追加される予定です。これらのジョブは非常に時間がかかります (5 分~1 時間かかります)。アイデアは、新しいワーカー サーバーを構築するだけで、システム全体の容量を増やすのに十分な構成にすることです。Web サーバー部分で追加の構成を行う必要はありません。
現在、PUSH/PULL アーキテクチャで python-zeromq を使用して基本的な実装を行っています。
新しいジョブ リクエストがあるたびに、Web サーバーはソケットを作成し、いずれかのワーカーに接続してジョブを送信します (応答は必要ありません。これはファイア アンド フォーゲット タイプのジョブです)。
context = zmq.Context()
socket = context.socket(zmq.PUSH)
socket.connect("tcp://IP:5000")
socket.send(msg)
そしてワーカー側では、これは常に実行されています:
context = zmq.Context()
socket = context.socket(zmq.PULL)
# bind to port in it's own IP
socket.bind("tcp://IP:5000")
print("Listening for messages...")
while True:
msg = socket.recv()
<do something>
今、私はこれをさらに調べましたが、これは正しい方法ではないと思います。新しいワーカー サーバーを追加するには、その IP を Web サーバー スクリプトに追加する必要があるため、両方に接続します。
私はむしろ、Webサーバーに永続的なソケットをオンにして(毎回作成するのではなく)、代わりにワーカーをWebサーバーに接続させることを好みます。ここのような並べ替え: https://github.com/taotetek/blog_examples/blob/master/python_multiprocessing_with_zeromq/workqueue_example.py
要するに、上記とは対照的に、Webサーバーのソケットは独自のIPにバインドされ、ワーカーはそれに接続します。ジョブはラウンドロビンスタイルで送信されると思います.
しかし、私が心配しているのは、Web サーバーが再起動されたり (かなり頻繁に発生すること)、しばらくオフラインになったりするとどうなるかということです。zeromq を使用すると、すべてのワーカー接続がハングしますか? どういうわけか無効になりますか?Web サーバーがダウンした場合、現在のキューは消えますか?
現在のセットアップでは、問題なく動作しているように見えますが、これを行う正しい (そして複雑すぎない) 方法が 100% 確実というわけではありません。