简体   繁体   中英

“keep-alive” header on connections created by keycloak's java adapter

I'm using Keycloak's java adapter in an application and would like to ensure that all the connections in the connection pool maintained by the adapter have "keep-alive" strategy when created.

Is there a way through configuration (or even changing the code) to do this?

For anyone not wanting to fork the Keycloak library, you can alter the client after the KeycloakDeploymentBuilder builds your KeycloakDeployment instance.

The code below will cause a default keep-alive strategy of 60 seconds as long as the DefaultConnectionKeepAliveStrategy does not find a value greater than 0 in any "Keep-Alive" headers returned to the client.

Keep in mind that this value is not used by the underlying DefaultRequestDirector if the reuseStrategy is not returning true. This is controlled by the "Connection: keep-alive" header in the response. You could also create code to set a default for the reuseStrategy as well if needed.

final KeycloakDeployment keycloakDeployment = KeycloakDeploymentBuilder.build(config);


final long connectionTimeOutSeconds = 60;
final HttpClient client = keycloakDeployment.getClient();
if(client instanceof AbstractHttpClient) {
    ((AbstractHttpClient) client).setKeepAliveStrategy(new CustomConnectionKeepAliveStrategy(connectionTimeOutSeconds));
}

////////////////////////////////////////////////////////

import org.apache.http.HttpResponse;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.protocol.HttpContext;

public class CustomConnectionKeepAliveStrategy extends DefaultConnectionKeepAliveStrategy {


   private final long defaultKeepAliveDurationInSeconds;

   public CustomConnectionKeepAliveStrategy(long defaultKeepAliveDurationInSeconds) {
       this.defaultKeepAliveDurationInSeconds = defaultKeepAliveDurationInSeconds;
   }

   @Override
   public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
       long keepAliveDuration = super.getKeepAliveDuration(response, context);

       if(keepAliveDuration > 0) {
           return keepAliveDuration;
       }

       return defaultKeepAliveDurationInSeconds * 1000;
   }
}

It should also be noted that the Keycloak server I work with returns a Connection: keep-alive header, so my connections were already being reused. My problem was that the default behavior is then to keep connections alive forever. This was causing issues as our firewall with Kubernetes Ingress was dropping the connection and our application was then intermittently failing to talk to Keycloak. The above code causes the connections to be thrown away when they become stale (older than 1 minutes in our case). The underlying Java http libraries will update the connection's expiry date so that connections which were recently used do not get thrown away.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM