GCEでCloud NATを経由させるとSocketTimeoutException


本記事の概要

下記記事にて構築したアプリケーションの運用中に発生した障害とその対応について記述します。
https://qiita.com/issei_0403/items/a69f42c85fb81e1efc62

構成

外部API接続時にIP制限がかかっているため、CloudNATで出口IPを固定しつつ外部APIに接続しています。
外部APIは秒間リクエスト数に制限があります。

障害の内容

  • アプリケーションがリクエストを投げている行でconnect time outが発生し外部APIに届いていない🤔
  • Stackdriver LoggingでCloud NATのログを見てみると、アプリケーション側で失敗したリクエストに紐付いていそうなCloud NATのログについて allocation_statusが"dropped"になっている🤔

(つーか1週間前まで何事もなくうごいてたのになんで急に動かなくなったんだ😡)

試したこと

1.アプリケーションで使用しているOkHttpのタイムアウト時間を長めにとってみる

※下記記事参照
https://qiita.com/issei_0403/items/716fc73afb86142d4933

1.の結果

Cloud NATのallocation_statusが"dropped"になる問題は解消。
しかし、外部APIへのリクエスト数が多すぎて怒られる😅

2.リクエストを投げる前にsleepしてみる

// もろもろ省略
import java.util.concurrent.TimeUnit;
TimeUnit.MILLISECONDS.sleep(200);

2.の結果

リクエスト制限以下にしたので、無事解消。

続き(2019/08/22)

40リクエスト程度さばいたところで、突如2分以上待たされる事象が発生し再度Timeoutが発生しました。
自動でスケーリングするとのことでしたが、GCE上のアプリケーション(今回はバッチ処理)をCloud NATを経由させると極端に長い待ちが突然発生してうまく動かないことがあるみたいです。
GCEに固定IPを割り当て、Cloud NATを経由させないことにしました。
結果Cloud NATを経由させた時と比較にならないレベルで爆速で動きました・・・。