This article has been included github.com/lkxiaolou/l… Welcome to star.

agreement

An agreement is simply an agreement that the communication parties must follow.

We know the common network transmission protocols are TCP, UDP, HTTP and so on. Generally speaking, the client side and the server side also have corresponding protocols, such as Redis, mysql, Zookeeper, etc., which are their own private protocols. Similarly, the Dubbo protocol in today’s title is also a private protocol, and they are application layer protocols, based on TCP or UDP design.

Generally, application layer protocols are based on TCP and UDP, and TCP is usually used for reliable transmission, such as most basic components, such as Redis and mysql. Udp is used only in scenarios that tolerate loss and require high performance, such as metric reporting.

This section describes several application protocols based on TCP.

Redis protocol

The Redis protocol is simple enough to cover. Redis protocol is designed based on TCP, and all commands sent by client and server end with CRLF. His format is as follows

*< parameter number > CRLF $< parameter 1 byte number > CRLF < parameter 1 data > CRLF... $< number of bytes of parameter n > CRLF < data of parameter n > CRLFCopy the code

For example, the client sends the command set mykey myValue to the server

*3 CRLF
$3 CRLF
SET CRLF
$5 CRLF
mykey CRLF
$7 CRLF
myvalue CRLF
Copy the code

Is $3 * 3 \ r \ n \ r \ nSET \ r \ n $5 \ r \ $7 on nmykey \ r \ n \ r \ nmyvalue \ r \ n

More information about the Redis protocol can be found at this link:

http://redisdoc.com/topic/protocol.html

The HTTP protocol

HTTP is the most common protocol, and its request packet format consists of three parts:

  • Request line: includes method, URL, version, separated by Spaces, and ending with \r\n
  • Request header: multiple lines, each in key:value format, ending with \r\n
  • Request body: The request header is separated from the request body by a blank line. The length of the request body is specified in the request headercontent-lengthgiven

Redis and HTTP are handled differently. They’re all based on TCP, and TCP is a protocol that transmits data as a stream, which in plain English means it’s like a stream of water, sending bytes over and over again, and TCP guarantees no repetition, no packet loss. In order to get the desired data, the receiver must “judge the packet boundary” from the stream data. This is the sticky packet problem of TCP. There are three ways to solve it:

  1. Sends fixed-length messages
  2. Use special tags to distinguish between message intervals
  3. Send the size of the message along with the message

The redis protocol uses the second, and HTTP and the next Dubbo protocol use the third. Fixed-length messages are ideal and rarely encountered in practice.

Dubbo agreement

Because dubbo supports many protocols, the Dubbo protocol mentioned in this article specifically refers to the default dubbo framework protocol, which is dubbo’s proprietary protocol. Its format is as follows:

  • 0-15: magic number, check whether it is dubbo protocol
  • 16: Determine whether to request or return
  • 17: Determine whether return is expected
  • 18: Checks whether it is an event message, such as a heartbeat event
  • 19-23: Serialization flag
  • 24-31: Flag response status (similar to HTTP status)
  • 32-63: request id
  • 64-95: Content length (bytes)
  • 96 -? : Serialized content (newline delimited)

Where are the attachments commonly used in the Dubbo protocol?

The Attachments of Dubbo, commonly likened to HTTP headers, carry implicit parameter information (not encoded into the request object), such as pressure markers. From his type

private Map<String, String> attachments;
Copy the code

It is generally inferred that attachments exist after 96 bytes of the Dubbo protocol, because the map doesn’t fit in the first one. From dubbo’s implementation, one of dubbo’s requests is encapsulated as a DecodeableRpcInvocation object containing methodName, parameterTypes, arguments, attachments, etc., The object is serialized into 96 bytes of dubbo protocol content and sent.

When used, the consumer terminal:

RpcContext.getContext().setAttachment("hello", "from_consumer");
Copy the code

The provider side:

RpcContext.getContext().getAttachment("hello");
Copy the code

This shows that the design of Dubbo protocol is not as good as that of HTTP protocol. In order to get some implicit parameters or to know where the request is sent, the request body must be resolved. This is also a stumbling block for the development of Dubbo protocol in the direction of mesh.

Does the Dubbo protocol support bringing back attachments in the return value?

When a consumer sends a request to the provider, it can carry an implicit parameter in the header. Can it return with an implicit parameter from the provider back to the Consumer?

For example, the network time is derived by subtracting the provider’s own processing time back to the consumer, who calculates the response time of the request. The provider is best to send the time back implicitly in the attachments.

Dubbo’s protocol is that both requests and replies are in the same format, so theoretically the consumer can send implicit arguments to the provider, which must be able to send them back.

It is supported by dubbo’s return object DecodeableRpcResult, but it is not supported by version 2.7.x but supported by version 2.6.x (>=2.6.3) in actual tests. Provider Settings:

RpcContext.getServerContext().setAttachment("hello", "from_provider");
Copy the code

Consumer terminal access:

RpcContext.getServerContext().getAttachment("hello")
Copy the code

The relevant issue link on Github is as follows:

https://github.com/apache/dubbo/pull/1843

What is the difference between protocol and serialization?

Dubbo supports rest, Thrift, GRPC, hessian and JSON serialization in addition to dubbo. What is the relationship between protocol and serialization?

The dubbo protocol contains the header and the content. The content after 96 bytes is serialized. By default, the content is serialized using Hessian2, and can also be changed to FastJSON, Gson, JDK, etc. You only need to configure to modify the protocol

<dubbo:protocol name="dubbo" serialization="fastjson"/>
Copy the code

If you had to make an analogy, you can transfer data in XML format as well as JSON over HTTP. HTTP is the protocol, JSON and XML are serialization.

The last

The dubbo protocol, while lacking in design, has not prevented it from becoming the most widely used protocol for Dubbo.


About the author: focus on back-end middleware development, the public number “bug master” author, pay attention to me, give you the most pure technical dry goods