在我们所做的各种管理平台集成项目中,经常会遇到与各子系统之间的数据交换问题,通常我们与这些子系统之间的数据交换都是通过数据库来进行,或建立中间库或通过表与表之间进行数据导入导出。这样做会使子系统之间的耦合性太强,互相之间的影响较大,经常会出现莫名其妙的问题,比如表被锁死,丢失数据等,导致数据库管理很难。
这就应该用activemq了个各系统都通过mq来处理数据,减小数据可以压力,与程序的耦合。并且activeMQ运行稳定,效率高,不容易丢失数据,并且内置断开自动连接机制,开发也方便。
1、activeMQ基本构架
连接工厂是客户用来创建连接的对象,例如ActiveMQ提供的IConnectionFactory 。
IConnection 封装了客户与服务之间一个虚拟的连接。
Session是生产和消费消息的一个单线程上下文。会话用于创建消息生产者(producer)、消息消费者
(consumer)和消息 (message)等。会话提供了一个事务性的上下
文,在这个上下文中,一组发送和接收被组合到了一个原子操作中。
目的地是客户用来指定它生产的消息的目标和它消费的消息的来源的对象。定义了两种消息传递域:点对点
(PTP)消息传递域和发布/订阅消息传递域。
在点对点消息传递域中,目的地被成为队列(queue);在发布/订阅消息传递域中,目的地被成为主题
(topic)。
消息生产者是由会话创建的一个对象,用于把消息发送到一个目的地。
消息消费者是由会话创建的一个对象,它用于接收发送到目的地的消息。消息的消费可以采用以下两种方法之
一:同步消费。通过调用消费者的receive方法从目的地中显式提取消息。receive方法可以一直阻塞到消息到
达。
异步消费。客户可以为消费者注册一个消息监听器,以定义在消息到达时所采取的动作。
(7)消息 ITextMessage
ObjectMessage。
解压后,可以看到MQ目录下有以下文件和目录
activemq-all-5.5.0.jar:所有MQ JAR包的集合,用于用户系统调用
bin:其中包含MQ的启动脚本
conf:包含MQ的所有配置文件
data:日志文件及持久性消息数据
example:MQ的示例
lib:MQ运行所需的所有Lib
webapps:MQ的Web控制台及一些相关的DEMO
双击bin目录下的activemq.bat文件即可启动MQ,成功之后出现以下界面。
每个消息只能有一个消费者。
消息的生产者和消费者之间没有时间上的相关性。无论消费者在生产者发送消息的时候是否处于运行状态,它都可
以提取消息。
每个消息可以有多个消费者。
生产者和消费者之间有时间上的相关性。订阅一个主题的消费者只能消费自它订阅之后发布的消息。JMS规范允许
客户创建持久订阅,这在一定程度上放松了时间上的相关性要求。持久订阅允许消费者消费它在未处于激活状态时
发送的消息。
在点对点消息传递域中,目的地被成为队列(queue);在发布/订阅消息传递域中,目的地被成为主题(topic)。
4、producer
using System;
using System.Collections.Generic;
using System.Text;
using Apache.NMS;
using Apache.NMS.ActiveMQ;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace Publish
{
class Program
{
static void Main(string[] args)
{
try
{
//1、创建一个连接池
IConnectionFactory factory = new ConnectionFactory("tcp://localhost:61616/");
using (IConnection connection = factory.CreateConnection())
{
//2、创建一个session 用于producer操作
using (ISession session = connection.CreateSession())
{
//3、给topic创建一个producer
IMessageProducer producer = session.CreateProducer(
new Apache.NMS.ActiveMQ.Commands.ActiveMQTopic("demo"));
//4、 创建消息并发送消息
int i = 0;
while (!Console.KeyAvailable)
{
ITextMessage msg = producer.CreateTextMessage();
msg.Text = i.ToString();
Console.WriteLine("向topic发送信息: " + i.ToString());
producer.Send(msg, Apache.NMS.MsgDeliveryMode.NonPersistent, Apache.NMS.MsgPriority.Normal, TimeSpan.MinValue);
System.Threading.Thread.Sleep(2000);
i++;
}
}
}
Console.ReadLine();
}
catch (System.Exception e)
{
Console.WriteLine("{0}",e.Message);
Console.ReadLine();
}
}
}
}
5、consumer
using System;
using System.Collections.Generic;
using System.Text;
using Apache.NMS;
using Apache.NMS.ActiveMQ;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace Subscribe
{
class Program
{
static void Main(string[] args)
{
try
{
//创建连接池
IConnectionFactory factory = new ConnectionFactory("tcp://localhost:61616/");
//开始连接
using (IConnection connection = factory.CreateConnection())
{
connection.ClientId = "demo listener";
connection.Start();
//Create the Session
using (ISession session = connection.CreateSession())
{
//创建Consumer
IMessageConsumer consumer = session.CreateDurableConsumer(new Apache.NMS.ActiveMQ.Commands.ActiveMQTopic("demo"), "demo listener", null, false);
consumer.Listener += new MessageListener(consumer_Listener);
Console.ReadLine();
}
connection.Stop();
connection.Close();
}
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
}
}
static void consumer_Listener(IMessage message)
{
try
{
ITextMessage msg = (ITextMessage)message;
Console.WriteLine("Receive: " + msg.Text);
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}