Symfoware

Symfowareについての考察blog

Amazon SQS互換メッセージキュー「ElasticMQ」にPHP + aws-sdkでキューを登録する

ElasticMQにPythonでメッセージの登録、読み取りを行ってみました。
Amazon SQS互換メッセージキュー「ElasticMQ」にPython(boto)からキューの登録

PHPからaws-sdk(v2)を使用し、メッセージを登録、Pythonで読み取ってみます。



サンプルプログラム



登録用のサンプルをCodeIgniterで作成しました。

・controller/Sqs.php


  1. <?php
  2. class Sqs extends CI_Controller {
  3.     
  4.     public function index() {
  5.         
  6.         $view_data = array('msg' => '');
  7.         
  8.         $message = $this->input->post('message');
  9.         if (!empty($message)) {
  10.             
  11.             //キューに登録実行
  12.             $sqs = $this->_connect_sqs();
  13.             $result = $sqs->createQueue(array('QueueName' => 'test_queue'));
  14.             
  15.             //登録用のURLを取得
  16.             $queueUrl = $result->get('QueueUrl');
  17.             
  18.             // メッセージ登録
  19.             $r = $sqs->sendMessage(array(
  20.                 'QueueUrl'    => $queueUrl,
  21.                 'MessageBody' => $message,
  22.             ));
  23.             
  24.             $view_data['msg'] = $message;
  25.         }
  26.         
  27.         $this->load->view('sqs/index', $view_data);
  28.         
  29.     }
  30.     
  31.     
  32.     
  33.     private function _connect_sqs() {
  34.         
  35.         $sqs = Aws\Sqs\SqsClient::factory(array(
  36.             'credentials' => array(
  37.                 'key' => 'dummy',
  38.                 'secret' => 'dummy'
  39.             ),
  40.             'endpoint' => 'http://192.168.1.104:9324',
  41.             'region' => 'elasticmq',
  42.         ));
  43.         
  44.         return $sqs;
  45.     }
  46.     
  47.     
  48. }




・view/sqs/index.php


  1. <html lang="ja">
  2. <head>
  3.     <meta charset="utf-8">
  4.     <title>SQSテスト</title>
  5. </head>
  6. <body>
  7. <form method="POST" action="/sqs">
  8.     <input type="text" id="message" name="message" />
  9.     <input type="submit" value="登録">
  10. </form>
  11. <?php echo $msg ?>
  12. </body>
  13. </html>




適当に文字を入力して登録すると、こんなエラーになります。


An uncaught Exception was encountered

Type: Aws\Common\Exception\TransferException

Message: [curl] 7: Failed to connect to localhost port 9324:
Connection refused [url] http://localhost:9324/queue/test_queue




どうも、登録実行用のQueueUrlを取得すると、アドレスがlocalhostで
返却される模様。

PHPのプログラムがまずいんだろうと思っていたのですが、
ElasticMQ側の設定を変更する必要がありました。

https://github.com/adamw/elasticmq
こちらのドキュメントに、custom.confの設定について記載があります。

ここのhostをQueueUrlとして返却しているのでは?

custom.confを作成して、hostに稼働しているサーバーのIPを指定します。


node-address {
    protocol = http
    host = 192.168.1.104
    port = 9324
    context-path = ""
}




作成したcustom.confを読み込んで起動。


# java -Dconfig.file=custom.conf -jar elasticmq-server-0.8.7.jar




適当な値を登録してみます。

610_01.png

610_02.png


Amazon SQS互換メッセージキュー「ElasticMQ」にPython(boto)からキューの登録
こちらで作成したPythonプログラムで内容を取得してみます。


$ python sample.py
symfoware




うまく行きました。





日本語が登録できない



Pythonでの登録は問題ないので、おそらくaws-sdkの問題だと思うのですが、
日本語(マルチバイト文字)が登録できません。
その他、一部記号も登録できないようです。

試してみると、どうやら
「マルチバイト文字から始まるとダメだが、アルファベットなどから開始し、
続けてマルチバイト文字を登録する場合はOK」という条件の模様。

具体的にはPHP側で「日本語」と登録してもPython側で読み取れませんが、
「A日本語」と登録すると読み出せます。

610_03.png


$ python sample.py
A日本語





ドキュメントを見てみると
sendMessage
MessageAttributesのStringValueを使えば良さそう。


  1. <?php
  2. class Sqs extends CI_Controller {
  3.     
  4.     public function index() {
  5.         
  6.         $view_data = array('msg' => '');
  7.         
  8.         $message = $this->input->post('message');
  9.         if (!empty($message)) {
  10.             
  11.             //キューに登録実行
  12.             $sqs = $this->_connect_sqs();
  13.             $result = $sqs->createQueue(array('QueueName' => 'test_queue'));
  14.             
  15.             //登録用のURLを取得
  16.             $queueUrl = $result->get('QueueUrl');
  17.             
  18.             // メッセージ登録
  19.             $r = $sqs->sendMessage(array(
  20.                 'QueueUrl'    => $queueUrl,
  21.                 'MessageBody' => 'from_php',
  22.                 'MessageAttributes' => array(
  23.                     'jp_string' => array(
  24.                         'StringValue' => $message,
  25.                         'DataType' => 'String',
  26.                     ),
  27.                 ),
  28.             ));
  29.             
  30.             $view_data['msg'] = $message;
  31.         }
  32.         
  33.         $this->load->view('sqs/index', $view_data);
  34.         
  35.     }
  36.     
  37.     
  38.     
  39.     private function _connect_sqs() {
  40.         
  41.         $sqs = Aws\Sqs\SqsClient::factory(array(
  42.             'credentials' => array(
  43.                 'key' => 'dummy',
  44.                 'secret' => 'dummy'
  45.             ),
  46.             'endpoint' => 'http://192.168.1.104:9324',
  47.             'region' => 'elasticmq',
  48.         ));
  49.         
  50.         return $sqs;
  51.     }
  52.     
  53.     
  54. }





読み取り側のPythonはこうなります。


  1. # -*- coding:utf-8 -*-
  2. from boto.sqs import regioninfo
  3. from boto.sqs.message import Message
  4. AWS_ACCESS_KEY='dummy_access_key'
  5. AWS_SECRET_KEY='dummy_secret_key'
  6. queue_name = 'test_queue'
  7. name = "elasticmq"
  8. endpoint = "192.168.1.104"
  9. # エンドポイントをサーバーIPとした仮想のリージョンを作成
  10. fake_region = regioninfo.SQSRegionInfo(name=name, endpoint=endpoint)
  11. # コネクション作成
  12. conn = fake_region.connect(
  13.     aws_access_key_id=AWS_ACCESS_KEY,
  14.     aws_secret_access_key=AWS_SECRET_KEY,
  15.     port=9324,
  16.     is_secure=False
  17. )
  18. # 任意の名前を指定して、キューを取得
  19. queue = conn.create_queue(queue_name)
  20. # 実運用では、これ以降を無限ループとする
  21. # 取得するメッセージの個数を指定して、メッセージを取得
  22. msgs = queue.get_messages(10)
  23. for msg in msgs:
  24.     # 内容を表示
  25.     print msg.get_body()
  26.     
  27.     # アトリビュートの内容を表示
  28.     print msg.message_attributes['jp_string']['string_value']
  29.     
  30.     # 処理したメッセージを削除
  31.     queue.delete_message(msg)




うまく行きました。


$ python sample.py
from_php
日本語


関連記事

テーマ:サーバ - ジャンル:コンピュータ

  1. 2015/03/31(火) 23:59:04|
  2. PHP
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
次のページ