ActiveMQ入门分享
背景描述:
因业务需求,需要用到ActiveMQ消息中间件,以前没接触过ActiveMQ,故而记录下来,若有错,请指教!(客户端语言是采用C++开发)
简述:
网上关于ActiveMQ的介绍(包括从协议、消息模型queue/topic、持久化存储、集群、监控等都做了一些介绍,可以去搜搜了解一下,提取自己需要的信息)。
把所有的消息放到消息中间件,打破了常规的客户端服务端阻塞式交互,也解决了一些痛病(比如一个请求在服务端由于网络或者其他原因处理时间过长,客户端那边一直在阻塞,后面的请求堆积,这样用户体验不好,也容易出问题)。
下面给出一些我觉得对我有帮助的一些文章,可做参考(感谢各位大佬的文章):
ActiveMQ使用
ActiveMQ介绍
XMPP协议介绍
AMQP协议介绍
业务需求:
接受消息中间件下发的消息,解析出做业务逻辑处理,并回复中间件处理结果,采用Topic消息模型。(相对来说需求不复杂,但整体了解ActiveMQ可没这么简单,我自己也在学习阶段,MQ博大精深)
CMS介绍:
对于ActiveMQ这个消息中间件而言,是跨系统、跨语言,解决强依赖性这个问题的困扰。
那么,CMS就是提供给C++语言和ActiveMQ交互的接口,C++怎么调用接口完成和ActiveMQ进行一次交互,直接来看demo;
消费者demo(异步接受数据 onMessage中接收数据):
#include <activemq/library/ActiveMQCPP.h>
#include <decaf/lang/Thread.h>
#include <decaf/lang/Runnable.h>
#include <decaf/util/concurrent/CountDownLatch.h>
#include <decaf/lang/Integer.h>
#include <decaf/lang/Long.h>
#include <decaf/lang/System.h>
#include <activemq/core/ActiveMQConnectionFactory.h>
#include <activemq/util/Config.h>
#include <cms/Connection.h>
#include <cms/Session.h>
#include <cms/TextMessage.h>
#include <cms/BytesMessage.h>
#include <cms/MapMessage.h>
#include <cms/ExceptionListener.h>
#include <cms/MessageListener.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <memory>
#include <decaf/util/Random.h>
using namespace activemq::core;
using namespace decaf::util::concurrent;
using namespace decaf::util;
using namespace decaf::lang;
using namespace cms;
using namespace std;
#define QUEUE_NAME "eventTopic"
//头文件公用
class HelloWorldConsumer : public ExceptionListener,
public MessageListener,
public Runnable {
private:
CountDownLatch latch;
CountDownLatch doneLatch;
Connection* connection;
Session* session;
Destination* destination;
MessageConsumer* consumer;
bool useTopic;
bool sessionTransacted;
std::string brokerURI;
private:
HelloWorldConsumer(const HelloWorldConsumer&);
HelloWorldConsumer& operator=(const HelloWorldConsumer&);
public:
HelloWorldConsumer(const std::string& brokerURI, int numMessages, bool useTopic = false, bool sessionTransacted = false) :
latch(1),
doneLatch(numMessages),
connection(NULL),
session(NULL),
destination(NULL),
consumer(NULL),
useTopic(useTopic),
sessionTransacted(sessionTransacted),
brokerURI(brokerURI) {
}
virtual ~HelloWorldConsumer() {
cleanup();
}
void close() {
this->cleanup();
}
virtual void run() {
try {
// Create a ConnectionFactory
auto_ptr<ConnectionFactory> connectionFactory(
ConnectionFactory::createCMSConnectionFactory(brokerURI));
// Create a Connection
connection = connectionFactory->createConnection();
connection->start();
connection->setExceptionListener(this);//异常监听
// Create a Session
if (this->sessionTransacted == true)
{
session = connection->createSession(Session::SESSION_TRANSACTED);
}
else
{
session = connection->createSession(Session::AUTO_ACKNOWLEDGE);
}
// Create the destination (Topic or Queue)
if (useTopic) {
destination = session->createTopic(QUEUE_NAME);
}
else {
destination = session->createQueue(QUEUE_NAME);
}
// Create a MessageConsumer from the Session to the Topic or Queue
consumer = session->createConsumer(destination);
consumer->setMessageListener(this);//注册监听
// Indicate we are ready for messages.
latch.countDown();
// Wait while asynchronous messages come in.
doneLatch.await();
}
catch (CMSException& e) {
printf("Consumer onException() CMS Exception occurred. Shutting down client. \n");
// Indicate we are ready for messages.
latch.countDown();
e.printStackTrace();
}
}
virtual void onMessage(const Message* message)
{
static int count = 0;
try {
const TextMessage* textMessage = dynamic_cast<const TextMessage*> (message);
if (NULL == textMessage)
{
printf("NULL==textMessage", message->getCMSType().c_str());
return;
}
string text = "";
if (textMessage != NULL)
{
text = textMessage->getText();
}
else
{
text = "NOT A TEXTMESSAGE!";
}
int nProPerty = textMessage->getIntProperty("Integer");//属性过滤
printf("consumer Message #%d Received: %s,nProPerty[%d]\n", count, text.c_str(), nProPerty);
}
catch (CMSException& e)
{
printf("Consumer onMessage() CMS Exception occurred. Shutting down client. \n");
e.printStackTrace();
}
// Commit all messages.
if (this->sessionTransacted)
{
session->commit();//提交事务
}
}
private:
void cleanup() {
if (connection != NULL)
{
try
{
connection->close();
}
catch (cms::CMSException& ex)
{
ex.printStackTrace();
}
}
// Destroy resources.
try
{
delete destination;
destination = NULL;
delete consumer;
consumer = NULL;
delete session;
session = NULL;
delete connection;
connection = NULL;
}
catch (CMSException& e)
{
e.printStackTrace();
}
}
};
生产者demo:
class HelloWorldProducer :{
private:
Connection* connection;
Session* session;
Destination* destination;
MessageProducer* producer;
bool useTopic;
bool sessionTransacted;
std::string brokerURI;
private:
HelloWorldProducer(const HelloWorldProducer&);
HelloWorldProducer& operator=(const HelloWorldProducer&);
public:
HelloWorldProducer(const std::string& brokerURI, bool useTopic = false, bool sessionTransacted = false) :
connection(NULL),
session(NULL),
destination(NULL),
producer(NULL),
useTopic(useTopic),
sessionTransacted(sessionTransacted),
brokerURI(brokerURI),
{ }
virtual ~HelloWorldProducer() {
cleanup();
}
void close() {
this->cleanup();
}
virtual void run() {
try {
// Create a ConnectionFactory
std::auto_ptr<ConnectionFactory> connectionFactory(
ConnectionFactory::createCMSConnectionFactory(brokerURI));
// Create a Connection
connection = connectionFactory->createConnection();
connection->start();
// Create a Session
if (this->sessionTransacted) {
session = connection->createSession(Session::SESSION_TRANSACTED);
}
else {
session = connection->createSession(Session::AUTO_ACKNOWLEDGE);
}
session = connection->createSession();
// Create the destination (Topic or Queue)
if (useTopic)
{
destination = session->createTopic(QUEUE_NAME);
}
else
{
destination = session->createQueue(QUEUE_NAME);
}
// Create a MessageProducer from the Session to the Topic or Queue
producer = session->createProducer(destination);
producer->setDeliveryMode(DeliveryMode::NON_PERSISTENT); //是否持久化
string text = "123444";
std::auto_ptr<TextMessage> message(session->createTextMessage(text));
producer->send(message.get());
}
catch (CMSException& e)
{
printf("Producer run() CMSException \n");
e.printStackTrace();
}
}
private:
void cleanup()
{
if (connection != NULL)
{
try
{
connection->close();
}
catch (cms::CMSException& ex)
{
ex.printStackTrace();
}
}
// Destroy resources.
try
{
delete destination;
destination = NULL;
delete producer;
producer = NULL;
delete session;
session = NULL;
delete connection;
connection = NULL;
}
catch (CMSException& e)
{
e.printStackTrace();
}
}
};