jms api 提供了一下的方式來建立乙個健壯的 jms 應用程式
•控制訊息的確認方式(acknowledgment)
•配置訊息的永續性(確保當 jms 提供者失敗時,訊息不會丟失)
•設定訊息的優先順序(影響訊息傳遞的順序)
•允許訊息過期(設定訊息的過期時間,這樣訊息過期後 jms provider 就會丟棄此訊息)
•建立臨時目的地(臨時目的會在建立它的連線被關閉時被銷毀)
•建立持久訂閱
•使用本地事務
控制訊息確認方式
如果一條訊息沒有被確認,那麼 jms provider 會認為此訊息沒有成功地被消費。一條訊息成功地被客戶端消費通常包含3個步驟:
1.客戶端接收到這條訊息
2.客戶端成功處理這條訊息
3.客戶端確認這條訊息
訊息的確認是由 jms provider 觸發還是由客戶端觸發,這取決於會話的確認模式。
在事務性會話中,事務提交的時候會自動確認訊息,當事務被回滾,所有消費的訊息都會被重傳。
在非事務性會話中,什麼時候以及如何確認訊息取決於 createqueuesession 、 createtopicsession 和 createsession 方法的第二個引數的取值。有三種可選的取值:
•session.auto_acknowledge 會話自動確認。當客戶端呼叫 receive 方法並成功返回以及呼叫 messagelistener 處理訊息並成功返回後,會話會自動確認已成功接收到訊息。在 auto_acknowledget 會話中,同步接收訊息是乙個例外(消費一條訊息包含三個步驟),在這種情況下,訊息接收和確認在同乙個步驟中發生。
•session.client_acknowledge 客戶端確認。客戶端通過呼叫訊息的 acknowledge 方法手動確認成功接收一條訊息。在這種模式下,訊息確認發生在會話級別,確認一條訊息會自動確認由此會話消費的所有訊息。例如,乙個消費者消費10條訊息,並在消費第5條訊息的時候呼叫了 acknowledge 方法,這會確認所有的10條訊息。
•session.dups_ok_acknowledge 這個選項會使會話延遲訊息的確認。在訊息傳遞過程中,如果 jms provider 失敗,這可能會導致傳遞一些重複的訊息,因此只有在消費者允許重複的訊息時才考慮使用此模式(如果重傳一條訊息,jms provider 必須設定訊息頭 jmsredelivered 為 true)。
當 queuesession 被關閉,jms provider 會保持那些客戶端已經接受到但還沒有確認的訊息,並在下一次客戶端連線到佇列的時候重傳這些訊息。同樣,當 topicsession 關閉,jms provider 也會保持那些持久 topicsubcriber 沒有確認的訊息。非持久 topicsubscriber 沒有確認的訊息,當會話關閉時會被丟棄。
如果使用佇列和持久訂閱,可以呼叫方法 session.recover 使會話停止當前訊息傳遞,並從第乙個沒有確認的訊息開始重新傳遞,這會使訊息傳遞的順序與訊息傳送的順序不一致。對於非持久訂閱的 topicsubscriber,當恢復會話時 jms provider 可能會丟棄沒有確認的訊息。
設定訊息的永續性
jms 提供了兩種訊息傳遞模式,這兩種模式決定了當 jms provider 失敗時訊息是否會丟失。deliverymode 介面提供了這兩種傳遞模式。
persistent 傳遞模式要求 jms provider 確保在訊息傳輸過程中如果 jms provider 失敗訊息不會丟失,這是預設的傳輸模式。使用這種模式傳送的訊息在傳送的時候會被記錄到乙個持久儲存中。
non_persistent 傳遞模式不要求 jms provider 把訊息儲存到持久儲存中,同樣也不保證如果 jms provider 失敗,訊息不會丟失。
有兩種方式設定訊息傳遞模式:
1.呼叫 messageproducer 的 setdelierymode 方法設定傳遞模式,此 messageproducer 傳送的訊息都使用這個方法設定的傳遞模式。
2.使用過載的 send 和 publish 方法設定特定訊息的傳遞模式
如果不指定傳遞模式,預設使用 persistent 模式。使用 non_persistent 可以提高效能以及降低儲存需求。
設定訊息優先順序
可以使用優先順序使 jms provider 優先傳遞緊急的訊息。有兩種方式設定訊息優先順序。
1.呼叫 messageproducer 的 setpriority 方法設定此 messageproducer 傳送的訊息的優先順序
2.呼叫過載的 send 和 publish 方法為特殊的訊息設定優先順序
訊息的優先順序從0(最低)到9(最高)有10種級別。如果沒有設定優先順序,預設優先順序為4。jms provider 會確保優先順序高的訊息會在優先順序低的訊息之前被傳遞,但並不保證會嚴格按照優先順序的順序來傳遞訊息。
允許訊息過期
預設情況下,訊息永遠不會過期。但如果一條訊息在一段時間之後就會被廢棄,那麼可以設定訊息的過期時間。有兩種方式可以設定訊息的過期時間。
1.呼叫 messageproducer 的 settimetolive 設定 messageproducer 傳送的訊息的預設過期時間
2.使用過載的 send 和 publish 方法設定特定訊息的過期時間
如果設定 timetolive 為0,那麼訊息永遠不會過期。
傳送訊息時,會使用當前時間與 timetolive 的和設定訊息的過期時間。任何在指定的過期時間之前沒有被傳遞的訊息都會被銷毀。
建立臨時目的
jms 提供了方法 queuesession.createtemporaryqueue 和 topicsession.createtemporarytopic 來建立臨時佇列 temporaryqueue 和臨時主題 temporarytopic,臨時目的在建立它們的連線被關閉時會被銷毀。
僅有使用建立臨時目的的連線建立的消費者才能消費臨時目的上的訊息,但任何乙個訊息生產者都可以向臨時目的上傳送訊息。如果關閉建立臨時目的地連線,那麼臨時目的也會被關閉,臨時目的上的訊息會丟失。
建立持久訂閱
為了確保發布/訂閱應用程式能夠接收到所有已發布的訊息,在發布端可以使用 persistent 傳遞模式傳輸訊息以確保訊息不回在傳輸過程中丟失,而在訂閱端則可以使用持久訂閱來保證能夠收到所有已發布的訊息。
topicsession.createsubscriber 方法建立乙個非持久訂閱者。非持久訂閱者只能接收到在它處於活動狀態時發布的訊息。
可以使用方法 topicsession.createdurablesubscriber 建立乙個持久訂閱者。持久訂閱在任何時候僅能有乙個訂閱者。
乙個持久訂閱者使用乙個由 jms provider 維護的唯一的識別符號註冊乙個持久訂閱。隨後的訂閱者會恢復之前訂閱者在關閉之前的狀態。如果乙個持久訂閱沒有處於活動狀態的訂閱者,jms provider 會保持訂閱的訊息直到這些訊息被訂閱者接收到或者訊息過期。
使用如下設定能夠建立乙個持久訂閱的唯一識別符號:
•為連線設定乙個唯一的客戶 id( connection.setclientid )
•訂閱的主題名以及訂閱的名稱
建立了乙個連線並設定了其客戶 id 之後,可以使用連線建立 session,並呼叫這個 session 的 createdurablesubscriber 來建立乙個持久訂閱者,這個方法接收兩個引數,第乙個引數是乙個主題名,第二個引數是建立的這個持久訂閱的名稱,例如:
string topicname = "mytopic";
string subname = "mysub";
topicsubscriber sub = topicsession.createdurablesubscriber( topicname, subname );
呼叫 topicconnection 的 start 方法後此訂閱者就處於活動狀態。這之後可以關閉此 topicsubscriber:
topicsubscriber.close();
jms provider 會儲存發布到這個主題上的訊息。如果任意乙個應用程式使用具有相同客戶 id 的連線,並使用相同的主題和訂閱名呼叫 createdurablesubscriber 方法,那麼這個持久訂閱就會被啟用,jms provider 就會把在此訂閱者處於不活動狀態發布的訊息傳遞給此訂閱者。
刪除乙個持久訂閱,首先要關閉訂閱者,然後使用訂閱名呼叫 unsubscribe 方法登出持久訂閱。
topicsubscriber.close();
topicsession.unsubscribe( "mysub" );
unsubscribe 方法會使 jms provder 刪除它維護的關於訂閱者的狀態資訊。
使用本地事務
可以把一系列操作組成乙個稱為事務的原子工作單元。如果乙個操作失敗,事務會被回滾,並可以嘗試重新執行這一組操作。如果這一組操作都成功,事務則會被提交。
jms 客戶端可以在事務中傳送和接受一組訊息。jms api 中的 session 介面提供了 commit 和 rollback 方法來提交回滾事務。事務提交意味著生產的所有訊息都會被傳送,消費的所有訊息都會被確認。事務回滾意味著生產的訊息都會被銷毀,消費的訊息都會被重傳直到它們過期。
乙個事務性會話始終包含在乙個事務中。只要呼叫了 commit 方法或 rollback 方法,這意味著乙個事務的結束,新的事務的開始。關閉事務性會話會回滾正在進行的事務。
當建立會話的時候可以指定會話是否為事務性的。方法 createqueuesession 與 createtopicsession 的第乙個引數是乙個 boolean 型別的,如果設為 true 則新建的會話為事務性的,如果為 false 新建的回話則不是事務性的。這兩個方法的第二個引數是設定確認模式的,這個值只有在非事務性回話中有效,事務性會話則會忽略確認模式,所以可以設定為0,例如:
topicsession = topicconnection.createtopicsession( true, 0 );
由於本地事務的提交與回滾是與回話相關聯的,所以不能把對佇列的主題的操作繫結到同乙個事務中。因為 queuereceiver、queuesender 與 topicsubscriber、topicpublisher 分別是由 queuesession 和 topicsession 建立的。
如何提高程式的健壯性,增加判斷。
如果後台在返回的時候少了乙個屬性?前端會不會報錯,這是我們前端開發一定會遇到的問題。那麼如何的提高程式的健壯性呢。關於這個問題,我們可以在例項化這個物件的時候進行判讀來增加程式的健壯性。下面是乙個參考示例。public classclientuserimplementsparcelable publ...
使用const 提高函式的健壯性
1,用const修飾函式的引數 1.1如果此引數是作輸出用,則不論它是什麼資料型別,也不論它採用 指標傳遞 或 引用傳遞 都不能加const修飾,否則該將失去輸出功能。如果此引數是作輸入用,則用const 修飾可以防止意外地改動該指標,採用規則 常量指標,或指標常量而定 如果直接採用值傳遞的話 則不...
使用const提高函式的健壯性
const不僅是用來定義const常量 更大的作用是修飾函式的引數 返回值 函式的定義體 const是constant的縮寫,恆定不變的意思。被const修飾的東西都受到強制保護,可以預防意外的變動,提高程式的健壯性。so use const whenever you need.用const修飾函式...