application.properties
ファイルには...
server.port=8086
server.connection-timeout=15000
サーバーがポート8086で実行されているため、ファイルが正しくロードされていることがわかります。
アプリケーションにはRestController
があります
@RestController
class TestController {
@GetMapping()
fun getValues(): ResponseEntity<*> {
return someLongRunningProcessPossiblyHanging()
}
}
エンドポイントを呼び出すと、リクエストがタイムアウトすることはなく、無期限にハングするだけです。
何か不足していますか?
注: Tomcatはこのフィールドをミリ秒単位ではなく分単位で使用することも通知されました(むしろ珍しい選択IMO)。これを1分を示すserver.connection-timeout=1
に設定しようとしましたが、これも機能しませんでした。
注:望まないanotherHTTPリクエストにより前のリクエストがタイムアウトし、各HTTPリクエストにタイムアウトになりすぎて、リクエストを処理するには時間がかかりすぎます。
connection-timeout
は、長時間実行される要求には適用されません。サーバーがクライアントが何かを言うのを待つとき、それは最初の接続に適用されます。
Tomcatドキュメント(Spring Bootではありません)として定義接続を受け入れた後、リクエストURI行が表示されるまでこのコネクタが待機するミリ秒数[...]
設定server.connection-timeout=4000
をテストするには、netcat
を使用して接続しますが、HTTPリクエスト/ヘッダーは送信しません。私は得る:
$ time nc -vv localhost 1234
Connection to localhost 1234 port [tcp/*] succeeded!
real 0m4.015s
user 0m0.000s
sys 0m0.000s
代替案
1)Async
brightinventions.pl-Spring MVCスレッドプールタイムアウト :から
Spring MVCでは、非同期メソッドを使用しない限り、タイムアウトを設定する方法はありません。非同期メソッドでは、spring.mvc.async.request-timeout =を使用して、非同期リクエスト処理がタイムアウトするまでの時間(ミリ秒単位)を設定できます。
spring.mvc.async.request-timeout=4000
を設定しましたが、これでブラウザでタイムアウトが発生します:
@GetMapping("/test-async")
public Callable<String> getFoobar() {
return () -> {
Thread.sleep(12000); //this will cause a timeout
return "foobar";
};
}
Spring Boot REST API-request timeout? を参照してください。
2)サーブレットフィルター
別の解決策は、サーブレットフィルターを使用することです brightinventions.pl-Spring MVCでのリクエストタイムアウト (Kotlin):
override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, filterChain: FilterChain) {
val completed = AtomicBoolean(false)
val requestHandlingThread = Thread.currentThread()
val timeout = timeoutsPool.schedule({
if (completed.compareAndSet(false, true)) {
requestHandlingThread.interrupt()
}
}, 5, TimeUnit.SECONDS)
try {
filterChain.doFilter(request, response)
timeout.cancel(false)
} finally {
completed.set(true)
}
}
3)Tomcatスタックスレッド検出バルブ?
Tomcatには スタックスレッド検出バルブ がありますが、Spring Bootを使用してプログラムで設定できるかどうかはわかりません。
エンドポイントを呼び出すと、リクエストがタイムアウトすることはなく、無期限にハングするだけです。
server.connection-timeout
はリクエストのタイムアウトではありません。これは、アイドル接続、つまり、すでに要求/応答ペアがあり、サーバーが2番目の要求を待機している接続のタイムアウトです。基本的にはサーバー側の読み取りタイムアウトです。