rust操作rabbitmq

Rust 操作 Rabbitmq

使用docker快速部署rabbitmq

shell 复制代码
docker pull rabbitmq:management
# 15672为rabbitmq 管理员端口,默认账号密码为guest(账号密码相同)
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management

rust 添加amqp库lapin

shell 复制代码
cargo add lapin

1. 连接到rabbitmq

rust 复制代码
let conn=lapin::Connection::connect(
      "amqp://localhost:5672",
      lapin::ConnectionProperties::default(),
  )
  .await?;
let chan=conn.create_channel().await?;

2. 交换机创建和队列创建

rust 复制代码
//创建一个名为itest的交换机,模式为话题模式
chan.exchange_declare(
    "itest",
    lapin::ExchangeKind::Topic,
    lapin::options::ExchangeDeclareOptions::default(),
    lapin::types::FieldTable::default(),
)
.await?;
//创建一个名为queue1的队列
chan.queue_declare(
    "queue1",
    lapin::options::QueueDeclareOptions::default(),
    lapin::types::FieldTable::default(),
)
.await?;
//绑定队列到交换机,将名为队列queue1绑到交换机itest,并设置路由名为/queue1
chan.queue_bind(
    "queue1",
    "itest",
    "/queue1",
    lapin::options::QueueBindOptions::default(),
    lapin::types::FieldTable::default(),
).await?;

3. 生产者发布消息

rust 复制代码
// 发送给itest交换机,交换机会把消息交给路由/queue1
chan.basic_publish(
    "itest",
    "/queue1",
    lapin::options::BasicPublishOptions::default(),
    "hello".as_bytes(),
    lapin::BasicProperties::default(),
).await.expect("publish message failed");

4. 消费者订阅消息

rust 复制代码
let consumer = chan
   .basic_consume(
        "queue1",
        "",
        lapin::options::BasicConsumeOptions::default(),
        lapin::types::FieldTable::default(),
    )
    .await?;
consumer.set_delegate(|d: lapin::message::DeliveryResult| async move {
    match d {
        Err(err) => eprintln!("subscribe message error {err}"),
        Ok(data) => {
            if let Some(data) = data {
                let raw = data.data.clone();
                let f = data.ack(lapin::options::BasicAckOptions::default());
                println!(
                    "accept msg {}",
                    String::from_utf8(raw).expect("parse msg failed")
                );
                if let Err(err) = f.await {
                    eprintln!("ack failed {err}");
                }
            }
        }
    }
});

最终demo

rust 复制代码
#[cfg(test)]
mod mq{
	#[tokio::test]
    async fn rabbitmq() -> Result<(), Box<dyn std::error::Error>> {
    //连接到rabbitmq
        let conn = lapin::Connection::connect(
            "amqp://localhost:5672",
            lapin::ConnectionProperties::default(),
        )
        .await?;
        let chan = conn.create_channel().await?;
        //初始化queue和exchange
        chan.queue_declare(
            "queue1",
            lapin::options::QueueDeclareOptions::default(),
            lapin::types::FieldTable::default(),
        )
        .await?;
        chan.exchange_declare(
            "itest",
            lapin::ExchangeKind::Topic,
            lapin::options::ExchangeDeclareOptions::default(),
            lapin::types::FieldTable::default(),
        )
        .await?;
        chan.queue_bind(
            "queue1",
            "itest",
            "/queue1",
            lapin::options::QueueBindOptions::default(),
            lapin::types::FieldTable::default(),
        )
        .await?;
        //发送消息
        tokio::spawn(async move {
            chan.basic_publish(
                "itest",
                "/queue1",
                lapin::options::BasicPublishOptions::default(),
                "hello".as_bytes(),
                lapin::BasicProperties::default(),
            )
            .await
            .expect("publish message failed");
        });
        let chan = conn.create_channel().await?;
        let consumer = chan
            .basic_consume(
                "queue1",
                "",
                lapin::options::BasicConsumeOptions::default(),
                lapin::types::FieldTable::default(),
            )
            .await?;
            //使用回调来触发接受到新消息时的操作,使用futures_lite 中StreamExt 可以不使用回调
        consumer.set_delegate(|d: lapin::message::DeliveryResult| async move {
            match d {
                Err(err) => eprintln!("subscribe message error {err}"),
                Ok(data) => {
                    if let Some(data) = data {
                        let raw = data.data.clone();
                        let f = data.ack(lapin::options::BasicAckOptions::default());
                        println!(
                            "accept msg {}",
                            String::from_utf8(raw).expect("parse msg failed")
                        );
                        if let Err(err) = f.await {
                            eprintln!("ack failed {err}");
                        }
                    }
                }
            }
        });
        tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
        Ok(())
    }
}

结果展示


rabbitmq 管理后台页面可以看到我们创建的itest交换机和queue1队列向绑定,queue1的路由地址为/queue1

简言

amqp 包其实无论是rust 的lapin还是golang的streadway/amqp,操作手法整体都是一样的,rabbitmq其它几种模式可以参考我goalng 的rabbitmq几种模式下操作方式来类推

相关推荐
子兮曰4 分钟前
AI Agent 完整入门指南:从 LLM 到生产落地的 30+ 个核心概念
前端·后端·agent
渔夫正在掘金34 分钟前
Cordis 插件热插拔能力深度解析
后端·node.js
不爱编程的小九九38 分钟前
小九源码-springboot004-springboot智能阅读推荐系统
java·spring boot·后端
码事漫谈1 小时前
为什么调试模式不崩溃,打包后却崩溃了?
后端
智驭未来掌门人1 小时前
利用FFmpeg快速实现一个RTSP推流服务器
后端
垚垚学技术_聚焦云原生2 小时前
K8s Pod 完整生命周期详解
后端
JavaGuide2 小时前
Github 史诗级故障,与此同时,Cursor 版「GitHub」正式上线!
前端·后端
不一样的少年_2 小时前
修了 Bug、做了重构,为什么老板还是觉得你没产出?
前端·后端·程序员
水深火乐2 小时前
安全地生成验证码、密码和 Token
后端
小强19882 小时前
SQL Server 慢查询怎么定位?一套从“卡”到“快”的完整排查流程
后端