[备忘] apache httpasyncclient基本用法

最近公司内技术分享有点密,快2周没更博客了,这次简单水一下java的http库使用,方便回查。

依赖

httpclient和httpasyncclient是两个maven包,前者提供同步api,后者提供异步api(future和callback都支持)。

基本用法

创建异步客户端,一定要设置setMaxConnTotal(并发连接最大数量)和setMaxConnPerRoute(每个域名最大并发连接数量),默认值限制的并发连接数量太小了,导致event loop线程根本跑不满,吞吐上不去。(追了一下源码,默认event loop的线程池数量与cpu个数一样,所以不用刻意设置)

必须手动启动帮它启动一下,否则用不了:

接着构造URI(方便设置query string):

接着用这个URI构造一个GET请求(有需要可以给request设置超时之类的,文章末尾会提一下):

然后就可以丢到异步event loop线程中去运行了,我们拿着future可以wait等待完成(future原理就是一个mutex+cond):

等待HttpResponse,取出其返回的Body(api里叫做entity),然后利用一个便捷的方法读取字节流并按utf-8解码为String:

POST表单

变化一下request的类型,然后设置一下form就好:

Callback方式

虽然请求是丢到event loop线程里异步完成的,但是调用者的future.get()其实还是阻塞等待的,如果要做纯异步的高吞吐程序,那就直接基于callback来处理应答吧(PS:还是Golang协程香):

最后说个坑

异步I/O虽然可以高吞吐的execute提交请求并等待callback,但是这里面涉及到一个不能过载的问题。

如果按照远超下游处理能力的速度发起请求,httpasyncclient的request队列就会堆积,等到event loop线程终于消费到队列末尾的request时,这个request已经排队很久了,会直接被标记为超时并callback告知失败,这个特性与request的setConnectionRequestTimeout超时配置项有关:

所以如果网络调用吞吐量很高的话,要么自己控制好请求发送速率,要么适当调大setConnectionRequestTimeout来允许request被处理之前排队更久。

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~