こんにちは、黒糖です。
日々、システムエンジニアとして、とあるECサイトの保守・運用業務を担っております。
先日、他ベンダー様とのWEB API 部分で、通信に失敗し、試行錯誤した末に、復帰することができましたので、備忘の意味も込めて、残しておきます。
結論から申しましょう。
原因としては、APIを受けるサーバはAWS上に構築されており、IPアドレスが可変であったことです。
ただ、そのAPIにリクエストを送信するWEB サーバから参照しているDNSサーバは、他ベンダー様指定のもので、名前解決の結果、もちろん可変後(変更後)のIPアドレスをしっかりと返してくれておりました。つまり、WEBサーバから、該当のAPIのFQDNで、nslookupコマンドを使用すると、何の問題もなく、現在のIPアドレスが返却されていたのです。
では、なぜJavaアプリケーションからだと急に通信に失敗するようになったか。(ちなみにFWのポリシー設定では、FQDNで許可設定を入れているので、該当のNWには出れていました。)
実はJava7では、デフォルトのDNSキャッシュ設定が、TTL=-1 つまり永続的にキャッシュするという設定が入っておりました。
これにより、APIを受けるサーバのIPが変わっても、以前に通信成功した時のIPアドレスに向けてリクエストを送信、結果として該当のサーバは存在していない(もしかしたら存在するかもしれないが、該当のAPIはそのサーバには存在しない)ので、通信に失敗したということです。
対策としては、上記のJVM側のDNSキャッシュをTTL=0(無効)に設定することで、都度都度、DNSサーバで名前解決をするようになり改善されました。
教訓として、通信が不通になってしまった場合、FWの設定に目を向けがちですが、JVMの設定に目を向けるのも大切だということです。(ひょっとするとTomcatやWebShereにもそのような設定が可能かもしれないので、そこも今後は調査対象とすべきです。)
AWS上で構築されているサーバとの通信が不通になった場合は、上記お試しいただけるとよろしいかと。(JVMのDNSキャッシュ設定は、java.securityというファイルを書き換えることで可能です。詳細な場所とかはググれば死ぬほど出てくるので割愛します。)
以上です。
P.S 私はアプリケーションの開発エンジニアですが、なぜこんなインフラチームがするような調査をしているのでしょう。フルスタックエンジニアを名乗らさせていただいてもいいですかね。サーバ構築とかもできますし。。。 とはいえ、フルスタックエンジニアだからといて、給料が上がるわけではないので、転職もそろそろ視野に入れようかな~ (3年目)