1. 程式人生 > 實用技巧 >RabbitMQ知識點整理13-關閉連線

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