メインコンテンツへスキップ
バージョン: 最新版

レート制限

Omise APIのレート制限内に収まり、効率的な連携を構築します。レート制限ヘッダー、429エラーの適切な処理、リクエストパターンの最適化について学びます。

概要

すべてのマーチャントに信頼性の高いサービスを確保するために、OmiseはAPIリクエストにレート制限を実装しています。レート制限により、単一の連携がAPIを圧倒することを防ぎ、公平なリソース配分を確保します。これらの制限を理解し尊重することは、堅牢な決済連携を構築するために不可欠です。

クイックスタート
  • デフォルト制限: APIキーごとに1分あたり1,000リクエスト
  • レスポンスのX-RateLimit-*ヘッダーを監視
  • HTTP 429を指数バックオフで処理
  • 大量操作にはリクエストキューイングを実装
  • 適切な場合はレスポンスをキャッシュ

レート制限の詳細

現在の制限

制限タイプスコープ
標準レート制限1,000リクエスト/分APIキーごと
バースト許容約100リクエスト短いバーストを許容
リセット期間60秒ローリングウィンドウ

制限にカウントされるもの

カウントされる:

  • すべてのAPIリクエスト(GET、POST、PATCH、DELETE)
  • 成功したリクエスト(2xxレスポンス)
  • 失敗したリクエスト(4xx、5xxレスポンス)
  • 認証失敗

カウントされない:

  • APIに到達する前にブロックされたリクエスト(無効なURL)
  • 静的アセットリクエスト
  • ダッシュボードアクセス
  • Omiseからのwebhook配信

レート制限の種類

OmiseはIPベースアカウントベースの両方のレート制限を実装しており、短時間のバーストには一時的な許容があります。これは、制限がAPIキーごとおよびIPアドレスごとに追跡されることを意味します。

リクエストの優先順位

システムが高負荷の場合、リクエストは以下の順序で優先されます:

優先度リクエストタイプ説明
1(最高)ライブモードでのPOST/PUT課金の作成、キャプチャ、返金
2ライブモードでのGETトランザクションの一覧表示、課金の取得
3(最低)すべてのテストモードリクエストテストAPIキーを使用したすべてのリクエスト
Vaultトークンの制限

Vault(vault.omise.co)でのトークン作成は、メインAPIよりも大幅に低いレート制限があります。連続してトークンを作成することは避け、代わりに有効期間内にトークンを再利用するか、繰り返し使用する場合はカードを顧客にアタッチしてください。

負荷テスト禁止

Omise APIに対する負荷テストは厳禁です。大規模なパフォーマンスを検証する必要がある場合は、適切なテストを手配するためにsupport@omise.coにお問い合わせください。


レート制限ヘッダー

すべてのAPIレスポンスにはレート制限情報がヘッダーに含まれます:

レスポンスヘッダー

HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 995
X-RateLimit-Reset: 1612137600

ヘッダーの説明

ヘッダー説明
X-RateLimit-Limitウィンドウ内で許可される最大リクエスト数1000
X-RateLimit-Remaining現在のウィンドウで残りのリクエスト数995
X-RateLimit-Reset制限がリセットされるUnixタイムスタンプ1612137600

コードでヘッダーを読み取る

# Ruby - レート制限ヘッダーを確認
require 'omise'

Omise.api_key = ENV['OMISE_SECRET_KEY']

response = Omise::Charge.retrieve('chrg_test_...')

# ヘッダーにアクセス
limit = response.http_headers['X-RateLimit-Limit']
remaining = response.http_headers['X-RateLimit-Remaining']
reset = response.http_headers['X-RateLimit-Reset']

puts "レート制限: #{remaining}/#{limit}"
puts "リセット時刻: #{Time.at(reset.to_i)}"
// Node.js - レート制限ヘッダーを確認
const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY
});

try {
const charge = await omise.charges.retrieve('chrg_test_...');

// レスポンスでヘッダーを利用可能
const headers = charge._response.headers;

const limit = headers['x-ratelimit-limit'];
const remaining = headers['x-ratelimit-remaining'];
const reset = headers['x-ratelimit-reset'];

console.log(`レート制限: ${remaining}/${limit}`);
console.log(`リセット時刻: ${new Date(reset * 1000)}`);

} catch (error) {
console.error('リクエスト失敗:', error);
}

HTTP 429レスポンス

レート制限を超えると、APIはHTTP 429 Too Many Requestsを返します:

429レスポンス形式

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1612137660
Retry-After: 60

{
"object": "error",
"location": "https://www.omise.co/api-errors#rate-limit-exceeded",
"code": "rate_limit_exceeded",
"message": "too many requests, please try again later"
}

レスポンスフィールド

フィールド説明
code"rate_limit_exceeded"
message人間可読のエラーメッセージ
Retry-After再試行まで待機する秒数

レート制限の処理

戦略1: 指数バックオフ(推奨)

増加する遅延でリトライ:

# Ruby - 指数バックオフ
require 'omise'

def create_charge_with_backoff(params, max_attempts: 5)
attempt = 0

begin
attempt += 1
Omise::Charge.create(params)

rescue Omise::Error => e
if e.code == 'rate_limit_exceeded' && attempt < max_attempts
# バックオフ遅延を計算: 1秒、2秒、4秒、8秒、16秒
delay = 2 ** (attempt - 1)

# サンダリングハード防止のためジッター(ランダム性)を追加
jitter = rand(0..delay * 0.1)
sleep(delay + jitter)

retry
else
raise
end
end
end

# 使用方法
charge = create_charge_with_backoff(
amount: 100000,
currency: 'thb',
card: token
)
// Node.js - 指数バックオフ
async function createChargeWithBackoff(chargeData, maxAttempts = 5) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
try {
return await omise.charges.create(chargeData);

} catch (error) {
if (error.code !== 'rate_limit_exceeded' || attempt === maxAttempts - 1) {
throw error;
}

// ジッター付き遅延を計算
const baseDelay = Math.pow(2, attempt) * 1000;
const jitter = Math.random() * baseDelay * 0.1;
const delay = baseDelay + jitter;

console.log(`レート制限。${(delay / 1000).toFixed(2)}秒後にリトライ...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}

// 使用方法
const charge = await createChargeWithBackoff({
amount: 100000,
currency: 'thb',
card: token
});

戦略2: Retry-Afterヘッダーを尊重

サーバーが提案するリトライ時間を使用:

<?php
function createChargeWithRetryAfter($params, $maxAttempts = 5) {
$attempt = 0;

while ($attempt < $maxAttempts) {
try {
$attempt++;
return OmiseCharge::create($params);

} catch (Exception $e) {
if ($e->getCode() !== 'rate_limit_exceeded' || $attempt >= $maxAttempts) {
throw $e;
}

// レスポンスからRetry-Afterヘッダーを取得
$retryAfter = $e->getResponse()->getHeader('Retry-After');
$delay = $retryAfter ? (int)$retryAfter : 60;

echo "レート制限。{$delay}秒待機中...\n";
sleep($delay);
}
}

throw new Exception('最大リトライ回数を超過');
}

// 使用方法
$charge = createChargeWithRetryAfter([
'amount' => 100000,
'currency' => 'thb',
'card' => $token
]);

最適化戦略

1. レスポンスをキャッシュ

# Ruby - Redisでキャッシュ
require 'redis'

class OmiseCache
def initialize
@redis = Redis.new
end

def get_charge(charge_id)
cache_key = "charge:#{charge_id}"

# まずキャッシュを試行
cached = @redis.get(cache_key)
return JSON.parse(cached) if cached

# APIから取得
charge = Omise::Charge.retrieve(charge_id)

# 5分間キャッシュ
@redis.setex(cache_key, 300, charge.to_json)

charge
end
end

cache = OmiseCache.new

# 最初の呼び出し - APIにヒット
charge = cache.get_charge('chrg_test_...')

# 以降の呼び出し - キャッシュから(APIリクエストなし)
charge = cache.get_charge('chrg_test_...')

2. ポーリングの代わりにWebhookを使用

// ❌ 悪い例 - ポーリングはレート制限を浪費
async function waitForChargeComplete(chargeId) {
let charge;

// 2秒ごとにポーリング - リクエストを浪費!
while (true) {
charge = await omise.charges.retrieve(chargeId);

if (charge.status === 'successful' || charge.status === 'failed') {
return charge;
}

await new Promise(resolve => setTimeout(resolve, 2000));
}
}

// ✅ 良い例 - Webhookを使用
app.post('/webhooks/omise', async (req, res) => {
const event = req.body;

if (event.key === 'charge.complete') {
const charge = event.data;

// 完了した課金を処理
await processCharge(charge);
}

res.sendStatus(200);
});

ベストプラクティス

1. 常にリトライロジックを実装

# ✅ 良い例 - リトライロジック組み込み
@retry(
stop=stop_after_attempt(5),
wait=wait_exponential(multiplier=1, min=1, max=60),
retry=retry_if_exception_type(omise.errors.RateLimitError)
)
def create_charge(amount, currency, card):
return omise.Charge.create(
amount=amount,
currency=currency,
card=card
)

2. レート制限使用状況を監視

# ✅ 良い例 - 追跡とアラート
after_action :track_rate_limit

def track_rate_limit
if response.headers['X-RateLimit-Remaining']
remaining = response.headers['X-RateLimit-Remaining'].to_i
limit = response.headers['X-RateLimit-Limit'].to_i

usage_percent = ((limit - remaining).to_f / limit * 100).round(2)

# メトリクスをログ
StatsD.gauge('omise.rate_limit.usage', usage_percent)

# 高い場合はアラート
if usage_percent > 90
AlertService.notify("Omiseレート制限使用率高: #{usage_percent}%")
end
end
end

3. レート制限を適切に処理

# ✅ 良い例 - ユーザーフレンドリーなエラー処理
def create_charge(params)
Omise::Charge.create(params)

rescue Omise::Error => e
if e.code == 'rate_limit_exceeded'
# 技術的な詳細をユーザーに公開しない
flash[:error] = "決済システムが現在混雑しています。しばらくしてからもう一度お試しください。"

# 監視用にログ
Rails.logger.warn("レート制限超過: #{e.message}")

# バックグラウンドジョブでリトライ
ChargeCreationJob.perform_later(params)
else
raise
end
end

レート制限チェックリスト

本番稼働前に:

  • リトライ用の指数バックオフを実装
  • Retry-Afterヘッダーを尊重
  • レスポンスのレート制限ヘッダーを監視
  • 高使用率(>80%)のアラートを設定
  • 適切な場合はレスポンスをキャッシュ
  • ポーリングの代わりにWebhookを使用
  • 可能な場合は操作をバッチ処理
  • 並列ワーカーを最大10に制限
  • リクエストを時間的に分散(1秒で100リクエストより5秒で20リクエスト/秒を推奨)
  • ステージングでレート制限処理をテスト
  • チーム用にレート制限戦略を文書化
  • レート制限エラーのフォールバック計画を用意
  • 本番でレート制限メトリクスを監視
  • 予想される高トラフィックイベントについてsupport@omise.coに連絡
  • 不要なAPI呼び出しのコードをレビュー

クイックリファレンス

現在の制限

APIキーごとに1分あたり1,000リクエスト

レート制限ヘッダー

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 995
X-RateLimit-Reset: 1612137600

HTTP 429レスポンス

{
"code": "rate_limit_exceeded",
"message": "too many requests, please try again later"
}

基本的なリトライパターン

begin
omise_request()
rescue Omise::Error => e
if e.code == 'rate_limit_exceeded'
sleep(2 ** attempt)
retry
end
raise
end

指数バックオフの式

遅延 = 基本遅延 * (2 ^ 試行回数) + ジッター

例:

  • 試行1: 1秒 + ジッター
  • 試行2: 2秒 + ジッター
  • 試行3: 4秒 + ジッター
  • 試行4: 8秒 + ジッター
  • 試行5: 16秒 + ジッター

関連リソース


連携の準備はできましたか? すべての必須ガイドを確認: 認証エラー処理ページネーションべき等性バージョニング


FAQ

レート制限を超えるとどうなりますか?

レート制限を超えると、APIはHTTP 429(Too Many Requests)とrate_limit_exceededエラーコードを返します。レスポンスには、再試行までに待機する秒数を示すRetry-Afterヘッダーが含まれます。

レート制限はテストモードとライブモードで共有されますか?

いいえ、テストモードとライブモードには別々のレート制限があります。テストAPIキーで行われたリクエストはライブモードの制限にカウントされず、その逆も同様です。

アカウントのレート制限の引き上げをリクエストできますか?

はい、連携により高いレート制限が必要な場合は、ユースケースの詳細を添えてsupport@omise.coにお問い合わせください。大量取引のマーチャント向けに、より高い制限が利用可能です。

Webhook配信はレート制限にカウントされますか?

いいえ、Omiseからサーバーへのwebhook配信はレート制限にカウントされません。Omiseへのお客様のAPIリクエストのみがカウントされます。

本番環境でレート制限エラーをどのように処理すべきですか?

ジッター付きの指数バックオフを実装し、Retry-Afterヘッダーを尊重し、高トラフィック期間中はリクエストのキューイングを検討してください。制限に達する前に積極的に速度を落とすために、X-RateLimit-Remainingヘッダーを監視してください。

キャッシュはレート制限の使用量を削減しますか?

はい、APIレスポンスをキャッシュすることで、レート制限の使用量を大幅に削減できます。顧客プロフィールや過去の課金情報など、データが頻繁に変更されない読み取り操作(GETリクエスト)をキャッシュしてください。