tio-http-server打包為二進制文件的實現(xiàn)及優(yōu)勢詳解
tio-http-server打包為二進制文件
打包 Java 應(yīng)用為二進制文件的優(yōu)勢
打包 Java 應(yīng)用為二進制文件,帶來了一系列的好處,這些好處對于提升應(yīng)用的性能、分發(fā)、以及運維方面都非常有益。以下是一些主要優(yōu)勢:
- 更快的啟動時間:二進制文件通常比傳統(tǒng)的 JVM 啟動方式快得多。這是因為它們直接編譯到了本地代碼,減少了JVM初始化和類加載所需的時間。這在需要快速啟動和執(zhí)行的微服務(wù)和云函數(shù)(如 AWS Lambda)中特別有用。
- 減少內(nèi)存占用:編譯成二進制文件的應(yīng)用通常有更小的內(nèi)存占用。這是因為它們避免了運行時環(huán)境的一些開銷,如 JVM 的垃圾收集和 JIT 編譯。
- 簡化部署:二進制文件使得部署過程更加簡單。你只需要一個文件,不再需要單獨安裝和配置 JVM 環(huán)境。這簡化了在不同環(huán)境中的部署和遷移過程。
- 提高性能:直接編譯為機器碼可以提高應(yīng)用性能,尤其是對于計算密集型應(yīng)用。這種方式可以更好地利用硬件資源,提高運行效率。
- 跨平臺兼容性:通過適當?shù)呐渲煤铜h(huán)境設(shè)置,可以為不同的操作系統(tǒng)和硬件架構(gòu)創(chuàng)建專門的二進制文件,增加應(yīng)用的可移植性。
- 安全性增強:編譯成二進制文件可以在一定程度上提高安全性,因為它減少了運行時代碼注入和其他基于 JVM 的攻擊的可能性。
- 減少依賴:由于所有必需的庫和依賴都被包含在單個二進制文件中,因此減少了對外部庫和環(huán)境的依賴。
- 優(yōu)化資源利用:在容器化和云基礎(chǔ)設(shè)施環(huán)境中,資源利用的優(yōu)化尤為重要。二進制文件的低內(nèi)存占用和快速啟動特性使得它們非常適合這些環(huán)境。
創(chuàng)建工程
首先,創(chuàng)建一個 Maven 工程并添加所需的依賴和配置。這里特別指出了使用 3.7.3.v20231223-RELEASE 版本的 tio-http-server,該版本做了優(yōu)化,使用了自定義的 mapcache 替代了 caffeine。示例中提供了 pom.xml 文件的配置,涵蓋了 Java 版本、依賴庫、以及特定的構(gòu)建配置。
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<graalvm.version>23.1.1</graalvm.version>
<mica-mqtt.version>2.2.6</mica-mqtt.version>
<mica-net.version>0.1.6</mica-net.version>
<tinylog.version>2.6.2</tinylog.version>
<mainClass.server>demo.DemoHttpServer</mainClass.server>
</properties>
<dependencies>
<dependency>
<groupId>com.litongjava</groupId>
<artifactId>tio-http-server</artifactId>
<version>3.7.3.v20231223-RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
</build>
<profiles>
<profile>
<id>jar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<!-- 非 GraalVM 環(huán)境用 tinylog -->
<dependency>
<groupId>org.tinylog</groupId>
<artifactId>slf4j-tinylog</artifactId>
<version>${tinylog.version}</version>
</dependency>
<dependency>
<groupId>org.tinylog</groupId>
<artifactId>tinylog-impl</artifactId>
<version>${tinylog.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<archive>
<manifest>
<mainClass>${mainClass.server}</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>server-graalvm</id>
<dependencies>
<!-- GraalVM 環(huán)境使用 jdk log -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.31</version>
</dependency>
<!-- GraalVM -->
<dependency>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
<version>${graalvm.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>tio-http-server-graal</finalName>
<plugins>
<plugin>
<groupId>org.graalvm.nativeimage</groupId>
<artifactId>native-image-maven-plugin</artifactId>
<version>21.2.0</version>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<skip>false</skip>
<imageName>${project.artifactId}</imageName>
<mainClass>${mainClass.server}</mainClass>
<buildArgs>
-H:+RemoveSaturatedTypeFlows
--allow-incomplete-classpath
--no-fallback
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>通過依賴可以分析得出tio-http-server僅僅依賴了fastjson2和slf4j-api
編寫代碼
接下來,編寫一個簡單的控制器 IndexController 和一個啟動類 DemoHttpServer。這些類定義了基本的 HTTP 請求處理邏輯,并設(shè)置了路由。
package demo.controller;
import com.litongjava.tio.http.common.HttpRequest;
import com.litongjava.tio.http.common.HttpResponse;
import com.litongjava.tio.http.server.util.Resps;
public class IndexController {
public HttpResponse index(HttpRequest request) {
return Resps.txt(request, "index");
}
public HttpResponse login(HttpRequest request) {
return Resps.txt(request, "login");
}
public HttpResponse exception(HttpRequest request) {
throw new RuntimeException("error");
}
}package demo;
import java.io.IOException;
import com.litongjava.tio.http.common.HttpConfig;
import com.litongjava.tio.http.common.handler.HttpRequestHandler;
import com.litongjava.tio.http.server.HttpServerStarter;
import com.litongjava.tio.http.server.handler.HttpRoutes;
import com.litongjava.tio.http.server.handler.SimpleHttpDispatcherHandler;
import com.litongjava.tio.http.server.handler.SimpleHttpRoutes;
import demo.controller.IndexController;
public class DemoHttpServer {
public static void main(String[] args) throws IOException {
// 實例化Controller
IndexController controller = new IndexController();
// 手動添加路由
HttpRoutes simpleHttpRoutes = new SimpleHttpRoutes();
simpleHttpRoutes.add("/", controller::index);
simpleHttpRoutes.add("/login", controller::login);
simpleHttpRoutes.add("/exception", controller::exception);
// 配置服務(wù)服務(wù)器
HttpConfig httpConfig;
HttpRequestHandler requestHandler;
HttpServerStarter httpServerStarter;
httpConfig = new HttpConfig(80, null, null, null);
requestHandler = new SimpleHttpDispatcherHandler(httpConfig, simpleHttpRoutes);
httpServerStarter = new HttpServerStarter(httpConfig, requestHandler);
// 啟動服務(wù)器
httpServerStarter.start();
}
}配置環(huán)境
為了打包成二進制文件,需要安裝 GraalVM 和 Maven。文檔中提供了詳細的安裝步驟,包括下載鏈接、解壓指令和環(huán)境變量設(shè)置。
Install GraalVM
Download and extract GraalVM:
wget https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_linux-x64_bin.tar.gz mkdir -p ~/program/ tar -xf graalvm-jdk-21_linux-x64_bin.tar.gz -C ~/program/
Set environment variables:
export JAVA_HOME=~/program/graalvm-jdk-21.0.1+12.1 export GRAALVM_HOME=~/program/graalvm-jdk-21.0.1+12.1 export PATH=$JAVA_HOME/bin:$PATH
Install Maven
Download and extract Maven:
wget https://dlcdn.apache.org/maven/maven-3/3.8.8/binaries/apache-maven-3.8.8-bin.zip unzip apache-maven-3.8.8-bin.zip -d ~/program/
Set environment variables:
export MVN_HOME=~/program/apache-maven-3.8.8/ export PATH=$MVN_HOME/bin:$PATH
打包
下面介紹如何使用 Maven 打包 Java Jar 文件,以及如何構(gòu)建二進制鏡像。
Build Java Jar (Optional)
mvn package
Build Binary Image
mvn clean package -DskipTests -Pserver-graalvm
實際執(zhí)行的打包命令是
/root/program/graalvm-jdk-21.0.1+12.1/lib/svm/bin/native-image -cp /root/.m2/repository/com/litongjava/tio-http-server/3.7.3.v20231223-RELEASE/tio-http-server-3.7.3.v20231223-RELEASE.jar:/root/.m2/repository/com/litongjava/tio-http-common/3.7.3.v20231223-RELEASE/tio-http-common-3.7.3.v20231223-RELEASE.jar:/root/.m2/repository/com/litongjava/tio-core/3.7.3.v20231223-RELEASE/tio-core-3.7.3.v20231223-RELEASE.jar:/root/.m2/repository/com/litongjava/tio-utils/3.7.3.v20231223-RELEASE/tio-utils-3.7.3.v20231223-RELEASE.jar:/root/.m2/repository/com/alibaba/fastjson2/fastjson2/2.0.43/fastjson2-2.0.43.jar:/root/.m2/repository/org/slf4j/slf4j-jdk14/1.7.31/slf4j-jdk14-1.7.31.jar:/root/.m2/repository/org/slf4j/slf4j-api/1.7.31/slf4j-api-1.7.31.jar:/root/code/java-ee-tio-boot-study/tio-http-server-study/tio-http-server-hello/target/tio-http-server-graal.jar -H:+RemoveSaturatedTypeFlows --allow-incomplete-classpath --no-fallback -H:Class=demo.DemoHttpServer -H:Name=tio-http-server-hello
打包過程中的部分日志如下
========================================================================================================================
GraalVM Native Image: Generating 'tio-http-server-hello' (executable)...
========================================================================================================================
[1/8] Initializing... (7.5s @ 0.08GB)
Java version: 21.0.1+12, vendor version: Oracle GraalVM 21.0.1+12.1
Graal compiler: optimization level: 2, target machine: x86-64-v3, PGO: ML-inferred
C compiler: gcc (linux, x86_64, 9.4.0)
Garbage collector: Serial GC (max heap size: 80% of RAM)
1 user-specific feature(s):
- com.oracle.svm.thirdparty.gson.GsonFeature
------------------------------------------------------------------------------------------------------------------------
1 experimental option(s) unlocked:
- '-H:Name' (alternative API option(s): -o tio-http-server-hello; origin(s): command line)
------------------------------------------------------------------------------------------------------------------------
Build resources:
- 5.80GB of memory (75.6% of 7.67GB system memory, determined at start)
- 4 thread(s) (100.0% of 4 available processor(s), determined at start)
[2/8] Performing analysis... [*****] (86.7s @ 0.67GB)
7,459 reachable types (84.7% of 8,809 total)
11,123 reachable fields (57.5% of 19,337 total)
39,511 reachable methods (59.1% of 66,902 total)
2,219 types, 129 fields, and 1,856 methods registered for reflection
60 types, 58 fields, and 55 methods registered for JNI access
4 native libraries: dl, pthread, rt, z
[3/8] Building universe... (10.6s @ 0.80GB)
[4/8] Parsing methods... [******] (34.7s @ 1.04GB)
[5/8] Inlining methods... [***] (4.2s @ 0.82GB)
[6/8] Compiling methods... [*************] (188.6s @ 1.06GB)
[7/8] Layouting methods... [[7/8] Layouting methods... [***] (8.2s @ 0.97GB)
[8/8] Creating image... [[8/8] Creating image... [***] (5.5s @ 1.07GB)
23.13MB (56.26%) for code area: 23,354 compilation units
16.49MB (40.11%) for image heap: 223,378 objects and 49 resources
1.49MB ( 3.63%) for other data
41.11MB in total
------------------------------------------------------------------------------------------------------------------------
Top 10 origins of code area: Top 10 object types in image heap:
12.91MB java.base 6.30MB byte[] for code metadata
4.43MB fastjson2-2.0.43.jar 2.77MB byte[] for java.lang.String
3.47MB svm.jar (Native Image) 1.57MB java.lang.String
353.79kB java.rmi 1.31MB java.lang.Class
265.89kB java.naming 616.51kB byte[] for general heap data
261.14kB tio-core-3.7.3.v20231223-RELEASE.jar 431.95kB byte[] for reflection metadata
249.74kB jdk.crypto.ec 349.64kB com.oracle.svm.core.hub.DynamicHubCompanion
168.27kB com.oracle.svm.svm_enterprise 309.25kB java.util.HashMap$Node
157.43kB java.logging 223.13kB java.lang.String[]
130.24kB jdk.naming.dns 218.28kB c.o.svm.core.hub.DynamicHub$ReflectionMetadata
627.32kB for 21 more packages 2.44MB for 2015 more object types
Use '-H:+BuildReport' to create a report with more details.
------------------------------------------------------------------------------------------------------------------------
Security report:
- Binary includes Java deserialization.
- Use '--enable-sbom' to embed a Software Bill of Materials (SBOM) in the binary.
------------------------------------------------------------------------------------------------------------------------
Recommendations:
G1GC: Use the G1 GC ('--gc=G1') for improved latency and throughput.
PGO: Use Profile-Guided Optimizations ('--pgo') for improved throughput.
INIT: Adopt '--strict-image-heap' to prepare for the next GraalVM release.
HEAP: Set max heap for improved and more predictable memory usage.
CPU: Enable more CPU features with '-march=native' for improved performance.
------------------------------------------------------------------------------------------------------------------------
30.1s (8.6% of total time) in 442 GCs | Peak RSS: 2.16GB | CPU load: 3.80
------------------------------------------------------------------------------------------------------------------------
Produced artifacts:
/root/code/java-ee-tio-boot-study/tio-http-server-study/tio-http-server-hello/target/tio-http-server-hello (executable)生成的二進制文件tio-http-server-hello有42M
啟動測試
啟動服務(wù)器,啟動時間僅為13ms,服務(wù)器啟動的日志如下包括服務(wù)器配置、啟動時間和進程 ID 等信息。
root@ping-Inspiron-3458:~/code/java-ee-tio-boot-study/tio-http-server-study/tio-http-server-hello# ./target/tio-http-server-hello Dec 26, 2023 6:29:33 PM com.litongjava.tio.server.TioServer start INFO: |----------------------------------------------------------------------------------------| | t-io site | https://www.litongjava.com/t-io | | t-io on gitee | https://gitee.com/ppnt/t-io | | t-io on github | https://github.com/litongjava/t-io | | t-io version | 3.7.3.v20231223-RELEASE | | ---------------------------------------------------------------------------------------| | TioConfig name | Tio Http Server | | Started at | 2023-12-26 18:29:33 | | Listen on | 0.0.0.0:80 | | Main Class | java.lang.invoke.LambdaForm$DMH/sa346b79c | | Jvm start time | 8ms | | Tio start time | 5ms | | Pid | 9426 | |----------------------------------------------------------------------------------------|
以上就是tio-http-server打包為二進制文件的實現(xiàn)及優(yōu)勢詳解的詳細內(nèi)容,更多關(guān)于tio-http-server打包為二進制的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java的方法和this關(guān)鍵字如何理解與應(yīng)用
Java語言中的“方法”(Method)在其他語言當中也可能被稱為“函數(shù)”(Function)。對于一些復雜的代碼邏輯,如果希望重復使用這些代碼,并且做到“隨時任意使用”,那么就可以將這些代碼放在一個大括號{}當中,并且起一個名字。使用代碼的時候,直接找到名字調(diào)用即可2021-10-10
Java Yml格式轉(zhuǎn)換為Properties問題
本文介紹了作者編寫一個Java工具類來解決在線YAML到Properties轉(zhuǎn)換時屬性內(nèi)容遺漏的問題,通過遍歷YAML文件的樹結(jié)構(gòu),作者成功實現(xiàn)了屬性的完整轉(zhuǎn)換,總結(jié)指出,該工具類適用于多種數(shù)據(jù)類型,并且代碼簡潔易懂2024-12-12
解決Maven項目pom.xml導入了Junit包還是用不了@Test注解問題
在Maven項目中,如果在非test目錄下使用@Test注解,可能會因為pom.xml中<scope>test</scope>的設(shè)置而無法使用,正確做法是將測試代碼放在src/test/java目錄下,或去除<scope>test</scope>限制,這樣可以確保Junit依賴正確加載并應(yīng)用于適當?shù)拇a部分2024-10-10

