tio-http-server打包為二進(jìn)制文件的實(shí)現(xiàn)及優(yōu)勢(shì)詳解
tio-http-server打包為二進(jìn)制文件
打包 Java 應(yīng)用為二進(jìn)制文件的優(yōu)勢(shì)
打包 Java 應(yīng)用為二進(jìn)制文件,帶來(lái)了一系列的好處,這些好處對(duì)于提升應(yīng)用的性能、分發(fā)、以及運(yùn)維方面都非常有益。以下是一些主要優(yōu)勢(shì):
- 更快的啟動(dòng)時(shí)間:二進(jìn)制文件通常比傳統(tǒng)的 JVM 啟動(dòng)方式快得多。這是因?yàn)樗鼈冎苯泳幾g到了本地代碼,減少了JVM初始化和類加載所需的時(shí)間。這在需要快速啟動(dòng)和執(zhí)行的微服務(wù)和云函數(shù)(如 AWS Lambda)中特別有用。
- 減少內(nèi)存占用:編譯成二進(jìn)制文件的應(yīng)用通常有更小的內(nèi)存占用。這是因?yàn)樗鼈儽苊饬诉\(yùn)行時(shí)環(huán)境的一些開(kāi)銷(xiāo),如 JVM 的垃圾收集和 JIT 編譯。
- 簡(jiǎn)化部署:二進(jìn)制文件使得部署過(guò)程更加簡(jiǎn)單。你只需要一個(gè)文件,不再需要單獨(dú)安裝和配置 JVM 環(huán)境。這簡(jiǎn)化了在不同環(huán)境中的部署和遷移過(guò)程。
- 提高性能:直接編譯為機(jī)器碼可以提高應(yīng)用性能,尤其是對(duì)于計(jì)算密集型應(yīng)用。這種方式可以更好地利用硬件資源,提高運(yùn)行效率。
- 跨平臺(tái)兼容性:通過(guò)適當(dāng)?shù)呐渲煤铜h(huán)境設(shè)置,可以為不同的操作系統(tǒng)和硬件架構(gòu)創(chuàng)建專門(mén)的二進(jìn)制文件,增加應(yīng)用的可移植性。
- 安全性增強(qiáng):編譯成二進(jìn)制文件可以在一定程度上提高安全性,因?yàn)樗鼫p少了運(yùn)行時(shí)代碼注入和其他基于 JVM 的攻擊的可能性。
- 減少依賴:由于所有必需的庫(kù)和依賴都被包含在單個(gè)二進(jìn)制文件中,因此減少了對(duì)外部庫(kù)和環(huán)境的依賴。
- 優(yōu)化資源利用:在容器化和云基礎(chǔ)設(shè)施環(huán)境中,資源利用的優(yōu)化尤為重要。二進(jìn)制文件的低內(nèi)存占用和快速啟動(dòng)特性使得它們非常適合這些環(huán)境。
創(chuàng)建工程
首先,創(chuàng)建一個(gè) Maven 工程并添加所需的依賴和配置。這里特別指出了使用 3.7.3.v20231223-RELEASE
版本的 tio-http-server
,該版本做了優(yōu)化,使用了自定義的 mapcache
替代了 caffeine
。示例中提供了 pom.xml
文件的配置,涵蓋了 Java 版本、依賴庫(kù)、以及特定的構(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>
通過(guò)依賴可以分析得出tio-http-server僅僅依賴了fastjson2和slf4j-api
編寫(xiě)代碼
接下來(lái),編寫(xiě)一個(gè)簡(jiǎn)單的控制器 IndexController
和一個(gè)啟動(dòng)類 DemoHttpServer
。這些類定義了基本的 HTTP 請(qǐng)求處理邏輯,并設(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 { // 實(shí)例化Controller IndexController controller = new IndexController(); // 手動(dòng)添加路由 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); // 啟動(dòng)服務(wù)器 httpServerStarter.start(); } }
配置環(huán)境
為了打包成二進(jìn)制文件,需要安裝 GraalVM 和 Maven。文檔中提供了詳細(xì)的安裝步驟,包括下載鏈接、解壓指令和環(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)建二進(jìn)制鏡像。
Build Java Jar (Optional)
mvn package
Build Binary Image
mvn clean package -DskipTests -Pserver-graalvm
實(shí)際執(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
打包過(guò)程中的部分日志如下
======================================================================================================================== 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)
生成的二進(jìn)制文件tio-http-server-hello有42M
啟動(dòng)測(cè)試
啟動(dòng)服務(wù)器,啟動(dòng)時(shí)間僅為13ms,服務(wù)器啟動(dòng)的日志如下包括服務(wù)器配置、啟動(dòng)時(shí)間和進(jìn)程 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打包為二進(jìn)制文件的實(shí)現(xiàn)及優(yōu)勢(shì)詳解的詳細(xì)內(nèi)容,更多關(guān)于tio-http-server打包為二進(jìn)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java的方法和this關(guān)鍵字如何理解與應(yīng)用
Java語(yǔ)言中的“方法”(Method)在其他語(yǔ)言當(dāng)中也可能被稱為“函數(shù)”(Function)。對(duì)于一些復(fù)雜的代碼邏輯,如果希望重復(fù)使用這些代碼,并且做到“隨時(shí)任意使用”,那么就可以將這些代碼放在一個(gè)大括號(hào){}當(dāng)中,并且起一個(gè)名字。使用代碼的時(shí)候,直接找到名字調(diào)用即可2021-10-10Java Yml格式轉(zhuǎn)換為Properties問(wèn)題
本文介紹了作者編寫(xiě)一個(gè)Java工具類來(lái)解決在線YAML到Properties轉(zhuǎn)換時(shí)屬性內(nèi)容遺漏的問(wèn)題,通過(guò)遍歷YAML文件的樹(shù)結(jié)構(gòu),作者成功實(shí)現(xiàn)了屬性的完整轉(zhuǎn)換,總結(jié)指出,該工具類適用于多種數(shù)據(jù)類型,并且代碼簡(jiǎn)潔易懂2024-12-12解決Maven項(xiàng)目pom.xml導(dǎo)入了Junit包還是用不了@Test注解問(wèn)題
在Maven項(xiàng)目中,如果在非test目錄下使用@Test注解,可能會(huì)因?yàn)閜om.xml中<scope>test</scope>的設(shè)置而無(wú)法使用,正確做法是將測(cè)試代碼放在src/test/java目錄下,或去除<scope>test</scope>限制,這樣可以確保Junit依賴正確加載并應(yīng)用于適當(dāng)?shù)拇a部分2024-10-10