-
Notifications
You must be signed in to change notification settings - Fork 596
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Akka Http Client pool connections are not reestablished after DNS positive-ttl #1226
Comments
That seems to be the case because akka's DNS resolver is based on JVM's You can already observe the behavior by just using It seems the JVM DNS caching layer is configured using |
Thank you @jrudolph for a quick response. The problem is not related to JVM's DNS resolver unfortunately, that would be something easy to fix. I've done a quick investigation too. According to logs from Akka, a hostname is only resolved when a new connection is created. Example:
In my case, because of high TPS (no idle connections) and the fact that the depricated server_A is still running and responding, a new connection is never created. After changing DNS entry, Akka Http client uses existing connection pool. Please correct me if I'm wrong, in that case 'positive-ttl' has no effect, because Akka Http client does not create new connections and not resolve the hostname. |
Yes, that's correct. I guess if you need connections to be refreshed we would need to add another feature to restrict the life-time of persistent connections (which could be a reasonable thing to do). |
I suspect that this is causing issues on our end where the underlying host isn't getting updated due to dns timeout not being honoured, is there a workaround for this? |
@mdedetrich I think so far it isn't clear what could or should be done on the Akka HTTP level. So far, the only confirmed "issue" in Akka Http is that it keeps active persistent connections open for as long as possible. I'd say that's pretty reasonable behavior. Why make a new connection (potentially to a new IP address) when the old one is still alive and serving requests? Or are you seeing something different? Can the server be changed to close connections after a while? Are there any other HTTP clients that actually couple DNS lifetimes with lifetimes of pool connections? |
That said, we might want to an API to give users more control over the pools. This could e.g. be a method that requests to close all connections to a given host without shutting down that pool completely. |
square/okhttp#3374 also suggested to solve this on the server side / loadbalancer. |
This is the reason I got interested in the thread. Regardless of the mechanism that you use to convert a "host reference" to a pool of servers, (DNS, LB) you end up with a pool of persistent connections. So let's say you have two servers A, B. Your client establishes a connection pool with roughly the same number of connections to each of the two, because balancing load is what your "host reference" is for. A connection lifetime (either in duration or request count) would help solve this by gradually rebalancing the connection pool. |
I agree that this would probably help. But also note, that you are pushing a backend issue to the client here. I think this issue can be seen as evidence that this is a brittle solution that requires full control over all sides of the connections. |
@jrudolph My issue was actually unrelated, so you can ignore my earlier comment |
Hi there I guess, it would be nice and meaningful to have behaviour similar to what Finagle did for their client. |
@imliar could you explain how this is related to this ticket? I tried to understand the documentation but from a glance I didn't understand what this is about? Maybe it's because finagle is about services while akka-http is only concerned about http?
I guess you mean |
@jrudolph Yes, but no Watermark connection pool is just one of mechanics for a pooling when you have minimal and maximal amount of connections in pool, and as far as you have more load than minimal amount of connections could serve, it will increase em up to higher mark. Connection shut down could be achieved with any pooling, but with WM amount of connections will never go down to zero (unless it's not specifically defined by configuration) resulting to cold connection pool. It could be a different topic ofc |
Sounds like our |
@jrudolph an example that doesn't involve any back-ends failing is gradual traffic switch. If that is achieved by having two load balances and a weighted DNS resolution (e.g. how AWS Route 53 does it), then the issue cannot be solved on load balancer level (as suggested referencing okhttp), since the traffic is actually getting diverted from one LB to another. In this case the only solution I'm aware of is to forcefully kill the "old" LB, thus throwing 5xx, which will kill connections on client's side and force akka-http to re-establish new connections, which in its turn resolves DNS. Doing so at high load, results in significant amount of errors and most likely opening a circuit breaker. And nether client nor server are happy about that. |
If it's gradual the load balancer can start to close idle persistent
connections and send connection:close headers, there's no need to send out
50x when it's not urgent.
|
@jrudolph I feel like there is chicken and egg problem here. Connections will never become idle because client will never move traffic away from old LB / stack. This is actually what we are trying to achieve - force client to start sending requests to new stack. |
@jrudolph do you consider any solution for the issue? Do you have any idea at least for workaround? |
@jrudolph I agree with @agorski and @alivanni and don't see a way how to workaround outside of akka-http. I cannot make additional arguments, but please consider it a real issue, it's critical to my team by causing trouble in production and if there is no solution we have to migrate away from akka-http client unfortunately (and I know another team in Zalando who did also because of this). |
There is a PR in progress which adds |
Related to #1768. We are aware and agree this is an area where we plan to improve. We're currently working on improving our DNS infrastructure and one of the next steps is to also take into account the TTL. |
My team is facing a related problem and needed some guidance regarding the same. We are using scredis library to connect to AWS redis. On change of ip of the redis node, re resolution of the host is not being attempted. The relevant section application conf setting is :
The relevant versions we are using are:
From the logs we see when the older ip address ceases to respond the reconnection attempt happens to older ip rather than trying to re resolve the hostname:
So in spite of connection being shut down the new connection does not re resolve the hostname. Could you direct us to what the reason could be. |
You can enable debug logging to see what the |
A more automatic solution (implementing what the title of this issue says) could be to add some logic to do manual DNS resolution directly in the pool using the |
We have found that under some circumstances, Akka's Http client is not honoring the positive-ttl expiry value, not picking up new DNS entries.
It looks as if under load, and using the default http connection pool, the client will never try resolving again the DNS entry if the connection is not closed, regardless of the positive-ttl value.
Steps to reproduce:
0. Using akka-http 10.0.6 and akka-core 2.5.2
test.com
toserver_A
withip_A
dns.inet-address { positive-ttl = 30s negative-ttl = 30s }
test.com
/etc/hosts
, for instance) to point toip_B
. NOTE:server_A
withip_A
is still running.Expected behaviour:
ip_B
.Current behaviour:
ip_A
.The text was updated successfully, but these errors were encountered: