0%

HTTP连接池

高频流数据传输

HTTP连接池

https://www.cnblogs.com/xrq730/p/10963689.html

使用线程池

减少线程创建和和销毁的时间、空间开销

1
2
3
4
This is a demo for testRunWithThreadPool!
cost: 36622ms
This is a demo for testRunWithoutThreadPool!
cost: 1783040ms

HTTP连接池

1
2
3
4
This is a demo for HttpClientWithoutPoolTest!
233ms 163ms 241ms 242ms 129ms
This is a demo for HttpClientWithPoolTest!
219ms 64ms 54ms 65ms 37ms

长短连接

HTTP1.1支持在一个TCP连接上传送多个HTTP请求和响应(复用TCP通道),减少了建立和关闭连接的消耗延迟,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点,这就是长连接,HTTP1.1默认使用长连接。

1
2
Keep-Alive: timeout=5,max=100
//表示tcp连接最多保持5秒,长连接接受100次请求就断开
  • timeout:指定了一个空闲连接需要保持打开状态的最小时长(以秒为单位)。需要注意的是,如果没有在传输层设置 keep-alive TCP message 的话,大于 TCP 层面的超时设置会被忽略。
  • max:在连接关闭之前,在此连接可以发送的请求的最大值。在非管道连接中,除了 0 以外,这个值是被忽略的,因为需要在紧跟着的响应中发送新一次的请求。HTTP 管道连接则可以用它来限制管道的使用。

此外,建立连接使用到了syns queue(半连接队列)与accept queue(全连接队列),不使用长连接而每次连接都重新握手的话,队列一满服务端将会发送一个ECONNREFUSED错误信息给到客户端,这次请求失效;即使不失效,后来的请求需要等待前面的请求处理,排队也会增加响应的时间。

  • http的keep-alive是为了复用已有连接
  • tcp的keep-alive是为了保证对端还存活
1
2
3
4
5
private CloseableHttpClient httpClient = null;
@Before
public void before() {
initHttpClient();
}
1
private CloseableHttpClient httpClient = HttpClients.custom().build();

连接池中的连接数量:假设每秒的调用量12次,根据接口的一个平均响应时长适当加一点余量,差不多设置在15~30比较合适,根据线上运行的实际情况再做调整。

http连接池缺点:过多的长连接会占用服务器资源,导致其他服务受阻;只适用于请求是经常访问同一主机(或同一个接口)的情况下。

HTTPS协议在通信层和应用层之间多了一层TLS ( Transport Layer Security,传输层安全性协议)

多路复用是HTTP2针对HTTP1.1的一大改进,可以在一个tcp连接上同时发起多个请求和接受多个响应,无需一个长连接占着一个请求。

线程池类 ThreadPoolExecutor

ThreadPoolExecutor#execute方法:线程池会对当前自身状态做出判断来决定是否创建新的worker来立即执行task,或者是将task放置在workQueue队列中。

对于线程来讲,如果不需要它返回结果则实现Runnable,而如果需要执行结果的话则可以实现Callable。在线程池同样execute提供一个不需要返回结果的任务执行,而对于需要结果返回的则可调用其submit方法。

ThreadPoolExecutor#runWorker,Worker在执行完任务后,还会循环获取任务队列里的任务执行(其中的getTask方法),也就是说Worker不仅仅是在执行完给它的任务就释放或者结束,它不会闲着,而是继续从任务队列中获取任务,直到任务队列中没有任务可执行时,它才退出循环完成任务。

并发机制的三个特性:原子性、可见性、有序性。synchronized关键字可以保证可见性和有序性却无法保证原子性。AtomicInteger的作用就是为了保证原子性。

new Thread(Runnable target) 将当前线程作为父线程,并继承父线程的线程分组、守护线程标识、classloader、栈大小等,并将传入的Runnable参数作赋值给this.target,在run()方法中,调用了target.run()

http请求步骤

  • 使用帮助类HttpClients创建CloseableHttpClient对象.
  • 基于要发送的HTTP请求类型创建HttpGet或者HttpPost实例.
  • 使用addHeader方法添加请求头部,诸如User-Agent, Accept-Encoding等参数.
  • 可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
  • 通过执行此HttpGet或者HttpPost请求获取CloseableHttpResponse实例
  • 从此CloseableHttpResponse实例中获取状态码,错误信息,以及响应页面等等.
  • 释放连接。无论执行方法是否成功,都必须释放连接

Java

注解

@Before:初始化方法 对于每一个测试方法都要执行一次
@After:释放资源 对于每一个测试方法都要执行一次
@Test:测试方法,在这里可以测试期望异常和超时时间
@Test(expected=ArithmeticException.class)检查被测方法是否抛出ArithmeticException异常
@Ignore:忽略的测试方法
@BeforeClass:针对所有测试,只执行一次,且必须为static void
@AfterClass:针对所有测试,只执行一次,且必须为static void
一个JUnit4的单元测试用例执行顺序为: @BeforeClass -> @Before -> @Test -> @After -> @AfterClass;
每一个测试方法的调用顺序为: @Before -> @Test -> @After;

diamond 运算符报错
1
2
java: -source 1.5 中不支持 diamond 运算符
(请使用 -source 7 或更高版本以启用 diamond 运算符)

https://blog.csdn.net/liu16659/article/details/80230164

RPC(Remote Procedure Call, 远程过程调用)TPS 系统吞吐量 Reaction Time 响应时间

消息队列

(activeMQ,rabbitMQ,kafaKa,RocketMQ,Redis等)

适用场景:以书架作类比,解耦、提速、广播、削峰这些方面的收益,超过放置书架、监控书架这些成本。

高并发、分布式架构下优于线程池

主要特点:异步、削峰、解耦

将比较耗时而且不需要即时(同步)返回结果的操作作为消息放入消息队列。

简单实现消息队列 代码:https://www.cnblogs.com/jimisun/p/10108067.html