次のインフラストラクチャがあります。
メッセージ用のポートでリッスンするNodeJS + Expressプロセス(process 1)を備えたEC2インスタンスがあります。プロセスはメッセージを受信するたびに、SQSキューに送信します。次に、同じマシンに別のプロセスがあり、ロングポーリングを使用してキューを読み取ります(process 2)。キューでメッセージを見つけると、RDSインスタンス上にあるMariaDBデータベースにデータを挿入します。
(明確にするために、メッセージはユーザーによって生成され、プロセス1がリッスンしているエンドポイントに任意の情報を含むことができるデータのチャンクを送信します)
次に、SQSを読み取るプロセス(process 2))をLambda関数に入れて、キューに書き込み、キューから読み取るものは完全に独立しています。問題は、これが可能かどうかわからないことです。
Lambda関数はイベントに応答して呼び出され、現在サポートされているイベントはS3、SNS、SES、DynamoDB、Kinesis、Cognito、CloudWatchおよびCloudformationですが、NOT SQS。
SNS通知を使用してLambda関数を呼び出すことを考えていたため、メッセージがキューにプッシュされるたびにSNS通知が起動され、Lambda関数が呼び出されましたが、少し遊んだ後、 SQSからSNS通知を作成します。SNS通知をキューに書き込むことのみが可能です。
今はどうすればいいのかわからないので、行き詰まっています。 AWSサービスの現在の制限により、このインフラストラクチャを作成することは不可能だと感じています。私がやりたいことをする別の方法はありますか、それとも私は行き止まりにいますか?
私が行ったいくつかの研究で私の質問を拡張するために、このgithubリポジトリはLambda関数からSQSキューを読み取る方法を示していますbutlambda関数は機能しますコマンドラインから起動された場合のみ:
https://github.com/robinjmurphy/sqs-to-lambda
Readmeで、著者は次のように述べています。
更新:Lambdaは、SNS通知をイベントソースとしてサポートするようになりました。これにより、このハッキングはSNS通知にまったく不要になります。 Lambda関数を使用してSQSキューのジョブを処理するという考えが気に入った場合は、それでも役立つ場合があります。
しかし、これは私の問題を解決しないと思います。SNS通知はLambda関数を呼び出すことができますが、メッセージがSQSキューで受信されたときに通知を作成する方法がわかりません。
ありがとう
ドットを接続するために使用できるいくつかの戦略があります。(A)同期またはRun-Sleep-Runは、SNS、SQS、Lambda間のデータプロセスフローを維持します。
戦略1:Lambda関数でSNSをリッスンしてリアルタイムで処理します[SQSキューはSNSトピックをサブスクライブできることに注意してください。 するだろう ロギング/監査/再試行処理に役立つ場合があります]
戦略2:データがSQSキューに供給されていると仮定します。 2つのLambda関数[Feeder&Worker]で試すことができます。
Feederは
scheduled lambda function
になり、SQS(存在する場合)からアイテムを取得してSNSトピックとしてプッシュします(そしてそれを永久に続けます)。Workerは
actual data processing
を実行するSNSトピックをリッスンするようにリンクされます
これで、SQSメッセージを使用してAWS Lambda関数をトリガーできます。さらに、メッセージポーリングサービスを実行したり、SQSからSNSへのマッピングを作成したりする必要がなくなりました。
私は同様の状況にありました(そして今、解決策が展開されています)。私は以下の方法でそれに対処しました:
つまり、イベントをSNSに公開します。次に、ラムダとSQSにファンアウトします。
注:これは、特定の順序で処理する必要があるイベントには適用されません。
以下のようないくつかの落とし穴(可能な解決策あり)があること:
両方の場合の解決策は、SQSキューのロングポーリングを行うことです。しかし、これはあなたのラムダ法案をより高価にします。
注1
ショートポーリングは、重み付けされたランダムなマシンのセットがReceiveMessage呼び出しでサンプリングされるデフォルトの動作です。つまり、サンプリングされたマシンのメッセージのみが返されます。キュー内のメッセージ数が少ない(1000未満)場合は、ReceiveMessage呼び出しごとに要求した数よりも少ないメッセージを取得する可能性があります。キュー内のメッセージ数が非常に少ない場合、特定のReceiveMessage応答でメッセージを受信できない可能性があります。その場合は、リクエストを繰り返す必要があります。 http://docs.aws.Amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html
AWS SQSはAmazonの最も古い製品の1つであり、2018年6月までのポーリング(ロングおよびショート)のみをサポートしていました。 この回答 で説明したように、AWS SQSはSQSでの新しいメッセージの到着時にラムダ関数をトリガーします。これに関する完全なチュートリアルは this document にあります。
私は以前、さまざまなメカニズムを使用してこの問題に取り組んでいました。以下に、使用できるいくつかのアプローチを示します。
Lambdaで簡単なポーリングアプリケーションを開発し、AWS CloudWatchを使用して5分ごとに呼び出すことができます。 CloudWatchイベントを使用して短いダウンタイムでラムダを呼び出すことにより、これをほぼリアルタイムで行うことができます。このためには、 this tutorial または this tutorial を使用します。 (これはラムダでより多くの費用がかかる可能性があります)
メッセージを保持したり、配信順序を保証したりする必要がない場合は、SQSは冗長であると考えることができます。 AWS SNS(シンプルな通知サービス)を使用してラムダ関数を直接呼び出し、必要な処理を行うことができます。このためには this tutorial を使用します。これはリアルタイムで行われます。ただし、主な欠点は、特定の時間にリージョンごとに開始できるラムダの数です。 this を読み、このアプローチに従う前に制限を理解してください。それにもかかわらず、AWS SNSは配信の順序を保証します。また、SNSはHTTPエンドポイントを直接呼び出し、DBにメッセージを保存できます。
いくつかの同様の要件があったため、ライブラリを構築し、SQSからLambda非同期に役立つようにオープンソース化することになりました。これが特定の要件を満たすかどうかはわかりませんが、一見の価値があると思います: https://read.iopipe.com/sqs-lambda-teaming-up-92c4096be49c