我目前正在使用kotlin作为主要语言,将我们的clojure服务之一迁移到vert.x。大多数事情都像魅力一样起作用,但是现在有一段时间我一直在努力解决一个问题。
我们所有的服务都使用micrometer.io和prometheus收集指标。根据{{3}},积分千分尺很简单:
val vertx = Vertx.vertx(
VertxOptions().setMetricsOptions(
MicrometerMetricsOptions()
.setPrometheusOptions(VertxPrometheusOptions().setEnabled(true))
.setEnabled(true)
)
)
通常,此方法很好用-通过添加单独的路线来收集和公开指标:
router.get("/metrics").handler(PrometheusScrapingHandler.create())
我苦苦挣扎的问题是,我没有办法知道仅定义一次与vert.x相关的设置(VertxOptions
)并在全球范围内发布它们-基本上每当有新的{{1 }}实例已创建。
这是一个问题,因为当前我必须在三个不同的地方定义这些设置:
1。) Server.kt
允许使用我的IDE启动服务
2。) ServerLauncher
此类的目的是使用gradle从命令行启动服务器。
3。)集成测试
Vert.x提供了一个漂亮的junit5扩展名(Vertx
),该扩展名会自动将VertxExtension
和Vertx
实例注入您的documentation中。缺点是无法配置注入的VertxTestContext
实例,因为它总是用test methods注入实例。
因此,您必须使用测试方法自行连接所有内容:
Vertx
我想知道,是否有任何方法可以只创建一次@Test
@DisplayName("Call prometheus endpoint and verify core metrics are present")
fun callPrometheusEndpoint(testCtx: VertxTestContext) {
val vertx = Vertx.vertx(
VertxOptions().setMetricsOptions(
MicrometerMetricsOptions()
.setPrometheusOptions(VertxPrometheusOptions().setEnabled(true))
.setEnabled(true)
)
)
vertx.deployVerticle(
MyVerticle(),
testCtx.completing()
)
WebClient.create(vertx)
.get(8080, "localhost", "/internal/prometheus")
.`as`(BodyCodec.string())
.send(testCtx.succeeding { resp ->
testCtx.verify {
// assertions to follow...
testCtx.completeNow()
}
})
}
实例一次定义VertxOptions
,从而覆盖/补充使用的默认设置?
更新1
我决定提取一个单独的Vertx
类,以配置Application
实例并摆脱Vertx
和Server.kt
。
ServerLauncher.kt
我发现没有办法将配置的class Application(
private val profileSetting: String? = System.getenv("ACTIVE_PROFILES"),
private val logger: Logger = LoggerFactory.getLogger(Application::class.java)!!
) {
fun bootstrap() {
val profiles = activeProfiles()
val vertx = bootstrapVertx(profiles)
val configRetriever = bootstrapConfigRetriever(vertx, profiles)
val myVerticle = MyVerticle(configRetriever)
vertx.deployVerticle(myVerticle) { startup ->
if (startup.succeeded()) {
logger.info("Application startup finished")
} else {
logger.error("Application startup failed", startup.cause())
vertx.close()
}
}
}
internal fun activeProfiles(): List<String> {
logger.info("Configured profiles: {}", profileSetting)
return profileSetting
?.let { it.split(',').map { p -> p.trim() }.filter { p -> p.isNotBlank() } }
?: emptyList()
}
internal fun bootstrapVertx(profiles: List<String>): Vertx {
registerModules()
val vertxOptions = VertxOptionsFactory(profiles).create()
return Vertx.vertx(vertxOptions)
}
internal fun bootstrapConfigRetriever(vertx: Vertx, profiles: List<String>): ConfigRetriever {
return ConfigRetrieverFactory(profiles).create(vertx)
}
private fun registerModules() {
Json.mapper.apply { registerKotlinModule() }
Json.prettyMapper.apply { registerKotlinModule() }
}
companion object {
@JvmStatic
fun main(args: Array<String>) = Application().bootstrap()
}
}
实例传递给Vertx
。
更新2
我创建了一个default settings,用于解决测试中预先配置vertx实例的问题。
答案 0 :(得分:1)
自Vert.x 3.6.0起,您可以放入Vert.x options in a file并用-options
加载它们。如果您使用的是CLI或Launcher
类,则该方法有效。
当您必须以嵌入式模式(例如测试)启动Vert.x时,您可以读取文件内容,并从VertxOptions
创建JsonObject
实例。
答案 1 :(得分:0)
我想与@tsegismont 的回答分享更多信息。
要使用 prometheus 指标,您可以将 options.json
定义如下(在向 pom 或 build.gradle 添加必要的包含后):
{ "metricsOptions": {
"enabled": true,
"prometheusOptions" : {
"enabled": true,
"embeddedServerOptions": {"port": 8080},
"startEmbeddedServer": true
} } }
它将在 host:8080/metrics
要在 options.json
中添加更多选项 - 我刚刚扫描了
BareCommand.getMetricsOptions
MicrometerMetricsOptionsConverter.fromJson
有易读的json解析函数。
要向 jar 添加选项:
java -jar your-vertx-app.jar -options options.json
要在 IDE 中使用它,您可以使用 Launcher.executeCommand
:
Java:
public static void main(final String[] args) {
Launcher.executeCommand("run", args);
}
科特林:
fun main(args: Array<String>) {
Launcher.executeCommand("run", "com.your.LauncherVerticle", *args)
}
之后,您可以在 kotlin 的情况下传递 -options options.json
参数或在 java 的情况下传递 com.your.LauncherVerticle -options options.json
来编程运行配置的参数。 Launcher.executeCommand
将使用此文件。