MQ的创建以及使用。
1,首先,需要创建一个连接,由连接创建我们需要的session。在新建连接工厂类对象的时候,use,password,brokerUrl,在这里,都是取得默认值,真实环境下,根据实际情况选择。创建完一个连接后,开启这个连接,根据需要创建不同类型的session,对应着两种不同的消息传输方式。
public class BaseMQ {
private static Logger logger = Logger.getLogger(BaseMQ.class);
private static Connection connection = null;
private static TopicSession topicSession;
private static QueueSession queueSession;
private static BaseMQ instance;
public static BaseMQ getInstance() {
if (instance == null) {
instance = new BaseMQ();
}
return instance;
}
/**
* 创建连接
*/
public void getConnection() {
ActiveMQConnectionFactory connectionFactory = null;
if (connection == null) {
String url = "mq.url=failover:(tcp://localhost:61616)?initialReconnectDelay=100";
String username = "admin";
String password = "admin";
if ((username != null && !username.equals(""))
&& (password != null && !password.equals("")))
connectionFactory = new ActiveMQConnectionFactory(username,
password, url);
else
connectionFactory = new ActiveMQConnectionFactory(url);
try {
connection = connectionFactory.createConnection();
connection.start();
topicSession = (TopicSession) connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
queueSession = (QueueSession) connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
} catch (JMSException e) {
logger.error(e.getMessage(), e);
if (connection != null) {
try {
connection.close();
} catch (JMSException e1) {
logger.error(e.getMessage(), e);
}
}
}
}
}
/**
* 创建topic消费者
* @param topicName
* @return
*/
public MessageConsumer topicSubscriber(String topicName, String selector){
try {
Topic topic=topicSession.createTopic(topicName);
MessageConsumer subscriber;
if(!selector.equals(""))
subscriber = topicSession.createConsumer(topic, selector);
else
subscriber = topicSession.createConsumer(topic);
return subscriber;
} catch (JMSException e) {
logger.error(e.getMessage(), e);
return null;
}
}
/**
* 创建Queue 消息生产者
* @param queueName Queue Name
* @return
*/
public MessageProducer queueProducer(String queueName){
try {
Queue queue = queueSession.createQueue(queueName);
MessageProducer producer = queueSession.createProducer(queue);
return producer;
} catch (JMSException e) {
logger.error(e.getMessage(), e);
return null;
}
}
/**
* 创建queue消费者
* @param queueName
* @param selector:过滤的条件
* @return
*/
public MessageConsumer queueConsumer(String queueName,String selector){
try {
Queue queue = queueSession.createQueue(queueName);
MessageConsumer consumer;
if(!selector.equals(""))
consumer = queueSession.createConsumer(queue, selector);
else
consumer = queueSession.createConsumer(queue);
return consumer;
} catch (JMSException e) {
logger.error(e.getMessage(), e);
return null;
}
}
/**
* 创建topic发布者
* @param topicName
* @return
*/
public MessageProducer topicPublisher(String topicName){
MessageProducer publisher = null;
try {
Topic topic = topicSession.createTopic(topicName);
publisher = topicSession.createProducer(topic);
} catch (JMSException e) {
logger.error(e.getMessage(), e);
}
return publisher;
}
/**
* 接收MQ发送的消息
* @param consumer
* @return
*/
public static String receiveMessage(MessageConsumer consumer){
String message = "";
try {
ActiveMQTextMessage msg=(ActiveMQTextMessage)consumer.receive();
if(msg != null){
ByteSequence bs = msg.getContent();
try {
message = new String(bs.data,"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
System.out.println("msgText"+msg.getText());
} catch (JMSException e) {
logger.error(e.getMessage(), e);
}
return message;
}
public static TextMessage createTopicMessage(String text) {
try {
TextMessage textMsg = topicSession.createTextMessage(text);
return textMsg;
} catch (JMSException e) {
logger.error(e.getMessage(), e);
return null;
}
}
public static TextMessage createQueueMessage(String text) {
try {
TextMessage textMsg = queueSession.createTextMessage(text);
return textMsg;
} catch (JMSException e) {
logger.error(e.getMessage(), e);
return null;
}
}
public TextMessage getTextMessage(String message, String type){
TextMessage textMessage = null;
try {
if(type.equalsIgnoreCase("queue")){
textMessage = queueSession.createTextMessage(message);
} else if(type.equalsIgnoreCase("topic")) {
textMessage = topicSession.createTextMessage(message);
}
} catch (JMSException e) {
logger.error(e.getMessage(), e);
}
return textMessage;
}
/**
* 发送MQ
* @param producer
* @param message
* @param propertyString
*/
public static void sendMessage(MessageProducer producer, TextMessage message, String propertyString){
try {
if (!propertyString.equals("")) {
String[] properties = propertyString.split("`,");
for (String string : properties) {
String[] property = string.split("`/");
String type = property[1];
if (type.equals("string")) {
message.setStringProperty(property[0], property[2]);
} else if (type.equals("int")) {
message.setIntProperty(property[0],
Integer.valueOf(property[2]));
} else if (type.equals("double")) {
message.setDoubleProperty(property[0],
Double.valueOf(property[2]));
}
}
}
producer.send(message);
} catch (JMSException e) {
logger.error(e.getMessage(), e);
}
}
/**
* 关闭不需要的资源
*/
public void close(){
if (queueSession != null) {
try {
queueSession.close();
} catch (JMSException e) {
logger.error(e.getMessage(), e);
}
} if (topicSession != null) {
try {
topicSession.close();
} catch (JMSException e) {
logger.error(e.getMessage(), e);
}
} if (connection != null) {
try {
connection.stop();
connection.close();
} catch (JMSException e) {
logger.error(e.getMessage(), e);
}
}
}
}
2 ,接收消息的两种方式
1)Consumer的receive()方法,这种方式是客户端主动的接收消息,是同步接收的。
2)客户端可以通过注册一个实现MessageListener 接口的对象到MessageConsumer。MessageListener只有一个必须实现的方法 —— onMessage,它只接收一个参数,即Message。在为每个发送到Destination的消息实现onMessage时,将调用该方法。这种方式是指当消息到达时,ActiveMQ主动通知客户端,是异步接收的。
public class ItConsumer {
static int m;
public static void main(String[] args) throws JMSException {
//new TestThread().start();
//new ItConsumer().receiveGetMqMeg();
new ItConsumer().listenerGetMqMeg();
}
public void receiveGetMqMeg(){
ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD+1, ActiveMQConnection.DEFAULT_BROKER_URL);
System.out.println(ActiveMQConnection.DEFAULT_BROKER_URL);
System.out.println(activeMQConnectionFactory.getBrokerURL());
ActiveMQConnection connection = null;
Session queSession=null;
ActiveMQMessageConsumer consumer=null;
int before = 0;
int after =0;
boolean flag =true;
int n = 0;
try {
if(connection==null){
System.out.println("新建connection");
connection=(ActiveMQConnection) activeMQConnectionFactory.createConnection();
/*try {
connection.setClientID("10");
} catch (Exception e2) {
System.out.println("ClientID : 10 已经被占用");
}
*/
if(!connection.isStarted()){
connection.start();
}
}
queSession=connection .createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue =queSession.createQueue("miniTest001");
if(consumer ==null){
System.out.println("新建consumer");
consumer=(ActiveMQMessageConsumer) queSession.createConsumer(queue);
}
System.out.println("ClientID==="+connection.getClientID());
System.out.println("consumerID===="+consumer.getConsumerId());
System.out.println("接受消息之前++++++++++++++执行了"+ ++before+"次+++++++++++++++++++");
//while(flag){
MapMessage tm=(MapMessage) consumer.receive();
System.out.println("接受消息之后++++++++++++++执行了"+ ++after+"次+++++++++++++++++++");
if(tm!=null){
System.out.println(connection.getClientID()+"^^^^^^^^^^^^^^^收到的消息为:"+tm.getInt("优先级别"));
}else{
flag =false;
System.out.println(connection.getClientID()+"----------------收到的消息为空");
}
System.out.println("同步,先等我做完");
//}
//consumer.close();
//queSession.close();
//connection.close();
/*consumer.setMessageListener(new MessageListener() {
int msg;
int inAfter =0;
@Override
public void onMessage(Message message) {
MapMessage tm = null;
System.out.println("接受消息之后++++++++++++++执行了"+ ++inAfter+"次+++++++++++++++++++");
if(message instanceof ActiveMQMapMessage){
tm = (MapMessage) message;
try {
msg=tm.getInt("优先级别"+1);
System.out.println("收到的消息:"+msg);
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
System.out.println("异步,你不完成,我可以做别的事情");
//queSession.commit();
consumer.close();
queSession.close();
connection.close();*/
} catch (JMSException e) {
e.printStackTrace();
}finally{
/*if(consumer!=null){
consumer.close();
}
queSession.close();
connection.close();*/
/*if(!connection.isClosed()){
connection.stop();
}*/
}
}
public void listenerGetMqMeg(){
ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD+1, ActiveMQConnection.DEFAULT_BROKER_URL);
System.out.println(ActiveMQConnection.DEFAULT_BROKER_URL);
System.out.println(activeMQConnectionFactory.getBrokerURL());
ActiveMQConnection connection = null;
Session queSession=null;
ActiveMQMessageConsumer consumer=null;
int before = 0;
int after =0;
boolean flag =true;
int n = 0;
try {
if(connection==null){
System.out.println("新建connection");
connection=(ActiveMQConnection) activeMQConnectionFactory.createConnection();
/*try {
connection.setClientID("10");
} catch (Exception e2) {
System.out.println("ClientID : 10 已经被占用");
}
*/
if(!connection.isStarted()){
connection.start();
}
}
queSession=connection .createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue =queSession.createQueue("miniTest001");
if(consumer ==null){
System.out.println("新建consumer");
consumer=(ActiveMQMessageConsumer) queSession.createConsumer(queue);
}
System.out.println("ClientID==="+connection.getClientID());
System.out.println("consumerID===="+consumer.getConsumerId());
System.out.println("接受消息之前++++++++++++++执行了"+ ++before+"次+++++++++++++++++++");
consumer.setMessageListener(new MessageListener() {
int msg;
int inAfter =0;
@Override
public void onMessage(Message message) {
MapMessage tm = null;
System.out.println("接受消息之后++++++++++++++执行了"+ ++inAfter+"次+++++++++++++++++++");
if(message instanceof ActiveMQMapMessage){
try {
if(message.getJMSMessageID().equals("2")){
tm = (MapMessage) message;
msg=tm.getInt("优先级别");
System.out.println("收到的消息:"+msg);
}
} catch (JMSException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
});
System.out.println("异步,你不完成,我可以做别的事情");
//queSession.commit();
/*consumer.close();
queSession.close();
connection.close();*/
} catch (JMSException e) {
e.printStackTrace();
}finally{
/*if(consumer!=null){
consumer.close();
}
queSession.close();
connection.close();*/
/*if(!connection.isClosed()){
connection.stop();
}*/
}
}
}
3,Producer
public class Producer {
public static void main(String[] args) {
ActiveMQConnectionFactory connectionFactory =new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, ActiveMQConnection.DEFAULT_BROKER_URL);
System.out.println(ActiveMQConnection.DEFAULT_BROKER_URL);
Connection connection = null;
int pri=9;
try {
connection=connectionFactory.createConnection();
connection.start();
Session queSession =connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Queue queue=queSession.createQueue("miniTest001");
MessageProducer publisher=queSession.createProducer(queue);
for(pri=1;pri<10;pri++){
if(pri%2==0){
publisher.setDisableMessageID(true);
}else{
publisher.setDisableMessageID(false);
}
MapMessage msg=queSession.createMapMessage();
msg.setJMSMessageID(pri+"");
msg.setInt("优先级别", pri);
System.out.println("**********发送的消息为:"+msg.getInt("优先级别"));
System.out.println("publisher.getDisableMessageID========"+publisher.getDisableMessageID());
System.out.println("msg.getJMSMessageID()===="+msg.getJMSMessageID());
//publisher.send(msg,DeliveryMode.NON_PERSISTENT, pri, 100*1000);
publisher.send(msg);
}
//queSession.commit();
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
/*if(connection!=null){
try {
connection.close();
System.out.println();
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}*/
}
}
}
此时,访问本地 localhost:8161,会看到一个名为“miniTest001”的消息队列。
4,MQ消息传输时,message的类型
在接收MQ消息的时,返回的message的类型,由几种不同的类型:TextMessage ,ByteMessage ,Mapmessage,ObjectMessage,StreamMessage。根据producer的发送类型,选择与之相同的类型处理,如果接受类型错误,由于这几种之间无法进行相互转换,因此可能报 “ java.lang.ClassCastException”。解决办法为:对消息进行处理之前,添加判断:
if(message instanceof ActiveMQTextMessage){
tm = (TextMessage) message;
try {
msg = tm.getText();
logger.info("获取前台发送的MQ信息" + msg);
} catch (JMSException e) {
}
}else if(message instanceof ActiveMQBytesMessage){
ByteSequence bs = ((ActiveMQBytesMessage)message).getContent();
msg = new String(bs.data);
}
5,MQ选择器(selector)
有的时候,我们只希望满足某些条件的consumer可以接收到相应的MQ消息,以防止MQ消息接收混乱,此时我们需要使用MQ选择器。
选择器由三部分组成:标识符、常量、和比较运算符。其中标识符就是比较比较运算符中被比较的那一部分,标识符必须来自消息头或者是来自消息属性,它是区分大小写的,而且必须和属性或者是JMS消息头名称精确匹配。为了使用消息选择器,消息的生产者必须在发送消息之前指定属性或者是JMS消息头信息。
①producer,给要发送的message,添加property或消息头信息。
message.setStringProperty();
message.setIntProperty(“IDCard”,1052);
message.setDoubleProperty();
message.setJMSCorrelationID("correlationID");
②在创建consumer的时候,把selector添加进去。
String selector1= IDCard=1052;
Consumer consumer1=Session.create(destinationName,selector1);
String selector2= JMSCorrelationID=“correlationID”;
Consumer consumer2=Session.create(destinationName,selector2);