AMQP Nginxから直接RabbitMQにメッセージを送信する(組み込みPerl)

製品ではAMQPを使用しています。 便利で、拡張性が向上し、複雑なシステムに新しいモジュールと拡張機能を事実上問題なく追加できます。 ブローカーとして、RabbitMQが使用されます。 Nginxはフロントエンドとして使用されます。 最近まで、どこでもブローカーと連携するためにphp-amqpとlibrabbitmq-0.0.1を使用していました。 しかし、システムのいくつかの部分では、これは私たちにとって冗長に思えました。



挑戦する



PHPをバイパスして、フロントエンドから直接RabbitMQブローカーにメッセージを送信する方法を学びます。 可能な限り非同期的に。 プログラミングと松葉杖を最小限に抑えます。

特定の統計情報を生成し、データをさらに転送し、それ以上何もしないシステムのサービス部分を最適化するために、すぐに予約します。 コンテンツはなく、ユーザーに何も提供する必要はありません。 また、遅いバックエンドはなく、どこでもブロックされるものはありません。



解決の方法。



Nginx用に多くのモジュールが作成さていますOpenrestyアセンブリのモジュールを既に使用しているか、使用する予定です。

しかし、特にamqpを使用するための準備はほとんどありません。

インターネットもほとんど空です。このトピックは2010年に人気がありましたが、今年は消滅しました。

0MQ用のNginxモジュールとRabbitMQ用のプラグインがありますが、ビルドされていますが機能しません。 そして再び、2010。



-Nginx用の独自のモジュールを作成できます。

-luaを使用できますが、既製のバインダーはありません。作成する必要があります。

-他の何かを使用することができます。たとえば、task約し、そのようなタスクのためにシャープにします。

しかし、これはすべて長く、私たちはまだプログラマーではありません)))



Perlでlibrabbitmqのラッパーが見つかりました。 幸いなことに、nginxは組み込みperlを実行できます。



私たちはすべてdebでパッケージ化しています。nginx= 1.2.4でこの特定のモジュールをビルドしても問題はありません。

--with-http_perl_moduleキーが使用されていることを確認する必要があります。 そして、組み立てられたモジュールのファイルがパスで検索されること。 たとえば、次のようになりました。

objs/src/http/modules/perl/blib/lib/nginx.pm usr/lib/perl/5.14

objs/src/http/modules/perl/blib/arch/auto/nginx/nginx.so usr/lib/perl/5.14/auto/nginx









ネット:: ここから取ったRabbitMQ



nginx.confの一部

 http { perl_modules /etc/nginx/perl; perl_require rmqsux.pm; ...
      
      







testsite.confの一部

 server { listen 80; server_name test01.dev; location / { perl rmqsux::amqppull; } }
      
      







サンプルスクリプト:

 whoareyou@test01:/etc/nginx/perl# cat rmqsux.pm package rmqsux; use nginx; use Net::RabbitMQ; use vars; rmqsux::connectmyrabbit; sub try (&@) { my($try,$catch) = @_; eval { &$try }; if ($@) { local $_ = $@; &$catch; } } sub catch (&) { $_[0] } sub connectmyrabbit { try { $mq = Net::RabbitMQ->destroy(); } catch { $mq = Net::RabbitMQ->new(); }; $mq->connect("192.168.1.100", { user => "test", password => "test", vhost => "testhost" }); $mq->channel_open(1); } sub disconnectmyrabbit { $mq->disconnect(); my $r = shift; $r->send_http_header("text/html"); $r->print("disconnected\n<br/>"); $r->status(200); } sub amqppull { my $r = shift; try { $mq->publish(1, "test", "qawsed"); } catch { rmqsux::connectmyrabbit; $mq->publish(1, "test", "oops died here"); }; $r->send_http_header("text/html"); return OK if $r->header_only; $r->print("send completed\n<br/>"); $r->status(200); $r->flush; } 1; __END__
      
      







総合テストに失敗しました 。 あなたはもっと匂うことができますが、rabbitmqは特別に調整する必要があります。

 silenkov@sn00p:/home$ ab -c 300 -n 100000 http://test01.dev/ This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking test01.dev (be patient) Completed 10000 requests Completed 20000 requests Completed 30000 requests Completed 40000 requests Completed 50000 requests Completed 60000 requests Completed 70000 requests Completed 80000 requests Completed 90000 requests Completed 100000 requests Finished 100000 requests Server Software: nginx Server Hostname: test01.dev Server Port: 80 Document Path: / Document Length: 20 bytes Concurrency Level: 300 Time taken for tests: 10.402 seconds Complete requests: 100000 Failed requests: 0 Write errors: 0 Total transferred: 13500000 bytes HTML transferred: 2000000 bytes Requests per second: 9613.40 [#/sec] (mean) Time per request: 31.206 [ms] (mean) Time per request: 0.104 [ms] (mean, across all concurrent requests) Transfer rate: 1267.39 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 14 126.9 2 3007 Processing: 1 14 30.0 9 1543 Waiting: 1 13 30.0 8 1543 Total: 3 29 136.8 11 3230 Percentage of the requests served within a certain time (ms) 50% 11 66% 15 75% 16 80% 16 90% 20 95% 49 98% 56 99% 1009 100% 3230 (longest request)
      
      





反復回数のうち、結果は5%以内で変動します。



多数のphp + librabbitmqにより300〜600 rpsが得られましたが、これは主にphpワーカーの最終的な数の問題です。



問題は次のとおりです。

-負荷がかかると、接続が頻繁に中断するため、スクリプト内でのこのようなトリッキーな動き)このエラーのしきい値を特定できませんでした。 最大6000 rps、何も確実に引き裂かれません。

-非同期で動作するかどうかは不明ですか? luaのすべてを書き換えることができれば、間違いなくそうなります。

-このアプローチ全体の問題はまだ明確ではありません。

-このマシンには封じ込めメカニズムが必要です。 Nginxは、どのバックエンドよりも高速です。 彼は少なくとも10万RPSを生きていますが、バックエンドはなくなりました。 ここではlimit_req_zoneが適しているようですが、負荷プロファイルにバーストを選択する必要があります。



一般に、パフォーマンスは非常に楽しいものです。 メッセージは失われず、4日目は何も漏れていません。 これですべてのテストが終了し、消費を続けます。 そこですべてを解析し、Postgresに詰め込む必要があります。Nginxにもこのモジュールがあり、すべてうまくいきます。



自転車に関するコメントは控えてください。 システムのそのような部分には多くのrpと非常に少ないリソースがあり、そのようなものを発明する必要があります。



また、私たちはどんな助けやアドバイスにも喜んでいます!



All Articles