在應用程序使用完之后,需要關閉連接,釋放資源:
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);