由於MSMQ的消息交互都需要對磁盤進行讀寫操作,所以提高MSMQ的消息吞吐能力相對比較有效的方法就是提高磁盤讀寫能力.可以簡單地把MSMQ的消息,日志等文件存儲到不同的磁盤來降低MSMQ對一個磁盤IO依賴從而達到更高的讀寫效能.由於MSMQ一般都是存儲流水數據,如果消息結構比較少和消費積累量不高的情況把MSMQ存儲放到內存則是一個非常不錯的選擇,這樣能夠大大提高MSMQ的讀寫效能(缺點:斷電部分數據存在丟失).下面針對MSMQ內存存儲的一些實現和簡單測試.
構建內存盤
首先要從內存中創建一個盤出來,這個可以通過一些工具就能實現,這里選擇了Dataram RAMDisk(這款工具如果的虛擬4G以下的空間是免費的).對於要分析多少內存則根據實際情況需要,以下是簡單地分析2G空間構建一個磁盤出來.如果你存儲的消息不大,而消息停留時間不長的情況其實足夠用的.

創建完成后只需要點擊Start RAMDisk按鈕即可產生一個內存盤.
制定內存盤備份
完全把數據存放到內存中風險還是比較大的,可以根據實里需要把內存盤的數據寫入一個鏡象文件中.Dataram RAMDisk這個工具想得比較周到的它提供了內存盤數據來源的鏡象文件和定期保存鏡象的設置.

保存鏡象信息就根據實際情況設置.
更改MSMQ存儲路徑
當內存盤構建完成后你只需要把MSMQ的文件存儲路徑指向內存盤即可.

性能測試對比
MSMQ的存儲指向內存盤后,其實整體的讀寫效率是不是會提高呢?下面做個簡單的測試.
測試消息的結構:
[ProtoContract]
public class Employee
{
[ProtoMember(1)]
public string EmployeeID { get; set; }
[ProtoMember(2)]
public string FirstName { get; set; }
[ProtoMember(3)]
public string LastName { get; set; }
[ProtoMember(4)]
public string Title { get; set; }
[ProtoMember(5)]
public string Address { get; set; }
[ProtoMember(6)]
public string City { get; set; }
[ProtoMember(7)]
public string Region { get; set; }
[ProtoMember(8)]
public string PostalCode { get; set; }
[ProtoMember(9)]
public string Notes { get; set; }
[ProtoMember(10)]
public string Extension { get; set; }
}
[ProtoContract]
public class Order
{
[ProtoMember(1)]
public string OrderID { get; set; }
[ProtoMember(2)]
public string CustomerID { get; set; }
[ProtoMember(3)]
public string EmployeeID { get; set; }
[ProtoMember(4)]
public DateTime OrderDate { get; set; }
[ProtoMember(5)]
public DateTime RequiredDate { get; set; }
[ProtoMember(6)]
public string ShipName { get; set; }
[ProtoMember(7)]
public string ShipAddress { get; set; }
[ProtoMember(8)]
public string ShipCity { get; set; }
[ProtoMember(9)]
public string ShipRegion { get; set; }
[ProtoMember(10)]
public string ShipPostalCode { get; set; }
[ProtoMember(11)]
public string ShipCountry { get; set; }
}
普通磁盤測試結果


內存盤測試結果


從測試結構來看,內存盤的收益還是很明顯的.接收消息和發送消息都有着1/3的提高.由於消息的並不大,在隊列中停留的時間不長,在跑了3億多的消息調度后內存占用的空間只用了30MB,這么小空間內存盤的鏡象短時間進一個保存應該不會存在多大問題.但內存盤畢竟有風險存在,如果你的業務調度消息是完全不允許丟失的話那還是不建議用內存盤做MSMQ的存儲.
這個測試結果也說明了一個問題,如果想提高MSMQ的吞吐能力,一個讀寫效率高的磁盤是比較重要的.
