我的工作每10分钟一次 并发送30K~HTTP邮件请求
我想计算失败次数(超时,404等等)并最终重试
这项工作最长可达10分钟。每个请求超时为3秒
在没有使用.get()
阻止的情况下完成所有异步任务时获取通知的最佳做法是什么我不想阻止,因为我每次迭代都会有30,000个任务。每个任务发送一个http请求,完成任务的最长时间为10分钟,执行超过40个核心。
我附上了使用spring的ListenableFuture的代码 方法.get是阻塞,在这个例子中,thread5将休眠10秒以获取TimeoutException
是否有任何特殊的数据结构可以检查每个完成的任务并将其删除?
我正在使用java8
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.apache.http.nio.reactor.ConnectingIOReactor;
import org.apache.http.nio.reactor.IOReactorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.HttpComponentsAsyncClientHttpRequestFactory;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.web.client.AsyncRestTemplate;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class AsyncRestTemplateTest {
private static final Logger logger = LoggerFactory.getLogger(AsyncRestTemplateTest.class);
public static void main(String[] args) throws IOReactorException {
String url = "http:/some.serivce";
int connectionTimeout = 3000;
int soTimeout = 3000;
int defaultMaxPerRoute = 2;
int maxTotal = 300;
IOReactorConfig customIOReactorConfig = IOReactorConfig.custom()
.setIoThreadCount(Runtime.getRuntime().availableProcessors())
.setConnectTimeout(connectionTimeout)
.setSoTimeout(soTimeout)
.build();
ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(customIOReactorConfig);
PoolingNHttpClientConnectionManager connManager = new PoolingNHttpClientConnectionManager(ioReactor);
connManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
connManager.setMaxTotal(maxTotal);
CloseableHttpAsyncClient customHttpAsyncClient = HttpAsyncClients.custom()
.setConnectionManager(connManager)
.build();
HttpComponentsAsyncClientHttpRequestFactory asyncRequestFactory = new HttpComponentsAsyncClientHttpRequestFactory(customHttpAsyncClient);
AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(asyncRequestFactory);
System.out.println("start");
List<ListenableFuture<ClientHttpResponseWrapper>> futures = new ArrayList<>();
for (int i = 0; i < 11; i++)
{
final int finalI = i;
ListenableFuture<ClientHttpResponseWrapper> future = asyncRestTemplate.execute(url, HttpMethod.GET, request -> logger.info("preRequest..."), response -> {
// executing http request
if (finalI == 5) {
try {
logger.info("sleeping [{}]", finalI);
Thread.sleep(10_000);
} catch (InterruptedException ignored) { }
}
return new ClientHttpResponseWrapper(response, finalI);
});
future.addCallback(new ListenableFutureCallback<ClientHttpResponseWrapper>() {
@Override
public void onFailure(Throwable ex) {
logger.error("onFailure [{}] [{}] [{}]", finalI, ex.getMessage(), ex.getStackTrace()[0].toString());
}
@Override
public void onSuccess(ClientHttpResponseWrapper result) {
if (result != null) {
try {
StringBuilder body = new StringBuilder();
if (!HttpStatus.OK.equals(result.getClientHttpResponse().getStatusCode())) {
BufferedReader rd = new BufferedReader(new InputStreamReader(result.getClientHttpResponse().getBody()));
String line;
while ((line = rd.readLine()) != null) {
body.append(line);
}
}
logger.info("onSuccess [{}] [{}] [{}]", finalI, result.getClientHttpResponse().getRawStatusCode(), body.toString());
} catch (IOException e) {
logger.error(e.getMessage());
}
}
}
});
futures.add(future);
}
System.out.println("end loop");
// BLOCK EXAMPLE
for (ListenableFuture<ClientHttpResponseWrapper> future : futures) {
try {
ClientHttpResponseWrapper result = future.get(5, TimeUnit.SECONDS);
logger.info("Result [{}] [{}]", result.getId(), result.getClientHttpResponse().getRawStatusCode());
} catch (IOException | InterruptedException | ExecutionException | TimeoutException e) {
logger.error("Result [{}] [{}]", null, e.getClass());
future.cancel(true);
}
}
System.out.println("END!!!");
}
private static class ClientHttpResponseWrapper {
ClientHttpResponse clientHttpResponse;
int id;
ClientHttpResponseWrapper(ClientHttpResponse clientHttpResponse, int id) {
this.clientHttpResponse = clientHttpResponse;
this.id = id;
}
ClientHttpResponse getClientHttpResponse() {
return clientHttpResponse;
}
public int getId() {
return id;
}
}
}