2015-12-03 24 views
1

我有一個定製的API來與他們的消息系統進行交互。但是這個API並沒有給我任何方式來確認我已經建立了一個連接,而無法連接一個異常將被拋出。環路異常

當我在連接時收到異常時,我有一個嘗試重新連接到服務器的異常偵聽器。我想這樣循環的異常重試連接。進行無限循環直到我能夠連接,或者直到程序關閉。我嘗試與突破標籤要做到這一點,像這樣:

reconnect: try{ 
    attemptReconnection(); 
}catch(Exception e){ 
    log.error(e); 
    break reconnect; 
} 

但無法找到重新連接標籤對我來說,是一個有點接近使用GOTO語句比我會很舒服投產。如果執行流量達到break;指令那麼這意味着你成功連接

do { // optional loop choice 
    try{ 
     attemptReconnection(); 
     break; // Connection was successful, break out of the loop 
    } catch(Exception e){ 
     // Exception thrown, do nothing and move on to the next connection attempt (iteration) 
     log.error(e); 
    } 
}while(true); 

回答

2

繼續這樣。否則,它將繼續前進到下一次迭代。 (注意循環的選擇是可選的,你可以使用幾乎任何你想要的循環)

1

Have tryReconnection在連接成功時返回true,否則返回false。

tryReconnection方法還應該捕獲並記錄異常。

然後:

while(!attemptReconnection()){ 

log.error("Connection failure"); 

} 
+0

嗯..我有同樣的概念,但這更清潔,更合適。不得不說我喜歡這個答案更哈哈。 –

1

不能說我有經驗的API,但我認爲這樣的事情會實現你之後的結果。

boolean success = false; 
while (!success){ 
    try{ 
     attemptReconnection(); 
     success = true; 
    } 
    catch(Exception e){ 
     log.error(e); 
    } 
} 

一旦attemptReconnection()執行沒有錯誤,success將被設置爲true,終止循環。

1

我建議控制重新連接的嘗試不是用while循環,而是用預定的事件。這一點,你可以很容易地發起多個連接並執行回退機制,不要過度消耗資源,同時嘗試重新連接

private ScheduledExecutorService scheduler; 
... 

public void connect() { 

    for (int i = 0; i < numberOfConnections; i++) { 
     final Runnable r = new Runnable() { 
      int j = 1; 

      public void run() { 
       try { 
        final Connection connection = createNewConnection(); 

       } catch (IOException e) { 
        //here we do a back off mechanism every 1,2,4,8,16... 512 seconds 
        final long sleep = j * 1000L; 
        if (j < 512) { 
         j *= 2; 
        } else { 
         j = 1; 
        } 
        LOGGER.error("Failed connect to host:port: {}:{}. Retrying... in {} millis", 
          host, port, sleep); 
        LOGGER.debug("{}", e); 
        scheduler.schedule(this, sleep, TimeUnit.MILLISECONDS); 
       } catch (InterruptedException e) { 
        Thread.currentThread.interrupt(); 
       } 
      } 
     }; 
     scheduler.schedule(r, 1, TimeUnit.SECONDS); 
    } 
} 

,如果你想關閉應用程序,以避免treadpool不要忘了做一個scheduler.shutdownNow()正在泄漏。

您甚至可以在連接後實現重新連接機制,並且在連接狀態發生更改時讓偵聽器執行connect方法以斷開連接。

0

使用Failsafe

RetryPolicy retryPolicy = new RetryPolicy() 
    .retryOn(ConnectException.class); 
    .withBackoff(1, 30, TimeUnit.SECONDS); 

Failsafe.with(retryPolicy).run(() -> attemptReconnection()); 

通過這種方法,故障保護需要照顧的重試你,和Failsafe讓你在指定的時候重試應進行一定的靈活性,以及​​是否要重試之間的延遲。