#はじめに
「サーバーをユーザーの近くに置けたら」——この願いを実現するのがエッジコンピューティングです。
エッジコンピューティングは、ユーザーに近い場所(エッジ)でコードを実行する技術です。従来のサーバーレスよりも低いレイテンシーでレスポンスを返すことができます。
この記事を読むと、以下のことができるようになります:
- エッジコンピューティングの利点を理解できる
- 主要なエッジプラットフォームを把握できる
- 適切なユースケースを判断できる
#エッジコンピューティングとは
エッジコンピューティングとは、ユーザーに物理的に近いサーバー(エッジサーバー)でコードを実行する技術です。
従来:
[ユーザー(東京)] ─────────────────> [サーバー(バージニア)]
往復 200ms
エッジ:
[ユーザー(東京)] ──> [エッジ(東京)]
往復 20ms
CDNのエッジロケーションでJavaScriptを実行できると考えるとわかりやすいです。
#従来のサーバーレスとの違い
#従来のサーバーレス(AWS Lambda等)
[ユーザー] → [CDN] → [API Gateway] → [Lambda] → [DB]
↑
リージョンは限定的
- 特定のリージョンで実行
- コールドスタートが発生
- 実行時間の制限が緩い
#エッジコンピューティング
[ユーザー] → [エッジ] → 必要に応じて [オリジン]
↑
世界中に分散
- ユーザーに最も近いエッジで実行
- コールドスタートがほぼない
- 実行時間の制限が厳しい
#比較表
| 項目 | 従来のサーバーレス | エッジ |
|---|---|---|
| レイテンシー | 数十〜数百ms | 数ms〜数十ms |
| コールドスタート | 数百ms〜数秒 | ほぼなし |
| 実行時間上限 | 数分〜15分 | 数十ms〜数秒 |
| メモリ | 最大10GB | 最大128MB程度 |
| ランタイム | 多様 | JavaScript/WASM中心 |
| データアクセス | 自由 | 制限あり |
#Cloudflare Workers
Cloudflareが提供するエッジコンピューティングプラットフォームです。
#基本的なWorker
// src/index.js
export default {
async fetch(request, env, ctx) {
return new Response('Hello from the edge!', {
headers: { 'Content-Type': 'text/plain' },
});
},
};
#リクエストの処理
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
// パスによる振り分け
if (url.pathname === '/api/hello') {
return new Response(JSON.stringify({ message: 'Hello!' }), {
headers: { 'Content-Type': 'application/json' },
});
}
// 地理情報の取得
const country = request.cf?.country || 'Unknown';
return new Response(`You are accessing from: ${country}`);
},
};
#KV(Key-Value ストレージ)
エッジで利用できる分散KVストアです。
export default {
async fetch(request, env, ctx) {
// 読み取り
const value = await env.MY_KV.get('key');
// 書き込み
await env.MY_KV.put('key', 'value');
// 削除
await env.MY_KV.delete('key');
return new Response(value);
},
};
#D1(SQLiteデータベース)
エッジで利用できるSQLiteベースのデータベースです。
export default {
async fetch(request, env, ctx) {
const { results } = await env.DB.prepare(
'SELECT * FROM users WHERE id = ?'
).bind(1).all();
return new Response(JSON.stringify(results), {
headers: { 'Content-Type': 'application/json' },
});
},
};
#wrangler.toml
name = "my-worker"
main = "src/index.js"
compatibility_date = "2024-01-01"
[[kv_namespaces]]
binding = "MY_KV"
id = "xxxxx"
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "xxxxx"
#Vercel Edge Functions
Vercelが提供するエッジランタイムです。
#基本的なEdge Function
// app/api/hello/route.ts (App Router)
export const runtime = 'edge';
export async function GET(request: Request) {
return new Response('Hello from the edge!');
}
#Middleware
すべてのリクエストの前に実行されるエッジ関数です。
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
// 地理情報によるリダイレクト
const country = request.geo?.country || 'US';
if (country === 'JP') {
return NextResponse.redirect(new URL('/ja', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: '/:path*',
};
#Edge Config
エッジで読み取れる設定ストアです。
import { get } from '@vercel/edge-config';
export const runtime = 'edge';
export async function GET() {
const featureFlag = await get('newFeature');
return new Response(JSON.stringify({ enabled: featureFlag }));
}
#その他のエッジプラットフォーム
#Deno Deploy
Denoランタイムベースのエッジプラットフォームです。
Deno.serve((req: Request) => {
return new Response('Hello from Deno Deploy!');
});
#Fastly Compute
Fastlyが提供するエッジコンピューティングです。
addEventListener('fetch', (event) => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
return new Response('Hello from Fastly!');
}
#AWS CloudFront Functions / Lambda@Edge
| 項目 | CloudFront Functions | Lambda@Edge |
|---|---|---|
| 実行場所 | 全エッジロケーション | リージョナルエッジ |
| 実行時間 | 最大1ms | 最大5秒(Viewer)/ 30秒(Origin) |
| メモリ | 2MB | 最大10GB |
| 言語 | JavaScript | Node.js, Python |
#ユースケース
#1. A/Bテスト
export default {
async fetch(request, env) {
const bucket = Math.random() < 0.5 ? 'A' : 'B';
const response = await fetch(request);
const html = await response.text();
const modifiedHtml = html.replace(
'{{VARIANT}}',
bucket === 'A' ? 'オリジナル' : '新デザイン'
);
return new Response(modifiedHtml, {
headers: { 'Content-Type': 'text/html' },
});
},
};
#2. 地理情報によるリダイレクト
export default {
async fetch(request) {
const country = request.cf?.country;
const redirectMap = {
JP: 'https://example.com/ja',
US: 'https://example.com/en',
DE: 'https://example.com/de',
};
if (redirectMap[country]) {
return Response.redirect(redirectMap[country], 302);
}
return fetch(request);
},
};
#3. 認証・認可
export default {
async fetch(request, env) {
const token = request.headers.get('Authorization')?.replace('Bearer ', '');
if (!token) {
return new Response('Unauthorized', { status: 401 });
}
// JWTの検証
const isValid = await verifyToken(token, env.JWT_SECRET);
if (!isValid) {
return new Response('Forbidden', { status: 403 });
}
return fetch(request);
},
};
#4. レスポンスの変換
export default {
async fetch(request) {
const response = await fetch(request);
const html = await response.text();
// HTMLを変換
const modifiedHtml = html
.replace(/http:\/\//g, 'https://')
.replace(/<script/g, '<script defer');
return new Response(modifiedHtml, {
headers: response.headers,
});
},
};
#5. API のキャッシュ
export default {
async fetch(request, env, ctx) {
const cacheKey = new Request(request.url, request);
const cache = caches.default;
// キャッシュを確認
let response = await cache.match(cacheKey);
if (!response) {
// オリジンからフェッチ
response = await fetch(request);
response = new Response(response.body, response);
response.headers.set('Cache-Control', 'max-age=60');
// キャッシュに保存
ctx.waitUntil(cache.put(cacheKey, response.clone()));
}
return response;
},
};
#制限事項
#実行時間
エッジ関数は高速な処理が求められます。
| プラットフォーム | 制限 |
|---|---|
| Cloudflare Workers | 10ms(無料)/ 50ms(有料)CPU時間 |
| Vercel Edge | 25秒(壁時計時間) |
| Deno Deploy | 50ms CPU時間 |
#メモリ
| プラットフォーム | 制限 |
|---|---|
| Cloudflare Workers | 128MB |
| Vercel Edge | 128MB |
#Node.js API
エッジランタイムでは、Node.jsの一部APIが利用できません。
使用不可:
fs(ファイルシステム)child_processnet- ネイティブモジュール
使用可能:
fetchcrypto(Web Crypto API)TextEncoder/TextDecoderURLHeaders、Request、Response
#デプロイとテスト
#Cloudflare Workers
# インストール
npm install -g wrangler
# ログイン
wrangler login
# ローカル開発
wrangler dev
# デプロイ
wrangler deploy
#Vercel
# ローカル開発
vercel dev
# デプロイ
vercel deploy
#まとめ
- エッジコンピューティングはユーザーに近い場所でコードを実行
- 低レイテンシー、コールドスタートがほぼない
- 主要プラットフォーム: Cloudflare Workers、Vercel Edge Functions
- 適したユースケース: 認証、リダイレクト、A/Bテスト、キャッシュ
- 制限: 実行時間、メモリ、Node.js API
- 従来のサーバーレスと適材適所で使い分け
#次のステップ
エッジコンピューティングを理解したところで、最後にWebSocketとServer-Sent Eventsについて学びましょう。リアルタイム通信を実現する技術を紹介します。