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几种模式下操作方式来类推

相关推荐
man20171 小时前
【2024最新】基于springboot+vue的闲一品交易平台lw+ppt
vue.js·spring boot·后端
hlsd#1 小时前
关于 SpringBoot 时间处理的总结
java·spring boot·后端
路在脚下@1 小时前
Spring Boot 的核心原理和工作机制
java·spring boot·后端
幸运小圣2 小时前
Vue3 -- 项目配置之stylelint【企业级项目配置保姆级教程3】
开发语言·后端·rust
好奇的菜鸟2 小时前
Spring Boot 启动时自动配置 RabbitMQ 交换机、队列和绑定关系
spring boot·rabbitmq
前端SkyRain3 小时前
后端Node学习项目-用户管理-增删改查
后端·学习·node.js
提笔惊蚂蚁3 小时前
结构化(经典)软件开发方法: 需求分析阶段+设计阶段
后端·学习·需求分析
老猿讲编程3 小时前
Rust编写的贪吃蛇小游戏源代码解读
开发语言·后端·rust
好奇的菜鸟3 小时前
RabbitMQ 通道(Channel)详解:方法使用、消息确认与拒绝
分布式·rabbitmq
黄小耶@3 小时前
python如何使用Rabbitmq
分布式·后端·python·rabbitmq