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

回到顶部