后端开发一直面临一个二难抉择:

  1. 开发速度优先:Spring(Java)、FastAPI(Python)、Nest.js(JavaScript)
  2. 性能优先:Gin(Go)、Axum(Rust)

TechEmpower Benchmarks 可以得知,选择前者需要承受巨大的性能损失,但后者又有迁移和学习成本,生态也相对较差。

Spring在极高的开发速度下还有勉强说得过去的性能,以及WebFlux、R2DBC。但是这也难以解决JVM最主要的内存问题,不论是GraalVM还是OpenJ9。

Benchmark排行榜中,我发现 vertx-postgres 达到了 Axum(Rust)的 93.4% 的性能,但是Vert.x没有Spring那么方便的注解。紧随其后的 "quarkus, vert.x" 也达到了 92.3%,并且了解后发现Quarkus仍有Spring的各种注解,还比Spring简洁:

package net.mioyi

import jakarta.ws.rs.GET
import jakarta.ws.rs.Path
import jakarta.ws.rs.Produces
import jakarta.ws.rs.core.MediaType

@Path("/")
class Resource(
    private val myService: MyService
) {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    fun index() = myService.f()
}
package net.mioyi
import jakarta.enterprise.context.ApplicationScoped

@ApplicationScoped
class MyService {
    fun f() = "1"
}

我还非常关心它的内存性能。编译到GraalVM Native Image:

docker run -it -v $(pwd):/app -w "/app" gradle:graal gradle buildNative

一共花了8.5分钟,编译后文件大小60MB左右。

刚运行只有10MB左右的内存占用,使用wrk默认压测配置,内存稳定在60~70MB之间,足够优秀了。

最后附Gradle配置:

plugins {
    kotlin("jvm") version "+"
    id("io.quarkus") version "+"
}

group = "net.mioyi"
version = "1.0.0"

repositories {
    mavenCentral()
}

dependencies {
    implementation(platform("io.quarkus.platform:quarkus-bom:+"))
    implementation("io.quarkus:quarkus-kotlin")
    implementation("io.quarkus:quarkus-rest")
}

kotlin {
    jvmToolchain(21)
}