This is a creation in Article, where the information may have evolved or changed.
A while ago I was furious because someone misinterpreted the role of rest in microservices and failed to use it correctly. Some people think that HTTP-based monolithic systems cannot be decomposed into microservices because of the inability to interact asynchronously based on HTTPS. Most people think that HTTP is rest, which is a sad thing to do. In our industry, these people are very experienced, should know that the two are actually different. If you can't tell the difference between them, take a look at rest cookbook or Dr. Roy's article first.
Well, it seems a little off-topic, let's go back to the question before: I was furious, I hope to guide you to the right direction, but also to provide some suggestions.
Rest and HTTP
First, it's not that building microservices must be based on HTTP. For this, take a look at some of the relevant articles published earlier by Infoq, or look at what we did in Wildfly/eap and other projects over the past 7 years.
HTTP is not the only choice, it has its shortcomings, not only because it is a text-based protocol, it is also more mature than the IIOP in terms of performance. This problem is exposed in the Narayana project, even if the binary version of the HTTP/2 is not.
This is not to say that there is a lack of performance in HTTP to persuade you to abandon it, we have other options. Traditional messaging middleware, such as A-MQ, supports many modes, including proxy and non-proxy modes, and also supports AMQP and MQTT protocols to make interactions between heterogeneous systems more unobstructed.
Of course, I'm not saying that you must not use HTTP to build MicroServices. But when we deal with a lot of distributed systems, we have to consider many other aspects, such as reliability, performance, coupling and so on. It is not HTTP-not, but JMS is the same. I know that HTTP-based services are easy to test and require only one browser. However, other tools, such as Arquillian, can also be considered.
asynchronous invocation
Now let's talk about asynchronous HTTP. Some people say that HTTP can implement asynchronous invocation, is this possible? Of course it is possible, I will give some references below.
First, we take some well-known projects as examples, such as Vert.x and Undertow, which implement asynchronous message interactions based on HTTP. Both are popular projects and many people use them to build large applications.
Second, you may not believe what I'm saying, but you can go through Infoq's article on the subject. There are many such articles, even dating back to 10 years ago. If I were to recommend a book on this subject, I would recommend an old friend of mine who was also a former colleague, Jim Webber, or another old friend of his current colleague, Bill Burke.
When using HTTP, the response code is important to us. We are familiar with the 200,403,404 response codes, but there are some things that make it possible to implement asynchronous interactions, such as 202. This is described in the HTTP protocol specification as 202:
The request has been accepted but has not been processed yet. the request may eventually not be processed because the system may not allow processing of the request . In this case, there is no way to resend a status code through an asynchronous operation. The 202 response does not guarantee processing results, it simply allows the server to receive requests without having the client wait for the results to be processed. Its response should include some content, such as the processing state of the current request, or let the client know where to go to get the processing state, or tell the client the approximate time to complete the request.
Obviously, the place I'm highlighting refers to "asynchronous processing." This response code is certainly not what we often see, and even if used, also because the browser is hidden, so still can't see. The point is that HTTP supports asynchronous invocation. As a developer, we can certainly take advantage of this.
If you're thinking about using a standard framework to handle asynchronous HTTP, you'll probably think of Jax-rs. There is a lot of relevant information on the Internet, and Bill Burke's book is good. He even wrote a jax-rs2.0, worth a look. Bill's standard-setting team also intentionally added an asynchronous client API to support callbacks in their new version protocol specification. And let's not forget the demo of Bill's early version of the protocol in 2009.
Is it really asynchronous?
If you read this, it should be clear that HTTP-based asynchronous processing is entirely possible. But I would like to point out some of its flaws, as some articles say.
When people talk about asynchronous interactions, they generally refer to the following two types. One is that the request is sent synchronously to the server, and the server returns a confirmation response, telling the client that the request will eventually be processed and return the result. This approach can improve concurrency. The other is "trigger and forget" mode, and the server will not return any acknowledgments to the client.
Fortunately, when most people refer to the second approach, they actually think of the first, because they simply ignore the confirmation response. The difference between the two is really crucial, in a real asynchronous system, it is not possible to only pass the length of time to determine whether an endpoint is a crash or just slow response. This is important when making a system architecture decision.
Weigh
Fischer,lynch and Patterson, three people, published a paper in 1985 and won the Dijkstra most influential paper award. In their paper, they prove the FLP theory that it is impossible to determine whether an endpoint has collapsed by the length of time. Most people think this is possible in a synchronous system, but it is not possible in an asynchronous system, even if there is only one bad processor in the entire system.
You may ask why this is so important. Obviously, if you're in a real asynchronous interaction scenario, you need to know which calls can get results directly and which don't. This is not on paper, the thesis has been very clear, so in the development of the time to be careful of this aspect of the problem.
Therefore, all the protocols concerning the transaction, including those in the Narayama, should be synchronous.
There is one more thing to keep in mind, some people confuse the brewer cap theory with the FLP. Although both the cap and the FLP are related to the behavior of the distributed system, there are some notable differences between them:
The CAP considers that it is not possible to implement storage systems that meet the following three-point support for reading and writing in asynchronous networks.
- Availability--Each request will eventually receive a response
- Consistency--The server returns the correct response for each request
- Partition fault tolerance--allow message loss
In a way, cap sounds a bit like FLP, but it's not. If you're really interested, take a look at Ken Birman's paper.
The FLP allows nodes in the network to crash, but no messages are allowed to be lost.
The above information is beyond the scope of what a developer should know, but it is always good to know more about the pitfalls of distributed systems. Also, we must be careful, sometimes when people talk about caps or FLP, it doesn't mean they really understand the principle behind them. The truth is that caps are often misunderstood and abused.