Welcome to 9ilk's Code World

(๑•́ ₃ •̀๑) 个人主页: 9ilk
(๑•́ ₃ •̀๑) 文章专栏: 项目
本篇博客主要是对消息队列项目组件的功能的一个测试,主要测试点在于在不同模式下的交换机,客户端是否能正确收到订阅队列的消息,这里我们测试的是广播交换、直接交换和主题交换。
广播交换模式测试
主要测试方案是:
- 声明一个交换机,且为广播模式
- 声明两个队列queue1和queue2,设置好binding_key然后和交换机进行绑定。
- 前面两个操作,为了以防万一,消费者客户端和生产者客户端都做一遍这个工作。
- 然后订阅客户端就可以订阅queue1,发布客户端发布的消息,订阅客户端应该都能收到
发布客户端:
cpp
#include "asyncWorker.hpp"
#include "channel.hpp"
#include"connection.hpp"
#include <google/protobuf/map.h>
#include <memory>
#include <string>
int main()
{
//1.实例化异步工作线程对现场
zmq::AsyncWorker::ptr awp = make_shared<zmq::AsyncWorker>();
//2.实例化连接对象
zmq::Connection::ptr conn = make_shared<zmq::Connection>("127.0.0.1",8085,awp);
//3.通过连接创建信道
zmq::Channel::ptr channel = conn->openChannel();
//4.通过信道提供的服务完成所需
//4.1声明一个交换机 exchange1,交换机类型为广播模式
google::protobuf::Map<string,string> tmp_map;
channel->declareExchange("exchange1",zmq::ExchangeType::FANOUT,true,false,tmp_map);
//4.2声明两个队列
channel->declareQueue("queue1",true,false,false,tmp_map);
channel->declareQueue("queue2",true,false,false,tmp_map);
//4.3绑定 queue1-exchange1 且bing_key设置为queue1
channel->queueBind("exchange1","queue1","queue1");
channel->queueBind("exchange1","queue2","news.music.#");
//5. 循环向交换机发布消息
for(int i = 0 ; i < 10 ; i++)
{
//广播
channel->basicPublish("exchange1",nullptr,"Hello Queue-"+to_string(i));
}
//6.关闭信道
conn->closeChannel(channel);
return 0;
}
订阅客户端:
cpp
#include "asyncWorker.hpp"
#include "channel.hpp"
#include"connection.hpp"
#include <functional>
#include <google/protobuf/map.h>
#include <memory>
#include<thread>
#include <string>
#include<iostream>
#include "../mqcommon/logger.hpp"
using namespace std;
void callBack(zmq::Channel::ptr channel,const string& tag,const zmq::BasicProperties* bp,const string& body)
{
cout << tag << "消费了消息:" << body << endl;
//应答
channel->basicAck(bp->id());
}
int main(int argc,char* argv[])
{
if(argc!=2)
{
DBG_LOG("Usage: ./consume_client queue_anme");
exit(1);
}
//1.实例化异步工作线程对现场
zmq::AsyncWorker::ptr awp = make_shared<zmq::AsyncWorker>();
//2.实例化连接对象
zmq::Connection::ptr conn = make_shared<zmq::Connection>("127.0.0.1",8085,awp);
//3.通过连接创建信道
zmq::Channel::ptr channel = conn->openChannel();
//4.通过信道提供的服务完成所需
//4.1声明一个交换机 exchange1,交换机类型为广播模式
google::protobuf::Map<string,string> tmp_map;
channel->declareExchange("exchange1",zmq::ExchangeType::FANOUT,true,false,tmp_map);
//4.2声明两个队列
channel->declareQueue("queue1",true,false,false,tmp_map);
channel->declareQueue("queue2",true,false,false,tmp_map);
//4.3绑定 queue1-exchange1 且bing_key设置为queue1
channel->queueBind("exchange1","queue1","queue1");
channel->queueBind("exchange1","queue2","news.music.#");
//6.订阅队列消息
auto functor = std::bind(callBack,channel,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3);
channel->basicConsume("consumer1",argv[1],false,functor);
//7.关闭信道
while(1)
{
std::this_thread::sleep_for(std::chrono::seconds(3));
}
conn->closeChannel(channel);
return 0;
}
直接交换模式测试
主要测试方案:
- 同样声明一个交换机和两个队列,交换机是直接交换模式
- 直接交换模式下,直接比较routing_key和binding_key是否相同
- 我们将消息设置为跟queue2的binding_key相同
- 因此分别启动两个订阅客户端分别订阅queue1、queue2,发布客户端发布消息之后应该是只有订阅了queue2的客户端能收到消息。
发布客户端:
cpp
#include "asyncWorker.hpp"
#include "channel.hpp"
#include"connection.hpp"
#include <google/protobuf/map.h>
#include <memory>
#include <string>
int main()
{
//1.实例化异步工作线程对现场
zmq::AsyncWorker::ptr awp = make_shared<zmq::AsyncWorker>();
//2.实例化连接对象
zmq::Connection::ptr conn = make_shared<zmq::Connection>("127.0.0.1",8085,awp);
//3.通过连接创建信道
zmq::Channel::ptr channel = conn->openChannel();
//4.通过信道提供的服务完成所需
//4.1声明一个交换机 exchange1,交换机类型为直接模式
google::protobuf::Map<string,string> tmp_map;
channel->declareExchange("exchange1",zmq::ExchangeType::DIRECT,true,false,tmp_map);
//4.2声明两个队列
channel->declareQueue("queue1",true,false,false,tmp_map);
channel->declareQueue("queue2",true,false,false,tmp_map);
//4.3绑定 queue1-exchange1 且bing_key设置为queue1
channel->queueBind("exchange1","queue1","queue1");
channel->queueBind("exchange1","queue2","news.music.#");
//5. 循环向交换机发布消息
for(int i = 0 ; i < 10 ; i++)
{
//直接
zmq::BasicProperties bp;
bp.set_id(zmq::uuidHelper::uuid());
bp.set_delivery_mode(zmq::DeliveryMode::DURABLE);
bp.set_routing_key("news.music.#");
channel->basicPublish("exchange1",&bp,"Hello Queue-"+to_string(i));
}
//6.关闭信道
conn->closeChannel(channel);
return 0;
}
消费客户端:
cpp
#include "asyncWorker.hpp"
#include "channel.hpp"
#include"connection.hpp"
#include <functional>
#include <google/protobuf/map.h>
#include <memory>
#include<thread>
#include <string>
#include<iostream>
#include "../mqcommon/logger.hpp"
using namespace std;
void callBack(zmq::Channel::ptr channel,const string& tag,const zmq::BasicProperties* bp,const string& body)
{
cout << tag << "消费了消息:" << body << endl;
//应答
channel->basicAck(bp->id());
}
int main(int argc,char* argv[])
{
if(argc!=2)
{
DBG_LOG("Usage: ./consume_client queue_anme");
exit(1);
}
//1.实例化异步工作线程对现场
zmq::AsyncWorker::ptr awp = make_shared<zmq::AsyncWorker>();
//2.实例化连接对象
zmq::Connection::ptr conn = make_shared<zmq::Connection>("127.0.0.1",8085,awp);
//3.通过连接创建信道
zmq::Channel::ptr channel = conn->openChannel();
//4.通过信道提供的服务完成所需
//4.1声明一个交换机 exchange1,交换机类型为广播模式
google::protobuf::Map<string,string> tmp_map;
channel->declareExchange("exchange1",zmq::ExchangeType::FANOUT,true,false,tmp_map);
//4.2声明两个队列
channel->declareQueue("queue1",true,false,false,tmp_map);
channel->declareQueue("queue2",true,false,false,tmp_map);
//4.3绑定 queue1-exchange1 且bing_key设置为queue1
channel->queueBind("exchange1","queue1","queue1");
channel->queueBind("exchange1","queue2","news.music.#");
//6.订阅队列消息
auto functor = std::bind(callBack,channel,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3);
channel->basicConsume("consumer1",argv[1],false,functor);
//7.关闭信道
while(1)
{
std::this_thread::sleep_for(std::chrono::seconds(3));
}
conn->closeChannel(channel);
return 0;
}
主题交换模式测试
- 发布三种routing_key消息,分别是news.music.queue、news.music.pop、news.sport
- 因此订阅queue1的收不到任何消息,订阅queue2的只能收到前两种
发布客户端:
cpp
#include "asyncWorker.hpp"
#include "channel.hpp"
#include"connection.hpp"
#include <google/protobuf/map.h>
#include <memory>
#include <string>
int main()
{
//1.实例化异步工作线程对现场
zmq::AsyncWorker::ptr awp = make_shared<zmq::AsyncWorker>();
//2.实例化连接对象
zmq::Connection::ptr conn = make_shared<zmq::Connection>("127.0.0.1",8085,awp);
//3.通过连接创建信道
zmq::Channel::ptr channel = conn->openChannel();
//4.通过信道提供的服务完成所需
//4.1声明一个交换机 exchange1,交换机类型为广播模式
google::protobuf::Map<string,string> tmp_map;
channel->declareExchange("exchange1",zmq::ExchangeType::FANOUT,true,false,tmp_map);
//4.2声明两个队列
channel->declareQueue("queue1",true,false,false,tmp_map);
channel->declareQueue("queue2",true,false,false,tmp_map);
//4.3绑定 queue1-exchange1 且bing_key设置为queue1
channel->queueBind("exchange1","queue1","queue1");
channel->queueBind("exchange1","queue2","news.music.#");
//5. 循环向交换机发布消息
for(int i = 0 ; i < 10 ; i++)
{
//直接
zmq::BasicProperties bp;
bp.set_id(zmq::uuidHelper::uuid());
bp.set_delivery_mode(zmq::DeliveryMode::DURABLE);
bp.set_routing_key("news.music.queue");
channel->basicPublish("exchange1",&bp,"Hello Queue-"+to_string(i));
}
zmq::BasicProperties bp;
bp.set_id(zmq::uuidHelper::uuid());
bp.set_delivery_mode(zmq::DeliveryMode::DURABLE);
bp.set_routing_key("news.music.pop");
channel->basicPublish("exchange1",&bp,"Hello pop");
bp.set_id(zmq::uuidHelper::uuid());
bp.set_delivery_mode(zmq::DeliveryMode::DURABLE);
bp.set_routing_key("news.sport");
channel->basicPublish("exchange1",&bp,"Hello sport");
//6.关闭信道
conn->closeChannel(channel);
return 0;
}
消费客户端:
cpp
#include "asyncWorker.hpp"
#include "channel.hpp"
#include"connection.hpp"
#include <functional>
#include <google/protobuf/map.h>
#include <memory>
#include<thread>
#include <string>
#include<iostream>
#include "../mqcommon/logger.hpp"
using namespace std;
void callBack(zmq::Channel::ptr channel,const string& tag,const zmq::BasicProperties* bp,const string& body)
{
cout << tag << "消费了消息:" << body << endl;
//应答
channel->basicAck(bp->id());
}
int main(int argc,char* argv[])
{
if(argc!=2)
{
DBG_LOG("Usage: ./consume_client queue_anme");
exit(1);
}
//1.实例化异步工作线程对现场
zmq::AsyncWorker::ptr awp = make_shared<zmq::AsyncWorker>();
//2.实例化连接对象
zmq::Connection::ptr conn = make_shared<zmq::Connection>("127.0.0.1",8085,awp);
//3.通过连接创建信道
zmq::Channel::ptr channel = conn->openChannel();
//4.通过信道提供的服务完成所需
//4.1声明一个交换机 exchange1,交换机类型为广播模式
google::protobuf::Map<string,string> tmp_map;
channel->declareExchange("exchange1",zmq::ExchangeType::TOPIC,true,false,tmp_map);
//4.2声明两个队列
channel->declareQueue("queue1",true,false,false,tmp_map);
channel->declareQueue("queue2",true,false,false,tmp_map);
//4.3绑定 queue1-exchange1 且bing_key设置为queue1
channel->queueBind("exchange1","queue1","queue1");
channel->queueBind("exchange1","queue2","news.music.#");
//6.订阅队列消息
auto functor = std::bind(callBack,channel,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3);
channel->basicConsume("consumer1",argv[1],false,functor);
//7.关闭信道
while(1)
{
std::this_thread::sleep_for(std::chrono::seconds(3));
}
conn->closeChannel(channel);
return 0;
}