前言:
今天兄弟们对“apache开启ip访问不了”大致比较珍视,各位老铁们都需要知道一些“apache开启ip访问不了”的相关资讯。那么小编也在网摘上网罗了一些对于“apache开启ip访问不了””的相关内容,希望咱们能喜欢,你们一起来了解一下吧!最近网关发版出现大量如下异常,而有如下文章:
org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
两个主机建立网络连接是一个比较复杂的过程,涉及到多个数据包的交换。建立网络连接本身就很耗时间,而 Http 连接需要三次握手,开销就更大。但是可以直接使用已经建立好的 Http 连接,那么花费就比较小。耗时更短,从而提高访问的吞吐量。
传统的 HttpURLConnection 并不支持连接池,如果要实现连接池机制,那么需要自己来管理连接对象。对于网络请求这种底层相对复杂的操作,没有一定经验的程序员很难写好这块代码逻辑。
除了 HttpURLConnection,常用的Http Client 要数 Apache 的 HttpClient。一般情况下, HttpClient 已经能满足业务需求了;但是在网关这种高并发场景下,使用 HttpClient 进行大量的请求网络,还是需要用连接池才能提高网关的TPS,不然很容易成为网关的瓶颈。
Apache 的 HttpClient的早期版本,提供了PoolingClientConnectionManager、DefaultHttpClient 等类来实现 Http 连接池,但这些类在 4.3.x 版本之后大部分已过时。后续版本提供了PoolingHttpClientConnectionManager 等类进行 Http 连接池的实现。PoolingHttpClientConnectionManager 是一个 Http 连接池管理器,用来服务于多线程时并发获取连接的请求。每个路由(IP)将池化不大于 defaultMaxPerRoute 参数的连接。
pom.xml 文件引入依赖
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version></dependency><dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.15</version></dependency><dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient-cache</artifactId> <version>4.5.13</version></dependency>
定义连接池主要参数
public class HttpPoolProperties { private Integer maxTotal; private Integer maxRoute; private Integer defaultMaxPerRoute; private String hostName; private Integer port; private Integer connectTimeout; private Integer connectionRequestTimeout; private Integer socketTimeout; private Integer validateAfterInactivity; // TODO 省略get set 方法}maxTotal:允许跨所有路线的最大连接数defaultMaxPerRoute:所有路由默认最大连接数maxPerRoute:指定某个路由的最大连接数
defaultMaxPerRoute 与 maxPerRoute 这两个参数存在优先级关系。具体可以参看 AbstractConnPool 类的如下方法的引用关系
private int getMax(T route) { Integer v = (Integer)this.maxPerRoute.get(route); return v != null ? v : this.defaultMaxPerRoute;}connectTimeout:多久等待与远程服务器抛出超时异常之前建立连接socketTimeout:多久等待服务器抛出超时异常之前,各种消息响应connectionRequestTimeout:多久试图抛出异常之前,先从连接池中的连接时等待(连接池不会立即返回,如果所有的连接被检出)staleConnectionCheckEnabled:可以在潜在的 IOExceptions 成本的性能有所提高被禁用
获取 HttpClient 对象
public static CloseableHttpClient createHttpClient(HttpPoolProperties httpPoolProperties) { ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory(); LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory.getSocketFactory(); Registry<ConnectionSocketFactory> registry = RegistryBuilder .<ConnectionSocketFactory> create().register("http", plainsf) .register("https", sslsf).build(); PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager( registry); // 将最大连接数增加 cm.setMaxTotal(httpPoolProperties.getMaxTotal()); // 将每个路由基础的连接增加 cm.setDefaultMaxPerRoute(httpPoolProperties.getDefaultMaxPerRoute()); if(StringUtils.hasText(httpPoolProperties.getHostName()) && httpPoolProperties.getPort()!=null) { HttpHost httpHost = new HttpHost(httpPoolProperties.getHostName(), httpPoolProperties.getPort()); // 将目标主机的最大连接数增加 cm.setMaxPerRoute(new HttpRoute(httpHost), httpPoolProperties.getMaxRoute()); } // 请求重试处理 HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() { public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { // 如果已经重试了5次,就放弃 if (executionCount >= 5) { return false; } // 如果服务器丢掉了连接,那么就重试 if (exception instanceof NoHttpResponseException) { return true; } // 不要重试SSL握手异常 if (exception instanceof SSLHandshakeException) { return false; } // 超时 if (exception instanceof InterruptedIOException) { return false; } // 目标服务器不可达 if (exception instanceof UnknownHostException) { return false; } // 连接被拒绝 if (exception instanceof ConnectTimeoutException) { return false; } // SSL握手异常 if (exception instanceof SSLException) { return false; } HttpClientContext clientContext = HttpClientContext .adapt(context); HttpRequest request = clientContext.getRequest(); // 如果请求是幂等的,就再次尝试 if (!(request instanceof HttpEntityEnclosingRequest)) { return true; } return false; } }; CloseableHttpClient httpClient = HttpClients.custom() .setConnectionManager(cm) .setRetryHandler(httpRequestRetryHandler).build(); return httpClient;}
记得点「赞」和「在看」↓
爱你们
标签: #apache开启ip访问不了