6 保證消息不丟失

1 消息持久化

1.1 exchange持久化

/*
 * 聲明消息隊列,且爲可持久化的
 *
 * EXCHANGE_NAME: 交換機名稱(name)
 * direct: 交換機類型(type)
 * true: 是否持久化(durable)
 * false: 是否自動刪除(autoDelete)
 * null: 其他參數(arguments)
 */
 channel.exchangeDeclare(EXCHANGE_NAME, "direct", true, false, null);

1.2 queue持久化

/*
 * 聲明消息隊列,且爲可持久化的
 *
 * QUEUE_NAME: 隊列名稱(name)
 * true: 是否持久化(durable)
 * false: 是否爲排他性隊列(exclusive)
    1: 只對首次聲明它的連接(Connection)可見
        1.1 首次聲明: 因爲另外一個連接無法聲明一個同樣的排他性隊列
        1.2 只區別連接(Connection)而不是通道(Channel),從同一個連接創建的不同的通道可以同時訪問某一個排他性的隊列

    2: 會在其連接斷開的時候自動刪除
        2.1 無論隊列是否被聲明成持久性的(Durable =true),只要調用連接的Close方法或者客戶端程序退出,RabbitMQ都會刪除這個隊列
        2.2 注意這裏是連接斷開的時候,而不是通道斷開。這個其實前一點保持一致,只區別連接而非通道。

 * false: 是否自動刪除(autoDelete)
 * null: 其他參數(arguments)
 */
channel.queueDeclare(QUEUE_NAME, true, false,  false,null);

1.3 消息持久化

// 消息持久化
AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
// 1:不持久化 2:持久化
builder.deliveryMode(2);
AMQP.BasicProperties properties = builder.build();
/*
 * EXCHANGE_NAME: 交換機名稱
 * "" : 路由key
 * properties: 基本屬性
 * message: 消息體
 */
channel.basicPublish(EXCHANGE_NAME, "", properties, message.getBytes());

2 ACK確認機制

2.1 自動確認

// 自動確認
channel.basicConsume(QUEUE_NAME, true, consumer);

只要消息從隊列中獲取,無論消費者獲取到消息後是否成功消息,都認爲是消息已經成功消費。

2.2 手動確認

// 手動確認
channel.basicConsume(QUEUE_NAME, false, consumer);

// 向服務端確認消息已被消費
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);

3 AMQP事務機制


// 開啓事務
try {
    String message = "I am simple_queue!";
    // 開啓事務
    channel.txSelect();
    // 往隊列中發出一條消息,使用rabbitmq默認交換機
    channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
    // 提交事務
    channel.txCommit();
} catch (Exception e) {
    e.printStackTrace();
    // 事務回滾
    channel.txRollback();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章