今天好好的捋一下ActiveMQ的一些关键名称。
1、ConnectionFactory 连接工厂
接口主要方法,createConnection()
2、ActiveMQConnectionFactory 连接工厂实现了ConnectionFactory 接口
public ActiveMQConnectionFactory(String userName, String password, String brokerURL) {
setUserName(userName);
setPassword(password);
setBrokerURL(brokerURL);
}
此处brokerURL笔者在使用时用了,failover:(tcp://127.0.0.1:61616)?randomize=false&maxReconnectAttempts=10000,失败重连机制,最大重连次数10000次。
实现接口ConnectionFactory 的createConnection() 方法,创建Connection连接。
protected ActiveMQConnection createActiveMQConnection(String userName, String password) throws JMSException {
if (brokerURL == null) {
throw new ConfigurationException("brokerURL not set.");
}
ActiveMQConnection connection = null;
try {
Transport transport = createTransport();
connection = createActiveMQConnection(transport, factoryStats);
connection.setUserName(userName);
connection.setPassword(password);
configureConnection(connection);
transport.start();
if (clientID != null) {
connection.setDefaultClientID(clientID);
}
return connection;
} catch (JMSException e) {
// Clean up!
try {
connection.close();
} catch (Throwable ignore) {
}
throw e;
} catch (Exception e) {
// Clean up!
try {
connection.close();
} catch (Throwable ignore) {
}
throw JMSExceptionSupport.create("Could not connect to broker URL: " + brokerURL + ". Reason: " + e, e);
}
}
3、连接池PooledConnectionFactory创建PooledConnection连接
PooledConnectionFactory poolFactory = new PooledConnectionFactory(connectionFactory);
conn = (PooledConnection)poolFactory.createConnection();
4、连接Connection
前面介绍了两种创建连接的方式,我们知道使用连接池的好处是,资源重复利用,统一资源管理与释放等。
connection创建后需调用start()方法。
资源使用后需调用close()方法关闭连接,以免泄露。(注,使用连接池创建可不用调用此方法)
5、会话session
创建连接后当然就要会话了,就比如拨打电话后需要说话,传递信息一样。
调用Connection的createSession(false,Session.AUTO_ACKNOWLEDGE)方法创建Session.
Connection接口中方法原型Session createSession(boolean transacted, int acknowledgeMode)
参数一:boolean transacted 通过字面意思可知这是事物是否开启的标志,事物开启就涉及到Session接口中的commit()和rollback()等方法。笔者的项目中设置了false,不开启事物。
参数二:int acknowledgeMode是应答模式,分为三种,
Session.AUTO_ACKNOWLEDGE模式,当客户成功的从receive方法或者从MessageListener.onMessage方法成功返回时,会话自动确认客户端收到消息。Session.CLIENT_ACKNOWLEDGE模式,需要客户端调用Message.acknowledge()方法返回确认。
Session.DUPS_OK_ACKNOWLEDGE模式,消息可能会重复发送,第二次重复发送消息时,消息头的JmsDelivered被置为true,客户端进行消息的重复处理。
void close() throws JMSException; 重点要注意使用完关闭会话。
6、目的地Destination
包括点对点(QUEUE)和订阅/发布(TOPIC)
Queue createQueue(String queueName) throws JMSException; 点对点只能有一个消费者
Topic createTopic(String topicName) throws JMSException; 发布/订阅可以有多个消费者
7、消息生产者MessageProducer
Session接口中MessageProducer createProducer(Destination destination) throws JMSException;
MessageProducer接口中几个重要的方法:
producer.setDeliveryMode(DeliveryMode.PERSISTENT); 设置持久化,消息持久保持,即使ActiveMQ挂掉。还有DeliveryMode.NON_PERSISTENT非持久化。
void setPriority(int defaultPriority) throws JMSException; 设置优先级,0-9,默认为4
void setTimeToLive(long timeToLive) throws JMSException; 设置消息有效时间,默认永远不过期
void close() throws JMSException; 关闭生产
void send(Message message) throws JMSException; 发送消息
8、消息消费者MessageConsumer
接口中重要的几个方法:
void setMessageListener(MessageListener listener) throws JMSException; 设置消息监听,实现MessageListener 接口的void onMessage(Message message);即可接收消息。异步,非阻塞。笔者项目使用此方式。
Message receive() throws JMSException; 接收消息的另一种方法。阻塞。
void close() throws JMSException;关闭消费
9、消息体
消息体有几种类型:
BytesMessage createBytesMessage() throws JMSException;
MapMessage createMapMessage() throws JMSException;
Message createMessage() throws JMSException;
ObjectMessage createObjectMessage() throws JMSException;
ObjectMessage createObjectMessage(Serializable object) throws JMSException;
StreamMessage createStreamMessage() throws JMSException;
TextMessage createTextMessage() throws JMSException;
TextMessage createTextMessage(String text) throws JMSException;
笔者项目采用 TextMessage类型。
10、虚拟topic
笔者项目使用了新特性虚拟topic,在此简单介绍一下,
1. 虚拟主题(Virtual Topics)
ActiveMQ中,topic只有在持久订阅(durablesubscription)下是持久化的。存在持久订阅时,每个持久订阅者,都相当于一个持久化的queue的客户端,它会收取所有消息。这种情况下存在两个问题:
1. 同一应用内consumer端负载均衡的问题:同一个应用上的一个持久订阅不能使用多个consumer来共同承担消息处理功能。因为每个都会获取所有消息。queue模式可以解决这个问题,broker端又不能将消息发送到多个应用端。所以,既要发布订阅,又要让消费者分组,这个功能jms规范本身是没有的。
2. 同一应用内consumer端failover的问题:由于只能使用单个的持久订阅者,如果这个订阅者出错,则应用就无法处理消息了,系统的健壮性不高。
为了解决这两个问题,ActiveMQ中实现了虚拟Topic的功能。使用起来非常简单。
对于消息发布者来说,就是一个正常的Topic,名称以VirtualTopic.开头。例如VirtualTopic.TEST。
对于消息接收端来说,是个队列,不同应用里使用不同的前缀作为队列的名称,即可表明自己的身份即可实现消费端应用分组。例如Consumer.A.VirtualTopic.TEST,说明它是名称为A的消费端,同理Consumer.B.VirtualTopic.TEST说明是一个名称为B的客户端。可以在同一个应用里使用多个consumer消费此queue,则可以实现上面两个功能。又因为不同应用使用的queue名称不同(前缀不同),所以不同的应用中都可以接收到全部的消息。每个客户端相当于一个持久订阅者,而且这个客户端可以使用多个消费者共同来承担消费任务。
笔者项目主要是一些同步任务修改一些产品信息,需要通过ActiveMQ实时发送消息,修改相关属性和缓存,接口实时吐出最新字段值。项目由于保密,不方便贴代码,但是通过以上相关关键信息的讲解,再加上百度一下相关的例子,相信大家能很快搭建一个属于自己的消息处理系统。