Docker SwarmでSpring Bootアプリケーションを実行していて、データベースにpostgresを使用しています。両方をドッカーサービスとして実行すると、ログに記録されているように、データベース接続が一貫してランダムに失敗します(タイムスタンプで確認できます)。
2017-10-26T 17:14:15。200415747Z app-db.1.1ayo6h8ro1og@scw-c2964a |ログ:クライアントからデータを受信できませんでした:接続がピアによってリセットされました
2017-10-26T 17:43:36。481718562Z app-db.1.1ayo6h8ro1og@scw-c2964a |ログ:クライアントからデータを受信できませんでした:接続がピアによってリセットされました
2017-10-26T 17:43:56。954152654Z app-db.1.1ayo6h8ro1og@scw-c2964a |ログ:クライアントからデータを受信できませんでした:接続がピアによってリセットされました
2017-10-26T 17:44:17。434171472Z app-db.1.1ayo6h8ro1og@scw-c2964a |ログ:クライアントからデータを受信できませんでした:接続がピアによってリセットされました
2017-10-26T 17:49:04。154174253Z app-db.1.1ayo6h8ro1og@scw-c2964a |ログ:クライアントからデータを受信できませんでした:接続がピアによってリセットされました
その理由を理解できず、発見できませんでした。任意のアイデアをいただければ幸いです。
編集:
アプリケーションをテストすると、次のようなエラーもスローされることに気づきました。
SQLTransientConnectionException:HikariPool-1-接続が利用できません。リクエストは937517ms後にタイムアウトしました
ありがとう。
Spring BootアプリとPostgreSQLのDocker Swarmスタックをデプロイするときにも同じエラーが発生します。約1週間これと闘った後、非アクティブのためにファイアウォールがコンテナー間の接続をドロップすることが問題であることがわかりました。 Linuxマシンで次のcmdを実行します。
Sudo sysctl -w \
net.ipv4.tcp_keepalive_time=600 \
net.ipv4.tcp_keepalive_intvl=60 \
net.ipv4.tcp_keepalive_probes=3
同様に、次のTomcat接続プールプロパティを含めました。
Tomcat:
max-active: 10
initial-size: 5
max-idle: 8
min-idle: 5
test-on-borrow: true
test-while-idle: true
test-on-return: false
test-on-connect: true
validation-query: SELECT 1
validation-interval: 30000
max-wait: 30000
min-evictable-idle-time-millis: 60000
time-between-eviction-runs-millis: 5000
remove-abandoned: true
remove-abandoned-timeout: 60
解決策はこのブログポストから来ました: ELASTICSEARCHでNODENOTAVAILABLEの例外を扱う
アイドル接続のクローズを防ぐ別の方法があります。この問題は、15分後にアイドル接続を閉じるデフォルトのスウォームサービスディスカバリに関連しています。
明示的に指定されたdnsrr
エンドポイントモード は問題を解決します。例:
version: '3.3'
services:
foo-service:
image: example/foo-service:latest
hostname: foo-service
networks:
- foo_network
deploy:
endpoint_mode: dnsrr
# ...
networks:
foo_network:
external: true
driver: overlay