2016-06-28 29 views
3

Ich habe einen Apache HTTP-Client wie folgt definiert:Hystrix: Apache HTTP-Client-Anfragen werden nicht unterbrochen

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); 

Ich habe einen hystrix Befehl play und haben die folgenden Eigenschaften aktiviert:

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

Die Befehl selbst ist wie folgt definiert:

@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); 
    } 

Ich versuche jetzt, den Befehl auszuführen 5-mal in einer Schleife:

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)); 

das Timeout auf 1 Millisekunde eingestellt wird, so dass der Prozess ein Verfahren HystrixRunTimeException wirft. Die HTTP-Anforderung wird jedoch weiterhin ausgeführt und gibt die Zeichenfolge "After-process method" aus.

Ich habe dieses Verhalten konsequent nur für HTTP-Client-Anfragen gesehen. Wenn die HTTP-Anfrage durch etwas anderes wie einen Thread-Schlaf oder eine sehr große For-Schleife ersetzt wird, wird der Hystrix-Thread wie erwartet unterbrochen.

Hat jemand einen Einblick, warum dies passieren kann?

+0

Siehe https://stackoverflow.com/questions/20693335/how-can-i-catch-interruptedexception-when-making-http-request-with-apache –

Antwort

2

Der Grund ist, dass die Unterbrechung eines Threads in Java nicht "erzwingt". Stattdessen wird durch das Aufrufen von Thread.interrupt() nur ein Flag gesetzt, das vom laufenden Thread interpretiert werden kann, aber nicht interpretiert werden muss. Weitere Informationen finden Sie hier: What does java.lang.Thread.interrupt() do?

Apache HTTP-Client interpretiert dieses Flag nicht. Daher wird die HTTP-Anforderung nicht abgebrochen und gerade abgeschlossen.