Ktor整合nacos注册中心
说起微服务,对于一直使用 java 生态的用户来说,首先想到的应该是 spring cloud 。Spring cloud 已经成为了 java 微服务中重要的标杆。但是同样是 jvm 语言的 kotlin 就没有这样好的环境了,虽然 kotlin 可以使用 spring 生态,而且 spring 在逐步整合 kotlin 的特性。
ktor 是 JetBrains 开发的 kotlin 框架,完全基于 kotlin。kror 提供了官方提供了很多 feature 使用。但是在使用过程中总会有一些功能是官方没有提供的。这时候就需要我们自己去完成。
什么是 feature
ktor 程序是有一系列的feature组成的。通过feature,我们可以自由的更改请求和响应。通过 install
方法将 feature 安装到应用里。例如:
fun Application.main() {
install(DefaultHeaders)
install(CallLogging)
install(Routing) {
get("/") {
call.respondText("Hello, World!")
}
}
}
而官方提供的一系列 feature 中,不可能满足我们所有的需求,此时就需要自定义我们的feature。
自定义 feature
针对自定义feature,官方也给了一篇简短的文档来说明如何自定义。定义一个 feature 主要是实现新的 ApplicationFeature 接口的伴生对象,并且去实现它的方法。
这里面主要有一个属性 key
和一个方法 install
。
public val key: AttributeKey<TFeature>
public fun install(pipeline: TPipeline, configure: TConfiguration.() -> Unit): TFeature
key 属性是一个唯一的标识,用来标识当前的 feature。而 install
方法为 feature 的主要实现功能。
在 install
方法中可以初始化 feature 功能。
服务注册 feature
通过查阅 nacos 的官方文档,可以了解到如何将服务注册到 naocs 上。在install里完成逻辑代码,install里面的逻辑只会执行一次,但是如果想每次请求和响应都需要执行方法,那么可以使用 pipeline.intercept
。
以下是 naocs 的注册实现,当然还有很多功能去完成。方法内有 NacosCOnfig
方法,通过该方法来读取 ktor 的 application.conf 配置文件。其中一些配置是我们需要写在 application.conf 中的,比如 nacos 的端口和地址。
nacos {
port: 8848
address: 127.0.0.1
}
@KtorExperimentalAPI
override fun install(pipeline: ApplicationCallPipeline, configure: Configuration.() -> Unit): NacosDiscover {
val nacosConfig = NacosConfig()
val config = HoconApplicationConfig(ConfigFactory.load())
val ktorConfig = config.config("ktor")
val ktorPort = ktorConfig.propertyOrNull("deployment.port")?.getString()?.toInt() ?: 8080
val configuration = Configuration().apply(configure)
val feature = NacosDiscover(configuration)
val addr = InetAddress.getLocalHost();
val serverAddress = addr.hostAddress
// 应用启动时进行
val naming = NamingFactory.createNamingService("${nacosConfig.nacosAddress}:${nacosConfig.nacosPort}")
val instance = Instance()
instance.ip = serverAddress
instance.port = ktorPort
instance.serviceName = feature.serverName
instance.isHealthy = true
val mateData = HashMap<String, String>()
mateData["framework"] = "ktor"
instance.metadata = mateData
naming.registerInstance(feature.serverName, instance)
return feature
}
具体代码可以看 Github ktor-nacos ,这样就完成了服务注册。
服务请求
当服务注册到 naocs 上的时候,此时就需要通过客户端进行请求。所以需要编写客户端的 feature。
客户端的 feature 主要作用是通过服务名获取服务的详细信息,然后去请求对应的服务。
override fun install(feature: NacosClient, scope: HttpClient) {
val nacosConfig = NacosConfig()
val naming = NamingFactory.createNamingService("${nacosConfig.nacosAddress}:${nacosConfig.nacosPort}")
scope.requestPipeline.intercept(HttpRequestPipeline.Render) {
val instances = naming.getAllInstances(context.url.host).filter { it.isHealthy and it.isEnabled }
val selectedNode = instances[currentNodeIndex]
context.url.host = selectedNode.ip
context.url.port = selectedNode.port
currentNodeIndex = (currentNodeIndex + 1) % instances.size
}
}
并且添加了负载均衡,每次将请求转发到不同的服务上。
总结
通过对 ktor 的基本了解,主要是通过编写 feature 和 pipeline 进行插件功能的实现。目前 ktor 的生态还很不完善,只提供了基础的组件,还有很多组件需要自己去整合完成,还需要社区不断的贡献。
项目已经开源到Github上。youngxhui/ktor-nacos
补充一个 ktor 资源网站 https://www.kotlinresources.com/#
参考链接
相关内容
如果你觉得这篇文章对你有所帮助,欢迎赞赏~
赞赏