activeMQ is a very powerful message middleware.
Supports multiple protocols including MQTT NIO, and is a perfect implementation of jms. When there are millions of end devices that need to connect to the server, proper processing and architecture can provide powerful service capabilities to the outside world.
First of all, you need to solve the performance problem of activeMQ single-node service, and you must not directly use the default configuration for production.
You can Baidu or refer to the log
http://m.blog.csdn.net/truong/article/details/73718621
http://blog.csdn.net/yinwenjie/article/details/50955502
http://blog.csdn. net/yinwenjie/article/details/50991443
http://blog.csdn.net/yinwenjie/article/details/51064242 If
a single node is completed, please refer to the blog post
http://www.cnblogs.com/leihenqianshang/articles/ After the construction of 5623858.html is
completed, the high-performance service architecture has come out. At this time, you need to write some test code.
1 Write first for the case where both the client and the consumer are based on the activeMQ API. The producer code is as follows:
package com.sunshine.mq; import javax.jms.Connection; import javax.jms.DeliveryMode; import javax.jms.JMSException; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TextMessage; import javax.jms.Topic; import org.apache.activemq.ActiveMQConnectionFactory; public class Producer { public static void main(String[] args) throws JMSException { // Connect to ActiveMQ server //ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.15:61616)"); //Here you can use the failover mechanism for multi-node configuration to achieve high availability and backend load balancing ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.15:1883)"); Connection connection = factory.createConnection(); connection.start(); Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // create theme Topic topic = session.createTopic("VirtualTopic.virtual-T.100990"); MessageProducer producer = session.createProducer(topic); // NON_PERSISTENT non-persistent PERSISTENT persistent, use persistent mode when sending messages //producer.setDeliveryMode(DeliveryMode.PERSISTENT); TextMessage message = session.createTextMessage(); for(int i = 0;i<10;i++){ message.setText("topic 消息。"+i); message.setStringProperty("property", "消息Property"); // publish topic message producer.send(message); System.out.println("Sent message: " + message.getText()); } session.close(); connection.close(); } }
We need multiple consumers to consume messages for distributed deployment purposes
Consumer 1
package com.sunshine.mq; import javax.jms.Connection; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageListener; import javax.jms.Queue; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; public class ConsumerA { public static void main(String[] args) throws JMSException, InterruptedException { // Connect to ActiveMQ server // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.17:1888,tcp://172.16.7.18:1889)"); // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.15:1887)"); // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.17:61616,tcp://172.16.7.18:61616)"); ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.17:1883,tcp://172.16.7.18:1883)"); Connection connection = factory.createConnection(); connection.start(); Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // create theme Queue topicA = session.createQueue("Consumer.GG.VirtualTopic.virtual-T.*"); // Consumer Group A creates a subscription MessageConsumer consumerA1 = session.createConsumer(topicA); Integer count = 0; while(true){ Message message = consumerA1.receive(); count++; TextMessage msg = (TextMessage)message; final String messageText = msg.getText(); System.out.println(messageText +", the total number of consumed messages is: "+count); } /**consumerA1.setMessageListener(new MessageListener() { // Subscription receive method public void onMessage(Message message) { TextMessage tm = (TextMessage) message; try { System.out.println("A 收到消息: " + tm.getText()+":"+tm.getStringProperty("property")); } catch (JMSException e) { e.printStackTrace (); } } });**/ //session.close(); //connection.close(); } }
Consumer 2
package com.sunshine.mq; import javax.jms.Connection; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.Queue; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; public class ConsumerB { public static void main(String[] args) throws JMSException, InterruptedException { // Connect to ActiveMQ server ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(nio://172.16.7.17:1888,nio://172.16.7.18:1889)"); // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.17:61616,tcp://172.16.7.18:61616)"); Connection connection = factory.createConnection(); connection.start(); Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // create theme Queue topicA = session.createQueue("Consumer.GG.VirtualTopic.virtual-T.*"); // Consumer Group A creates a subscription MessageConsumer consumerA1 = session.createConsumer(topicA); Integer count = 0; while(true){ Message message = consumerA1.receive(); count++; TextMessage msg = (TextMessage)message; final String messageText = msg.getText(); System.out.println(messageText +", the total number of consumed messages is: "+count); } /**consumerA1.setMessageListener(new MessageListener() { // Subscription receive method public void onMessage(Message message) { TextMessage tm = (TextMessage) message; try { System.out.println("B 收到消息: " + tm.getText()+":"+tm.getStringProperty("property")); } catch (JMSException e) { e.printStackTrace (); } } });**/ //session.close(); //connection.close(); } }
Consumer 3
package com.sunshine.mq; import javax.jms.Connection; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.Queue; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; public class ConsumerC { public static void main(String[] args) throws JMSException, InterruptedException { // Connect to ActiveMQ server ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(nio://172.16.7.17:1888,nio://172.16.7.18:1889)"); // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.17:61616,tcp://172.16.7.18:61616)"); // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(mqtt://172.16.7.17:1883,mqtt://172.16.7.18:1883)"); Connection connection = factory.createConnection(); connection.start(); Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // create theme Queue topicA = session.createQueue("Consumer.GG.VirtualTopic.virtual-T.*"); // Consumer Group A creates a subscription MessageConsumer consumerA1 = session.createConsumer(topicA); Integer count = 0; while(true){ Message message = consumerA1.receive(); count++; TextMessage msg = (TextMessage)message; final String messageText = msg.getText(); System.out.println(messageText +", the total number of consumed messages is: "+count); } /**consumerA1.setMessageListener(new MessageListener() { // Subscription receive method public void onMessage(Message message) { TextMessage tm = (TextMessage) message; try { System.out.println("B 收到消息: " + tm.getText()+":"+tm.getStringProperty("property")); } catch (JMSException e) { e.printStackTrace (); } } });**/ //session.close(); //connection.close(); } }
The result of the test is that the messages generated by the producer are loaded to different consumer clients, and each consumer client consumes different messages. Here, no matter whether the message produced by the producer goes to the queue or goes to the topic, the result is to realize the routing of the message.
Suppose there is a situation where the device only supports the MQTT protocol, uses MQTTClient to send messages, or just wants to use MQTT, then how to deal with this architecture? The reason is the same, because of the urgency of linux-c or C++ client developers, the producer simulates the program
package com.sunshine.mqtt; import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; import org.eclipse.paho.client.mqttv3.MqttCallback; import org.eclipse.paho.client.mqttv3.MqttClient; import org.eclipse.paho.client.mqttv3.MqttConnectOptions; import org.eclipse.paho.client.mqttv3.MqttDeliveryToken; import org.eclipse.paho.client.mqttv3.MqttMessage; import org.eclipse.paho.client.mqttv3.MqttTopic; import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; public class MyMqttClient { private String host="tcp://172.16.7.15:1887"; private String userName="admin"; private String passWord = "activemq.123"; private MqttConnectOptions options; private MqttClient client; private MqttMessage message ; private String[] myTopics={"test_result/20179112982783"}; private int[] myQos={2}; private MqttTopic topic; private String myTopic = "test/20179112982783"; public MyMqttClient(){ try { client=new MqttClient(host,"test99990000",new MemoryPersistence()); options = new MqttConnectOptions(); options.setCleanSession(false); options.setUserName(userName); options.setPassword(passWord.toCharArray()); options.setConnectionTimeout(10); options.setKeepAliveInterval(20); client.setCallback(new MqttCallback(){ @Override public void connectionLost(Throwable cause) { } @Override public void messageArrived(String topicName, MqttMessage message) throws Exception { System.out.println("topicName is :"+topicName); System.out.println("Message is:"+message.toString()); } @Override public void deliveryComplete(IMqttDeliveryToken token) { }}); client.connect(options); client.subscribe(myTopics,myQos); } catch (Exception e) { e.printStackTrace (); } } public void sendMessage(String topicT,String messageTest){ try { message = new MqttMessage(); message.setQos(0); message.setRetained(true); message.setPayload(messageTest.getBytes()); topic = client.getTopic(topicT); MqttDeliveryToken token = topic.publish(message); token.waitForCompletion(); System.out.println("Send message:"+messageTest); } catch (Exception e) { e.printStackTrace (); } } }
package com.sunshine.mqtt; import java.text.SimpleDateFormat; import java.util.Date; import org.junit.Test; public class MyMqttTest { @Test public void testMQTT(){ MyMqtt mqtt = new MyMqtt(); mqtt.sendMessage("I sent a message to the client"); } @Test public void testMQTTClient(){ MyMqttClient client=new MyMqttClient(); //client.sendMessage("I sent a message to the server, my SN is 20179112982783"); } @Test public void testIotConnect() throws InterruptedException{ MyMqttClient client=new MyMqttClient(); for(int i=0;i<10;i++){ client.sendMessage("VirtualTopic/100990"+i,"mqtt-msg:"+i+">"+("100990"+i)); } } }
three consumers
package com.sunshine.mq; import javax.jms.Connection; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.Queue; import javax.jms.Session; import javax.jms.TextMessage; import javax.jms.TopicConnectionFactory; import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.command.ActiveMQBytesMessage; public class ConsumerTopicA { public static void main(String[] args) throws JMSException, InterruptedException { // 连接到ActiveMQ服务器 // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.17:1888,tcp://172.16.7.18:1889)"); // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.15:1887)"); // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.17:61616,tcp://172.16.7.18:61616)"); //ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.17:1883,tcp://172.16.7.18:1883)"); ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin", "failover:(tcp://172.16.7.17:1888,tcp://172.16.7.18:1889)"); Connection connection = factory.createConnection(); connection.start(); Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // 创建主题 Queue topicA = session.createQueue("Consumer.GG.VirtualTopic.*"); // 消费者A组创建订阅 MessageConsumer consumerA1 = session.createConsumer(topicA); Integer count = 0; while(true){ //在实际生产过程中不建议使用receive 会造成阻塞并损耗大量资源 建议直接使用spring jms 监听器 ActiveMQBytesMessage message = (ActiveMQBytesMessage) consumerA1.receive(); count++; // TextMessage msg = (TextMessage)message; // String messageText = msg.getText(); System.out.println(new String(message.getMessage().getContent().getData()) +",消费消息总数为:"+count); } /**consumerA1.setMessageListener(new MessageListener() { // 订阅接收方法 public void onMessage(Message message) { TextMessage tm = (TextMessage) message; try { System.out.println("A 收到消息: " + tm.getText()+":"+tm.getStringProperty("property")); } catch (JMSException e) { e.printStackTrace(); } } });**/ //session.close(); //connection.close(); } }
package com.sunshine.mq; import javax.jms.Connection; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.Queue; import javax.jms.Session; import javax.jms.TextMessage; import javax.jms.TopicConnectionFactory; import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.command.ActiveMQBytesMessage; public class ConsumerTopicB { public static void main(String[] args) throws JMSException, InterruptedException { // 连接到ActiveMQ服务器 // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.17:1888,tcp://172.16.7.18:1889)"); // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.15:1887)"); // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.17:61616,tcp://172.16.7.18:61616)"); //ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.17:1883,tcp://172.16.7.18:1883)"); ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin", "failover:(tcp://172.16.7.17:1888,tcp://172.16.7.18:1889)"); Connection connection = factory.createConnection(); connection.start(); Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // 创建主题 Queue topicA = session.createQueue("Consumer.GG.VirtualTopic.*"); // 消费者A组创建订阅 MessageConsumer consumerA1 = session.createConsumer(topicA); Integer count = 0; while(true){ ActiveMQBytesMessage message = (ActiveMQBytesMessage) consumerA1.receive(); count++; // TextMessage msg = (TextMessage)message; // String messageText = msg.getText(); System.out.println(new String(message.getMessage().getContent().getData()) +",消费消息总数为:"+count); } /**consumerA1.setMessageListener(new MessageListener() { // 订阅接收方法 public void onMessage(Message message) { TextMessage tm = (TextMessage) message; try { System.out.println("A 收到消息: " + tm.getText()+":"+tm.getStringProperty("property")); } catch (JMSException e) { e.printStackTrace(); } } });**/ //session.close(); //connection.close(); } }
package com.sunshine.mq; import javax.jms.Connection; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.Queue; import javax.jms.Session; import javax.jms.TextMessage; import javax.jms.TopicConnectionFactory; import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.command.ActiveMQBytesMessage; public class ConsumerTopicC { public static void main(String[] args) throws JMSException, InterruptedException { // 连接到ActiveMQ服务器 // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.17:1888,tcp://172.16.7.18:1889)"); // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.15:1887)"); // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.17:61616,tcp://172.16.7.18:61616)"); //ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin","failover:(tcp://172.16.7.17:1883,tcp://172.16.7.18:1883)"); ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin", "failover:(tcp://172.16.7.17:1888,tcp://172.16.7.18:1889)"); Connection connection = factory.createConnection(); connection.start(); Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // 创建主题 Queue topicA = session.createQueue("Consumer.GG.VirtualTopic.*"); // 消费者A组创建订阅 MessageConsumer consumerA1 = session.createConsumer(topicA); Integer count = 0; while(true){ ActiveMQBytesMessage message = (ActiveMQBytesMessage) consumerA1.receive(); count++; // TextMessage msg = (TextMessage)message; // String messageText = msg.getText(); System.out.println(new String(message.getMessage().getContent().getData()) +",消费消息总数为:"+count); } /**consumerA1.setMessageListener(new MessageListener() { // 订阅接收方法 public void onMessage(Message message) { TextMessage tm = (TextMessage) message; try { System.out.println("A 收到消息: " + tm.getText()+":"+tm.getStringProperty("property")); } catch (JMSException e) { e.printStackTrace(); } } });**/ //session.close(); //connection.close(); } }
此时客户端只支持单个broker地址,可以通过一些策略分配给客户端相对比较空闲的broker