Java Http客户端怎么选用
背景
- 最近工作做一个功能,将多台机器的处理结果汇总到一台机器进行落盘.在考虑了时间/接入复杂度和其他影响因素后决定直接使用http协议进行传输.而在Java生态中主要有两个被广泛使用的http客户端Apache的HttpClient和OkHttp.技术选型也会在这两个客户端之间对比
需求和测试场景
- 每台服务器每秒产生的数据量最高接近3w条.每条数据大小约为4k
- http服务端能稳定处理全部的请求
- http客户端和服务端之间为25Gb/s的内网链接
- 机器为32核128G内存机器
测试方式
- 业务系统是一个SpringBoot的应用,单例模式以Spring Bean的形式进行编写:
@Service
public class HttpCall{
//使用默认的配置,默认的连接数/Connection per host
private OkHttpClient client = new OkHttpClient();
//也同样使用默认的配置
private CloseableHttpClient client = HttpClientBuilder.create().build();
...
}
- 非单例模式用多线程创建多个对象的方式实现:
@Service
public class SendUtil{
public void doSend(){
Thread thread = new Thread(()->{
HttpCall call = new HttpCall();
...
});
}
}
- 本次测试中,外部会有25个线程分别使用单例和非单例模式发送并测试两种不同的客户端
测试结果
客户端 | 模式 | CPU(Top多核) | QPS | 内存情况(相对) |
---|---|---|---|---|
OKHttp | 单例 | 173% | 9350 | 低 |
OKHttp | 非单例 | 220% | 9360 | 中 |
Apache | 单例 | 60% | 1300 | 中 |
Apache | 非单例 | 190% | 16000 | 高 |
内存情况
统计方式: jmap -dump:live,format=b,file=1.bin 1 + MAT
-
OKHttp单例模式下OKHttp库retained size为164480字节
-
OKHttp非单例模式下OKHttp库retained size为772656字节
-
Apache HttpClient单例模式下Apache Http库retained size为1,105,104字节
-
Apache HttpClient非单例模式下Apache Http库retained size为1,815,664字节
结论
- 追求高发送QPS且内存充足的情况下.每一个线程独享的使用Apache HttpClient(非单例/无竞争)
- 发送QPS不高,需要CPU/内存占用少一点的情况下.使用单例模式下的OKhttp客户端