@TOC

The basic concepts of MQ

1. Summary of MQ

MQ, short for Message Queue, is a container that holds messages during their transmission. It is used for communication between distributed systems. Common service communications:After joining MQ:

Second, the advantages of MQ

1. Apply decoupling

Services are no longer connected by protocol, but decoupled (more extensible) by using the producer/consumer mode to allow the middleware MQ to connect to the data communication on both sides. Common service communications:After joining MQ:

2. Speed up asynchronously

Common service communication: the need to block successfully to obtain the response status before writing data to the database, blocking synchronization is performed down.After joining MQ:

3. Cut peaks and fill valleys

Common service communication: when 5000 requests are sent to the server at a moment, the server can handle the maximum 1000 requests and dies instantly.

After joining MQ: Put the request into the queue waiting to be processed, the system from mq pull 1000 requests per second for processing (just can be processed by the card in 1000, the real press cases), thus become the handle 5000 requests from 1 second peak, split into five seconds, handle 1000 requests per second gentle treatment period, oh no, is loaded with processing period.

As you can see from the graph below, the peak has indeed been clipped

3. Disadvantages of MQ

The system availability decreases

The more external dependencies a system introduces, the worse its stability will be. Once MQ is down, services are affected. How can MQ be highly available?

System complexity enhancement

The addition of MQ has greatly increased the complexity of systems where synchronous remote calls between systems are now asynchronous calls through MQ. How to ensure that the message is not lost and so on.

Common MQ products

MQ is an abstract concept that has spawned various implementations based on its ideas, such as the common ones: RabbitMQ, RocketMQ, Kafka.

5. RabbitMQ introduction

It is suggested to directly read the summary, the following knowledge can be slowly tasted (the following quotes Guide brother)

1. The introduction of the RabbitMQ

RabbitMQ is a messaging middleware that uses Erlang to implement AMQP(Advanced Message Queuing Protocol). It originated in financial systems and is used to store and forward messages in distributed systems.

RabbitMQ has grown in popularity due to its excellence in ease of use, scalability, reliability and high availability. The specific features of RabbitMQ can be summarized as follows:

  • Reliability: RabbitMQ uses mechanisms to ensure the reliability of messages such as persistence, transport confirmation, and release confirmation.
  • Flexible routing: Messages are routed through the exchange before they are queued. For typical routing, RabbitMQ already provides some built-in switches. For more complex routing functions, multiple switches can be bound together, or you can implement your own switch through a plug-in mechanism. This will be covered later when we cover the core concepts of RabbitMQ.
  • Scalability: Multiple RabbitMQ nodes can form a cluster or dynamically expand the cluster based on service requirements.
  • High availability: Queues can be mirrored on machines in a cluster, making them available even if some nodes fail.
  • Supports multiple protocols: RabbitMQ supports multiple messaging middleware protocols, such as STOMP and MQTT, in addition to AMQP.
  • Multi-language clients: RabbitMQ supports almost all common languages, such as Java, Python, Ruby, PHP, C#, JavaScript, etc.
  • Easy-to-use management interface: RabbitMQ provides an easy-to-use user interface that allows users to monitor and manage messages, nodes in a cluster, etc. Install RabbitMQ and the admin interface will come with RabbitMQ.
  • Plugin mechanisms: RabbitMQ provides many plug-ins to extend in many ways, but you can also write your own. This feels a bit like Dubbo’s SPI mechanism.

RabbitMQ is essentially a producer and consumer model, responsible for receiving, storing, and forwarding messages. Think of it as sending a package to the post office, which stores it and eventually sends it to the postman. RabbitMQ is like a system of post office, mailbox and postman. In computer terms, the RabbitMQ model is more like a switch model.

Take a look at the picture – the overall model architecture of RabbitMQ.

1.1 Producers and consumers

  • Producer: the party that produces messages
  • Consumer: the party that consumes the message (the person to whom the message is sent)

A message typically consists of two parts: a header (or Label) and a body. The body of the message, also called payLoad, is opaque, and the header is made up of a set of optional attributes. These attributes include routing-key, priority (priority over other messages), delivery-mode (indicating that the message may require persistent storage), and so on. After the producer sends the message to RabbitMQ, RabbitMQ sends the message to the interested Consumer based on the message header.

1.2 Exchange

In RabbitMQ, messages are not sent directly to a Queue, they have to pass through the Exchange layer, which allocates our messages to the corresponding Queue.

Exchanges are used to receive messages sent by producers and route them to queues on the server. If they are not routed, they may be returned to the Producer or discarded. Here you can think of the switch in RabbitMQ as a simple entity.

RabbitMQ has four types of exchanges, each of which has a different routing policy: Direct (default), Fanout, Topic, and headers. This will be covered when we introduce Exchange Types.

An Exchange is shown as follows:When a producer sends a message to a switch, it typically specifies oneRoutingKey, which specifies the routing rule for this message, and thisA RoutingKey needs to be used in conjunction with the exchange type and BindingKey to be effective.

RabbitMQ uses Binding to associate exchanges with queues, A BindingKey is usually specified during binding so RabbitMQ knows how to route messages to queues correctly, as shown below. A binding is a routing rule that connects a switch to a message queue based on a routing key, so a switch can be thought of as a routing table made up of bindings. Exchange and Queue bindings can be many-to-many.

Binding schematic diagram:When a producer sends a message to the exchange, a RoutingKey is required, and when the BindingKey matches the RoutingKey, the message is routed to the corresponding queue. When binding multiple queues to the same exchange, these bindings allow the same BindingKey to be used. BindingKey does not work in all cases. It depends on the type of switch, such as fanout, and instead routes messages to all queues bound to that switch.

1.3 Queue

A Queue is used to hold messages until they are sent to consumers. It is the container and destination of the message. A message can be put into one or more queues. The message remains in the queue, waiting for the consumer to connect to the queue to pick it up.

RabbitMQ messages can only be stored in queues, as opposed to messaging middleware such as Kafka. Kafka stores messages at the logical level of the topic (topic), and the corresponding queue logic is just a displacement identifier in the actual storage file of the topic. The RabbitMQ producer produces the message and ultimately delivers it to the queue, from which the consumer can retrieve and consume the message.

Multiple consumers can subscribe to the same queue, and messages in the queue are round-robin for processing among multiple consumers, rather than each consumer receiving all messages and processing them, thus avoiding repeated consumption of messages.

RabbitMQ does not support queue-level broadcast consumption, so secondary development on top of broadcast consumption is cumbersome and not recommended.

1.4 Broker (Service node of message-oriented middleware)

For RabbitMQ, a RabbitMQ Broker can simply be regarded as a RabbitMQ service node, or RabbitMQ service instance. In most cases a RabbitMQ Broker can also be thought of as a RabbitMQ server.

The following figure shows the process by which a producer stores a message into a RabbitMQ Broker and a consumer consumes data from the Broker.This completes some of the basic RabbitMQ concepts shown in Figure 1, but let’s move onExchange Types

1.5 Exchange Types

The main Exchange types for RabbitMQ are FANout, Direct, Topic, and headers. The AMQP specification also mentions system and custom Exchange types.

(1) the fanout

The Exchange routing rule of the FANout type is very simple. It routes all messages sent to the Exchange to all queues bound to it without any judgment, so the Fanout type is the fastest of all switch types. The fanout type is often used to broadcast messages.

(2) direct

Exchange routing rules of type Direct are also simple, routing messages to queues where bindingKeys match routingkeys exactly.For example, if the routing key is set to “Warning” when sending a message, the message will be routed to Queue1 and Queue2. If the routing key is set to “Info “or” DEBUG “when sending messages, messages will only be routed to Queue2. If messages are sent using other routing keys, they are not routed to either queue. The direct type is commonly used to process tasks with a higher priority. The message is sent to the corresponding queue according to the priority of the task. In this way, more resources can be assigned to the queue with a higher priority.

(3) the topic

As mentioned above, the routing rules of the direct type switch match BindingKey and RoutingKey exactly. However, such strict matching method cannot meet the requirements of actual business in many cases. Topic exchanges extend the matching rules. Similar to direct exchanges, they route messages to queues that match BindingKey and RoutingKey, but the matching rules are a little different:

  • The RoutingKey is a dot “. Delimited string (dot ‘. Each separate string is called a word), such as “com.rabbitmq.client”, “java.util.concurrent”, “com.hidden. Client”;
  • BindingKey is also a dot like RoutingKey. Delimited strings;
  • There can be two special strings “*” and “#” in BindingKey for fuzzy matching, where “*” is used to match one word and “#” is used to match multiple words (possibly zero).

The above picture shows an example:

  • The messages whose routing key is com.rabbitmq.client are routed to both Queuel and Queue2.
  • Messages with a routing key of “com.hidden.client” are routed to Queue2 only.
  • The messages whose routing key is com.hidden.demo will only be routed to Queue2.
  • The messages whose routing key is java.rabbitmq.demo are routed to Queuel only.
  • Messages with a routing key of “java.util.concurrent” will be discarded or returned to the producer (the mandatory parameter is required) because it does not match any routing key.
④ Headers (not recommended)

A HEADERS exchange does not rely on the matching rules of the routing key to route a message, but matches it based on the HEADERS attribute in the content of the sent message. When sending a message to the exchange, RabbitMQ will fetch the headers of the message and compare the matching keys to the queue and the exchange binding. If they match, the message will be routed to the queue. Otherwise, the queue will not be routed to. Headers switches tend to be poor in performance and impractical, and you’ll almost never see them.

2. To summarize

To put it more broadly, the RabbitMQ architecture is client, switch and queue. These three roles make up the various modes used by RabbitMQ with different modes of switch (direct, sector, principal and header) and different configurations: Simple mode (), work queue mode, publish/subscribe mode, routing mode, wildcard mode, its most core is queue, provider and corresponding queuing, consumption corresponding queuing.

3. Install RabbitMQ in the Windows local environment

3.1 download the Erlang

RabbitMQ is based on the Erlang environment, download Erlang (24), erlang.org/download/ot…

3.2 Installing RabbitMQ (3.9.5)

Github.com/rabbitmq/ra…

3.3 start

I don’t think I need to tell you what to press for this

Successful startup, as follows

3.4 Installing management Plug-ins

Right-click the shortcut to open the folder directoryRun rabbitmq-plugins enable rabbitmq_management

5. Access the background

Background management website:http://localhost:15672/The default initial account after installation: guest password: guset

Learn about RabbitMQ from a simple example

Example 1.

Rely on:

		 <dependency>
	        <groupId>org.springframework.boot</groupId>
			 <artifactId>spring-boot-starter-amqp</artifactId>
	        <version>2.41.</version>
	    </dependency>
Copy the code

Producers:

package boot.spring.test;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/ * * *@description:
 * @author: lx *@date: 2021/09/04 3:12 p.m. *@Copyright: lx * /
public class Provider {

	/** * The declared queue name */
	private final static String QUEUE_NAME = "test_queue";

	public static void main(String[] args) throws IOException, TimeoutException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		connectionFactory.setHost("127.0.0.1");
		// The default port number
		connectionFactory.setPort(5672);
		connectionFactory.setUsername("guest");
		connectionFactory.setPassword("guest");
		connectionFactory.setVirtualHost("/");

		// Obtain the TCP long connection
		Connection conn = connectionFactory.newConnection();

		// Create a communication "channel", equivalent to a virtual connection in TCP
		Channel channel = conn.createChannel();
		// Start a RabbitMQ transaction, throw an exception and roll back if no MQ feedback is received
		channel.txSelect();

		// Create a queue, declare and create a queue, if the queue already exists, use this queue
		// First argument: queue name
		// The second parameter: persistent or not, false for non-persistent data, data will be lost when MQ stops
		False means that all consumers can access the queue. True means that consumers who own it only once can use it forever. Other consumers are not allowed to access the queue
		False indicates that the queue is not automatically deleted after the connection is down
		// Other extra arguments: null
		channel.queueDeclare(QUEUE_NAME, true.false.false.null);
		String message = "hello world!";

		try {
			// The first parameter: switch, this is the simple demo version, no switch
			// Second argument: queue name
			// Third argument: additional setting properties
			// The fourth argument: an array of message bytes to pass
			channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
		} catch (Exception e) {
			// An abnormal rollback occurred
			channel.txRollback();
		}

		// The normal process commits the transaction
		channel.txCommit();
		channel.close();
		conn.close();
		System.out.println("Sent successfully!"); }}Copy the code

Consumer:

package boot.spring.test;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/ * * *@description:
 * @author: lx *@date: 2021/09/04 下午 3:33
 * @Copyright: lx * /
public class Consumer {

	private final static String QUEUE_NAME = "test_queue";

	public static void main(String[] args) throws IOException, TimeoutException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		connectionFactory.setHost("127.0.0.1");
		connectionFactory.setPort(5672);
		connectionFactory.setUsername("guest");
		connectionFactory.setPassword("guest");
		connectionFactory.setVirtualHost("/");

		// Obtain the TCP long connection
		Connection conn = connectionFactory.newConnection();

		// Create a communication "channel", equivalent to a virtual connection in TCP
		Channel channel = conn.createChannel();

		// Create a queue, declare and create a queue, if the queue already exists, use this queue
		// First argument: queue name
		// The second parameter: persistent or not, false for non-persistent data, data will be lost when MQ stops
		False means that all consumers can access the queue. True means that consumers who own it only once can use it forever. Other consumers are not allowed to access the queue
		False indicates that the queue is not automatically deleted after the connection is down
		// Other extra arguments: null
		channel.queueDeclare(QUEUE_NAME, true.false.false.null);

		// Create a message consumer
		// First argument: queue name
		// Second argument: The second argument indicates whether the message is automatically acknowledged. False indicates that the message is manually programmed
		// Third argument: pass in the implementation class of DefaultConsumer
		channel.basicConsume(QUEUE_NAME, false.newReceiver(channel)); }}/ * * *@description:
 * @author: lx *@date: 2021/09/04 下午 3:37
 * @Copyright: lx * /
class Receiver extends DefaultConsumer {

	private Channel channel;

	/** * overrides the constructor, the channel object needs to be passed in from the outer layer, which is used in handleDelivery@param channel
	 */
	public Receiver(Channel channel) {
		super(channel);
		this.channel = channel;
	}

	@Override
	public void handleDelivery(String consumerTag,
	                           Envelope envelope,
	                           AMQP.BasicProperties properties,
	                           byte[] body)
			throws IOException {
		String message = new String(body);
		System.out.println("Messages received by consumers:" + message);
		System.out.println("Message TagID:" + envelope.getDeliveryTag());
// int i = 1 / 0;
		// False indicates that only current messages are signed. If set to true, all unsigned messages for the consumer are signed
		channel.basicAck(envelope.getDeliveryTag(), false); }}Copy the code

2. Repeat spending

Start the producer, go to the admin page, and you can see that the message has been queued and is ready to be consumed.After the Debug consumer is started, you can view on the management page that the message status changes from ready to respond. The total number still exists. In this case, the message is received but not responded.The breakpoint causes MQ to time out without receiving a response, the state rolls back to ready, and the message is still in the queue, but in fact the consumer has already consumed it once, which leads to a problem – repeated consumption.There are many other scenarios where you can have an exception rollback, such as an application sending exception, which, by the way, can cause the consumer application to crash, and MQ can block the consumer process while waiting for a responseA proxy is used to capture and forward, simulating packet loss

The solution

Since repeated consumption is unavoidable, how do we deal with it? The business logic for processing messages on the consumer side remains idempotent. Idempotence, in plain English, is just one piece of data, or one request, given to you over and over again, and you have to make sure that the corresponding data doesn’t change, you can’t go wrong.

1. You get the message and do the database insert. That would be easy. Give the message a unique primary key, so that even if repeated consumption occurs, primary key collisions will occur, avoiding dirty data in the database. 2. If you get this message and do the redis set operation, then it is easy to solve, because you will get the same result no matter how many times you set the set operation, which is supposed to be idempotent. 3. Prepare a third-party medium to keep track of your spending. In the case of Redis, a message is assigned a global ID, and as long as the message has been consumed, < ID,message> is written to Redis in k-V form. Before the consumer begins to consume, go to Redis to check whether there is any consumption record.

3. Message loss

The message is lost during network transmission. MQ is down and the message is lost

4. Message backlog

A program exception can cause the consumer program to crash, and MQ can remain blocked waiting for a response, causing messages to pile up

5. High availability of MQ

Blog.csdn.net/yygEwing/ar…

Six, source code analysis

Learn more about RabbitMQ from a simple source code analysis

RabbitMQ Server is a Message Broker Virtual Host designed for multi-tenancy and security purposes to divide the basic components of an AMQP into Virtual groups, similar to the namespace concept of a network. RabbitMQserver can be partitioned into multiple vhosts when different users use the same RabbitMQserver service, and each user can create an exchange/queue Connection on their own Vhost: Publisher/Consumer/broker TCP Channel: How to establish a Connection every time you access RabbitMQ. Establishing a TCP Connection on a high volume of messages can be expensive and inefficient. A channel is a logical connection established within a connection. If the application supports multiple threads, it is common for each thread to create a separate channel for communication. AMQPmethod contains a channelId to help the client and Message Broker identify a channel. So channels are completely isolated from each other. As a lightweight Connection, Channel greatly reduces the overhead of establishing TCP Connection in the operating system.

1. Review design patterns

1.1 Factory method pattern

The common behavior of multiple code sections is abstracted into interfaces to define, and the concrete implementation is defined after the subclass implements the parent class. Finally, a factory class is used to select and return the corresponding instantiated object based on the passed parameter. Keyword: Factory class generally with Factory

1.2 Abstract factory pattern

Abstract factory is an abstract class of other factory classes, that is, AbstractXXX abstract factory class is extracted from the common behavior of other factory classes. In abstract factory mode, another implementation of abstract factory is used, including agents, adapters and abstract factories. The two cache-mode implementations of CacheService are added with adapters that correspond to the methods of the CacheService interface, and then dynamic proxies are used, where the method calls are encoded to the invoke method of the invocation handler when the proxy instance calls the method. You can think of the adapter classes for different caching patterns as building classes for factories that have common getters and setters. These common behaviors are abstracted into CacheService, where methods called in service actually call methods in the adapter class through dynamic proxies.

        CacheService proxy_EGM = JDKProxy.getProxy(CacheServiceImpl.class, new EGMCacheAdapter());
        proxy_EGM.set("user_name_01".Little Fuge.);
        String val01 = proxy_EGM.get("user_name_01");
        System.out.println("Test Results:" + val01);
        
	    CacheService proxy_IIR = JDKProxy.getProxy(CacheServiceImpl.class, new IIRCacheAdapter());
        proxy_IIR.set("user_name_01".Little Fuge.);
        String val02 = proxy_IIR.get("user_name_01");
        System.out.println("Test Results:" + val02);
Copy the code

1.3 Builder mode

In daily life, decorating house would be based on different scenarios, brand, model, price and so on combination formed A variety of decorate A style, set A: contemporary and contracted, plan B: light luxury pastoral, package C: european-style luxury) will not change some basic material, and the combination of often change over time, you can choose the builder pattern to build the code. Builder

1.4 Prototype Mode

In the exam, each examinee gets roughly the same exam paper topic, are from the same exam question pool random combination of a set of questions out and distributed to all examinees for the exam, but the questions, the same topic order, easy to cause cheating, and still constantly create initialization unified object. Use prototype patterns: Create complex objects by cloning, avoid repeated initialization operations, and do not need to be coupled to other classes that belong to the class. However, there are some disadvantages that can make this pattern extremely cumbersome if the objects include clones of circular references, as well as clones of deeply used objects in the class. Cloneable is implemented (out of order in overridden clone methods)

1.5 Singleton Mode

Get the same instance each time you get or create. For example: Spring’s @autowird automatic injection of objects is also a representation of the singleton pattern. The underlying singleton pattern is determined by the Bean injection pattern. The singleton pattern is to put the instance created by new into the container, and get the instance object every time. NewInstance proposes to use the enumerated singleton pattern to solve the most important problem; Thread-safe, free serialization, single instance. enum

1.6 Adapter Mode

Create an adapter interface for classes that have common behavior but call different methods. The implementation class of the adapter actually calls the corresponding methods of the original object. The interface has been uniformly wrapped so that external use does not need to care about the internal logic. And in the call only need to pass unified parameters, so that meet the role of adaptation. Adapter

1.7 Bridge Mode

The main role of the bridge pattern is to combine multiple matching uses by separating the abstract from the implementation. To put it bluntly, the core implementation is A class A with A class B interface, passing the implementation of class B through constructors, and that class B is the bridge of the design. Through the simulation of wechat and Alipay in different payment modes, the combination of face brush, fingerprint and password reflects the reasonable application of bridge mode in such scenarios. ZfbPay = new zfbPay (new PayFingerprintMode()); Bridge/ passes in other objects at initialization as a judgment of the class’s execution method

1.8 Combination mode (no fine products)

The main solution of the composite pattern is a series of simple logical nodes or extended complex logical nodes under different structure organization, for external calls can still be very simple.

1.9 Decorative mode (no fine items)

new BufferedReader(new FileReader(“”)); , this code you are familiar with, I believe that learning Java development to byte stream, character stream, file stream content have seen such code, a layer nested a layer, a layer nested a layer, byte flow character stream and so on, and the use of this way is a manifestation of the decorator mode.

1.10 Appearance mode (no fine products)

The facade pattern, also known as the facade pattern, is designed to reduce the complexity of the logical combination of interfaces used by callers. This provides an intermediate layer between the caller and the actual interface provider, which provides the API interface for the wrapping logic. Sometimes the facade pattern is also used in the middleware layer to wrap the generic complex logic in the service so that the consumer can only care about business development.

1.11 Free Yuan mode

The share mode is used to share common objects, reducing memory usage and improving system access efficiency. These shared objects usually consume memory or need to query a large number of interfaces or use database resources, so they are all removed and used as shared objects. Through a variety of ways to reuse the data cache the entire object, reduce memory footprint and the number of queries Seconds kill under the scenario of the activity, activity information is not the same, only the goods inventory in the event of a transformation, every time information from a database access to the activities of the object in addition to the inventory information is consistent with the other, this time can use the flyweight pattern, The repeated parts are cached for repeated use. Here, the element factory is used, the active information is cached from the database with map during initialization, and the inventory information is later fetched from redis and spliced into the active information.

1.12 Agent Mode (no details)

The agency model is a bit like the boss and the little brother, and a bit like the distributor. The main solution is to provide convenient proxy services for access to some resources and easy operation of object classes. This pattern of design thinking is often found in our systems, or in the components you use, which give you a very simple and easy way to control the service classes that you would otherwise have to write a lot of code to use. Basically: a series of encapsulation designs after the implementation of the proxy. We adopt the development of a part of the core functions of Mybatis – Spring middleware to reflect the power of the proxy mode, so it involves some knowledge points about the creation of proxy classes and the registration of beans in Spring, which may be rarely used in ordinary business development. But it is a very common operation in middleware development. In addition to developing middleware, proxy mode can also be the packaging of services, Internet of Things components and so on, making complex services into lightweight invocation and cache use. You can understand it as the light switch in your home. We cannot operate the human flesh connection of 220V wire, but we can use the switch to avoid electric shock. The design of proxy mode can make the code more clean, clean and easy to maintain. Although many additional classes are added in this part of the development, including the registration of their own processing beans, etc., such middleware is highly reusable and more intelligent, which can be easily extended to various service applications.

1.13 chain of responsibility

I am familiar with this, more commonly used and relatively simple one, the core of the responsibility chain model is to solve a group of services in the execution of the processing relationship, a bit like you have no money to spend, the need for family financial expenditure approval, less than 10 yuan to find daughter approval, 100 yuan first daughter approval in daughter-in-law approval. You can imagine that when you want to change jobs you are arranged to be signed off on by the various leaders.

Chain of Responsibility model1.The core idea is chain execution, and the execution of each node depends on the execution result of the node at the next level.2.Abstract parent class: Action Property: Action Action is used to store the object pointing to the next node reference abstract method: start() The implementation of the subclass to define the current node specific logic implementation method: Action () node to execute the decision branch, success-enter the next nodedoReturn subclass: openDeviceAction (multiple subclass nodes, etc.) Override the start () method to implement the concrete logical assembly execution class: Call (encapsulate the sequence of execution actions, logic, and where needed) creates the required node, uses setNext to specify the next node (execution order), and calls the action () of the first node to start3.Key words linked list data structure, the essence of responsibility chain is a linked list data structure, through the Node points to the Next Node to ensure the execution order of the Node, (Next, Node)Copy the code

1.14 Command Mode

The core logic of the command scene is that the caller does not need to care about the implementation of specific logic. In this scene, the ordering personnel only need to hand over the various cuisines to the second cook, and then the second cook gives the dishes to each chef for cooking. That is, the ordering personnel do not need to communicate with various chefs, only need to give orders in a unified environment. In fact, my understanding is that this pattern is a kind of behavior encapsulation, the next time you want to use this part of the code directly call method, rather than writing a long series of code. The feature here is that the called party and the behavior are abstracted to the interface, in which the caller can use the polymorphic call to use the concrete implementation of the called party and the behavior method command mode use scenario needs to be divided into three relatively large blocks; Command, implementation, caller, and the separation of these three pieces of content is also a key factor in the selection of suitable scenarios, through such separation can make logic have the nature of a single responsibility, easy to expand.

1.15 Iterator mode (no details)

The iterator pattern is the iterator we use every day. Although this design pattern is rarely seen in our actual business development scenarios, it is traversed almost daily using the List collection provided by the JDK. The enhanced for loop is a loop that outputs data, but it is not an iterator pattern. Iterator mode is characterized by the implementation of the Iterable interface, through the way of next to get collection elements, and at the same time with the element deletion operations. Enhanced for loops are not. In addition, elements are not allowed to be deleted during iteration. The advantage of this design pattern is that it allows us to iterate over different data structure elements in the same way. Array, linked list, tree, etc., while users do not need to care about the traversal processing logic of each kind of data structure when using traversal, so that the use becomes unified and easy to use.

1.16 Intermediary Mode (no details)

The intermediary mode is to solve the repeated calls between complex functional applications, adding a layer of intermediary packaging services in this middle, to provide simple, universal and easily extensible service capabilities. Such a design pattern can be almost seen in our daily life and practical business development, for example; The plane 🛬 lands with a little sister Shouting at the tower, waiting for the train from any direction will get off and get off the platform, the company’s system has a center platform specifically for you to package all interfaces and provide unified services, and so on, all of which use the intermediary mode. In addition, some of the middleware you use encapsulates the underlying differentiation of multiple databases and provides a very simple way to use them. Personal understanding is to solve the problem of resource sequence scheduling in complex scenarios.

1.17 Memo Mode (no details)

The memo mode is a design mode with the core functions of recovery or rollback, configuration, version and resetting, and this design mode belongs to the behavior mode. On the basis of not destroying the original object, the memo operation class is added to realize the memo mode by recording the behavior of the original object. In my personal understanding, when an information is modified, the last message is recorded through the cache and storage table, and then rolled back to the required configuration information through the history record.

1.18 Observer mode

Simply speaking, the observer 🕵 mode means that when a behavior occurs, information is transmitted to another user for receiving and corresponding processing. There is no direct coupling between the two.

For example; Sniper, Li Yunlong. And many frameworks will have listeners, through annotations, when the listening mode is executed, it will also execute the corresponding listening method (listening database inventory changes, front-end statistics inventory changes, etc.). There is also the consumer pattern in MQ, again by listening for messages in queues and then consuming them, which is also the idea of the observer pattern, listening for actions, subscriptions

1.19 Status Mode

State model describes a behavior under various state changes, such as our one of the most common site of page, under the login and don’t you login show content is slightly different (not login cannot display personal information), and the login and login is by changing our state, and make the whole behavior has changed.At least some people born in the 1980s and 1990s have used a tape player. On the top of the tape player is a row of buttons. When you put the tape into the machine, you can use the buttons to tell the player to play the content on the tape. You can only press other buttons when you are in one state (this is also a key point in design mode). In different states, different pages are displayed and different data can be queried. If district-level units only look at the current area, city-level units can look at all areas and control them step by step according to the state, unit and the difference of a certain field.

1.20 Policy Mode

The policy pattern is also the most commonly used and simplest design pattern, and is often used to replace the choice scenario of multi-branch ifelse, if the business process has an indefinite future trend of scaling, otherwise it does not fit the usage scenario. For example, the current system needs to make a function to access the third-party payment, here we can use the strategy mode to create a specific implementation of branches of different payment methods, even if temporarily supported: Wechat, Alipay, wallet and other payment methods, but with the development of business volume and the surge of user groups, it is inevitable to expand to support unionPay payment and other scenarios. In this case, it is reasonable to use the strategic mode. Finally, the policy pattern is implemented by abstracting the behavior methods of multiple branches in an interface, the implementation of which is defined by subclasses. The policy pattern also requires a policy control class to invoke specific implementations using polymorphism based on incoming objects. Ifelse –> Policy interface, implementation class, policy control class (important: remember that the current business is extensible to choose to use, otherwise if just write dead two or three branches to use policy mode will increase memory consumption and management costs)

1.21 Template mode (no fineness)

The core design idea of the template pattern is to define the order of execution of abstract methods in an abstract class, and to make the abstract methods subclass only, but not to design independently accessible methods. Simply put, make your schedule very clear. The template pattern is very convenient in defining the uniform structure, namely the implementation standard, which is a good control of the subsequent implementers do not care about the call logic, according to the uniform way of execution. Then the inheritors of the class need only care about the concrete implementation of the business logic.

1.22 Visitor Mode (no details)

The core issue for visitors is to add volatile business access logic to a stable data structure, such as user information, employee information, and so on. A design pattern that decouples these two parts of the business to enhance scalability.

1.23 Interpreter mode

The Interpreter Pattern, which provides a way to evaluate the syntax or expressions of a language, is a behavioral Pattern. This pattern implements an expression interface that interprets a particular context. This pattern is used in SQL parsing, symbol processing engines, and so on. A bit like in a code generator, the {name} expression is replaced with a “three” interpretation of the actual queried data.

2. Understand the data interaction between RabbitMQ and the client

3. Look at the code with questions

3.1 How did the message get into the team?

3.2 How are messages consumed?

3.3 How does the Client Establish a Connection?

3.4 What is a channel?

3.5 How can RabbitMQ be Asynchronous?

3.6 How do RabbitMQ ensure that messages are not lost? Ack

3.7 Why do consumers automatically consume messages in the queue after startup?

3.8 Will consumers continue to consume after they stop running consumers after receiving consumption information?

4. Core ideas

What is the core idea of RabbitMQ? What are its characteristics? What design patterns are used? What impressed you most?

Idea to download the source code, read.

Vii. Reference:

The elder brother of the Guide: github.com/Snailclimb/… Little Fu Ge: bugstack.cn/itstack/its… B station Baidu welcome to reprint, please indicate the source.

Update log

  • 9-7
  • Fixed some typos
  • Added a supplement
  • Added the overall learning framework diagram and the second node (Design pattern) content

I’m Lin Xi, thank you so much for your support! Learn together and make progress together!