HttpClient 提交Json数据,服务端通过流解析得到的json不完整(结构残缺,导致解析失败)
我有个web项目,接受postjson请求,解析字符串入索引,实现批量插入。现在遇到一个问题,大多数请求都是正常的,但是偶尔会出现几个请求,它们提交给我的json是残缺的,不完整,导致我的json解析失败。客户端是apache HttpClient.
服务端现象:
][1]
客户端httpclient是通过解析实体生成json发过来的,httpclient部分代码:
注:buildHttpClient 方法的是做重试的,没有别的业务
public static String postJson(String url, String authorName, String authorPass, String json) throws Exception { CloseableHttpClient httpClient = null;
HttpPost httpPost = null;
String result = null;
long begin = System.currentTimeMillis();
try {
httpClient = buildHttpClient();
httpPost = new HttpPost(url);
httpPost.setConfig(requestConfig);
StringEntity se = new StringEntity(json, ContentType.APPLICATION_JSON);
se.setContentType("application/json");
if (!StringUtils.isBlank(authorName) && !StringUtils.isBlank(authorPass)) {
String author = getAuthor(authorName, authorPass);
if (StringUtils.isNotBlank(author)) {
httpPost.setHeader("Authorization", author);
}
}
httpPost.setEntity(se);
begin = System.currentTimeMillis();
HttpResponse response = httpClient.execute(httpPost, HttpClientContext.create());
if (response != null) {
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
result = EntityUtils.toString(resEntity, CHARSET_UTF8);
}
}
} catch (Exception e) {
long end = System.currentTimeMillis();
logger.error("postEntity error,cost time:"+(end - begin)+" exception :", e);
throw e;
}finally {
httpClient.close();
}
return result;
}
private static CloseableHttpClient buildHttpClient(){
return HttpClients.custom().setRetryHandler(new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int executionCount,
HttpContext context) {
System.out.println("retrying.... "+executionCount);
if (executionCount > 3) {
System.out.println("final try.... "+executionCount);
logger.info("retry reach to 3 times");
return false;
}
if (exception instanceof NoHttpResponseException) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("NoHttpResponse start to retry times:"+executionCount);
System.out.println("NoHttpResponse start to retry times:"+executionCount);
System.out.println("retry success, NoHttpResponse retry times: "+executionCount);
return true;
}
if (exception instanceof SocketTimeoutException){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("SocketTimeout start to retry times:"+executionCount);
System.out.println("SocketTimeout start to retry times:"+executionCount);
System.out.println("retry success, SocketTimeout retry times: "+executionCount);
return true;
}
if (exception instanceof ConnectionPoolTimeoutException){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("ConnectionPoolTimeout start to retry times:"+executionCount);
System.out.println("ConnectionPoolTimeoutException start to retry times:"+executionCount);
System.out.println("retry success, ConnectionPoolTimeoutException retry times: "+executionCount);
return true;
}
if (exception instanceof ConnectTimeoutException){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("ConnectionPoolTimeout start to retry times:"+executionCount);
System.out.println("ConnectTimeoutException start to retry times:"+executionCount);
System.out.println("retry success, ConnectTimeoutException retry times: "+executionCount);
return true;
}
if (exception instanceof ConnectException){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("ConnectException start to retry times:"+executionCount);
System.out.println("ConnectException start to retry times:"+executionCount);
System.out.println("retry success, ConnectException retry times: "+executionCount);
return true;
}
if (exception instanceof IOException){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("IOException start to retry times:"+executionCount);
System.out.println("IOException start to retry times:"+executionCount);
System.out.println("retry success, IOException retry times: "+executionCount);
return true;
}
return false;
}
}).build();
}
服务端通过HttpServletRequest读取流解析,没有用RequestBody 因为出现这个问题后,我为了得到每次插入的数据大小就自己做解析了。
这是个批量插入的rest接口,发现每个异常出现的时候,json大小都不固定,有的60多K,有的300k,但是大多数请求json都是可以被正常解析的。
顺便说明下,这个接口的调用量还是比较频繁的,都是写入,一共6台机器,单台TPS大概在20-30/s,写入elasticsearch平均耗时80ms-200ms,http请求响应时间平均耗时300-800ms
有没有遇到同类现象的朋友,你们是怎么处理的呢?
回答:
要么找到json缺半截的问题,
要么只能要求客户端重发了.
如果是在搞不定的话,换xml格式的吧...
以上是 HttpClient 提交Json数据,服务端通过流解析得到的json不完整(结构残缺,导致解析失败) 的全部内容, 来源链接: utcz.com/p/179906.html