Slide 1

Slide 1 text

Nginxのcacheにはまった話 2019/12/4(Wed) mornIngTalk #4 Future Architect Tsuji Daishiro

Slide 2

Slide 2 text

構成の概要 ✓ Nginxはリバースプロキシ ✓ クライアントアプリからNginxを経由してバックエンドのHerokuアプリのAPIにアクセス 2

Slide 3

Slide 3 text

nginx.conf ✓ nginx.confの一部 ✓ よくあるupstreamを使ったconfig 3 http { upstream backend { server sample.herokuapp.com:443; } server { location /hoge { proxy_pass https://backend; proxy_set_header Host sample.herokuapp.com; proxy_redirect off; } } } nginx.conf

Slide 4

Slide 4 text

事象 4

Slide 5

Slide 5 text

問題の事象 ✓ たまに404のNot Foundがレスポンスとして返ってくる ✓ 観測すると10回に1回程度の頻度 ✓ 通常は “OK” などの文字列が返ってくる 5 404としてレスポンスが返ってきたときのBodyのHTMLの一例

Slide 6

Slide 6 text

原因 6

Slide 7

Slide 7 text

原因 ✓ NginxのDNSのcacheの仕様によるものだった ✓ https://www.nginx.com/blog/dns-service-discovery-nginx-plus/ 7 As NGINX starts up or reloads its configuration, it queries a DNS server to resolve backends.example.com. The DNS server returns the list of three backends discussed above, and NGINX uses the default Round Robin algorithm to load balance requests among them. NGINX chooses the DNS server from the OS configuration file /etc/resolv.conf. This method is the least flexible way to do service discovery and has the following additional drawbacks: • If the domain name can’t be resolved, NGINX fails to start or reload its configuration. • NGINX caches the DNS records until the next restart or configuration reload, ignoring the records’ TTL values. • We can’t specify another load-balancing algorithm, nor can we configure passive health checks or other features defined by parameters to the server directive, which we’ll describe in the next section.

Slide 8

Slide 8 text

原因 ✓ NginxのDNSのcacheの仕様によるものだった ✓ https://www.nginx.com/blog/dns-service-discovery-nginx-plus/ 8 As NGINX starts up or reloads its configuration, it queries a DNS server to resolve backends.example.com. The DNS server returns the list of three backends discussed above, and NGINX uses the default Round Robin algorithm to load balance requests among them. NGINX chooses the DNS server from the OS configuration file /etc/resolv.conf. This method is the least flexible way to do service discovery and has the following additional drawbacks: • If the domain name can’t be resolved, NGINX fails to start or reload its configuration. • NGINX caches the DNS records until the next restart or configuration reload, ignoring the records’ TTL values. • We can’t specify another load-balancing algorithm, nor can we configure passive health checks or other features defined by parameters to the server directive, which we’ll describe in the next section. 再起動やリロードするまでDNSレコードをキャッシュ。TTLは無視。

Slide 9

Slide 9 text

問題にならないケースも ✓ DNSレコードをキャッシュしても問題にならないケースがある ✓ ドメイン名に対して、名前解決先のIPアドレスが一定の場合 9 hoge.com 192.168.1.1 192.168.1.2 固定のIPアドレスに紐づく場合など

Slide 10

Slide 10 text

今回のケース ✓ バックエンドのサービスがHeroku ✓ SaaS ✓ デプロイしたサービスに紐づくドメインのグローバルIPが都度変わる $ nslookup sample.herokuapp.com ✓ Internalの通信にALBをはさむ場合も同様 10 あるタイミングで名前解決したDNSレコードが有効とは限らない

Slide 11

Slide 11 text

何が起こっていたか ✓ デプロイしたサービスとは別のサービスと通信していると判断 ✓ グローバルIPの割り当て方法について、サポートから明確な回答は得られず。 11 sample.heroku.com → x.x.x.x x.x.x.x のIPアドレスは自分たちのサービスに割り当てられて おらず、別のサービスに割り当てられている。 別のサービス 自分たちのサービス 別のサービスと通信したときの404 Not Foundのレスポンス

Slide 12

Slide 12 text

対応策 12

Slide 13

Slide 13 text

対応策 ✓ 都度名前解決させる ✓ set, resolver, proxy_passを用いることで実装可能 ✓ upstreamを諦める(少し頑張ればupstreamでも実装できるよう。未確認) 13 http { resolver 169.254.169.253 valid=0s; server { listen 80 default_server; server_name _; root /usr/share/nginx/html; location /hoge { set $url "https://sample.herokuapp.com/hoge"; proxy_pass $url; proxy_redirect off; } } } nginx.conf

Slide 14

Slide 14 text

No content