关于RabbitMQ-C入门使用需要注意的几个问题

RabbitMQ-C是AMQP通信协议的RabbitMQ实现的C语言接口;

Java接口的文档倒是挺多的,C语言的很少,讨论的人也很少。在使用的过程中,我遇到了这几个坑:

1.connection的句柄amqp_connection_state_t_不是线程安全的

这第一个坑就是,当我们想开启5个线程,每个线程独立打开通道,独立声明交换机,共用一个socket时,出现的冲突。C语言版本打开一个连接后是用一个结构体amqp_connection_state_t_作为句柄标示一个连接;该句柄不是线程安全的,多个线程同时使用,肯定会冲突的。

2.如何获取指定channel的数据

针对第一个问题,我最初的解决方案是加锁,肯定会影响性能,但经过测试性能损耗在可接受范围;于是加了锁,问题解决了。

我开启了5个线程,分块发送了一个大文件,5个线程都能获取到数据;可接着问题就来了,本来我的控制策略是:0号线程接收A队列中的数据,1号线程接收B队列的数据,依次类推;

可实际是0号线程从A,B,C,D,E队列中都接收到了数据。接收数据是通过consume的方式实现的,查看amqp_consume_message的源码,发现它跟队列和通道无关,只是到connection这一级别,从socket中先取一个frame,然后再接收data;所以缺乏一个根据通道区分的分拣器(可能是我代码读的不深入,其实是有这样的分拣器??)。最后我的解决方法是,5个线程不共用同一个connection(socket)。而且python也是采用多connection的方式实现的。

3.没有主动请求一条数据的example

RabbitMQ-C的example和网上的博客都是通过consume方式获取数据,但consume是通过推送的方式被动消费数据,当调用amqp_basic_consume开始一个消费者后,服务器就开始推送数据,而调用amqp_consume_message只是从本地的缓冲区中读取数据,每次服务器都推送了300条数据;
而我想一条一条的主动取,example中并没有关于主动get数据的方式。后来经过多次读源码,写例子,才发现amqp_basic_get就是一条一条的取数据,当然这个函数不能像amqp_basic_consume一样仅仅调用一次;而是在每次amqp_read_message之前都要调用amqp_basic_get方法;

如果只调用一次amqp_basic_get那么当我们第二次调用amqp_read_message的时候就会阻塞,所以它们必须成对出现。

4.关于服务器

rabbitMQ的节点是依赖.erlang.cookie的。必须使C:/WINDOWS/.erlang.cookie
和C:/User/myPcName/.erlang.cookie保持一致,以C:/WINDOWS中的为准Win7改了用户名的时候,myPcName可能不会跟着改,导致erlang.cookie中的内容不一致。

Note:交流请发邮件goko-712@163.com;或者留言评论,别发站内信。

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
RabbitMQ-c是一个C语言的客户端库,用于与RabbitMQ通信。以下是RabbitMQ-c的使用教程: 1. 下载和安装RabbitMQ-c库 可以从RabbitMQ-c的官方网站下载RabbitMQ-c库,下载完后解压缩即可。接着,打开终端窗口,进入解压缩后的目录,输入如下命令进行安装: ``` $ mkdir build && cd build $ cmake .. && make && sudo make install ``` 2. 创建连接并声明队列 首先,我们需要创建一个连接对象,并声明需要使用的队列。这可以通过以下代码实现: ``` amqp_connection_state_t conn; conn = amqp_new_connection(); amqp_socket_t *socket = amqp_tcp_socket_new(conn); amqp_socket_open(socket, "localhost", 5672); amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"); amqp_channel_open(conn, 1); amqp_queue_declare(conn, 1, amqp_cstring_bytes("hello"), 0, 0, 0, 1, amqp_empty_table); ``` 3. 发送和接收消息 发送和接收消息需要使用basic_publish和basic_consume方法。以下是发送和接收消息的示例代码: ``` // 发送消息 char message[] = "Hello World!"; amqp_bytes_t message_bytes = amqp_cstring_bytes(message); amqp_basic_publish(conn, 1, amqp_empty_bytes, amqp_cstring_bytes("hello"), 0, 0, NULL, message_bytes); // 接收消息 amqp_basic_consume(conn, 1, amqp_cstring_bytes("hello"), amqp_empty_bytes, 0, 1, 0, amqp_empty_table); amqp_frame_t frame; int result = amqp_simple_wait_frame(conn, &frame); if (result < 0) { return -1; } if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) { return -1; } amqp_message_t message; result = amqp_read_message(conn, frame.channel, &message, NULL); if (result < 0) { return -1; } printf("Received message: %.*s\n", (int)message.body.len, (char*)message.body.bytes); amqp_destroy_message(&message); ``` 4. 关闭连接 在使用RabbitMQ-c之后,需要关闭连接。可以通过以下代码实现: ``` amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS); amqp_connection_close(conn, AMQP_REPLY_SUCCESS); amqp_destroy_connection(conn); ```
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值