[Bài đọc] Triển khai các ứng dụng Spring Boot

18. Deployment

Spring Boot được xây dựng trên Spring và phục vụ bất cứ nơi nào Spring có thể phục vụ. Nó thỏa mãn tính di động của Spring. Spring Boot cho phép nhà phát triển tập trung vào sự phát triển của ứng dụng trước, và loại bỏ đi sự cần thiết phải quá quan tâm đến các khía cạnh khác của vòng đời ứng dụng, bao gồm triển khai và quản lý.  

Nó nhằm mục đích hướng đến việc “sẵn sàng cho ra sản phẩm” có thể đưa vào sử dụng ngay.Chính vì điều này, Spring Boot thực hiện một vài thứ khác biệt. Bài viết này sẽ tóm tắt một số chiến lược chung để triển khai một ứng dụng Spring Boot.

Bắt đầu với Spring Boot

Có nhiều cách để bắt đầu, bao gồm   Spring Initializr tại start.spring.io webservice và – nếu bạn đang sử dụng Spring Tool Suite – có một trình hướng dẫn quen thuộc hơn đã được tích hợp sẵn, cuối cùng cũng gọi cùng một webservice tương tự.Chúng ta thường bắt đầu bằng cách kiểm tra Actuator, và các checkbox Web , sau đó chọn để tạo ra một dự án Maven .Điều này sẽ cung cấp cho bạn hai lớp khởi động, Application.java và ApplicationTests.java, cũng như tệp pom.xml sẵn sàng sử dụng của Maven .

Đây là việc khởi động dự án được giải nén:

Việc build Maven phụ thuộc vào khởi động các phụ thuộc Spring Boot. Những phụ thuộc này khá quan trọng .Chúng mang theo các ngăn xếp đã được đăng ký và sẵn sàng sử dụng phù hợp với công việc từ trước đó. Nếu bạn muốn build một ứng dụng web, bạn inject phụ thuộc trong khởi động của Spring Boot, như sau:

Maven kế thừa thông tin về các phiên bản phụ thuộc để sử dụng từ pom, cũng được cung cấp bởi Spring Boot. Bạn không cần phải lo lắng về việc xếp các version dự án Spring chung và các phụ thuộc của bên thứ ba.  

Các lớp Java được tạo ra là bản mẫu.Bạn sẽ không thường xuyên thay đổi các lớp, mặc dù bạn có thể. Đây là các bản mẫu bạn sẽ gặp phải trong Spring Boot. Ví dụ lớp Application.java mà Spring Boot cung cấp:

package demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

Chúng ta sẽ thêm vào một controller MVC RESTful Spring. Đây là bản sửa đổi mã Application.java hoàn chỉnh với controller REST MVC của Spring trả về “Hello, World ” khi một request /hello/World được thực hiện:

package demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

@RestController
class GreetingController {

@RequestMapping("/hello/{name}")
String hello(@PathVariable String name) {
return "Hello, " + name + "!";
}
}

Triển khai embedded web server

Khi đưa vào hoạt động, Spring Boot sử dụng “public static void main” để khởi chạy một embedded web server.

Nếu bạn sử dụng Maven build ( mvn clean install ) được cung cấp bởi Spring Boot Initialzr, bạn sẽ nhận được một file jar .File jar này tiện dụng vì nó bao gồm tất cả các phụ thuộc khác và những thứ như web server của bạn bên trong kho lưu trữ. Bạn có thể cho bất cứ ai file jar này và họ có thể chạy toàn bộ ứng dụng Spring của bạn mà không phiền phức: không cần công cụ xây dựng, không thiết lập, không cấu hình máy chủ web, v.v. chỉ cần java -jar … your.jar .

Tomcat

Khi bạn chạy ứng dụng của mình, Spring Boot sẽ phát hiện rằng bạn có một controller Spring MVC và khởi động một thể hiện của Apache Tomcat 7 được nhúng theo mặc định. Bạn có thể kiểm tra điểm cuối REST bằng cách mở trình duyệt và nhập vào thanh địa chỉ:  http://localhost:8080/hello/World .

Có rất nhiều tùy chọn cấu hình cho Tomcat được nhúng. Bạn có thể bật HTTPS (chấm dứt SSL/TLS) cho dịch vụ web của bạn khá dễ dàng bằng cách  cung cấp một   EmbeddedServletContainerCustomizer.Mô-đun được mô tả có một ứng dụng web có thể chạy trên HTTPS, chỉ yêu cầu chứng chỉ SSL/TLS và nhúng web server của riêng nó. Chạy ứng dụng cụ thể đó thực sự đơn giản:

java -Dspring.profiles.active=production -Dkeystore.file=file:///$PWD/src/main/resources/keystore.p12 -jar target/oauth-1.0.0.BUILD-SNAPSHOT.jar.

EmbeddedServletContainerCustomizer này  cấu hình SPI cho phép bạn khai thác hầu hết sức mạnh của cấu hình XML cho một thể hiện Apache Tomcat độc lập. Những thứ nhỏ hơn, giống như server port, có thể được cấu hình bằng cách chỉ định các thuộc tính thông qua dòng lệnh (như–D-style arguments) hoặc thông qua tệp thuộc tính đã tải (ví dụ Spring Boot sẽ tự động tham khảo bất kỳ thuộc tính nào trong tệp có tên application.properties trên CLASSPATH ).Do đó, để thay đổi cổng mà Tomcat lắng nghe, bạn có thể chỉ định –Dserver.port = 8081 , để lắng nghe trên cổng 8081. Nếu bạn chỉ định server.port = 0, nó sẽ tự động tìm một cổng chưa sử dụng để nghe.

Theo mặc định, Spring Boot sử dụng Tomcat 7. Nếu bạn muốn sử dụng Tomcat 8, bạn chỉ cần ghi đè lên bản dựng của Maven  tomcat.version và điều này sẽ kích hoạt việc sử dụng phiên bản mới cho các lần chạy lại trên Apache Tomcat sau này.

Jetty

Tất nhiên, một số bạn có thể muốn sử dụng Jetty embedded servlet container. Jetty cũng là một lựa chọn tốt. Bạn có thể  loại trừ mô-đun Tomcat khởi động Spring Boot và sau đó nhập mô-đun Spring Boot Starter Jetty. Spring Boot sẽ tự động ủy thác cho Jetty, thay vì sử dụng mặc định. Đây là bản sửa đổi phần dependencies của bản dựng Maven:

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

Nếu bạn muốn chuyển sang Jetty 9, điều đó cũng dễ dàng. Đảm bảo bạn có những thuộc tính sau đây trong bản dựng Maven.

<properties>
<java.version>1.7</java.version>
<jetty.version>9.1.0.v20131115</jetty.version>
<servlet-api.version>3.1.0</servlet-api.version>
</properties>

Máy chủ ứng dụng Java EE

Làm thế nào để triển khai đến một bản cài đặt Tomcat sẵn có, hoặc các máy chủ ứng dụng Java EE cổ điển như WebSphere, WebLogic hoặc JBoss ? Đơn giản! Nó vẫn chỉ là Spring, vì vậy không cần thiết phải làm thêm quá nhiều điều. Bạn sẽ cần thực hiện ba thay đổi trực quan: di chuyển từ việc xây dựng một   tệp file jar sang xây dựng   một file war trong Maven : chú thích ra mô tả của plugin spring-boot-maven- plugin trong tệp pom.xml của bạn , sau đó thay đổi kiểu đóng gói Maven thành war .Cuối cùng, thêm một điểm truy cập web vào ứng dụng của bạn. Spring cấu hình hầu hết mọi thứ cho bạn bằng cách sử dụng cấu hình Java Servlet 3. Bạn chỉ cần sử dụng nó. Sửa đổi lớp Application của bạn như sau:

package demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application extends SpringBootServletInitializer {

public static void main(String[] args) {
SpringApplication.run(applicationClass, args);
}

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(applicationClass);
}

private static Class<Application> applicationClass = Application.class;
}


@RestController
class GreetingController {

@RequestMapping("/hello/{name}")
String hello(@PathVariable String name) {
return "Hello, " + name + "!";
}
}

Lớp cơ sở mới này – SpringBootServletInitializer – gọi đến một API cấu hình Java kiểu Servlet 3 cho phép bạn mô tả trong code cái mà bạn chỉ có thể mô tả trong tệp web.xml trước đó. Các lớp cấu hình như vậy được phát hiện và được gọi khi khởi động ứng dụng. Điều này cho phép Spring Boot nói với máy chủ web về các ứng dụng, bao gồm cả các yêu cầu Servlet, Filter và Listener thường được yêu cầu cho các dự án Spring khác nhau.

Lớp mới này bây giờ có thể được sử dụng để chạy ứng dụng bằng cách sử dụng bản nhúng Jetty hoặc Tomcat bên trong, và nó có thể được triển khai tới bất kỳ thùng chứa Servlet 3 nào. Bạn có thể gặp vấn đề nếu bạn có các lớp mâu thuẫn với những phần của cả một máy chủ ứng dụng lớn hơn. Trong trường hợp này, hãy sử dụng các công cụ xây dựng để loại trừ hoặc tạo tùy chọn các API có liên quan. Dưới đây là những thay đổi đối với bản dựng Maven mà chúng ta phải thực hiện để khởi động dịch vụ Spring Boot REST và chạy trên JBoss WildFly (AS trước đây được gọi là JBoss AS):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.demo</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>

<packaging>war</packaging>
<description>Demo project</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<properties>
<start-class>demo.Application</start-class>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.version>
</properties>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>http://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>http://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>http://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>http://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>

Sau đó, chúng ta có thể chạy lại bản dựng và copy tệp file .war vào thư mục $WILDFLY_HOME/standalone/deployments .

Khởi động máy chủ ứng dụng nếu nó chưa chạy, và sau đó bạn có thể đưa ứng dụng lên tại http://localhost:8080/$YOURAPP/hello/World. Một lần nữa phải nhắc lại rằng, chúng ta đã thay thế $YOURAPP cho tên của ứng dụng.

Đến với Cloud

Không có câu chuyện về triển khai sẽ được hoàn thành mà không cần đề cập đến mục tiêu triển khai phát triển nhanh nhất hiện nay: cloud! Tất nhiên, khi chúng ta nói về cloud một cách cụ thể: nếu bạn đang nói về việc triển khai một Amazon Web Services hoặc là Google Compute Engine, thì nó hoạt động như bình thường, giống như bạn đang chạy ứng dụng trên Linux box ở trung tâm dữ liệu của riêng bạn. Bởi vì, về cơ bản, đó là những gì bạn đang làm.

Triển khai PaaS trên Cloud Foundry và Heroku

Nếu bạn đang cố gắng triển khai ứng dụng cho một nền tảng như là dịch vụ, tính linh hoạt của Spring sẽ giúp bạn có rất nhiều lựa chọn ở đây. Dù sao đi nữa triển khai cho Heroku, đặc biệt là với cách tiếp cận tệp jar, là nguyên trạng cho Heroku kể từ khi nền tảng đó như một dịch vụ. Đơn giản chỉ cần đặt câu trả lời java -jar trong Procfile của bạn.

Với Cloud Foundry, bạn có thể triển khai ứng dụng độc lập hoặc dưới dạng ứng dụng web kiểu .war .Khi bạn đã tạo ứng dụng của mình (ví dụ: sử dụng mvn clean install ) và cài đặt công cụ dòng lệnh cf , thì chỉ cần trả lời yêu cầu của lệnh cf push như dưới đây:

➜  cf push --path target/demo-0.0.1-SNAPSHOT.jar

Name> $YOURAPP

Instances> 1

1: 128M
2: 256M
3: 512M
4: 1G
Memory Limit> 256M

Creating $YOURAPP... OK

1: $YOURAPP
2: none
Subdomain> $YOURAPP

1: cfapps.io
2: none
Domain> cfapps.io

Creating route $YOURAPP.cfapps.io... OK
Binding $YOURAPP.cfapps.io to $YOURAPP... OK

Create services for application?> n

Bind other services to application?> n

Save configuration?> y

Saving to manifest.yml... OK
Uploading $YOURAPP... OK
Preparing to start $YOURAPP... OK
-----> Downloaded app package (8.7M)
-----> Java Buildpack source: system
-----> Downloading Open JDK 1.7.0_51 from http://d2vm4m9hl67ira.cloudfront.net/openjdk/lucid/x86_64/openjdk-1.7.0_51.tar.gz (1.4s)
Expanding Open JDK to .java-buildpack/open_jdk (1.3s)
-----> Downloading Spring Auto Reconfiguration 0.8.7 from http://d2vm4m9hl67ira.cloudfront.net/auto-reconfiguration/auto-reconfiguration-0.8.7.jar (0.0s)
-----> Uploading droplet (43M)
Checking status of app '$YOURAPP'...
0 of 1 instances running (1 starting)
0 of 1 instances running (1 starting)
1 of 1 instances running (1 running)
Push successful! App '$YOURAPP' available at http://$YOURAPP.cfapps.io

Ứng dụng sẽ được kích hoạt và khởi chạy, có thể truy cập từ http: //$YOURAPP.cfapps.io/hello/Cloud%20Foundry một lần nữa, chúng ta đã sử dụng $YOURAPP để giữ chỗ cho tên ứng dụng.

Kết luận

Theo mặc định Spring Boot nhằm mục đích tạo nhanh ra những sản phẩm có thể sử dụng ngay. Điều này có nghĩa rằng nó vẫn có thể chỉnh sửa lại những mặc định đó để cho ra sản phẩm nếu cần thiết. Spring Boot cung cấp sẵn một bản dựng Apache Tomcat. Spring Boot cấu hình mọi thứ cho bạn theo cách tự nhiên nhất từ ​​phát triển đến sản xuất trong các nền tảng ngày nay, cũng như trong các nền tảng hàng đầu giống như một dịch vụ.  

Spring Boot cung cấp nhiều cơ hội để ghi đè cấu hình, bao gồm các thuộc tính có thể cấu hình và các cuộc gọi lại tùy chỉnh.

Leave a Reply

Your email address will not be published. Required fields are marked *