簡體   English   中英

Hystrix:Apache http 客戶端請求不中斷

[英]Hystrix: Apache http client requests are not interrupted

我有一個 apache HTTP 客戶端,定義如下:

private static HttpClient httpClient = null;
HttpParams httpParams = new BasicHttpParams();
httpParams.setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, Boolean.TRUE);
httpParams.setParameter(CoreProtocolPNames.USER_AGENT, "ABC");

HttpConnectionParams.setStaleCheckingEnabled(httpParams, Boolean.TRUE);

SSLSocketFactory sf = SSLSocketFactory.getSocketFactory();

SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
schemeRegistry.register(new Scheme("https", 443, sf));

//Initialize the http connection pooling
PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager(schemeRegistry);

// Initialize the connection parameters for performance tuning
connectionManager.setMaxTotal(12);
connectionManager.setDefaultMaxPerRoute(10);

httpClient = new DefaultHttpClient(connectionManager, httpParams);

我有一個 hystrix 命令play並啟用了以下屬性:

hystrix.command.play.execution.isolation.thread.timeoutInMilliseconds=1
hystrix.command.play.execution.isolation.thread.interruptOnTimeout=true

命令本身定義如下:

    @HystrixCommand(groupKey="play_group",commandKey="play")
    public String process(String request) throws UnsupportedOperationException, IOException, InterruptedException {
        System.out.println("Before -  process method : " + request);
        callHttpClient(request);
        System.out.println("After -  process method" + request);
        return "";
    }

    private void callHttpClient(String request) throws ClientProtocolException, IOException, InterruptedException {
        HttpGet get = new HttpGet("http://www.google.co.in");
        HttpResponse response = httpClient.execute(get);
        System.out.println("Response:" + response);
    }

我現在嘗試在循環中執行命令 5 次:

    public static void main(String[] args) throws UnsupportedOperationException, IOException, InterruptedException {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContextTest.xml");
        HystrixPlayground obj = ctx.getBean(HystrixPlayground.class);

        long t1 = System.currentTimeMillis();
        for (int i = 0; i < 5; i++) {
            try{
                System.out.println(obj.process("test" + i));
            } catch(Exception ex) {
                System.out.println(ex);
            }
            long t2 = System.currentTimeMillis();
            System.out.println("Time(ms) : ---->" + (t2 - t1));

超時設置為 1 毫秒,因此 process 方法拋出 HystrixRunTimeException。 但是,http 請求繼續執行並打印“After - process method”字符串。

我只針對 http 客戶端請求一直看到這種行為。 如果 http 請求被線程睡眠或非常大的 for 循環之類的其他內容替換,則 hystrix 線程會按預期中斷。

有沒有人知道為什么會發生這種情況?

原因是在 Java 中中斷線程不會“強制停止”它。 相反,調用Thread.interrupt()只是設置一個標志,該標志可以但不必由正在運行的線程解釋。 在此處查看更多信息: java.lang.Thread.interrupt() 是做什么的?

Apache HTTP 客戶端不解釋此標志(因為 JRE 的套接字讀取操作不能被中斷)。 因此,HTTP 請求不會被取消而只是完成。

似乎過去一些 IO 操作,在某些平台(solaris)上可以使用Thread.interrupt()中斷。 現在,對於 java.io 似乎不再可能/不再指定,但對於 java.nio 仍然可能。 (有關更多詳細信息,請參閱Java 錯誤 4385444Java 錯誤 7188233

因此,即使對於某些平台/版本,似乎仍然可以使用Thread.interrupt()中斷阻塞 IO,這似乎顯然不推薦:

所以httpclient沒有任何問題。 使用 Hystrix,您應該在 Hystrix 超時時abort()請求。 如果您正在使用回退,您可以在getFallback()調用它,否則您可以在獲得結果后調用它。 例如:

try {
    hystrixCommand.execute();
} catch (HystrixRuntimeException e) {
    switch (e.getFailureType()) {
    case TIMEOUT:
       // supposing you add a getHttpRequest getter on your command.
       hystrixCommand.getHttpRequest().abort();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM