From a4a7e8bcbd2283257be4d4bbd5e5188003064293 Mon Sep 17 00:00:00 2001 From: Martynas Date: Fri, 13 Dec 2024 22:24:30 +0100 Subject: [PATCH] Set `mem_limit` on `linkeddatahub` service Set a custom `HttpRequestRetryHandler` lambda on the `ApacheConnector` --- docker-compose.yml | 5 ++- .../atomgraph/linkeddatahub/Application.java | 41 ++++++++++++++++++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 26a5f9a7b..25109191c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,6 +28,7 @@ services: linkeddatahub: user: root # otherwise the ldh user does not have permissions to the mounted folder which is owner by root build: . + mem_limit: 2048m depends_on: - fuseki-admin - fuseki-end-user @@ -117,7 +118,7 @@ services: - CLIENT_HOST=linkeddatahub - VARNISH_SIZE=1G entrypoint: /bin/sh -c "cp /etc/varnish/default.vcl.template /etc/varnish/default.vcl && sed -i 's|$${BACKEND_HOST}|'"$$BACKEND_HOST"'|g' /etc/varnish/default.vcl && sed -i 's|$${BACKEND_PORT}|'"$$BACKEND_PORT"'|g' /etc/varnish/default.vcl && sed -i 's|$${CLIENT_HOST}|'"$$CLIENT_HOST"'|g' /etc/varnish/default.vcl && /usr/local/bin/docker-varnish-entrypoint \"$$0\" \"$$@\"" - command: [ "-t", "86400" ] # time to live + command: [ "-t", "86400", "-p", "timeout_idle=60s" ] # time to live volumes: - ./platform/varnish-backend.vcl.template:/etc/varnish/default.vcl.template:ro varnish-end-user: @@ -132,7 +133,7 @@ services: - CLIENT_HOST=linkeddatahub - VARNISH_SIZE=1G entrypoint: /bin/sh -c "cp /etc/varnish/default.vcl.template /etc/varnish/default.vcl && sed -i 's|$${BACKEND_HOST}|'"$$BACKEND_HOST"'|g' /etc/varnish/default.vcl && sed -i 's|$${BACKEND_PORT}|'"$$BACKEND_PORT"'|g' /etc/varnish/default.vcl && sed -i 's|$${CLIENT_HOST}|'"$$CLIENT_HOST"'|g' /etc/varnish/default.vcl && /usr/local/bin/docker-varnish-entrypoint \"$$0\" \"$$@\"" - command: [ "-t", "86400" ] # time to live + command: [ "-t", "86400", "-p", "timeout_idle=60s" ] # time to live volumes: - ./platform/varnish-backend.vcl.template:/etc/varnish/default.vcl.template:ro email-server: diff --git a/src/main/java/com/atomgraph/linkeddatahub/Application.java b/src/main/java/com/atomgraph/linkeddatahub/Application.java index f1d51f147..a18fd0260 100644 --- a/src/main/java/com/atomgraph/linkeddatahub/Application.java +++ b/src/main/java/com/atomgraph/linkeddatahub/Application.java @@ -204,7 +204,9 @@ import net.sf.saxon.s9api.XsltExecutable; import nu.xom.XPathException; import org.apache.http.HttpClientConnection; +import org.apache.http.HttpHost; import org.apache.http.HttpResponse; +import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.ConnectionKeepAliveStrategy; @@ -214,6 +216,7 @@ import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.HttpCoreContext; import org.apache.jena.query.DatasetFactory; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.rdf.model.ResIterator; @@ -230,7 +233,6 @@ import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.apache.connector.ApacheClientProperties; -import org.glassfish.jersey.apache.connector.ApacheConnectionClosingStrategy; import org.glassfish.jersey.apache.connector.ApacheConnectorProvider; import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.client.RequestEntityProcessing; @@ -1384,7 +1386,8 @@ public void releaseConnection(final HttpClientConnection managedConn, final Obje }; if (maxConnPerRoute != null) conman.setDefaultMaxPerRoute(maxConnPerRoute); if (maxTotalConn != null) conman.setMaxTotal(maxTotalConn); - + int maxRetryCount = 3; + ClientConfig config = new ClientConfig(); config.connectorProvider(new ApacheConnectorProvider()); config.register(MultiPartFeature.class); @@ -1396,6 +1399,23 @@ public void releaseConnection(final HttpClientConnection managedConn, final Obje config.property(ClientProperties.FOLLOW_REDIRECTS, true); config.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.BUFFERED); // https://stackoverflow.com/questions/42139436/jersey-client-throws-cannot-retry-request-with-a-non-repeatable-request-entity config.property(ApacheClientProperties.CONNECTION_MANAGER, conman); + config.property(ApacheClientProperties.RETRY_HANDLER, (HttpRequestRetryHandler) (IOException ex, int executionCount, HttpContext context) -> + { + // Extract the HTTP host from the context + HttpHost targetHost = (HttpHost) context.getAttribute(HttpCoreContext.HTTP_TARGET_HOST); + String serverName = targetHost != null ? targetHost.getHostName() : "Unknown"; + + if (executionCount > maxRetryCount) { + if (log.isWarnEnabled()) log.warn("Maximum tries reached for client HTTP pool to server '{}'", serverName); + return false; + } + if (ex instanceof org.apache.http.NoHttpResponseException) { + if (log.isWarnEnabled()) log.warn("No response from server '{}' on {} call", serverName, executionCount); + return true; + } + return false; + }); + //config.property(ApacheClientProperties.CONNECTION_CLOSING_STRATEGY, new ApacheConnectionClosingStrategy.GracefulClosingStrategy()); if (keepAliveStrategy != null) config.property(ApacheClientProperties.KEEPALIVE_STRATEGY, keepAliveStrategy); @@ -1461,6 +1481,7 @@ public void releaseConnection(final HttpClientConnection managedConn, final Obje }; if (maxConnPerRoute != null) conman.setDefaultMaxPerRoute(maxConnPerRoute); if (maxTotalConn != null) conman.setMaxTotal(maxTotalConn); + int maxRetryCount = 3; ClientConfig config = new ClientConfig(); config.connectorProvider(new ApacheConnectorProvider()); @@ -1473,7 +1494,23 @@ public void releaseConnection(final HttpClientConnection managedConn, final Obje config.property(ClientProperties.FOLLOW_REDIRECTS, true); config.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.BUFFERED); // https://stackoverflow.com/questions/42139436/jersey-client-throws-cannot-retry-request-with-a-non-repeatable-request-entity config.property(ApacheClientProperties.CONNECTION_MANAGER, conman); + config.property(ApacheClientProperties.RETRY_HANDLER, (HttpRequestRetryHandler) (IOException ex, int executionCount, HttpContext context) -> + { + // Extract the HTTP host from the context + HttpHost targetHost = (HttpHost) context.getAttribute(HttpCoreContext.HTTP_TARGET_HOST); + String serverName = targetHost != null ? targetHost.getHostName() : "Unknown"; + if (executionCount > maxRetryCount) { + if (log.isWarnEnabled()) log.warn("Maximum tries reached for client HTTP pool to server '{}'", serverName); + return false; + } + if (ex instanceof org.apache.http.NoHttpResponseException) { + if (log.isWarnEnabled()) log.warn("No response from server '{}' on {} call", serverName, executionCount); + return true; + } + return false; + }); + return ClientBuilder.newBuilder(). withConfig(config). sslContext(ctx).