14

私は、それぞれが入力を受け取り、出力を生成するいくつかのC++プログラムを含むプロジェクトに取り組んでいます。データ(数十から数百バイト、おそらくJSON)は基本的に(非同期に)一方向に流れ、プログラムはLAN上のさまざまなLinuxコンピューターに配置する必要があります。

データは一方向にしか流れないので、HTTPのようなトランザクションモデルは必要ないと思います。メッセージキューモデル(ファイアアンドフォーゲット)が最も理にかなっており、各プログラムのロジックを単純化する必要があると思います。メッセージがリモートキューに正常に追加されたことに注意するだけでおそらく十分です。

私が探しているのは、このメッセージキューをCまたはC++で実装する方法に関する推奨事項です。POSIXおよびBoostメッセージキューは単一のホストに制限されているようであり、RabbitMQ弱いC / C ++サポートを持っているようであり、MQ4CPPはビジネスクリティカルな役割に対して不十分にサポートされているようです。私はこれについて間違っていますか?Boost ASIOACE、または自分でソケットコードを書くのはどうですか?ご提案をお待ちしております。

4

6 に答える 6

12

単純なメッセージングのサポートという点では、ZeroMQに勝るものはありません。多くの言語バインディングで利用可能であり、単純な送受信からpub / sub、ファンアウト、さらにはメッセージングパイプラインまですべてをサポートします。コードは簡単に消化でき、パターンの切り替えも非常に簡単です。

Weather Update Serverのサンプル(20の奇妙な言語)を見ると、パブリッシュ/サブスクライブのセットアップを簡単に作成できることがわかります。

zmq::context_t context (1);
zmq::socket_t publisher (context, ZMQ_PUB);
publisher.bind("tcp://*:5556");
publisher.bind("ipc://weather.ipc");

while(1) {
    //  Send message to all subscribers
    zmq::message_t message(20);
    snprintf ((char *) message.data(), 20 ,
        "%05d %d %d", zipcode, temperature, relhumidity);
    publisher.send(message);
}

あまり面倒なことなく、C#とPythonの混合プロセスで使用しました。

于 2012-05-05T02:01:54.657 に答える
2

RabbitMQは、AMQPの実装の1つにすぎません。ApacheQpidまたはC/C++に適した他のバリアントを調査することをお勧めします。私はそれを直接経験したことはありませんが、Cにはlibamqpがあります。要件が正確にはわかりませんが、適切に実装されたAMQPは産業用の強度であり、短時間で手作業で構築するものよりも桁違いに高速で安定している必要があります。

于 2012-05-04T00:46:49.577 に答える
2

個人的には、質問がわかれば、低レベルのTCP接続を使うべきだと思います。それはあなたが望むすべての保証された配信を持っており、かなり良いバークレーソケットAPIを持っています。非常に単純なプロトコル(たとえば、4バイトのNBOメッセージの長さ、nバイトのデータ)を実装する場合は、非常に単純で、非常にカスタマイズ可能で、非常に単純になることがわかりました。これを使用すると、(前述のように)優れたCサポートも得られます(つまり、クラスやメソッドには含まれていませんが、C ++サポートを意味します)。ソケットコードも非常に簡単で、Linux / UNIX / POSIX IO関数の標準非同期フラグを備えた非同期IOがあります(これは他の利点の1つであり、POSIXプログラミングについて何か知っている場合は、基本的にソケットAPIを知っています) 。

ソケットAPIを学習するための最良のリソースの1つは次のとおりです。

  • Beejのネットワークプログラミングガイド:http://beej.us/guide/bgnet/ これは、詳細に加えて全体的なプログラミングモデルが必要な場合に非常に役立ちます。
  • マニュアルページ:関数のシグネチャ、戻り値、引数だけが必要な場合は、これらだけで十分です。Linuxのものは非常によく書かれていて便利manだと思います(証明:私のコンソールを見てくださいman:、、、、、、、、、... )manmanmanmakeman

また、データをネットワーク送信可能にするために、データがJSONであれば、心配する必要はありません。JSONは単なるASCII(またはUTF-8)であるため、長さヘッダーのみを使用してネットワーク経由で生で送信できます。バイナリで複雑なものを送信しようとしているのでない限り、これは完璧なはずです(バイナリで複雑なものが必要な場合は、シリアル化を確認するか、多くの準備をしてくださいSegmentation Fault)。


また、おそらく、ソケットパスを使用する場合は、TCPを使用する必要があります。UDPは一方向の側面を提供しますが、信頼性を高めることは、Linuxカーネルによって提供される最上位のTCPに対して、自家製のソリューションを打ち負かすことですが、TCPは明らかなオプションです。

于 2012-05-03T23:03:14.163 に答える
1

同様のアプリケーションにBoostSerializationとソケット送信を使用しています。シリアル化の例はここにあります:

http://code.google.com/p/cloudobserver/wiki/TutoriaslBoostSerialization

そしてこのページで:

http://www.boost.org/doc/libs/1_38_0/doc/html/boost_asio/examples.html

シリアル化の下に、サーバーとクライアントの作成方法の例があります。特定のポート上に1つのサーバーを作成すると、そのポートと通信できる複数のコンピューター上に複数のクライアントを生成できます。

ブーストシリアル化を使用することの欠点は、シリアル化する単純なデータ構造がある場合、オーバーヘッドが大きくなることですが、それは簡単になります。

于 2012-05-03T22:55:14.697 に答える
1

もう1つの推奨事項は、分散フレームワークOpenCLです。ドキュメントOpenCLC++ Wrapper for APIは、ライブラリに関する詳細情報を提供します。特に、API関数cl::CommandQueueは、ネットワーク設定内のデバイスにキューを作成する場合に役立ちます。

于 2012-05-03T23:11:50.923 に答える
1

もう1つのメッセージングソリューションはICE(http://www.zeroc.com/)です。それはマルチプラットフォーム、多言語です。より多くのRPCアプローチを使用します。

于 2012-05-04T16:40:13.257 に答える