How to Build a Spring Boot 12-Factor Application

Time:2022-8-11

[Note] This article is translated from: How to build a Spring Boot 12-Factor app (theserverside.com)
Here, we take a look at how the Spring Boot framework supports a twelve-factor approach, and what gaps tools like GitHub, Docker, and Kubernetes fill.
No International Standards Organization specifies a standard that a Spring Boot application must meet as a microservice. Heroku co-founder Adam Wiggins' 12 tips for developers deploying to the Heroku platform is the closest a developer can get to a set of cloud-native development guidelines.
Known as the Twelve-Factor Application Methodology, these 12 commandments have become the de facto standard for creating modern cloud-native microservices targeting Docker and Kubernetes deployments.
The most popular platform for developing Java-based microservices is Spring Boot. Here are the principles of how Spring Boot supports the twelve-factor application methodology.

1. Spring Boot codebase

Not every 12-factor principle maps directly to Spring Boot. Codebase principles are an example of where responsibility falls outside the Spring framework.
According to the twelve-factor application, each Spring Boot microservice should have its own independent codebase. This can be achieved by creating a single Git repository where developers can contribute code, merge branches, and fix bugs. If your Spring Boot application is hosted in its own Git repository, then you have correctly implemented the 12-factor codebase requirement.
How to Build a Spring Boot 12-Factor Application

2. Externalized dependency management

If you use the Spring Boot initializer to create a project, you must choose between Gradle or Maven as the project's build tool. Both tools externalize managing dependencies.
Your Spring Boot application will correctly implement 12-factor dependency management if you place the JAR file outside of your project's lib directory and list all of your program's external dependencies in your Maven POM or Gradle build file.

3. Spring Boot and Kubernetes configuration

According to the twelve-factor application methodology, Spring Boot applications should read their configuration data from the environment. For example, if a cloud-native Spring Boot application is deployed to a Docker container and managed in a Kubernetes cluster, the application should read its configuration data from the Kubernetes ConfigMap – not from JavaBean fields or even application properties files. Spring's cascading configuration processing system fully meets this 12-factor requirement.
Any JavaBean annotated with Spring @ConfigurationProperties will look for configuration data in multiple places. The rule for beans decorated with @ConfigurationProperties is to always use the configuration at the highest externalization level. Properties hardcoded in the JavaBean will be overridden by data in the ApplicationProperties file, which will be overridden by JVM parameters, and ultimately by parameters provided by Docker or the Kubernetes ConfigMap.
With the @ConfigurationProperties annotation, your 12-factor Spring Boot application will conform to the configuration.

4. Support Services and Spring Boot

The ability to treat support services as additional resources has been built into the Java language since its inception, so even if developers work together, it's hard to violate this 12-factor constraint.
For example, all databases accessed through Java Database Connectivity (JDBC) require a URL and driver, which implicitly makes the database an additional resource. It is impossible to implement JDBC or JPA in Java without treating the database as a backing service. The same goes for NoSQL databases, Kafka queues, and RESTful web services. If you're coding in Jakarta EE or Spring Boot, you almost have to follow the 12-factor guidelines to treat all external resources as supporting services.

5. Build, publish and run

The recommendation for developers to follow a strict build, release, and run strategy seems somewhat self-evident. Ironically, this is also probably one of the most frequently violated 12-factor rules.
The idea here is that you should always build your code from your codebase. A release is a tagged build associated with a versioned configuration file. It is a combination of tagged builds and versioned configuration data that you deploy and run on your server.
Code running on the server should not be updated to fix bugs. Configuration settings should not be adjusted at runtime to overcome Java performance issues. All code that goes into a deployment comes from a build, which is based on code versioned in a bare Git repository.
Once paired with a build to create a release, configuration data must not be changed. If changes are required, the team must go through the full build, release, and run cycle again. There should be no shortcuts that violate the 12-Factor Build, Release, and Run principles.

6. Stateless Spring Boot process

The Java and Jakarta EE APIs have many classes and interfaces that implicitly add state to the application, the most important of which is the HttpSession object for the Servlet and JSP APIs.
To achieve 12-factor compliance, Spring Boot provides an alternative to HttpSession called Spring Session. This helps externalize data that would otherwise be statefully held on an application server such as Tomcat or Jetty. This is a prime example of how Spring Boot provides additional APIs and reimplements common classes to ensure applications and microservices maintain 12-factor compliance.
Additionally, Spring Boot allows developers to easily externalize state in NoSQL databases such as Cassandra and MongoDB, which also helps simplify the development of stateless microservices.
It must be noted that the responsibility for ensuring that microservices run as stateless processes also largely falls on the shoulders of software developers. If the developer decides to keep the user state in an instance variable instead of externalizing that data in a shared resource, Spring, Docker, or Kubernetes cannot make the application scale as a stateless process.

7. Port binding

Port binding is another 12-factor principle that is beyond the scope of the Spring Boot framework. Instead, the Docker container maps the internal port used by the Tomcat or Undertow server to the public port. In a clustered environment, the kubectl utility will bind the port of the Kubernetes Pod as a public service. Either way, Spring Framework is not responsible for port binding requirements.
Spring does provide the ability to change the ports used internally by a packaged Spring Boot application, but Kubernetes or Docker will take care of the external port binding, making the cloud native application publicly accessible.

8. Concurrency

According to the twelve-factor application methodology, cloud-native applications should be able to scale out to support high-volume concurrent request-response cycles from clients. As long as the Spring Boot application is stateless, the Kubernetes replica set takes care of creating new Pods using Docker containers that can handle the increasing workload concurrently.

9. Fast startup and shutdown

The ninth principle of the twelve-factor application methodology is disposability, which insists that microservices should start up quickly and shut down gracefully.
For ease of handling, Spring Boot implements the lazy loading design pattern. It also performs smart initialization to reduce the number of objects created at cloud-native microservice startup. Additionally, when developers use the resource classes provided by the Spring Framework, the inversion of control ensures that resources are gracefully terminated when Kubernetes nodes are exhausted or Docker containers go offline.

10. Parity between environments

There will always be differences between development, user acceptance testing, pre-production, and production environments. But the twelve-factor approach insists that these environments be as similar as possible.
To facilitate environment peering, the Spring Boot build will create a runnable JAR file with an application server such as Tomcat embedded in it. The same embedded Tomcat JAR file packaged in a Docker container will be used for each different deployment environment. Since each environment deploys the same compiled code and application server, peer-to-peer between environments is finally achieved.
In addition, Spring Profiles provide an easy way to define and configure properties that need to be changed from one environment to another, allowing developers to resolve differences between environments that inevitably occur.

11. Logs as a stream of events

Twelve-Factor applications insist on viewing logs as streams of events.
All standard Java logging frameworks used by Spring Boot write their data to an event stream, which is saved to a common directory on the Kubernetes node running the Docker container. These log files are then easily consumed by Kubernetes DaemonSets such as FluentD or Logstash. These DaemonSets then stream the logs to tools like Elasticsearch and Logstash for consumption.
As long as you use a framework-standard Java logging framework, you can rest assured that you have a 12-factor compliant Spring Boot application in terms of log consumption.

12. Admin Process Management

Applications often need to run management processes that are not directly related to the request-response cycle that handles client-server interactions. According to the Twelve Factor Application, the code implementing these procedures should not be placed in a separate code base. The management process should be packaged as part of a standard, version-controlled build, and the process itself should execute in the same runtime environment used by the app.
It's very easy to add support for managing processes in a cloud-native Spring Boot application. Spring Batch projects can easily add support for jobs that run once and exit. Additionally, any Git repository can be configured to contain folders that allow adding scripts that can be run in the REPL shell when needed.
There is no clear standard for the development of cloud-native microservices, but the twelve-factor application approach is close. If you're a Java developer and want to create 12-factor apps, Spring Boot will help your team stay cloud-native compliant.

Recommended Today

php displays Chinese graphically and specifies the ttf font library

1 <?php 2 header("Content-Type:image/png"); 3 $img=imagecreatetruecolor(400,300); 4 // imagejpeg($img); 5 // imagejpeg($img,"./img/copy_img01.jpg",10); 6 $color1=imagecolorallocate($img,100,100,100); 7 $color2=imagecolorallocate($img,255,0,0); 8 $str="北京欢迎你!"; 9 imagefill($img,0,0,$color1); 10 // imagestring($img,5,0,0,$str,$color2); 11 $fontfile="F:\phpStudy\WWW\myweb\FZXBSJW.ttf"; 12 imagettftext($img,24,0,100,100,$color2,$fontfile,$str); 13 imagepng($img); 14 imagedestroy($img); 15 // header("Content-Type:text/html"); 16 // echo "gave over!"; Line 13 imagepng($img) must have, and the Chinese font path must be an absolute path.