AWS X-Ray
開発者ガイド

AWS Lambda 関数を実装する

Scorekeep は、2 つの AWS Lambda 関数を使用します。1 つ目は、新しいユーザー用にランダムな名前を生成する lambda ブランチからの Node.js 関数です。ユーザーが名前を入力せずにセッションを作成すると、アプリケーションは、AWS SDK for Java で random-name という名前の関数を呼び出します。X-Ray SDK for Java は、計測された AWS SDK クライアントを使用して行われたその他すべての呼び出しのように、Lambda の呼び出しに関する情報をサブセグメントに記録します。

注記

random-name Lambda 関数を実装するには、Elastic Beanstalk 環境の外でその他のリソースを作成する必要があります。詳細については readme、手順については「AWS Lambda との統合」を参照してください。

2 つ目の関数 scorekeep-worker は、Scorekeep API と関係なく実行される Python 関数です。ゲームが終了すると、API はセッション ID とゲーム ID を SQS キューに書き込みます。ワーカー関数はキューから項目を読み取り、Scorekeep API を呼び出して Amazon S3 内のストレージのゲームセッションごとに完全なレコードを構築します。

Scorekeep には、両方の関数を作成するための AWS CloudFormation テンプレートとスクリプトが含まれています。X-Ray SDK を関数コードとバンドルする必要があるため、テンプレートはコードなしで関数を作成します。Scorekeep をデプロイすると、.ebextensions フォルダに含まれている設定ファイルにより、SDK を含むソースバンドルが作成され、AWS Command Line Interface によって関数コードと設定が更新されます。

ランダム名

Scorekeep は、ユーザーがサインインしたりユーザー名を指定したりせずにゲームセッションを開始するとランダム名関数を呼び出します。random-name への呼び出しが Lambda で処理されると、「トレースヘッダー」が読み出されます。これには、X-Ray SDK for Java によって書き込まれるトレース ID とサンプリングデシジョンを含みます。

Lambda は、サンプリングされたリクエストごとに X-Ray デーモンを実行し、2 つのセグメントを書き込みます。最初のセグメントでは、関数を呼び出す Lambda の呼び出しに関する情報を記録します。このセグメントには、Scorekeep によって記録されるサブセグメントと同じ情報が含まれますが、Lambda の視点からという点で異なります。2 番目のセグメントは、関数の動作を表します。

Lambda は、関数コンテキストを通じて X-Ray SDK に関数セグメントを渡します。Lambda 関数を実装した場合、SDK を使用して受信リクエストのセグメントを作成することはありません。セグメントは Lambda によって提供され、SDK を使用してクライアントの実装およびサブセグメントの書き込みを行います。


         Scorekeep で Lambda 関数を呼び出して、新しいユーザーのランダム名を取得する方法を示すサービスマップ

random-name 関数は、Node.js で実装されています。Node.js 内の SDK for JavaScript を使用して Amazon SNS 通知を送信し、X-Ray SDK for Node.js を使用して AWS SDK クライアントを計測します。注釈を書き込むため、関数は AWSXRay.captureFunc を使用してカスタムサブセグメントを作成し、実装された関数に注釈を書き込みます。Lambda では、関数セグメントに直接注釈を書き込むことはできません。作成したサブセグメントにのみ書き込むことができます。

_lambda/random-name/index.js - Random 名 Lambda 関数

var AWSXRay = require('aws-xray-sdk-core'); var AWS = AWSXRay.captureAWS(require('aws-sdk')); AWS.config.update({region: process.env.AWS_REGION}); var Chance = require('chance'); var myFunction = function(event, context, callback) { var sns = new AWS.SNS(); var chance = new Chance(); var userid = event.userid; var name = chance.first(); AWSXRay.captureFunc('annotations', function(subsegment){ subsegment.addAnnotation('Name', name); subsegment.addAnnotation('UserID', event.userid); }); // Notify var params = { Message: 'Created randon name "' + name + '"" for user "' + userid + '".', Subject: 'New user: ' + name, TopicArn: process.env.TOPIC_ARN }; sns.publish(params, function(err, data) { if (err) { console.log(err, err.stack); callback(err); } else { console.log(data); callback(null, {"name": name}); } }); }; exports.handler = myFunction;

この関数は、サンプルアプリケーションを Elastic Beanstalk にデプロイするときに自動的に作成されます。xray ブランチには、空白の Lambda 関数を作成するスクリプトが含まれています。.ebextensions フォルダの設定ファイルは、デプロイ時に npm install を使用して関数パッケージを構築した後、AWS CLI を使用して Lambda 関数をアップデートします。

ワーカー

実装されたワーカー関数は、ワーカー関数と関連リソースを作成してからでないと実行できないため、自身のブランチ xray-worker で提供されます。手順については、ブランチの readme を参照してください。

この関数は、5 分ごとにバンドルされている Amazon CloudWatch Events イベントによってトリガーされます。実行されると、この関数は Scorekeep によって管理される Amazon SQS キューから項目を取得します。各メッセージには、完了したゲームに関する情報が含まれています。

ワーカーは、ゲームレコードが参照する他のテーブルからゲームレコードとドキュメントを取得します。たとえば、DynamoDB のゲームレコードには、ゲーム中に実行されたムービーのリストが含まれています。リストには、ムービー自体は含まれておらず、別個のテーブルに格納されたムービーの ID が含まれています。

セッションと状態は、参照としても保存されます。これにより、ゲームテーブル内のエントリが大きくなりすぎることはありませんが、ゲームに関するすべての情報を取得するには追加の呼び出しが必要です。このワーカーは、これらのすべてのエントリを間接参照し、ゲームの完全なレコードを Amazon S3 に単一のドキュメントとして構築します。データで分析を行う場合、読み取り量の多いデータ移行を実行してデータを Amazon S3 から取得しなくても、Amazon Athena を使用して DynamoDB で直接クエリを実行できます。


         Scorekeep ワーカー関数が Amazon SQS、Amazon S3、Scorekeep API を使用する方法を示すサービスマップ

ワーカー関数では、AWS Lambda のその設定においてアクティブトレースが有効になっています。ランダム名関数とは異なり、ワーカーは実装されたアプリケーションからリクエストを受信しないため、AWS Lambda はトレースヘッダーを受け取りません。アクティブトレースを使用すると、Lambda はトレース ID を作成してサンプリングの決定を行います。

X-Ray SDK for Python は、SDK をインポートしてその patch_all 関数を実行し、Amazon SQS と Amazon S3 の呼び出しに使用する AWS SDK for Python (Boto) および HTT クライアントにパッチを適用する関数の上部にある数行にすぎません。ワーカーが API を呼び出すと、SDK はトレースヘッダーをリクエストに追加し、API を通じて呼び出すをトレースします。

_lambda/scorekeep-worker/scorekeep-worker.py -- ワーカー Lambda 関数

import os import boto3 import json import requests import time from aws_xray_sdk.core import xray_recorder from aws_xray_sdk.core import patch_all patch_all() queue_url = os.environ['WORKER_QUEUE'] def lambda_handler(event, context): # Create SQS client sqs = boto3.client('sqs') s3client = boto3.client('s3') # Receive message from SQS queue response = sqs.receive_message( QueueUrl=queue_url, AttributeNames=[ 'SentTimestamp' ], MaxNumberOfMessages=1, MessageAttributeNames=[ 'All' ], VisibilityTimeout=0, WaitTimeSeconds=0 ) ...

このページの内容: