web-dev-qa-db-ja.com

同じリクエストでNginxキャッシュとバックエンドデータベースのキーを削除する

Proxy_cacheを使用するWebサーバーとしてオープンソースのNginxを使用しています。

キャッシュ内のキーを削除するという独自のユースケースがあり、応答をキャッシュせずにDB内のキーを削除するようにバックエンドサーバーにリクエストを渡します。

したがって、同じリクエストでWebサーバーキャッシュとバックエンドDBのキーを削除します。
クライアント=>ロードバランサー=> Nginx(proxy_cache)=>アプリケーション=> PostgreSQL

例:Nginx.conf

if ( $http_x_delete_key ){
  content_by_lua_file ./purge_key.lua;
  proxy_pass          http://backend_servers; 
}

例:purge_key.lua

...
if ngx ~= nil then
    ...
    delete_file(filename)
    ngx.log(ngx.NOTICE, 'deleted')
    -- ngx.exit(ngx.OK);
    -- return
end

Nginxlocationセクションの 'if'ブロックは、フローを停止し( nginx "location if"の動作 )、バックエンドに送信せずに応答を返し、要求をそのまま渡しません。
無料の「ngx_cache_purge」モジュールを使用してOpenRestyをコンパイルしたこともありますが、purgeコマンドも要求をバックエンドに渡しません。

通常、バックエンド応答を使用してキーをタイムアウトまたは更新しますが、私の場合、同じ要求またはその応答のいずれかでキーを削除するには、より明示的な制御が必要です。

Openresty + Memcache、Apache httpd、Apache Traffic Server、またはVarnish(vcl_purge and pass)はこのユースケースを解決しますか、それとも他の方法がありますか?

2
dv3

私はこれを行う方法を見つけました。

HTTPリクエストヘッダーの値に応じて、luaスクリプトを実行して、Nginxのproxy_cache内のキャッシュファイル(キーのハッシュと、x:yキャッシュレベルの場合は最後のx + y文字)を削除します。

コンテンツハンドラフェーズとして「content_by_lua」の代わりに「access_by_lua」を使用すると、「ngx.exit」または「ngx.OK」を記述しなくても、常に終了して戻ります。

シナリオでバックエンドから送信されるコンテンツや応答を生成していないため、luaスクリプトを NGX_HTTP_ACCESS_PHASE で実行する必要があります。 NGX_HTTP_CONTENT_PHASE では実行しません。

例:Nginx.conf

proxy_cache_bypass     $http_x_delete_key;
proxy_no_cache         $http_x_delete_key;

if ( $http_x_delete_key ){
  ...
  access_by_lua_file ./purge_key.lua;
}

キーの削除リクエストが来ると、Nginxは
1。 luaスクリプトを実行してキャッシュファイルを削除しますが、アクセスフェーズにあるためすぐには戻りません
2。リクエストはキャッシュをバイパスします
3。リクエストを受信すると、アプリケーションはDB内のキーを削除します
4。応答はNginxproxy_cacheにキャッシュされません

1
dv3

一般的なアプローチは、アプリケーションにキャッシュとデータベースの両方からの削除を行わせることです。または、nginxでホストされているluaに両方を実行させます。

一般的に言って、マルチステージ/マルチアップストリームの種類のリクエスト処理は、ウェブサーバー/ネットワーク層ではなく、アプリケーション層です。構成駆動型プロキシサーバーは、その問題を解決する形に曲げるべきではありません。

したがって、アプリケーションの一部としてそれを実行し、適切なフットプリントがアップストリームコードベースにあるのかluaにあるのかを判断します。おそらく最良の場所はアップストリームコードベースです。

0
Jonah Benton