# # # Message Middleware
Message middleware: Focus on data transmission and acceptance, using efficient and reliable asynchronous message delivery mechanism to integrate distributed system
Jms:java Messaging Service, API for message oriented middleware in the Java platform
AMQP: Application-tier standard protocol for Unified Messaging Services
Common Message Middleware
ActiveMQ
RabbitMQ
Kafka
JMS specification
Provider: A messaging middleware server that implements the JMS specification
Client: An application that sends or accepts messages
Producer/Publisher: The client who created and sent the message
Consumer/Subscriber: The client that receives and processes the message
Message: Data content passed between applications
Message patterns: The way messages are passed between clients, topic and queue patterns are defined in JMS
JMS message pattern
Queue model:
 
 
  
  - Clients include producers and consumers
- Messages can only be consumed by one consumer
- Ready to spend
Topic Model:
 
 
  
  - Clients include publishers and Subscribers
- Messages can be consumed by all subscribers
- Messages sent to a topic before consumers can consume subscriptions
JMS encoded Interface:
 
 
  
  - ConnectionFactory: Used to create a connection factory connected to the message middleware
- Connection: Represents the communication link between the application and the messaging server
- Destination: Where messages are published and received, including queues and topics
- Session: Represents a single thread context for sending and receiving messages
- Messageconsumer: Created by the session to receive messages sent to the destination
- MessageProducer: Created by the session for sending messages to the destination
- Message: An object that is transmitted between a consumer and a producer, including a message header, a set of message properties, a message body
Using ACTIVEMQ
Queue model
Producer
        //1. 创建ConnectionFactory        ConnectionFactory factory = new ActiveMQConnectionFactory(url);        //2. 创建Connection        Connection connection = factory.createConnection();        //3. 启动Connection        connection.start();        //4. 创建Session        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);        //5. 创建Destination        Destination destination = session.createQueue(queueName);        //6. 创建MessageProducer        MessageProducer producer = session.createProducer(destination);        for (int i = 0; i < 100; i++) {            //7. 创建消息            TextMessage message = session.createTextMessage("test" + i);            //8. 发布消息            producer.send(message);            System.out.println("发送消息: " + message.getText());        }        //9. 关闭连接        connection.close();
Consumer
        1.        Create ConnectionFactory ConnectionFactory factory = new activemqconnectionfactory (URL); 2.        Create Connection Connection Connection = Factory.createconnection (); 3.        Start Connection Connection.start (); 4.        Create session Session session = Connection.createsession (false, Session.auto_acknowledge); 5.        Create Destination Destination Destination = Session.createqueue (queuename); 6.        Create Messageconsumer Messageconsumer consumer = session.createconsumer (destination); 7. Create Message Listener Consumer.setmessagelistener (new MessageListener () {@Override public void OnMessage (M                Essage message) {TextMessage TextMessage = (textmessage) message;                try {System.out.println ("Receive message:" + textmessage.gettext ());                } catch (JMSException e) {e.printstacktrace ();        }            }        }); 9. Close connection (message listener asynchronous execution, required programAll running ends to close the connection)//Connection.close (); 
Topic model
Producer
        //1. 创建ConnectionFactory        ConnectionFactory factory = new ActiveMQConnectionFactory(url);        //2. 创建Connection        Connection connection = factory.createConnection();        //3. 启动Connection        connection.start();        //4. 创建Session        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);        //5. 创建Destination        Destination destination = session.createTopic(topicName);        //6. 创建MessageProducer        MessageProducer producer = session.createProducer(destination);        for (int i = 0; i < 100; i++) {            //7. 创建消息            TextMessage message = session.createTextMessage("test" + i);            //8. 发布消息            producer.send(message);            System.out.println("发送消息: " + message.getText());        }                //9. 关闭连接        connection.close();
Consumer
        1.        Create ConnectionFactory ConnectionFactory factory = new activemqconnectionfactory (URL); 2.        Create Connection Connection Connection = Factory.createconnection (); 3.        Start Connection Connection.start (); 4.        Create session Session session = Connection.createsession (false, Session.auto_acknowledge); 5.        Create Destination Destination Destination = Session.createtopic (topicname); 6.        Create Messageconsumer Messageconsumer consumer = session.createconsumer (destination); 7. Create Message Listener Consumer.setmessagelistener (new MessageListener () {@Override public void OnMessage (M                Essage message) {TextMessage TextMessage = (textmessage) message;                try {System.out.println ("Receive message:" + textmessage.gettext ());                } catch (JMSException e) {e.printstacktrace ();        }            }        }); 9. Close connection (message listener asynchronous execution, required programAll running ends to close the connection)//Connection.close (); 
Spring JMS
 
 
  
  - ConnectionFactory Connection factory for managing connections
- Provided by spring
- Singleconnectionfactory and Cachingconnectionfactory
- Jmstemplate template class for sending and receiving messages
- Provided by spring and registered in a container can be used
- Thread Safety
- MessageListener Message Listener
- Implement a OnMessage method that receives only one message parameter
Spring Using the JMS sample
Common.xml
<?xml version= "1.0" encoding= "UTF-8"? ><beans xmlns= "Http://www.springframework.org/schema/beans" xmlns: Xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:context= "Http://www.springframework.org/schema/context" xs i:schemalocation= "Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/ Spring-beans.xsd Http://www.springframework.org/schema/context http://www.springframework.org/schema/context/ Spring-context.xsd "> <context:annotation-config/> <!--activemq provide us with connectionfactory--<be An id= "targetconnectionfactory" class= "org.apache.activemq.ActiveMQConnectionFactory" > <property name= "broke Rurl "value=" tcp://127.0.0.1:61616 "/> </bean> <!--Spring JMS provides us with a connection pool--<bean id=" connection Factory "class=" org.springframework.jms.connection.SingleConnectionFactory "> <property name=" Targetconnectionfactory "ref=" Targetconnectionfactory "/> </BEAN>        <!--a queue destination, point-to-point <bean id= "queuedestination" class= "Org.apache.activemq.command.ActiveMQQueue" > <constructor-arg value= "queue"/> </bean> <!--a theme destination, publish a subscription message--<bean id= "Topicdestinatio N "class=" Org.apache.activemq.command.ActiveMQTopic "> <constructor-arg value=" topic "/> </bean>< ;/beans>
Producer.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">    <import resource="common.xml" />    <!-- 配置JmsTemplate,用于发送消息-->    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">        <property name="connectionFactory" ref="connectionFactory" />    </bean>    <bean class="com.qyluo.jms.spring.producer.ProducerServiceImpl" /></beans>
Cosumer.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">    <!-- 导入公共配置 -->    <import resource="common.xml" />    <!-- 配置消息监听器 -->    <bean id="consumerMessageListener" class="com.qyluo.jms.spring.consumer.ConsumerMessageListener" />    <!-- 配置消息监听容器 -->    <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">        <property name="connectionFactory" ref="connectionFactory" />        <property name="destination" ref="topicDestination"/>        <property name="messageListener" ref="consumerMessageListener"/>    </bean></beans>
Producerserviceimpl
public class ProducerServiceImpl implements ProducerService {    @Autowired    JmsTemplate jmsTemplate;    @Resource(name = "topicDestination")    Destination destination;    @Override    public void sendMessage(final String message) {        //使用JmsTemplate发送消息        jmsTemplate.send(destination, new MessageCreator() {            //创建一个消息            @Override            public Message createMessage(Session session) throws JMSException {                TextMessage textMessage = session.createTextMessage(message);                return textMessage;            }        });        System.out.println("发送消息: " + message);    }}
Appproducer
public class AppProducer {    public static void main(String[] args) {        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("producer.xml");        ProducerService service = context.getBean(ProducerService.class);        for (int i = 0; i < 100; i++) {            service.sendMessage("text" + i);        }        context.close();    }}
Consumermessagelistener
public class ConsumerMessageListener implements MessageListener { @Override public void onMessage(Message message) { TextMessage textMessage = (TextMessage) message; try { System.out.println("接收消息: " + textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } } }
Appconsumer
public class AppConsumer {    public static void main(String[] args) {        ApplicationContext context = new ClassPathXmlApplicationContext("consumer.xml");    }}
ACTIVEMQ Cluster
Cluster mode
 
 
  
  - Client cluster: Multiple consumers consume the same queue
- Broker clusters: Synchronizing messages between multiple brokers
- Master Slave: Achieving High Availability
ACTIVEMQ failure Transfer (failover)
Allows clients to reconnect to other messaging servers on the transport layer when one of the messaging servers is down
Syntax: failover: (Uri1,..., urin)? transportoptions
Transportoptions parameter Description
 
 
  
  - Randomize default is true to indicate whether random policies are used when URI connections are selected in the URI list
- Initialreconnectdelay default is 10, in milliseconds, indicating the time to wait between the first attempt to reconnect
- Maxreconnectdelay default is 30000, unit milliseconds, maximum time interval for re-connection
Broker Cluster cluster configuration
Networkconnector (Network Connector): network communication between ACTIVEMQ servers
Divided into static connectors and dynamic connectors
Static connectors:
<networkConnectors>    <networkConnector uri="static:(tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)"/></networkConnectors>
Dynamic connectors:
<networkConnectors>    <networkConnector uri="multicast://default"/></networkConnectors><transportConnectors>    <transportConnector uri="tcp://localhost:0" discoverUri="multicast://default"/></transportConnectors>
Master/slave cluster configuration
ActiveMQ Master Slave Cluster scenario
 
 
  
  - Share Nothing storage master/slave (obsolete, 5.8+ removed)
- GKFX Storage Master/slave Shared storage
- Replicated LevelDB Store copy-based LevelDB store
Comparison of two cluster modes
Way | High Availability | Load Balancer |
--|----------|--------------|
Master/slave | is | No |
Broker Cluster | No | is |
Perfect cluster solution for three servers
Node A and Node B do message synchronization, Node A and node C do message synchronization, Node B and node C do master/slave to persist resources
 
 
  
   
   | Server | Service Port | Management Ports | Storage | Network connector | Use | 
 
  
  
   
   | Node-a | 61616 | 8161 | - | Node-b, Node-c | Consumers | 
 
   
   | Node-b | 61617 | 8162 | /share_file/kahadb | Node-a | Producers, consumers | 
 
   
   | Node-c | 61618 | 8163 | /share_file/kahadb | Node-a | Producers, consumers | 
 
  
Best Practices in enterprise systems
Actual Business Scenario Features
 
 
  
  - Sub-business systems have the possibility of clustering
- The same message is broadcast to all child business systems that are interested in this type of message
- The same type of message is consumed in the cluster by the load
- The occurrence of business and the final consistency of message release
Virtual Theme Solutions using ACTIVEMQ
 
 
  
  - Publisher: publishes a message to a topic with the topic name beginning with virtualtopic, such as Virtualtopic.test
- Consumer: Gets a message from the queue, indicating its identity in the queue name, such as Consumer.a.virtualtopic.test
Using XA series interfaces in JMS to ensure strong consistency
 
 
  
  - Introducing Distributed Transactions
- Require business operations to support XA protocol
Local transaction solution using the message table
Solutions for using memory logs
Event bus based on message mechanism
Event-Driven architecture
RabbitMQ
RabbitMQ: Using a switch to bind to a queue
 
 
  
  - Create ConnectionFactory
- Create connection
- Create Channel
- Define Exchange, type I must be fanout
- Define queue and bind queues
Kafka
Kafka using Group.id to group consumers
 
 
  
  - Configure the message person parameter group.id to load the message at the same time
- Configure the server partitions parameter to control the number of consumer under the same group.id less than partitions
- Kafka only guarantees that the message under the same group.id is ordered.
Learning Notes--java Message Middleware