RabbitMQ知識點整理13-關閉連線
在應用程式使用完之後,需要關閉連線,釋放資源:
channel.close();
connection.close();
顯式地關閉Channel 是個好習慣,但這不是必須的,在Connection關閉的時候,Channel 也會自動關閉。
AMQP 協議中的Connection 和Channel 採用同樣的方式來管理網路失敗、內部錯誤和顯式地關閉連線。Connection 和Channel 所具備的生命週期如下所述。
Open : 開啟狀態,代表當前物件可以使用。
Closing : 正在關閉狀態。當前物件被顯式地通知呼叫關閉方法( shutdown) ,這樣就產生了一個關閉請求讓其內部物件進行相應的操作, 並等待這些關閉操作的完成。
Closed : 已經關閉狀態。當前物件己經接收到所有的內部物件己完成關閉動作的通知,並且其也關閉了自身。
Connection 和Channel 最終都是會成為Closed 的狀態,不論是程式正常呼叫的關閉方法,或者是客戶端的異常,再或者是發生了網路異常。
在Connection 和Channel 中,與關閉相關的方法有addShutdownListener(ShutdownListener listener) 和removeShutdownListener (ShutdownListnerlistener) 。當Connection 或者Channel的狀態轉變為Closed 的時候會呼叫ShutdownListener 。而且如果將一個ShutdownListener 註冊到一個己經處於Closed狀態的物件(這裡特指Connection 和Channel 物件)時,會立刻呼叫ShutdownListener 。
getCloseReason 方法可以讓你知道物件關閉的原因; isOpen 方法檢測物件當前是否處於開啟狀態; close(int closeCode , String closeMessage ) 方法顯式地通知當前物件執行關閉操作。
當觸發ShutdownListener 的時候,就可以獲取到ShutdownSignalException ,這個ShutdownSignalException 包含了關閉的原因,這裡原因也可以通過呼叫前面所提及的getCloseReason 方法獲取。
ShutdownSignalException 提供了多個方法來分析關閉的原因。isHardError 方法可以知道是Co 且口ectio醜的還是Channel 的錯誤; getReason 方法可以獲取cause 相關的資訊
public void shutdownCompleted(ShutdownSignalException cause) { String hardError = ""; String applInit = ""; if (cause.isHardError()) { hardError = "connection"; } else { hardError = "channel"; } if (cause.isInitiatedByApplication()) { applInit = "application"; } else { applInit = "broker"; } logger.warn("Connectivity to MQ has failed. It was caused by " + applInit + " at the " + hardError + " level. Reason received " + cause.getReason()); } }
如上面的程式碼, 當連線connection被關閉時,這個連線connection上開啟的所有通道channel都會一併被關閉,這個時候就會觸發註冊在這個connection和所有channel上的ShutdownListener監聽器,如果只是某個channel被關閉,則僅僅會觸發該channel上的ShutdownListener監聽器。ShutdownSignalException異常包含了關閉的異常資訊,通過呼叫cause.getReason()獲取異常出現的原因等資訊。
connection.addShutdownListener(new ShutdownListener() {
public void (ShutdownSignalException cause) {
......
}
});
// channel 新增監聽器
channel.addShutdownListener(new ShutdownListener() {
public void (ShutdownSignalException cause) {
......
}
});
// 移除監聽器
connection.removeShutdownListener(listener);
channel.removeShutdownListener(listener);