推荐序一
Towards a More Exciting, More Reactive Tomorrow
Hi, Spring fans! It's an interesting time to be alive. Today, the possible applications any programmer can build today are much more numerous than they were when I first started. The opportunities are so much more than they were before. It's possible to write code that runs on the server-side, on the backend, in giant systems, in big data platforms, in streaming platforms, on mobile phones, in cars, in the browser, on your watch, on your tablets, on your TVs, etc., all while using fairly similar languages, and while using similar skills. All of these destinations are also open and - often - open-source. It costs almost nothing to build this stuff. It takes time and it takes a computer with an internet connection. But, the tools are free. This is an ideal scenario. We can do almost anything today. I am very excited to see the opportunities expand in the last 20 years.
You know what I did not expect to happen so quickly? For the possibilities to become so good. I did not expect them to become so refined, so polished in so short a period of time. I was excited when Java ME came out. Now we have Android and iOS. I was excited when Hadoop came out. Now we have Spark and TensorFlow. I was excited when JDBC, the Servlet specification and Struts came out. Now we have Spring. I was excited when Netscape introduced JavaScript. Now we have Vue.js and React and Angular. I was excited when Spring came out. Now we have Spring Boot. I was excited when C++ came out. Now we have Kotlin. I was excited when Ant came out. Now we have Maven and Gradle. I was excited when the ideas around continuous delivery started to crystalize. Now we have a Gitops-centric culture powered by technologies like Kubernetes. Everything has gotten so much better in the last 20 years. All of these things were exciting to me when they first arrived. But they're better now. They're easier. They're faster. They're cheaper. They're a natural evolution of the ideas we've known for a long time.
I feel the same enthusiasm — excitement — when I look at reactive code. I love Spring. I know that it's one of the most powerful ways to express my microservices. Today, I am excited about the opportunity to use Spring and Reactor to build much more resource-efficient, easier-to-understand, reactive services.
Reactive Programming is a natural next step in the creation of cloud native applications. Reactive libraries offer me several tentpole benefits.
I’ll expand on those points here:
Reactive Programming offers one abstraction, no matter what the application (server-sent events, RSocket, WS, HTTP, Kafka, etc). A unified abstraction greatly simplifies the integration and composition of disparate services and data.
Reactive Programming supports more declarative, concise, deterministic ways to express complex, multithreaded algorithms. Remember: only one person TRULY understands how to write safe, concise multithreaded Java code... and it’s NOT you! (It is not me, either!) I don't know who it is. It's better to let the library and framework do the dangerous work of managing concurrency.
Reactive Programming supports services that are more robust. Reactive libraries give us an API protocol to signal that our consumer is overwhelmed, or that it can not handle anymore. Libraries like Project Reactor provide operators to consistently handle errors, back-pressure, and more. The result is safer code with much fewer lines of code.
I believe that all new projects should embrace Reactive Programming, if possible.
So, when I saw that there is a book being written in Chinese to help people understand how to write reactive applications, I was very excited! I hope you'll take the opportunity to read this book, dear reader, and to learn how to work with Reactor and to see how it supports you when building reactive applications with Spring. The opportunities we have today are endless. We have the tools to build almost anything, easily, and to ship that software into production for very cheap. And I am excited to see what you will build with these tools.
Josh Long
Spring 官方布道师
Java Champion 成员
Kotlin GDE 谷歌官方认证开发专家
San Francisco, USA
July 2020
推荐序二
Dear Reader,
Welcome on your journey to building more efficient and resilient applications, welcome to Reactive Programming!
On this path, you will challenge yourself and you will be rewarded with a new mindset that will help you create your next distributed Java services. Interacting with remote services is a common task performed by distributed systems and those interactions take time outside of the calling application control. Multiple reasons are behind this time fluctuation: network latency, the nature of the task run or even a system interruption. At the end of the day, if the calling code needs a result back it will be negatively impacted by that same time because it needs to actively wait for it.
Enter Reactive Programming which gives you the great power of bending space-time to your will! Or sort of... It gives you the ability to remove the negative impact of waiting for anything, so your Thread or CPU is not pinned and can perform other tasks.
Since you can't control how long a remote call will last, you will need to "schedule" the activities your application needs to perform "when" those remote services produce a result. For instance, if your application talks to a remote REST endpoint, it will eventually produce an HTTP response.
"Non Blocking" applications will provide a listener reacting only "when" an underlying network event signals the response back to you. What will do the calling Thread then? It will be able to return to the server worker pool or preparing a next HTTP call, thus increasing service concurrent capacity. It's a scalable design some runtimes have adopted for years, you can implement it with a single thread like Node.JS!
"Non-Blocking" is foundational to Reactive Programming but what does "Reactive" mean anyway? It's maybe not the first time you read the word "Reactive", it has various meanings and it's even mistaken for the popular UI library ReactJS. In this book, when "Reactive" is mentioned, it will always refer to the "reactive-streams" specification which is a clear documented definition adopted by major libraries. "Reactive Streams" defines how an arbitrary "producer" can interact with one or more "consumers" in a Reactive way. Once implemented, the contract offers two key qualities designed to help developers build 100% non-blocking applications: Error Isolation and Flow Control. The former quality contributes to a greater resiliency and availability, producers errors must not interrupt the application, and instead they will forward errors to registered listeners. The latter quality means that producers can't produce more data than consumers are able to consume at any given time. This rule is also known as "backpressure" and it is designed to avoid "unbounded buffers" which has resources consequences on the application host. It helps that one of the major adopters of "Reactive Streams" is the Spring Reactive stack itself including Spring WebFlux and Project Reactor. They do a great job at hiding away a lot of the technical details from the specification I've briefly mentioned in this intro. They provide rich APIs to build reactive flows and help you focus on the "what" and not the "how".
In fact, there are various elements in these libraries designed to ease your first experience with Reactive Programming. First and foremost, Spring can become as much reactive as you need: You can start developing on top of a well-known programming model, Spring MVC, running on Tomcat and you can selectively introduce the modern reactive "WebClient" coming with Spring WebFlux. You can also start returning Project Reactor reactive types Flux and Mono in your Spring MVC controllers the same way you can return CompletableFuture. Ultimately you can just swap your container and start running on top of Netty or Tomcat reactive bridge. Spring conventions such as annotations also matter and most Java developers have learned them for sometimes many years! For instance, @RestController works in both Spring MVC and WebFlux as one could expect. Learning Reactive Programming with Spring is intended to feel like you are learning at home, in a familiar setup.
In this book, you will work with the Spring Reactive stack. I highly recommend you pair this learning opportunity with a good use case that could benefit from going Reactive. For instance, an application depending on a remote service, or an application on the edge of your system serving as a port of entry for many concurrent users.
Learning a new mindset is never easy but it is highly rewarding. Many of the lessons Reactive programming offers apply to all modern software engineering. I think the greatest of these lessons is that it always pays off to be ready with a plan when a component outside your control does not work as you expect.
Good luck!
Stephane Maldini
Netflix 高级软件工程师
Spring Reactor 项目创始人
Reactor-Netty 项目负责人
Spring Framework 项目贡献者