tio-http-server-native

将基于 tio-http-server 的 jar 编译成二进制文件运行 pom.xml

  <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>
    <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.v20240130-RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.30</version>
      <optional>true</optional>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.10.1</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>${project.artifactId}</finalName>
  </build>
  <profiles>
    <profile>
      <id>jar</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <dependencies>
        <!-- 非 GraalVM 环境用 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>native</id>
      <dependencies>
        <!-- GraalVM 环境使用 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>

启动类

package demo;

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 com.litongjava.tio.utils.json.GsonFactory;
import com.litongjava.tio.utils.json.Json;
import demo.controller.IndexController;

import java.io.IOException;

public class DemoHttpServer {

  public static void main(String[] args) throws IOException {
    Json.setDefaultJsonFactory(new GsonFactory());
    // 实例化Controller
    IndexController controller = new IndexController();

    // 手动添加路由
    HttpRoutes simpleHttpRoutes = new SimpleHttpRoutes();
    simpleHttpRoutes.add("/", controller::index);
    simpleHttpRoutes.add("/txt", controller::txt);
    simpleHttpRoutes.add("/json", controller::json);
    simpleHttpRoutes.add("/exception", controller::exception);

    // 配置服务服务器
    HttpConfig httpConfig;
    HttpRequestHandler requestHandler;
    HttpServerStarter httpServerStarter;

    httpConfig = new HttpConfig(80, null, null, null);
    requestHandler = new SimpleHttpDispatcherHandler(httpConfig, simpleHttpRoutes);
    httpServerStarter = new HttpServerStarter(httpConfig, requestHandler);
    // 启动服务器
    httpServerStarter.start();
  }

}

实体类

package demo.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Hello {
  private String name;
  private String from;
}

Controller

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;
import demo.model.Hello;

public class IndexController {

  public HttpResponse index(HttpRequest request) {
    return Resps.txt(request, "index");

  }

  public HttpResponse txt(HttpRequest request) {
    return Resps.txt(request, "index");
  }

  public HttpResponse exception(HttpRequest request) {
    throw new RuntimeException("error");
  }

  public HttpResponse json(HttpRequest httpRequest) {
    Hello hello = new Hello("Tong Li", "Earth");
    return Resps.json(httpRequest, hello);
  }
}

maven and jdk

mvn -version
Apache Maven 3.8.8 (4c87b05d9aedce574290d1acc98575ed5eb6cd39)
Maven home: /root/program/apache-maven-3.8.8
Java version: 21.0.1, vendor: Oracle Corporation, runtime: /root/program/graalvm-jdk-21.0.1+12.1
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "5.15.0-92-generic", arch: "amd64", family: "unix"

打包成二进制文件

mvn package -DskipTests -Pnative

打包过程中执使用的 native-image 命令如下

/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.v20240130-RELEASE/tio-http-server-3.7.3.v20240130-RELEASE.jar:/root/.m2/repository/com/litongjava/tio-http-common/3.7.3.v20240130-RELEASE/tio-http-common-3.7.3.v20240130-RELEASE.jar:/root/.m2/repository/com/litongjava/tio-core/3.7.3.v20240130-RELEASE/tio-core-3.7.3.v20240130-RELEASE.jar:/root/.m2/repository/com/litongjava/tio-utils/3.7.3.v20240130-RELEASE/tio-utils-3.7.3.v20240130-RELEASE.jar:/root/.m2/repository/com/google/code/gson/gson/2.10.1/gson-2.10.1.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-native-study/target/tio-http-server-graal.jar -H:+RemoveSaturatedTypeFlows --allow-incomplete-classpath --no-fallback -H:Class=demo.DemoHttpServer -H:Name=tio-http-server-native-study

编译成功,编译过重中日志如下

========================================================================================================================
GraalVM Native Image: Generating 'tio-http-server-native-study' (executable)...
========================================================================================================================
[1/8] Initializing...                                                                                    (8.9s @ 0.07GB)
 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-native-study; 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)
Found pending operations, continuing analysis.
[2/8] Performing analysis...  [******]                                                                  (88.3s @ 0.61GB)
    6,631 reachable types   (83.0% of    7,986 total)
    8,971 reachable fields  (54.2% of   16,566 total)
   33,828 reachable methods (56.6% of   59,732 total)
    2,137 types,   123 fields, and 1,824 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...                                                                              (11.6s @ 0.69GB)
[4/8] Parsing methods...      [*****]                                                                   (32.0s @ 0.76GB)
[5/8] Inlining methods...     [***]                                                                      (4.6s @ 0.81GB)
[6/8] Compiling methods...    [*************]                                                          (184.0s @ 0.70GB)
[7/8] Layouting methods...    [***]                                                                     (10.1s @ 0.74GB)
[8/8] Creating image...       [[8/8] Creating image...       [***]                                                                      (5.2s @ 0.89GB)
  17.10MB (53.14%) for code area:    18,845 compilation units
  13.83MB (42.98%) for image heap:  201,318 objects and 49 resources
   1.25MB ( 3.88%) for other data
  32.17MB in total
------------------------------------------------------------------------------------------------------------------------
Top 10 origins of code area:                                Top 10 object types in image heap:
  11.95MB java.base                                            4.63MB byte[] for code metadata
   2.56MB svm.jar (Native Image)                               2.48MB byte[] for java.lang.String
 352.71kB java.rmi                                             1.40MB java.lang.String
 265.40kB java.naming                                          1.12MB java.lang.Class
 260.34kB tio-core-3.7.3.v20240130-RELEASE.jar               613.59kB byte[] for general heap data
 249.64kB jdk.crypto.ec                                      373.98kB byte[] for reflection metadata
 242.15kB gson-2.10.1.jar                                    310.83kB com.oracle.svm.core.hub.DynamicHubCompanion
 171.04kB tio-utils-3.7.3.v20240130-RELEASE.jar              253.84kB java.util.HashMap$Node
 162.92kB com.oracle.svm.svm_enterprise                      193.38kB c.o.svm.core.hub.DynamicHub$ReflectionMetadata
 155.25kB java.logging                                       191.68kB char[]
 660.28kB for 20 more packages                                 2.30MB for 1787 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.
------------------------------------------------------------------------------------------------------------------------
                       27.7s (8.0% of total time) in 365 GCs | Peak RSS: 1.74GB | CPU load: 3.06
------------------------------------------------------------------------------------------------------------------------
Produced artifacts:
 /root/code/java-ee-tio-boot-study/tio-http-server-study/tio-http-server-native-study/target/tio-http-server-native-study (executable)
========================================================================================================================
Finished generating 'tio-http-server-native-study' in 5m 46s.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  05:53 min
[INFO] Finished at: 2024-01-31T10:22:24+08:00
[INFO] ------------------------------------------------------------------------

测试启动成功

./target/tio-http-server-native-study
Jan 31, 2024 10:38:59 AM com.litongjava.tio.server.TioServer start
INFO:
|----------------------------------------------------------------------------------------|
| t-io on gitee     | https://gitee.com/ppnt/t-io                                        |
| t-io on github    | https://github.com/litongjava/t-io                                 |
| ---------------------------------------------------------------------------------------|
| TioConfig name    | Tio Http Server                                                    |
| Started at        | 2024-01-31 10:38:59                                                |
| Listen on         | 0.0.0.0:80                                                         |
| Main Class        | java.lang.invoke.LambdaForm$DMH/sa346b79c                          |
| Jvm start time    | 9ms                                                                |
| Tio start time    | 5ms                                                                |
| Pid               | 203800                                                             |
|----------------------------------------------------------------------------------------|

访问测试接口

  • http://localhost/
  • http://localhost/txt
  • http://localhost/json
  • http://localhost/exception

json 接口返回有时的{},其他接口正常,原因不明

测试代码地址

https://github.com/litongjava/java-ee-tio-boot-study/tree/main/tio-http-server-study/tio-http-server-native-study