<!-- 使用httpclient的实现,带连接池 -->
<bean id="pollingConnectionManager" class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager">
<!--整个连接池的并发-->
<property name="maxTotal" value="1000"/>
<!--每个主机的并发-->
<property name="defaultMaxPerRoute" value="1000"/>
</bean>
<bean id="httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder" factory-method="create">
<property name="connectionManager" ref="pollingConnectionManager"/>
<!--关闭重试, 默认是3次, 0 代表不重试-->
<property name="retryHandler">
<bean class="org.apache.http.impl.client.DefaultHttpRequestRetryHandler">
<constructor-arg value="0"/>
<constructor-arg value="false"/>
</bean>
</property>
<property name="defaultHeaders">
<list>
<bean class="org.apache.http.message.BasicHeader">
<constructor-arg value="User-Agent"/>
<constructor-arg value="Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36"/>
</bean>
<bean class="org.apache.http.message.BasicHeader">
<constructor-arg value="Accept-Encoding"/>
<constructor-arg value="gzip,deflate"/>
</bean>
<bean class="org.apache.http.message.BasicHeader">
<constructor-arg value="Accept-Language"/>
<constructor-arg value="zh-CN"/>
</bean>
</list>
</property>
</bean>
<bean id="httpClient" factory-bean="httpClientBuilder" factory-method="build"/>
<!-- 使用HttpClient实现 -->
<bean id="clientHttpRequestFactory"
class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
<constructor-arg ref="httpClient"/>
<!--连接超时时间,毫秒-->
<property name="connectTimeout" value="60000"/>
<!--读写超时时间,毫秒-->
<property name="readTimeout" value="60000"/>
<!--连接不够用的等待时间,不宜过长,必须设置,比如连接不够用时,时间过长将是灾难性的 -->
<property name="connectionRequestTimeout" value="200"/>
<!-- 缓冲请求数据,默认值是true。通过POST或者PUT大量发送数据时,建议将此属性更改为false,以免耗尽内存-->
<property name="bufferRequestBody" value="true"/>
</bean>
<!-- 配置带有连接池的org.springframework.web.client.RestTemplate -->
<alias name="defaultRestTemplate" alias="restTemplate"/>
<bean id="defaultRestTemplate" class="org.springframework.web.client.RestTemplate">
<constructor-arg ref="clientHttpRequestFactory"/>
<property name="errorHandler">
<bean class="org.springframework.web.client.DefaultResponseErrorHandler"/>
</property>
<!--添加内容转换器-->
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />
<bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter" />
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
<!-- <value>application/octet-stream</value>-->
</list>
</property>
</bean>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
<value>application/xml;charset=UTF-8</value>
</list>
</property>
</bean>
<bean class="org.springframework.http.converter.FormHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/x-www-form-urlencoded</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
<!-- 在代码中使用@Async("executor")开启异步任务 -->
<task:executor id="executor" pool-size="10-100" queue-capacity="10" keep-alive="10" rejection-policy="CALLER_RUNS"/>
<task:annotation-driven executor="executor"/>
// 通过代码配置RestTemplate的Http连接池
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setDefaultMaxPerRoute(1000);
connectionManager.setMaxTotal(1000);
this.restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory(
HttpClientBuilder.create().setConnectionManager(connectionManager).build()
));
// 使用Reactor+SpringMVC可以实现异步,WebFlux中直接使用WebClient实例来异步请求
// 相当于RestTemplate、AsyncRestTemplate是SpringMVC中的【RestTemplate + Reactor可以变成和WebClient一样的效果,AsyncRestTemplate是一个轻量的异步实现】,WebClient是WebFlux中的,但是WebClient性能更好
Mono.fromCallable(() -> restTemplate.getForObject(TARGET_HOST + "/hello/" + latency, String.class))
.subscribeOn(Schedulers.elastic());
********************************* 不积跬步无以至千里,不积小流无以成江海 *********************************