症状
カスタムランタイムを使用して HTTP 関数を作成し、匿名 HTTP トリガーを設定し、次のようなルートを持つ HTTP サーバーを実装します。
@app.route('/test', methods=['POST', 'GET'])
def test():cURL またはブラウザ経由で関数にアクセスすると、404 エラーが返されます。
# cURL
curl -v https://123456789.cn-hangzhou.fc.aliyuncs.com/2016-08-15/proxy/CustomDemo/func-http/test
# Browser
https://123456789.cn-hangzhou.fc.aliyuncs.com/2016-08-15/proxy/CustomDemo/func-http/test原因
HTTP 関数のデフォルト URL は、次のフォーマットに従います。
https://<account-id>.<region>.fc.aliyuncs.com/2016-08-15/proxy/<service-name>/<function-name>/<path>Function Compute は、/2016-08-15/proxy/<service-name>/<function-name> プレフィックスを含む完全な URL パスを、カスタムランタイムの HTTP サーバーに転送します。アプリケーションでは /test というルートしか定義されていないため、受信したパス /2016-08-15/proxy/CustomDemo/func-http/test と一致せず、404 エラーが発生します。
ソリューション
この不一致を解決するには 3 つの方法があります。状況に応じて選択してください。
x-fc-invocation-target ヘッダーの使用:最も手軽な修正方法です。コードやインフラストラクチャの変更は不要です。
カスタムドメイン名のバインド:本番環境でクリーンで短い URL を使用したい場合に推奨されます。
関数コード内のルートの更新:デフォルトの URL フォーマットを維持し、コードの変更のみで対応できます。
解決策 1:x-fc-invocation-target ヘッダーの追加
x-fc-invocation-target ヘッダーを追加して、関数パスとリクエストパスを分離します。Function Compute はこのヘッダーを使用してターゲット関数を識別し、<path> のみを HTTP サーバーに転送します。
構文:
curl -v -H "x-fc-invocation-target: 2016-08-15/proxy/<service-name>/<function-name>" \
https://<account-id>.<region>.fc.aliyuncs.com/<path>例:
curl -v -H "x-fc-invocation-target: 2016-08-15/proxy/CustomDemo/func-http" \
https://123456789.cn-hangzhou.fc.aliyuncs.com/testこのヘッダーを使用すると、Function Compute はリクエストを func-http にルーティングし、/test を HTTP サーバーに転送します。これにより、@app.route('/test', ...) の定義と一致します。
解決策 2:カスタムドメイン名のバインド
関数にカスタムドメイン名をバインドします。これにより、Function Compute はプロキシプレフィックスなしで、ドメイン以降のパスのみを HTTP サーバーに転送します。
設定手順については、「カスタムドメイン名の設定」をご参照ください。
サービス CustomDemo と関数 func-http のルーティングルールを設定する際は、ドメインパスを /* に設定してください。
バインド後、関数に直接アクセスします。
curl -v https://test.abc.com/test解決策 3:関数コード内のルートの更新
HTTP サーバーのコード内のルートを、Function Compute が転送する完全なパスと一致するように変更し、関数を再デプロイします。
ルート定義を更新します。
@app.route('/2016-08-15/proxy/CustomDemo/func-http/test', methods=['POST', 'GET'])
def test():再デプロイ後、元の URL でアクセスできるようになります。
curl -v https://123456789.cn-hangzhou.fc.aliyuncs.com/2016-08-15/proxy/CustomDemo/func-http/testこの方法では、サービス名と関数名がルートにハードコーディングされます。どちらかが変更された場合は、ルートを更新して再デプロイする必要があります。