ぼくは明日、昨日のじぶんに頼りたい

明日のためのメモです。

OpenRestyを使わずにnginxでCache Key Preprocessingしたい

OpenRestyで簡単にできるCache Key Preprocessing を素のnginxで使いたいだけです。
OpenResty使えよって気持ちはわかるのですが、追加のモジュールを入れるのは気が重いので使わない方法を調べてみました。

まずはOpenRestyを試してみる

準備

公式のイメージを利用します。

github.com

初期のdefault.confはコンテナから取得しました。

$ docker cp <コンテナID>:/etc/nginx/conf.d/default.conf conf.d/default.conf

以下のdocker-composeファイルでconfをマウントします。

version: "3"
services:
  openresty:
    image: openresty/openresty:1.19.9.1-6-alpine
    container_name: openresty-test
    ports:
      - "8081:80"
    volumes:
      - type: bind
        source: "./conf.d"
        target: "/etc/nginx/conf.d"

confの修正

Cache Key Preprocessingに記載されている以下の部分をdefault.confに追記します。

 location = /t {
     rewrite_by_lua '
         local args = ngx.req.get_uri_args()
         args.SID = nil
         args.UID = nil
         ngx.req.set_uri_args(args)
     ';

     echo $args;
 }

試す

$ docker-compose up -d
$ curl 'localhost:8081/t?RT=62&SID=BC3781C3-2E02-4A11-89CF-34E5CFE8B0EF&UID=44332&L=EN&M=1&H=1&UNC=0&SRC=LK'    
UNC=0&H=1&SRC=LK&L=EN&M=1&RT=62

ドキュメントにも書いてあるように、順番変わりましたがSIDとUIDがなくなりました。
OpenRestyを使えてしまえば、すごく簡単です。すごいです。
echoもだいぶ強力です。

nginxでやりたい

準備

公式のイメージを利用します。

github.com

初期のdefault.confはコンテナから取得しました。
あらためてlua-nginx-moduleecho-nginx-moduleも使わない話でした。

以下のdocker-composeファイルでconfをマウントします。

version: "3"
services:
  nginx:
    image: nginx:1.20.2-alpine
    container_name: nginx-test
    ports:
      - "8080:80"
    volumes:
      - type: bind
        source: "./conf.d"
        target: "/etc/nginx/conf.d"

confの修正(#1)

とりあえずレスポンスを返すことで、echoで確認できてたことを確認できるようにします。
default.confに追記します。

    location /t {
        set $_args $args;

        default_type application/json;
        return 200 '{"args": "$args", "_args": "$_args"}';
    }

試す(#1)

$ docker-compose up -d
$ curl 'localhost:8080/t?RT=62&SID=BC3781C3-2E02-4A11-89CF-34E5CFE8B0EF&UID=44332&L=EN&M=1&H=1&UNC=0&SRC=LK'
{"args": "RT=62&SID=BC3781C3-2E02-4A11-89CF-34E5CFE8B0EF&UID=44332&L=EN&M=1&H=1&UNC=0&SRC=LK", "_args": "RT=62&SID=BC3781C3-2E02-4A11-89CF-34E5CFE8B0EF&UID=44332&L=EN&M=1&H=1&UNC=0&SRC=LK"}

confの修正(#2)

recruit.gmo.jp

正規表現を使ってrewriteできれば良さそうです。

    location /t {
        set $_args $args;
        # SIDを削除
        if ($_args ~ (.*)SID=[^&]*(.*)) {
            set $_args $1$2;
        }
        # UIDを削除
        if ($_args ~ (.*)UID=[^&]*(.*)) {
            set $_args $1$2;
        }

        default_type application/json;
        return 200 '{"args": "$args", "_args": "$_args"}';
    }

試す(#2)

$ docker-compose up -d
$ curl 'localhost:8080/t?RT=62&SID=BC3781C3-2E02-4A11-89CF-34E5CFE8B0EF&UID=44332&L=EN&M=1&H=1&UNC=0&SRC=LK'
{"args": "RT=62&SID=BC3781C3-2E02-4A11-89CF-34E5CFE8B0EF&UID=44332&L=EN&M=1&H=1&UNC=0&SRC=LK", "_args": "RT=62&&&L=EN&M=1&H=1&UNC=0&SRC=LK"}

アンパサンド、正規表現力が足りてないとかあると思いますができました。これで良いことにしたいと思います。

proxy_cacheで使ってみる

confの修正

以下を適当に追記しました。

proxy_cache_path /var/cache/nginx/test levels=1:2 keys_zone=my-key:16m max_size=100m inactive=1d;
...
proxy_cache my-key;
proxy_cache_valid 200 302 1d;
proxy_cache_key "$host$uri$is_args$_args";
add_header X-Nginx-Cache $upstream_cache_status;

試す

# RT=62 => X-Nginx-Cache: MISS
$ curl -I 'localhost:8080/tpcache?RT=62&SID=BC3781C3-2E02-4A11-89CF-34E5CFE8B0EF&UID=44332&L=EN&M=1&H=1&UNC=0&SRC=LK'     
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 21 Mar 2022 04:25:37 GMT
Content-Type: text/html
Content-Length: 612
Connection: keep-alive
Last-Modified: Tue, 16 Nov 2021 15:04:23 GMT
ETag: "6193c877-264"
X-Nginx-Cache: MISS
Accept-Ranges: bytes

# RT=62(最初と同じもの)=> X-Nginx-Cache: HIT
$ curl -I 'localhost:8080/tpcache?RT=62&SID=BC3781C3-2E02-4A11-89CF-34E5CFE8B0EF&UID=44332&L=EN&M=1&H=1&UNC=0&SRC=LK'     
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 21 Mar 2022 04:25:53 GMT
Content-Type: text/html
Content-Length: 612
Connection: keep-alive
Last-Modified: Tue, 16 Nov 2021 15:04:23 GMT
ETag: "6193c877-264"
X-Nginx-Cache: HIT
Accept-Ranges: bytes

# RT=63 => X-Nginx-Cache: MISS
$ curl -I 'localhost:8080/tpcache?RT=63&SID=BC3781C3-2E02-4A11-89CF-34E5CFE8B0EF&UID=44332&L=EN&M=1&H=1&UNC=0&SRC=LK'     
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 21 Mar 2022 04:26:22 GMT
Content-Type: text/html
Content-Length: 612
Connection: keep-alive
Last-Modified: Tue, 16 Nov 2021 15:04:23 GMT
ETag: "6193c877-264"
X-Nginx-Cache: MISS
Accept-Ranges: bytes

# RT=62, SID変更(BC37..→AD37..) => X-Nginx-Cache: HIT
$ curl -I 'localhost:8080/tpcache?RT=62&SID=AD3781C3-2E02-4A11-89CF-34E5CFE8B0EF&UID=44332&L=EN&M=1&H=1&UNC=0&SRC=LK'     
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 21 Mar 2022 04:26:50 GMT
Content-Type: text/html
Content-Length: 612
Connection: keep-alive
Last-Modified: Tue, 16 Nov 2021 15:04:23 GMT
ETag: "6193c877-264"
X-Nginx-Cache: HIT
Accept-Ranges: bytes

# RT=62, UID変更(44332→55443) => X-Nginx-Cache: HIT
$ curl -I 'localhost:8080/tpcache?RT=62&SID=BC3781C3-2E02-4A11-89CF-34E5CFE8B0EF&UID=55443&L=EN&M=1&H=1&UNC=0&SRC=LK'     
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 21 Mar 2022 04:27:19 GMT
Content-Type: text/html
Content-Length: 612
Connection: keep-alive
Last-Modified: Tue, 16 Nov 2021 15:04:23 GMT
ETag: "6193c877-264"
X-Nginx-Cache: HIT
Accept-Ranges: bytes

期待された形でX-Nginx-Cacheが返ってきました。良さそうです。
念のためキャッシュされたファイルも確認します。

$ docker exec -it nginx-test sh
$ cd /var/cache/nginx/test
$ ls
5  8
$ cat 8/62/2764b90faf9a7484b00c51d615edb628
...
KEY: localhost/tpcache?RT=62&&&L=EN&M=1&H=1&UNC=0&SRC=LK     
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 21 Mar 2022 04:25:37 GMT
...

アンパサンド、とりあえずOKということで終わります。