有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java线程已经开始阻塞实现ClientHttpRequestInterceptor的post

已经实现了一个请求拦截器,该拦截器将auth头添加到输出请求并执行,但似乎在添加该拦截器后,我的服务在30分钟左右开始提供504s newrelic,我可以看到活动线程接近200个,创建资源紧缩和o获取线程转储,我可以看到所有线程都被卡住了。 拦截器内部

ClientHttpResponse response = clientHttpRequestExecution.execute(httpRequest, body);

我仔细阅读了这篇文章,认为连接池可能已经耗尽,因为默认池大小是每台主机5个,因此我将其添加到最大100个,每台主机50个,以确保此池不会在其他客户端调用中共享。这确实有助于解决一些问题,但大约90分钟后,开始出现相同的问题。这让它成为一颗滴答作响的定时炸弹

   @SneakyThrows
    @Override
    public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] body, ClientHttpRequestExecution clientHttpRequestExecution) {

            httpRequest.getHeaders().put("Authorization", Collections.singletonList(String.format(TOKEN_FORMAT, getAuthorizationToken())));
            
            httpRequest.getHeaders().add(header1);
            httpRequest.getHeaders().add(AUTHENTICATION_META_HEADER, header2);
            
            ClientHttpResponse response = clientHttpRequestExecution.execute(httpRequest, body);
            
            
            if (response.getStatusCode() == HttpStatus.UNAUTHORIZED && response.getHeaders().get(AUTHENTICATE_HEADER).stream().anyMatch(parameter -> parameter.contains(TOKEN_EXPIRED))) {
                
                httpRequest.getHeaders().put("Authorization", Collections.singletonList(String.format(TOKEN_FORMAT, refreshAuthorizationToken())));
                
                response = clientHttpRequestExecution.execute(httpRequest, body);
            }
            if (response.getStatusCode() == HttpStatus.UNAUTHORIZED || response.getStatusCode() == HttpStatus.FORBIDDEN) {
                Profiler.increment("authorization_failed");
            }
            return response;
        
    }
<bean id="outboundRestTemplateForAuthNZ" class="org.springframework.web.client.RestTemplate">
        <constructor-arg>
            <bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
                <constructor-arg name="httpClient" ref="outboundHttpClient"/>
                <property name="readTimeout" value="10000"/>
                <property name="connectTimeout" value="10000"/>
            </bean>
        </constructor-arg>
        <property name="messageConverters">
            <list>
                <ref bean="outboundHttpJSONMessageConverter"/>
            </list>
        </property>
        <property name="interceptors">
            <list>
                <ref bean="interceptor1"/>
                <ref bean="authNZClientRequestInterceptor"/>
            </list>
        </property>
    </bean>
    <bean id="outboundPoolingHttpClientConnManager" class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager">
        <property name="maxTotal" value="100"/>
        <property name="defaultMaxPerRoute" value="50"/>
    </bean>

    <bean id="outboundHttpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder" factory-method="create">
        <property name="connectionManager" ref="outboundPoolingHttpClientConnManager"/>
    </bean>

    <bean id="outboundHttpClient" factory-bean="outboundHttpClientBuilder" factory-method="build"/>

我是否遗漏了一些导致资源短缺的因素,或者仅仅是我需要根据我的流量需求配置非常高的值 目前,我在这里将池大小定义为

<property name="maxTotal" value="100"/>
<property name="defaultMaxPerRoute" value="50"/>

或者在同一个请求上有多个拦截器不是一个好的做法吗

考虑到令牌只有在我们得到401时才会刷新,甚至那个调用也需要5-10毫秒,所以这不会造成瓶颈


共 (0) 个答案