Tomcat安全
httpclient的两个重要的参数maxPerRoute及MaxTotal
httpclient的连接池3个参数
HTTP请求时connectionRequestTimeout 、connectionTimeout、socketTimeout三个超时时间的含义
1.connectionRequestTimout:指从连接池获取连接的timeout
2.connetionTimeout:指客户端和服务器建立连接的timeout,
就是http请求的三个阶段,一:建立连接;二:数据传送;三,断开连接。超时后会ConnectionTimeOutException
3.socketTimeout:指客户端和服务器建立连接后,客户端从服务器读取数据的timeout,超出后会抛出SocketTimeOutException
httpclient封装了java中进行http网络请求的底层实现,是一个被广泛使用的组件。
httpclient是支持池化机制的,这两个参数maxPerRoute及MaxTotal就是表示池化设置的。
服务之间发送http请求常用的有Apache的Fluent以及spring的restTemplate等。对httpclient进行封装的有:Apache的Fluent、es的restHighLevelClient、spring的restTemplate等。
以ES的restHighLevelClient为例说明
- /**
- * Creates a new {@link RestClient} based on the provided configuration.
- */
- public RestClient build() {
- if (failureListener == null) {
- failureListener = new RestClient.FailureListener();
- }
- CloseableHttpAsyncClient httpClient = AccessController.doPrivileged(new PrivilegedAction<CloseableHttpAsyncClient>() {
- @Override
- public CloseableHttpAsyncClient run() {
- return createHttpClient();
- }
- });
- RestClient restClient = new RestClient(httpClient, defaultHeaders, nodes,
- pathPrefix, failureListener, nodeSelector, strictDeprecationMode);
- httpClient.start();
- return restClient;
- }
- private CloseableHttpAsyncClient createHttpClient() {
- //default timeouts are all infinite
- RequestConfig.Builder requestConfigBuilder = RequestConfig.custom()
- .setConnectTimeout(DEFAULT_CONNECT_TIMEOUT_MILLIS)
- .setSocketTimeout(DEFAULT_SOCKET_TIMEOUT_MILLIS);
- if (requestConfigCallback != null) {
- requestConfigBuilder = requestConfigCallback.customizeRequestConfig(requestConfigBuilder);
- }
- try {
- HttpAsyncClientBuilder httpClientBuilder = HttpAsyncClientBuilder.create().setDefaultRequestConfig(requestConfigBuilder.build())
- //default settings for connection pooling may be too constraining
- .setMaxConnPerRoute(DEFAULT_MAX_CONN_PER_ROUTE).setMaxConnTotal(DEFAULT_MAX_CONN_TOTAL)
- .setSSLContext(SSLContext.getDefault())
- .setTargetAuthenticationStrategy(new PersistentCredentialsAuthenticationStrategy());
- if (httpClientConfigCallback != null) {
- httpClientBuilder = httpClientConfigCallback.customizeHttpClient(httpClientBuilder);
- }
- final HttpAsyncClientBuilder finalBuilder = httpClientBuilder;
- return AccessController.doPrivileged(new PrivilegedAction<CloseableHttpAsyncClient>() {
- @Override
- public CloseableHttpAsyncClient run() {
- return finalBuilder.build();
- }
- });
- } catch (NoSuchAlgorithmException e) {
- throw new IllegalStateException("could not create the default ssl context", e);
- }
- }
例子2:Apache的Fluent,其Executor类
- /**
- * An Executor for fluent requests
- * <p/>
- * A {@link PoolingHttpClientConnectionManager} with maximum 100 connections per route and
- * a total maximum of 200 connections is used internally.
- */
- //最大100 connections per route 以及 最大200个 connection
- CONNMGR = new PoolingHttpClientConnectionManager(sfr);
- CONNMGR.setDefaultMaxPerRoute(100);
- CONNMGR.setMaxTotal(200);
- CLIENT = HttpClientBuilder.create().setConnectionManager(CONNMGR).build();
maxPerRoute及MaxTotal参数含义
maxPerRoute及MaxTotal这两个参数的含义是什么呢?
下面用测试代码说明一下
测试端
- public class HttpFluentUtil {
- private Logger logger = LoggerFactory.getLogger(HttpFluentUtil.class);
- private final static int MaxPerRoute = 2;
- private final static int MaxTotal = 4;
- final static PoolingHttpClientConnectionManager CONNMGR;
- final static HttpClient CLIENT;
- final static Executor EXECUTOR;
- static {
- LayeredConnectionSocketFactory ssl = null;
- try {
- ssl = SSLConnectionSocketFactory.getSystemSocketFactory();
- } catch (final SSLInitializationException ex) {
- final SSLContext sslcontext;
- try {
- sslcontext = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
- sslcontext.init(null, null, null);
- ssl = new SSLConnectionSocketFactory(sslcontext);
- } catch (final SecurityException ignore) {
- } catch (final KeyManagementException ignore) {
- } catch (final NoSuchAlgorithmException ignore) {
- }
- }
- final Registry<ConnectionSocketFactory> sfr = RegistryBuilder.<ConnectionSocketFactory>create()
- .register("http", PlainConnectionSocketFactory.getSocketFactory())
- .register("https", ssl != null ? ssl : SSLConnectionSocketFactory.getSocketFactory()).build();
- CONNMGR = new PoolingHttpClientConnectionManager(sfr);
- CONNMGR.setDefaultMaxPerRoute(MaxPerRoute);
- CONNMGR.setMaxTotal(MaxTotal);
- CLIENT = HttpClientBuilder.create().setConnectionManager(CONNMGR).build();
- EXECUTOR = Executor.newInstance(CLIENT);
- }
- public static String Get(String uri, int connectTimeout, int socketTimeout) throws IOException {
- return EXECUTOR.execute(Request.Get(uri).connectTimeout(connectTimeout).socketTimeout(socketTimeout))
- .returnContent().asString();
- }
- public static String Post(String uri, StringEntity stringEntity, int connectTimeout, int socketTimeout)
- throws IOException {
- return EXECUTOR.execute(Request.Post(uri).socketTimeout(socketTimeout)
- .addHeader("Content-Type", "application/json").body(stringEntity)).returnContent().asString();
- }
- public static void main(String[] args) {
- HttpUtil httpUtil = new HttpUtil();
- String url = "http://localhost:9064/app/test"; // 服务端sleep 5秒再返回
- for (int i = 0; i < 5; i++) { // MaxPerRoute若设置为2,则5线程分3组返回(2、2、1),共15秒
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- String result = HttpFluentUtil.Get(url, 2000, 2000);
- System.out.println(result);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }).start();
- }
- }
- }
服务器端
很简单的springmvc
- @GetMapping(value="test")
- public String test() throws InterruptedException {
- Thread.sleep(1000);
- return "1";
- }
测试1:测试端MaxPerRoute=5 MaxTotal=4
服务器端结果
可以看到先接收4个请求,处理完成后,再接收下一次剩余的1个请求。即其一次最多接收MaxTotal次请求
测试2:测试端MaxPerRoute=2 MaxTotal=5
服务器端结果
可以看到接收2个请求,2个请求,1个请求,即说明maxPerRoute意思是某一个服务每次能并行接收的请求数量。
什么场景下要设置?
知道了两个参数的含义,那么在什么情况下要对这两个参数进行设置呢?
比如说下面的场景
服务1要通过Fluent调用服务2的接口。服务1发送了400个请求,但由于Fluent默认只支持maxPerRoute=100,MaxTotal=200,比如接口执行时间为500ms,由于maxPerRoute=100,所以要分为100,100,100,100分四批来执行,全部执行完成需要2000ms。而如果maxPerRoute设置为400,全部执行完需要500ms。在这种情况下(提供并发能力时)就要对这两个参数进行设置了。
设置的方法
1、Apache Fluent可以使用上面测试的HttpFluentUtil工具类来执行请求
2、RestTemplate类似使用下面的方式
- @Bean
- public HttpClient httpClient() {
- Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
- .register("http", PlainConnectionSocketFactory.getSocketFactory())
- .register("https", SSLConnectionSocketFactory.getSocketFactory())
- .build();
- PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
- connectionManager.setMaxTotal(restTemplateProperties.getMaxTotal());
- connectionManager.setDefaultMaxPerRoute(restTemplateProperties.getDefaultMaxPerRoute());
- connectionManager.setValidateAfterInactivity(restTemplateProperties.getValidateAfterInactivity());
- RequestConfig requestConfig = RequestConfig.custom()
- .setSocketTimeout(restTemplateProperties.getSocketTimeout())
- .setConnectTimeout(restTemplateProperties.getConnectTimeout())
- .setConnectionRequestTimeout(restTemplateProperties.getConnectionRequestTimeout())
- .build();
- return HttpClientBuilder.create()
- .setDefaultRequestConfig(requestConfig)
- .setConnectionManager(connectionManager)
- .build();
- }
- @Bean
- public ClientHttpRequestFactory httpRequestFactory() {
- return new HttpComponentsClientHttpRequestFactory(httpClient());
- }
- @Bean
- public RestTemplate restTemplate() {
- return new RestTemplate(httpRequestFactory());
- }
其中RestTemplateProperties通过配置文件来配置
- max-total
- default-max-per-route
- connect-timeout 获取连接超时
- connection-request-timeout 请求超时
- socket-timeout 读超时
3、ES的restHighLevelClient设置
- @Bean
- public RestHighLevelClient restHighLevelClient(){
- //解析hostlist配置信息
- String[] split = hostlist.split(",");
- //创建HttpHost数组,其中存放es主机和端口的配置信息
- HttpHost[] httpHostArray = new HttpHost[split.length];
- for(int i=0;i<split.length;i++){
- String item = split[i];
- httpHostArray[i] = new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":")[1]), "http");
- }
- //创建RestHighLevelClient客户端
- //return new RestHighLevelClient(RestClient.builder(httpHostArray));//.setMaxRetryTimeoutMillis(5 * 60 * 1000)); //超时时间设为5分钟);
- RestClientBuilder builder = RestClient.builder(httpHostArray);
- builder.setRequestConfigCallback(requestConfigBuilder -> {
- requestConfigBuilder.setConnectTimeout(connectTimeoutMillis);
- requestConfigBuilder.setSocketTimeout(socketTimeoutMillis);
- requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeoutMillis);
- return requestConfigBuilder;
- });
- builder.setHttpClientConfigCallback(httpClientBuilder -> {
- httpClientBuilder.setMaxConnTotal(maxConnectTotal);
- httpClientBuilder.setMaxConnPerRoute(maxConnectPerRoute);
- return httpClientBuilder;
- });
- return new RestHighLevelClient(builder);
- }
里面的5个变量,通过spring的@Value注入,这里省略。
总结:
- max-total:连接池里的最大连接数
- default-max-per-route:某一个/每服务每次能并行接收的请求数量
- connect-timeout 从连接池里获取连接超时时间
- connection-request-timeout 请求超时时间
- socket-timeout 读超时时间
参考:https://blog.csdn.net/u013905744/java/article/details/94714696
Tomcat安全的更多相关文章
- Tomcat一个BUG造成CLOSE_WAIT
之前应该提过,我们线上架构整体重新架设了,应用层面使用的是Spring Boot,前段日子因为一些第三方的原因,略有些匆忙的提前开始线上的内测了.然后运维发现了个问题,服务器的HTTPS端口有大量的C ...
- docker——容器安装tomcat
写在前面: 继续docker的学习,学习了docker的基本常用命令之后,我在docker上安装jdk,tomcat两个基本的java web工具,这里对操作流程记录一下. 软件准备: 1.jdk-7 ...
- Tomcat shutdown执行后无法退出进程问题排查及解决
问题定位及排查 上周无意中调试程序在Linux上ps -ef|grep tomcat发现有许多tomcat的进程,当时因为没有影响系统运行就没当回事.而且我内心总觉得这可能是tomcat像nginx一 ...
- 记一次tomcat线程创建异常调优:unable to create new native thread
测试在进行一次性能测试的时候发现并发300个请求时出现了下面的异常: HTTP Status 500 - Handler processing failed; nested exception is ...
- Linux CentOS 配置Tomcat环境
一.下载Tomcat 下载Tomcat方式也有两种,可以参考我的前一篇博文Linux CentOS配置JDK环境,这边就不再赘述. 二.在Linux处理Tomcat包 1.创建tomcat文件夹 mk ...
- 在Linux虚拟机下配置tomcat
1.到Apache官网下载tomcat http://tomcat.apache.org/download-80.cgi 博主我下载的是tomcat8 博主的jdk是1.8 如果你们的jdk是1.7或 ...
- tomcat开发远程调试端口以及利用eclipse进行远程调试
一.tomcat开发远程调试端口 方法1 WIN系统 在catalina.bat里: SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.compi ...
- Eclipse中启动tomcat报错java.lang.OutOfMemoryError: PermGen space的解决方法
有的项目引用了太多的jar包,或者反射生成了太多的类,异或有太多的常量池,就有可能会报java.lang.OutOfMemoryError: PermGen space的错误, 我们知道可以通过jvm ...
- mac下安装及配置tomcat
mac下的软件不像windows下的程序那样写注册表,对于tomcat的安装来说,在mac下是名符其实的绿色软件,具体操作如下: 1.到 apache官方主页 下载完整 tar.gz文件包.(没有专门 ...
- 设置tomcat远程debug
查看端口占用情况命令: netstat -tunlp |grep 8000 tomcat 启动远程debug: startup.sh 中的最后一行 exec "$PRGDIR"/& ...
随机推荐
- python学习笔记20(字符串格式化)
Python中内置有对字符串进行格式化的操作% 模板 格式化字符串时,Python使用一个字符串作为模板.模板中有格式符,这些格式符为真实值预留位置,并说明真实数值应该呈现的格式.Python用一个t ...
- 1200: [HNOI2005]木梳 - BZOJ
Description Input 第一行为整数L,其中4<=L<=100000,且有50%的数据满足L<=104,表示木板下侧直线段的长.第二行为L个正整数A1,A2,…,AL ...
- 转Spring+Hibernate+EHcache配置(二)
Spring AOP+EHCache简单缓存系统解决方案 需要使用Spring来实现一个Cache简单的解决方案,具体需求如下:使用任意一个现有开源Cache Framework,要求可以Cache系 ...
- C++中cin、cin.get()、cin.getline()、getline()、gets()等函数的用法
学C++的时候,这几个输入函数弄的有点迷糊:这里做个小结,为了自己复习,也希望对后来者能有所帮助,如果有差错的地方还请各位多多指教(本文所有程序均通过VC 6.0运行) 1.cin 2.cin.get ...
- uploadify 下载组件使用技巧和在线预览 word,excel,ppt,pdf的方案
http://www.cnblogs.com/wolf-sun/p/3565184.html uploadify 上传工具的使用技巧 http://www.cnblogs.com/wolf-sun/p ...
- 多线程 (四)GCD
学习GCD要掌握几个概念 任务:需要执行的代码块可以看作一个任务 队列:把任务放到队列里,遵循先进先出的原则 队列又分为串行队列和并行队列 串行队列:顺序执行 并发队列:同时执行多个任务 同步:在当前 ...
- CURL与PHP-CLI的应用【CLI篇】
CLI的普通应用 什么是PHP-CLI php-cli是php Command Line Interface的简称,即PHP命令行接口,在windows和linux下都是支持PHP-CLI模式的; 为 ...
- 跨平台的目录遍历实现方法(windows和linux已经测试)
dirent.h是gcc下的一个头文件,在windows中是没有的.这个文件中封装了几个对目录进行操作函数: static DIR *opendir (const char *dirname);sta ...
- QDialog之屏蔽Esc键(过滤,或者丢弃)
http://blog.csdn.net/u011012932/article/details/50357323
- P154、面试题28:字符串的排列
题目:输入一个字符串,打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a.b.c所能排列出来的所有字符串abc.acb.bac.bca.cab.cba. 测试用例: 1)功能测试( ...