Amazonのクラウドサービス、AWSのLambdaを使ってサーバー側で動く、Webでデータを取得して返してくる、JavaScriptプログラムを作ってみました。
CORSやHTTPの関係で直接取得できないデータの代理取得に使えます。(容量制限などには注意!)
AWS Lambda、関数を作成、Node.js 14.x とちょっと古い Node.js が標準で使えます。
サンプルのWebAPIを作ってくれます。
「テスト」を押して、イベント名「test」と入れて、動かしてみましょう!
レスポンス(response)に、パラメータであるeventをいれるように変更して、再度、テスト!
ちゃんと動いてますね!
課金時間(Billed Duration)が7ミリ秒と出ています。最小のメモリ128MBで1ミリ秒あたり0.0000000021USDなので、120円/$換算で、0.00000176円かかる計算です。100万回動かして、1.76円!
Node.jsで、fetchを使う場合、node-fetchモジュールを加える必要があります。関数をエクスポートして、して、下記のようにモジュールを準備します。
npm init
(省略、エンター連打でok)
npm i node-fetch
index.js を 編集。
import fetch from "node-fetch";
export const handler = async (event) => {
const txt = await (await fetch("https://fukuno.jig.jp/")).text();
const response = {
statusCode: 200,
body: txt,
};
return response;
};
node_modules 毎圧縮したファイルを、AWS Lambdaのコードソース、「アップロード元」からアップロード。
Node.jsののモジュール表記であるrequireではなく、その後決まったweb標準のimport/exportを使うために、package.jsonに "type": "module" を加えます。
Webで取得するために、300ミリ秒かかったりするので、0.0000756円/回。100万回で75.6円。安いとは言え100倍近く差が出るので、一時ファイルシステムを使ってキャッシュしてみましょう。
import fetch from "node-fetch";
import * as fs from "fs";
export const handler = async (event) => {
let txt = null;
try {
txt = fs.readFileSync("/tmp/temp.txt", "utf-8");
} catch (e) {
}
if (!txt) {
txt = await (await fetch("https://fukuno.jig.jp/")).text();
fs.writeFileSync("/tmp/temp.txt", txt);
}
const response = {
statusCode: 200,
body: txt,
};
return response;
};
512MB以上の容量がある(AWS Lambda 実行環境 - AWS Lambda)、/tmp/ に取得したデータを一時的に置くと、連続してアクセスされた場合のレスポンスが格段に速くなります。
初回はインスタンスの立ち上げ含めて、600ミリ秒、2回目はファイル書き込みが発生し16ミリ秒、3回目以降は3ミリ秒で返ってきます。
Lambdaキャッシュ作戦、大成功!安価にスケールするサービスが作れそう!
links
- ミリ秒単位で借りるクラウドコンピューター、AWS Lambda で Deno を動かそう!