使用Spring Boot、Micrometer和Zipkin进行分布式跟踪
希望做的事情
-
- Spring Boot、Micrometer、RestTemplate を使用する
-
- 複数アプリケーション間でトレースIDを伝播する
- トレース情報をZipkinに送信する
这篇文章是我参考的依据。
组成
创建一个 Spring Boot 应用程序
API服务的实现
创建一个与构成图的api-service相对应的应用程序。
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "3.2.0"
id("io.spring.dependency-management") version "1.1.4"
kotlin("jvm") version "1.9.20"
kotlin("plugin.spring") version "1.9.20"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java {
sourceCompatibility = JavaVersion.VERSION_17
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.springframework.boot:spring-boot-starter-actuator")
// Micrometer Observation APIをOpenTelemetryにブリッジするライブラリ
implementation("io.micrometer:micrometer-tracing-bridge-otel:1.2.0")
// トレース情報を Zipkin に送信するライブラリ
implementation("io.opentelemetry:opentelemetry-exporter-zipkin:1.32.0")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs += "-Xjsr305=strict"
jvmTarget = "17"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
要想在网络上自动传播跟踪,需要使用自动配置的RestTemplateBuilder。
import org.springframework.boot.autoconfigure.AutoConfigureAfter
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration
import org.springframework.boot.web.client.RestTemplateBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.client.RestTemplate
@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter(HttpMessageConvertersAutoConfiguration::class)
class RestTemplateAutoConfiguration(
private val restTemplateBuilder: RestTemplateBuilder
) {
@Bean
fun restTemplate(): RestTemplate {
return restTemplateBuilder.build()
}
}
import org.springframework.http.ResponseEntity
import org.springframework.stereotype.Service
import org.springframework.web.client.RestTemplate
import org.springframework.web.client.getForEntity
import org.springframework.web.util.UriComponentsBuilder
@Service
class CustomerService(
private val restTemplate: RestTemplate
) {
fun get(): CustomerRes {
val uri = UriComponentsBuilder.fromUriString("http://localhost:8081")
.path("customer")
.toUriString()
val response: ResponseEntity<CustomerRes> = restTemplate.getForEntity(
uri,
CustomerRes::class
)
return response.body!!
}
}
data class CustomerRes(
val value: String
)
import org.apache.commons.logging.LogFactory
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class CustomerController(
private val customerService: CustomerService
) {
private val logger = LogFactory.getLog(CustomerController::class.java)
@RequestMapping("/customer")
fun get(): HelloRes {
logger.info("get() has been called")
val result = customerService.get()
return HelloRes(
result.value
)
}
class HelloRes(
val value: String
)
}
spring:
application:
name: api-service customer-service # Zipkin に送信されるサービス名。同一のサービスと認識されてしまう為、一意である必要がある
management:
tracing:
sampling:
probability: 1.0 # トレース情報の送信割合。1.0 で全てのトレース情報が送信される
logging:
level:
root: INFO
顾客服务的执行
我会创建一个与构成图中的客户服务相对应的应用程序。
build.gradle.kts 文件与api-service相同。
import org.apache.commons.logging.LogFactory
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class CustomerController {
private val logger = LogFactory.getLog(CustomerController::class.java)
@GetMapping("/customer")
fun get(): CustomerRes {
logger.info("get() has been called")
return CustomerRes("AAA株式会社")
}
class CustomerRes(
val value: String
)
}
spring:
application:
name: api-service customer-service # Zipkin に送信されるサービス名。同一のサービスと認識されてしまう為、一意である必要がある
management:
tracing:
sampling:
probability: 1.0 # トレース情報の送信割合。1.0 で全てのトレース情報が送信される
logging:
level:
root: INFO
启动 Zipkin
docker run -d -p 9411:9411 openzipkin/zipkin
使用Zipkin查看跟踪信息
環境搭建完成后,我们将使用 Zipkin 查看实际的跟踪信息。
我们会多次运行应用程序。
http://localhost:8080/customer
访问 Zipkin。
http://localhost:9411/