By Leijuan
Hello everyone, I am Chen Libing (Leijuan), a Java/Kotlin engineer, a developer of Alibaba RSocket Broker, and a founder of the Reactive foundation. Currently, I'm focusing on technologies, such as Reactive/RSocket, Serverless, WebAssembly, and Deno/Rust.
Today, I would like to talk to you about why I think Spring is still one of the best platforms in the cloud-native era.
In 2015, I participated in the SpringOne 2015 conference in Washington. The keynote speech was entitled Cloud Native Enterprise, the slogan of the conference was cloud-native, and all the posters were related to cloud-native.
You may feel strange because containers were not popular at that time. How could that be called cloud-native? Many people may have different understandings about cloud-native, and more people believe cloud-native is about culture rather than containers. To be sure, cloud-native is not equal to containers. It is a software development culture. Even Serverless or WebAssembly FaaS platforms based on V8 isolation that emerge later are still cloud-native.
Spring has done a lot for the cloud-native trend. For example, Spring Cloud supports the distributed architecture and is a necessary framework for distributed and cloud Java applications. All cloud vendors have implemented products based on Spring Cloud, such as Spring Cloud Alibaba, AWS, Azure, and GCP. Spring Cloud simplifies the integration of Java applications with cloud services.
The Spring ecosystem has been in the leading position as microservices become popular. Many people may wonder one thing. We all know the achievements made before Spring, but it seems that there has been no development over the past two years. Can Spring continue to lead the technology trend?
The reason for these doubts is that when we talk about development based on the cloud and cloud-native environment, we generally focus on the selection of technology stacks, which is mainly about costs.
Every developer or small- and medium-sized enterprise wants to do more with fewer cloud resources, most notably, memory and CPU. Memory consumption needs to be low. If you can compile stand-alone executable programs, try to choose a lightweight development framework. In addition, you should consider a fully asynchronous framework that can be efficiently used in certain languages. This ensures full use of the CPU and avoids waste caused by thread waiting.
Many people tend to choose technology stacks, such as Rust, Node.js, and Golang. Java starts slowly, consumes a lot of memory, and seems to be relatively expensive. It seems Java is not suitable for the cloud-native era in the future.
Can the Spring ecosystem based on the Java language be adapted to new development methods, such as cloud-native, Serverless, and FaaS? Will it still be the best platform in the cloud-native era?
Next, I will analyze this problem from four perspectives: the development of Java and JDK, JVM languages full of benign competition, mature Spring Boot and Spring Cloud for service-oriented architecture, and Spring Reactive, which makes event-driven architectures easier to use.
We know Spring is based on the Java framework, and JDK is the foundation for running Java programs. If you want to discuss whether Spring is still one of the best platforms for cloud-native, we need to check whether JDK provides a solid foundation for the development of Spring.
The first is version iteration. Currently, OpenJDK is developing at a fast pace. In previous years, a major version was released every three years, but now a version is released every six months. It is the same for JavaScript, which was released once a year. TypeScript was released three times a year, and Java was released twice a year.
The second is JDK feature updates. If you pay attention to JDK, you can find see more features have been incorporated into JDK, such as lightweight thread Bloom project similar to co-routines, Panama project (SIMD support), which improves Native call support, and more advanced GC algorithms.
Oracle has developed GraalVM based on OpenJDK to solve the problems of slow startup and high memory consumption in Java. It can directly run commands in languages, such as JavaScript, Python, and Ruby in JVM, so it is a veritable Polyglot JVM. GraalVM also provides the Native Image feature, which can convert Java code into a stand-alone executable program. Spring has also launched the Spring Native project, which can conveniently convert Spring Boot applications into native images. As such, Spring applications can start faster and consume less memory. After native-image conversion, Spring applications can meet the requirements of every developer or small- and medium-sized company for less expensive cloud migration. GraalVM has an excellent solution for Java command line applications – Picocli + GraalVM Native Image + upx. It can compile Java applications into more convenient executable programs.
The following figure shows the support for languages and Native Image from GraalVM:
In addition, various cloud vendors are actively developing JDKs, such as AliJDK, Amazon Corretto, and Azul. They are all contributing significantly to JDK development.
Therefore, JDK is still a good foundation for Spring.
JDK does not support only Java. On the contrary, it supports a variety of languages, such as Kotlin, Scala, and Groovy. Here, we call them JVM languages. Currently, JVM languages are in a state of benign competition.
We know that each language has its own usage scenarios. In the cloud-native era, multi-language development is very important. Developers must select different development languages based on real-world business scenarios. Spring can be directly integrated with JVM languages or the languages supported by GraalVM so developers can make full use of the Spring technology stack for development.
Kotlin is the language that best supports Spring. The integration of Kotlin and Spring has penetrated all aspects of the framework, including the integration of Spring Boot and Kotlin, Spring Webflux support for Kotlin Coroutines and Flow, and support for Kotlin from Spring Data, Spring Integration, and Spring Cloud Function. The deep integration with Kotlin aims to combine languages and frameworks better and improve development efficiency. In addition, Scala is well-integrated with Spring.
Java, Kotlin, and Scala are well-integrated with Spring. The sections below describe them in detail to help you understand the current development of JVM languages.
The development of Java is still very fast. The development of OpenJDK results in the release of a new Java version every six months. Each version will be accompanied by syntax and standard library upgrades to facilitate developers. The syntax and features have been improved a lot from Java 9 to Java 16, such as var keywords (local variable type derivation), Text block, Pattern Matching for instanceof, Record, and sealed interface.
Kotlin is not specifically JVM-based, but it also includes Native and JavaScript. However, Kotlin provides more stable support for most JVM and Android features.
Kotlin is being developed very fast and has incubated several sub-projects, such as the latest Kotlin Multiplatform Mobile and Kotlin Compose for Desktop. The former features one set of code for multiple mobile phone platforms, while the latter features one set of code for developing multi-OS desktop applications. The most focused change is Kotlin intermediate representation (IR) introduced by Kotlin 1.5. The new IR allows Kotlin code to be compiled and output to various target platforms, and the program can be better, for example, Kotlin WebAssembly.
Scala 3 was released in May 2021. In addition to the new features, Scala 3 also removes some obscure features from Scala 2 to make it more user-friendly.
Another core change in Scala 3 is compiler adjustment. The name of the compiler is TASTy, which is short for Typed Abstract Syntax Trees. The structure is listed below:
With TASTy, Scala.js is now available, and Scala WebAssembly will be available in the future.
Both Kotlin and Scala are friendly to functional programming and make up for Java's shortcomings in this regard. In addition, Kotlin and Scala both support JavaScript compilation and output, which is very helpful for V8-based Serverless platforms, such as the Serverless platforms of Cloudflare. In addition, Kotlin and Scala are actively exploring support for WebAssembly, which is good news for supporting Web development.
Many other JVM languages, such as Groovy and Clojure, are also actively developing. These JVM languages compete with and learn from each other, which is good news for developers.
The section above introduced the JDK and JVM languages Spring requires. Now, let's talk about two very successful Spring projects, Spring Boot and Spring Cloud.
Spring Boot and Spring Cloud are two highly successful projects widely used by Internet companies based on Java technology stacks. Recently, Josh Long, Spring's top evangelist, gave a speech about Spring Reactive. He also wrote a book called Spring Reactive.
Why have Spring Boot, Spring Cloud, and Spring Reactive received so much attention?
We know there are two important architectures for cloud-native: service-oriented architecture and event-driven architecture. Service-oriented architecture is usually based on the synchronous request/response model. Spring Boot and Spring Cloud aim to support this feature. Event-driven architecture is based on an asynchronous message model and message routing. The core of Spring Reactive is to support this architecture.
Next, I'll show you how Spring specifically supports these two important architectures in cloud-native. You can have a clear understanding of the three important projects in Spring: Spring Boot, Spring Cloud, and Spring Reactive.
Scala 3 official website: https://www.scala-lang.org/blog/2021/05/14/scala3-is-here.html
Generally, cloud-native applications tend to adopt microservice design. The core of microservice design is service-oriented architecture design and API management. Spring Boot and Spring Cloud are designed to support this feature. These two projects have been very successful and are widely used by Internet companies that use Java technology stacks.
As we know, the most typical structure of a service interface is the Request/Response mode, especially the Request/Response mode of the Web. The Request/Response mode of remote RPCs is also included in this category, such as HTTP REST, gRPC, and Dubbo.
Corresponding to the service-oriented architecture design in Spring, Spring MVC can support Web and HTTP REST APIs very well and also support OpenAPI. Other RPC types are also supported by the corresponding Spring Boot starter, making the development very convenient. If you want to expose services of other forms, such as traditional services like Web Service and SOAP, this can also be achieved through the Spring Web Services (spring-ws) project.
The other is API management, mainly involving service governance and service consumer calling. The corresponding core technology stack is the Spring Cloud project. Spring Cloud provides service-based architecture and API management with a variety of infrastructures, such as service registration and discovery, load balancing, API Gateway, and circuit breaking. These infrastructures facilitate better service management and governance and allow consumers to make better use of services.
As a result, service-based architecture and API management correspond to Spring Boot and Spring Cloud. The following figure shows a typical architecture:
If your architecture is service-oriented (for example, service orchestration, if service governance, and API Gateway are involved), Spring Cloud is a good choice due to its complete features, stable framework, and complete documentation. It has been tested and practiced by Alibaba. If your company is based on the Java technology stack, Spring Cloud is the best support and practice for implementing the microservice architecture.
Alibaba made Spring Cloud Alibaba open-source in July 2018. So far, it has won more than 19,000 stars, exceeding the total number of other implementations. According to the Report on Open-source Digitalization in Microservice Field 2020 (Article in Chinese) released by X-lab, Spring Cloud Alibaba has become the most active and popular implementation for development with the most complete toolchain. You can consider this during selection.
Outside of the service-oriented architectures we described earlier, there is another architecture mode: event-driven architecture. Event-driven architecture is generally considered to be the preferred cloud-native architecture. How does Spring support this architecture? This involves the Spring Reactive project, and the core supports event-driven architecture.
Spring Reactive is designed for asynchronous messages. Messages or events are the first choices of the enterprise integration pattern (EIP). Spring Reactive aims to make event-driven architecture the preferred and simple choice for application architecture.
I have talked to some senior Spring Boot and Spring Cloud programmers familiar with various service interface designs, including code-level details. However, when it came to EIP, they all said this was a well-known masterpiece by Martin Fowler. When asked whether systems were used, such as Apache Camel and Spring Integration, everyone said the service-oriented architecture could already meet the business needs.
Then, a question arises. Why are well-known EIP, ESB, or EDA not adopted in the architecture design? Is it forgotten because other projects are more famous? Is the threshold too high? Is it a pure theory and completely divorced from practice?
The service-oriented architecture design is based on the service interface call, and the call is synchronous, so service orchestration and API management play a very important role. We will also introduce some message-driven designs in the service-oriented architecture design to handle some asynchronous or data analysis scenarios with Kafka or other MQ systems. For example, we need to send an email after a user registers, perform a security audit when a user login triggers an event, trigger incremental indexes of a search engine after commodity information or price changes, and trigger various notifications after a user places an order.
Service orientation has its advantages, but it needs to solve many problems, such as non-blocking, service registration and discovery, high performance, and easy integration. This is why many experts say event-driven architecture is the mainstream in cloud-native scenarios.
Event-driven architecture does not involve responsible mechanisms, such as service registration and discovery. Message-based routing is also very easy, and asynchronous messaging has higher performance ( the cost is lower). SaaS service integration is simpler (EventBridge), and FaaS can be triggered easier. If you want to know more, you can read a book entitled Building Event-Driven Microservices. Here is the event-driven architecture design based on microservices recommended by Red Hat:
In this figure, all systems communicate through messages, and microservices are no longer from interface-oriented request/response design. They do not handle requests/responses from different applications but continuously process messages from Broker in an asynchronous manner.
If cloud-native focuses on event-driven architecture, Spring Reactive aims to make event-driven architecture easy to use and develop. It is the same as what Spring Boot and Spring Cloud do for service-oriented architecture. In addition, the two architectures are not contradictory and can coexist and complement each other.
If you want to implement a better event-driven architecture, two foundations are indispensable: asynchronization and messaging. Asynchronization can solve the problem of thread waiting, while messages and message routing can achieve loose coupling of applications. Currently, more products use asynchronous message solutions. Various message middleware and well-known HTTP/2 achieve communication based on asynchronous messages.
Why is asynchronization needed? We know the message processing model is different from the synchronous service call. For example, the Event Loop and Actor models for message processing are very efficient. If we need to handle synchronous service calls based on the thread pool when we are processing messages, the model and performance will inevitably be affected. Synchronization is not forbidden at all, but we need to avoid scenarios where too many services are called synchronously.
Spring needs a lot of work to deal with asynchronization and message scenarios. We know Java does not support asynchronization very much. The CompletionStage API has been added to Java 1.8, and the Reactive Stream feature has been added to Java 9 to support Flow. The Bloom project for lightweight threads is under development and is not expected to be released until Java 17.
Therefore, most Java projects currently use the Reactive framework. The Spring Team has developed the Reactor framework to ensure asynchronous processing from the bottom layer. It is compatible with Netty and Kafka, explaining why the project is called Spring Reactive.
Many projects have added support for asynchronization, such as Spring Webflux, Spring Integration, and Spring Data. All these adjustments aim to ensure that it is completely asynchronous from the bottom layer. You can understand it as the non-independent networking and independent networking of 5G, but Spring chooses the Reactive mode with independent ecology. The workload is also very large. Therefore, two major issues are involved: database and distributed communication.
Currently, most NoSQL products provide asynchronous interfaces to access NoSQL products asynchronously. NoSQL has developed rapidly, but it still has not shaken the position of databases. We all know the specification for database access in Java is JDBC, but JDBC is a synchronous interface. As a result, Spring started the R2DBC project. The purpose is to access the database through the Reactive asynchronous interface. Currently, the experience of using JDBC and R2DBC under the Spring framework is almost the same.
Let me share two messages with you. Spring 5.3 already has built-in R2DBC support, namely, spring-r2dbc, which is equivalent to spring-jdbc. The MySQL database that everyone likes to use has also released the stable edition of mariadb-r2dbc 1.0.0, and Oracle has also released the R2DBC driver. Also, the DB framework, Spring JPA, and MyBatis in Java have added R2DBC adaptation. Hibernate has also launched the hibernate-reactive project (based on Vert.x database). It is not based on R2DBC, but it is fully asynchronous.
Another problem is distributed communication, which plays an important role in the microservice architecture. Spring has always supported HTTP, but HTTP is mainly designed for browsers. The communication advantages between backend services are not obvious, and HTTP has no advantage in performance. gRPC based on HTTP/2 asynchronous messaging is a good choice, but Spring has not provided built-in gRPC support. This is not a big problem for most developers because the third-party grpc-spring-boot-starter is also very good.
If you are concerned about Spring releases, you should know that Spring 5.2 and later versions choose the RSocket protocol and build RSocket into the spring-message project. Why? RSocket is a fully asynchronous binary message communication protocol that provides a complete communication model and implements peer-to-peer communication. It is very suitable for event-driven architecture. This is why Spring Reactive incorporates RSocket into the core of Spring. Spring and Alibaba's Team play a leading role in the development of RSocket.
CNCF provides the CloudEvents specification, which mainly addresses event communication in heterogeneous systems. Messages and events are consistent in data structure with Headers, Payload (data), and extensions that contain message headers. The latest cloudevents-java SDK 2.1 and Spring messaging add support for CloudEvents and support the encoding and decoding of CloudEvents interfaces. They have unified and integrated messages and events, making it easier to process CloudEvents and messages in Spring.
Products that can be integrated with enterprises implement integration with Reactive, such as Apache Camel, Alpakk based on Akka, Mule 4 of MuleSoft, and Spring Integration. They can be seamlessly integrated with Spring Reactive.
Why is Spring still one of the best platforms in the cloud-native era? In summary, Java and JDK are developing very well, and JVM languages are developing smoothly and are full of competition. The mature Spring Boot and Spring Cloud make the service-oriented architecture design simple and easy to use, while Spring Reactive makes event-driven architecture easier to use. At the same time, more enterprise systems can be integrated with Spring Reactive, whether it is IoT devices, ESB products, SaaS, or cloud services.
For microservice scenarios, Spring Cloud provides a mature architecture-oriented service foundation, and Spring Reactive uses a future-oriented, event-driven architecture that is. However, this does not mean the service-oriented architecture is outdated. It is very successful. Perhaps event-driven architecture is more suitable, or the two can be used together in the cloud-native or new Serverless environment. So, don't worry. Spring has done very well in both aspects.
1,076 posts | 263 followers
FollowAlibaba Container Service - April 28, 2020
Adrian Peng - February 1, 2021
Alibaba Cloud Native - December 10, 2024
kirito.moe - April 14, 2020
Alibaba Developer - January 5, 2022
Aliware - April 10, 2020
1,076 posts | 263 followers
FollowMSE provides a fully managed registration and configuration center, and gateway and microservices governance capabilities.
Learn MoreCustomized infrastructure to ensure high availability, scalability and high-performance
Learn MoreAccelerate software development and delivery by integrating DevOps with the cloud
Learn MoreA one-stop, cloud-native platform that allows financial enterprises to develop and maintain highly available applications that use a distributed architecture.
Learn MoreMore Posts by Alibaba Cloud Community