Reputation: 104
We use okhttp in our Java apps deployed on k8s cluster. Our source app doesn't have istio enabled and connects to destination with envoy sidecar. Connectivity chain looks like this:
SRC --------> Envoy -> DST
So in fact SRC app establish a connection not directly to DST app, but to Envoy proxy in front of it. When DST apps shuts down, it terminates all the connection between DST and Envoy, but connections between SRC and Envoy remains open. That's why SRC app starts to receive 503 errors. Another message from SRC to DST also gets 503 because we keep reusing idle connection established in connection pool of okhttp. Solution to this problem is to reestablish new TCP connection instead of use one of the idle connections from connection pool. Is it possible to configure okhttp to terminate whole TCP connection based on single HTTP 503 received?
Upvotes: 1
Views: 694
Reputation: 3033
Here is what I use in Java 17
private final OkHttpClient client = new OkHttpClient.Builder().addNetworkInterceptor(c -> {
var response = c.proceed(c.request());
if (response.code() == 503) {
c.connection().socket().close();
}
return response;
}).build();
Upvotes: 0
Reputation: 13458
Something like this should work
import okhttp3.OkHttpClient
import okhttp3.Request
fun main() {
val client = OkHttpClient.Builder()
.eventListenerFactory(LoggingEventListener.Factory())
.addNetworkInterceptor { chain ->
chain.proceed(chain.request()).also { response ->
println(response.code)
if (response.code == 503) {
println("closing")
chain.connection()?.socket()?.close()
}
}
}
.build()
val response1 = client.newCall(Request.Builder().url("https://httpbin.org/get").build()).execute()
val response2 = client.newCall(Request.Builder().url("https://httpbin.org/status/503").build()).execute()
val response3 = client.newCall(Request.Builder().url("https://httpbin.org/get").build()).execute()
}
Upvotes: 0