所需依赖
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<version>4.5.10</version>
</dependency>
<dependency>
<groupId>net.jodah</groupId>
<artifactId>failsafe</artifactId>
<version>2.3.1</version>
</dependency>
fluent-hc用于构建http请求,failsafe用于定义安全失败重试, 所谓安全失败重试其实就是某一个任务失败了, 但是无关大碍,我们看见可以进行多次尝试, 比如一些连接失败等等。。。
实现failsafe安全失败
可以配置拦截到的异常, 延时重试, 尝试次数
private final RetryPolicy<Object> retryPolicy = new RetryPolicy<>()
//如果获得这个异常,则执行重试
.handle(SocketTimeoutException.class)
//延迟俩秒
.withDelay(Duration.ofSeconds(2))
//最多尝试俩次
.withMaxRetries(2);
拓展知识
1.failover:失效转移
Fail-Over的含义为“失效转移”,是一种备份操作模式,当主要组件异常时,其功能转移到备份组件。其要点在于有主有备,且主故障时备可启用,并设置为主。如Mysql的双Master模式,当正在使用的Master出现故障时,可以拿备Master做主使用
2.failfast:快速失败
从字面含义看就是“快速失败”,尽可能的发现系统中的错误,使系统能够按照事先设定好的错误的流程执行,对应的方式是“fault-tolerant(错误容忍)”。以JAVA集合(Collection)的快速失败为例,当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。例如:当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException异常(发现错误执行设定好的错误的流程),产生fail-fast事件。
3.failback:失效自动恢复
Fail-over之后的自动恢复,在簇网络系统(有两台或多台服务器互联的网络)中,由于要某台服务器进行维修,需要网络资源和服务暂时重定向到备用系统。在此之后将网络资源和服务器恢复为由原始主机提供的过程,称为自动恢复
4.failsafe:失效安全
Fail-Safe的含义为“失效安全”,即使在故障的情况下也不会造成伤害或者尽量减少伤害。维基百科上一个形象的例子是红绿灯的“冲突监测模块”当监测到错误或者冲突的信号时会将十字路口的红绿灯变为闪烁错误模式,而不是全部显示为绿灯。
构建Get请求
//传入重试机制
String content = Failsafe.with(retryPolicy).get(() ->
//构建一个get请求
//请求connectTimeout()设置连接超时
//socketTimeout() 设置文本读取超时
//execut() 执行远程连接的核心方法,就是发起一个HttpRequest并返回一个HttpResponse
//returnContent() 获取返回请求结果Content,其实也就是流文本
Request.Get(url)
.connectTimeout(1000)
.socketTimeout(500)
.execute().returnContent().asString()
);
connectTimeout()设置连接超时
socketTimeout() 设置文本读取超时
execut() 执行远程连接的核心方法,就是发起一个HttpRequest并返回一个HttpResponse
returnContent() 获取返回请求结果Content,其实也就是流文本
构建Post请求
String content = Failsafe.with(retryPolicy).get(() ->
//构建一个post请求
//请求体body可以使用方法bodyString()按照文本格式传入即可
// 如:json字符串的文本类型APPLICATION_JSON
//设置连接时间和文本读取时间,
//execute执行这个请求获得respond
Request.Post(h5Url)
.bodyString(dataJson, ContentType.APPLICATION_JSON)
.connectTimeout(DEFAULT_CONNECT_TIMEOUT)
.socketTimeout(DEFAULT_SOCKET_TIMEOUT)
.execute().returnContent().asString()
);
还有一些额外的经常用到的方法
bodyForm()方法构造表单提交。
.bodyForm(Form.form().add("username", "vip").add("password", "secret").build())
根据需要返回不同的文本类型asBytes(),asString(),也支持直接写入文件saveContent()
.saveContent(new File("result.dump")); //保存为文件
自定义响应处理
如上所说,execut()执行后得到一个HttpResponse对象,可以使用方法handleResponse()自定义响应处理。
Document result = Request.Get(url)
.execute().handleResponse(new ResponseHandler<Document>() {
public Document handleResponse(final HttpResponse response) throws IOException {...}
});
组件fluent-hc优点:
fluent-hc本质是对HttpClient的封装,链式操作简便,易于解读
不必处理连接管理和资源分配
连接池技术减少资源开销增强性能
Executor执行器的对象是从连接池中获取的HttpClient对象。采用HTTP连接池技术降低了频繁建立HTTP连接的时间开销,减少了TCP连接建立和释放时socket通信服务器端资源的浪费,同时支持更高的并发量。