从HttpClient的重复请求 [英] duplicate requests from HttpClient

查看:1105
本文介绍了从HttpClient的重复请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Android上的HttpClient 4.0.1 ......我做了报头组,它是当前米利斯POST请求......我看到在几米利斯(5-10)的请求,点击服务器的两倍我把对方..但标题是相同的两个请求。出现这种情况很零星的......我看到Wireshark的请求之间没有真正的区别......我只是不知道如何这可能发生。任何人都遇到了这个之前,或者对如何进一步调试任何提示?

这里是code我用它来创建客户端:

 公共静态的HttpClient getAndroidHttpClient(最终诠释超时){
    //设置的模式
    SchemeRegistry schemeRegistry =新SchemeRegistry();
    schemeRegistry.register(新计划(HTTP,PlainSocketFactory.getSocketFactory(),80));
    schemeRegistry.register(新计划(https开头,新EasySSLSocketFactory(),443));

    //设置我们的PARAMS
    的HttpParams PARAMS =新BasicHttpParams();
    params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,超时);
    params.setIntParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK,超时);
    params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT,超时);
    params.setLongParameter(ConnManagerPNames.TIMEOUT,超时);
    params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS,1);
    params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE,新ConnPerRouteBean(1));
    params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE,假);

    HttpProtocolParams.setUserAgent(PARAMS,Android的客户端V1.0);
    HttpProtocolParams.setVersion(参数,可以HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(参数,可以UTF8);

    ThreadSafeClientConnManager赌侠=新ThreadSafeClientConnManager(参数,可以schemeRegistry);

    DefaultHttpClient defaultHttpClient =新DefaultHttpClient(赌侠,则params);

    返回defaultHttpClient;
}
 

解决方案

那么,什么似乎是这里发生的事情是,你的客户端发送一个请求,没有得到及时的响应,并因此重试相同的请求再次(因为它应该)。这反过来又导致了多个 POST 请求被发送到你的服务器(几乎连续),您的服务器目前无法处理适当。

要验证/调试这一点,尝试禁用HTTP重如下:

  defaultHttpClient.setHtt prequestRetryHandler(新DefaultHtt prequestRetryHandler
                                             (0,假));
 

这当然会处理您的重复的要求的问题,但引入了另一个更严重的问题;即,它会尝试的一次的(而且只有一次)和失败。从我从你的意见得到的信息,这里有一些想法,你可以试试:

请与伪code裸露,因为我没有所有的细节如何您的客户端架构

处理多个帖子在继承

  • 关闭自动重试(如上)
  • 包装你的 POST 请求,类似于如何<一环href="http://w3mentor.com/learn/java/android-development/android-http-services/example-of-simple-retry-technique-to-deal-with-timeouts-in-android/">this实施
  • 然后要么睡眠之间你的手动的重试或实现您的的指数退避

无论什么时候,你的服务器的需要处理的重复请求,以合理的方式的能力,这是HTTP毕竟。但是,你至少给它一个机会处理之前,它的轰炸重复第一个。

我建议的第一的它处理请求时所要采取的步骤是设定某种形式的(副本)的标记的。然后,如果/当它收到一个欺骗,这将继续处理的第一的请求(像往常一样),并自动忽略的受骗者。

所以只是总结,这整个计划的要点是将你的服务器有机会设置欺骗标志。在此之后,它是你的服务器的工作放弃(或处理)根据需要重复的请求。难道这一切有意义吗?

I am using HttpClient 4.0.1 on android... I make a POST request with a header set that is the current millis... I see that request hit the server twice within a few millis (5-10) of each other.. but the header I set is the same for both requests. This happens very sporadically... I see no real difference between the requests in wireshark... I just have no clue how this could be happening. Anyone run into this before or have any tips on how to further debug it?

here is the code I use to create the client:

public static HttpClient getAndroidHttpClient(final int timeOut) {
    // set up the schemas
    SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    schemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));

    // set up our params
    HttpParams params = new BasicHttpParams();
    params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeOut);
    params.setIntParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, timeOut);
    params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, timeOut);
    params.setLongParameter(ConnManagerPNames.TIMEOUT, timeOut);
    params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 1);
    params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(1));
    params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);

    HttpProtocolParams.setUserAgent(params, "android-client-v1.0");
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(params, "utf8");

    ThreadSafeClientConnManager conman = new ThreadSafeClientConnManager(params, schemeRegistry);

    DefaultHttpClient defaultHttpClient = new DefaultHttpClient(conman, params);

    return defaultHttpClient;
}

解决方案

So what appears to be happening here is that your client sends a request, does not get a response in a timely manner, and as a result retries the same request again (as it should). This, in turn, results in multiple POST requests being sent to your server (almost in succession), which your server cannot currently deal with appropriately.

To verify/debug this, try disabling HTTP retries as follows:

defaultHttpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler
                                             (0, false));

This of course will deal with your duplicate requests issue, but then introduces another more serious issue; namely, it will try once (and only once) and fail. From the information I got from your comments, here are a few ideas you can try:

Please bare with the pseudocode as I don't have all the details of how your client is architected

Handle Multiple POSTS in Succession

  • Disable automatic retries (as above)
  • Wrap your POST requests in a loop similar to how this is implemented
  • Then either sleep between your manual retries or implement your version of exponential backoff

No matter what, your server will need the capability to handle duplicate requests in a reasonable way, this is HTTP afterall. However, you're at least giving it a chance to process the first one before it's bombarded with duplicates.

I recommend that the first step it takes when processing a request is to set some form of a (duplicate) flag. Then if/when it receives a dupe, it continues processing the first request (as usual) and silently ignores the dupes.

So just to summarize, the point of this whole scheme was to give your server a chance to set the dupe flag. After that, it's your server's job to discard (or handle) duplicate requests as needed. Does this all make sense?

这篇关于从HttpClient的重复请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆