微服务框架:如果不用 Spring Boot,还可以选择谁?

前言

在 Java 和 Kotlin 中, 除了使用Spring Boot创建微服务外,还有很多其他的替代方案。

名称 开发商
Helidon SE 甲骨文
Ktor JetBrains
Micronaut Object Computing
Quarkus Red Hat
Spring Boot Pivotal

本文,基于这些微服务框架,创建了五个服务,并使用Consul的服务发现模式实现服务间的 相互通信。因此,它们形成了异构微服务架构(Heterogeneous Microservice Architecture, 以下简称 MSA):

本文简要考虑了微服务在各个框架上的实现(更多细节请查看源代码:https : //github.com/rkudryashov/heterogeneous-microservices)

  • 技术栈:
  • JDK 13
  • Kotlin
  • Gradle (Kotlin DSL)
  • JUnit 5
  • 功能接口(HTTP API):
  • GET /application-info{?request-to=some-service-name}
  • GET /application-info/logo
  • 实现方式:
  • 使用文本文件的配置方式
  • 使用依赖注入
  • HTTP API
  • MSA:
  • 使用服务发现模式(在Consul中注册,通过客户端负载均衡的名称请求另一个微服务的HTTP API)
  • 构建一个 uber-JAR

先决条件

  • JDK 13
  • Consul

从头开始创建应用程序

要基于其中一个框架上生成新项目,你可以使用web starter 或其他选项(例如,构建工具或 IDE):

名称 支持的开发语言
Helidon Java,Kotlin
Ktor Kotlin
Micronaut Groovy、Java、Kotlin
Quarkus Java、Kotlin、Scala
Spring Boot Groovy、Java、Kotlin

Helidon服务

该框架是在 Oracle 中创建以供内部使用,随后成为开源。Helidon 非常简单和快捷,它提供了两个版本:标准版(SE)和MicroProfile(MP)。在这两种情况下,服务都是一个常规的 Java SE 程序。(在Helidon上了解更多信息)

Helidon MP 是 Eclipse MicroProfile的实现之一,这使得使用许多 API 成为可能,包括 Java EE 开发人员已知的(例如 JAX-RS、CDI等)和新的 API(健康检查、指标、容错等)。在 Helidon SE 模型中,开发人员遵循“没有魔法”的原则,例如,创建应用程序所需的注解数量较少或完全没有。

Helidon SE 被选中用于微服务的开发。因为Helidon SE 缺乏依赖注入的手段,因此为此使用了Koin。

以下代码示例,是包含 main 方法的类。为了实现依赖注入,该类继承自KoinComponent。

首先,Koin 启动,然后初始化所需的依赖并调用startServer()方法—-其中创建了一个WebServer类型的对象,应用程序配置和路由设置传递到该对象;

启动应用程序后在Consul注册:

object HelidonServiceApplication : KoinComponent {
​
    @JvmStatic
    fun main(args: Array<String>) {
        val startTime = System.currentTimeMillis()
        startKoin {
            modules(koinModule)
        }
​
        val applicationInfoService: ApplicationInfoService by inject()
        val consulClient: Consul by inject()
        val applicationInfoProperties: ApplicationInfoProperties by inject()
        val serviceName = applicationInfoProperties.name
​
        startServer(applicationInfoService, consulClient, serviceName, startTime)
    }
}
​
fun startServer(
    applicationInfoService: ApplicationInfoService,
    consulClient: Consul,
    serviceName: String,
    startTime: Long
): WebServer {
    val serverConfig = ServerConfiguration.create(Config.create().get("webserver"))
​
    val server: WebServer = WebServer
        .builder(createRouting(applicationInfoService))
        .config(serverConfig)
        .build()
​
    server.start().thenAccept { ws ->
        val durationInMillis = System.currentTimeMillis() - startTime
        log.info("Startup completed in $durationInMillis ms. Service running at: http://localhost:" + ws.port())
        // register in Consul
        consulClient.agentClient().register(createConsulRegistration(serviceName, ws.port()))
    }
​
    return server
}

路由配置如下:

private fun createRouting(applicationInfoService: ApplicationInfoService) = Routing.builder()
    .register(JacksonSupport.create())
    .get("/application-info", Handler { req, res ->
        val requestTo: String? = req.queryParams()
            .first("request-to")
            .orElse(null)
​
        res
            .status
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值