我目前正在使用kotlin作为主要语言,将我们的clojure服务迁移到vert.x。大多数事情都很有魅力,但有一个问题我已经挣扎了相当一段时间了。
我们所有的服务都使用micrometer.io和普罗米修斯来收集度量。根据文档的说法,积分千分尺是笔直向前的:
val vertx = Vertx.vertx(
VertxOptions().setMetricsOptions(
MicrometerMetricsOptions()
.setPrometheusOptions(VertxPrometheusOptions().setEnabled(true))
.setEnabled(true)
)
)通常,这种方法工作得很好--通过添加一个单独的路由来收集和公开度量:
router.get("/metrics").handler(PrometheusScrapingHandler.create())我所面临的问题是,我不可能只定义这些vert.x相关设置(VertxOptions)一次并在全球发布它们--基本上是在创建新的Vertx实例时。
这是一个问题,因为目前我必须在三个不同的地方定义这些设置:
1. Server.kt
允许使用我的IDE启动服务
2.) ServerLauncher
这个类的目的是使用gradle从命令行启动服务器。
3.集成测试
Vert.x提供了一个漂亮的junit5扩展(VertxExtension),它自动将Vertx和VertxTestContext实例注入到试验方法中。缺点是无法配置注入的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一次,从而覆盖/补充所使用的默认设置,无论何时创建Vertx实例?
更新1
我决定提取一个单独的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实例传递给VertxExtention的方法。
更新2
我创建了一个拉请求来解决在测试中预先配置vertx实例的问题。
发布于 2019-02-01 13:49:25
从Vert.x3.6.0开始,您可以放置文件中的Vert.x选项并使用-options加载它们。如果您使用的是CLI或Launcher类,则可以使用该方法。
当您必须以嵌入式模式(例如测试)启动Vert.x时,您可以读取文件内容,并从一个VertxOptions创建JsonObject实例。
发布于 2021-05-10 07:32:16
我想分享一些更多的信息给@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解析函数。
java -jar your-vertx-app.jar -options options.jsonLauncher.executeCommandjava:
public static void main(final String[] args) {
Launcher.executeCommand("run", args);
}科特林:
fun main(args: Array<String>) {
Launcher.executeCommand("run", "com.your.LauncherVerticle", *args)
}在java情况下,您可以传递-options options.json参数(如果是kotlin或com.your.LauncherVerticle -options options.json )来对运行配置的参数进行编程。Launcher.executeCommand将使用此文件。
https://stackoverflow.com/questions/54479117
复制相似问题