解析Spring Cloud Sleuth的跟踪数据-示例

2023-04-12 07:32:57 浏览数 (1)

假设我们有一个微服务架构,其中包括两个服务:用户服务和订单服务。当用户下单时,订单服务会向用户服务发送一个请求,获取用户的信息。此时,我们可以使用Spring Cloud Sleuth来跟踪这个请求的整个调用链路,包括每个服务的处理情况和耗时。具体代码如下:

在用户服务中:

代码语言:javascript复制
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;

...

@RestController
public class UserController {

    @Autowired
    private Tracer tracer;

    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) throws InterruptedException {
        Span span = tracer.nextSpan().name("getUser").start();
        try (Tracer.SpanInScope ws = tracer.withSpan(span)) {
            TimeUnit.SECONDS.sleep(1);
            User user = new User();
            user.setId(id);
            user.setName("Alice");
            user.setAge(18);
            return user;
        } finally {
            span.finish();
        }
    }
}

在订单服务中:

代码语言:javascript复制
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.concurrent.TimeUnit;

...

@RestController
public class OrderController {

    @Autowired
    private Tracer tracer;

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/orders/{id}")
    public Order getOrder(@PathVariable Long id) throws InterruptedException {
        Span span = tracer.nextSpan().name("getOrder").start();
        try (Tracer.SpanInScope ws = tracer.withSpan(span)) {
            TimeUnit.SECONDS.sleep(1);
            User user = restTemplate.getForObject("http://localhost:8080/users/"   id, User.class);
            Order order = new Order();
            order.setId(id);
            order.setUser(user);
            return order;
        } finally {
            span.finish();
        }
    }
}

在上面的代码中,我们分别在用户服务和订单服务中使用了Tracer接口来记录每个请求的Trace ID和Span ID,并通过注解和标签记录了请求的开始、结束时间和耗时。当我们访问订单服务时,Spring Cloud Sleuth会自动将Trace ID和Span ID传递给用户服务,并

在订单服务中,我们使用RestTemplate调用用户服务的getUser接口,并将返回的User对象作为Order对象的一个字段。在getUser接口中,我们使用了TimeUnit.SECONDS.sleep(1)来模拟请求的处理时间,以便更好地观察调用链路的情况。

当我们在浏览器中访问http://localhost:8081/orders/1时,我们可以在控制台中看到类似以下的输出:

代码语言:javascript复制
Span name: getOrder
Span begin: 1649145286467
Span end: 1649145287478
Span annotations: [cs=1649145286467, cr=1649145287478]
Span tags: {http.host=localhost, http.method=GET, http.path=/users/1, http.status_code=200, span.kind=client, http.url=http://localhost:8080/users/1}
Span name: getUser
Span begin: 1649145286467
Span end: 1649145287478
Span annotations: [sr=1649145286467, ss=1649145287477, ss=1649145287477, cr=1649145287477]
Span tags: {http.host=localhost, http.method=GET, http.path=/users/1, http.status_code=200, span.kind=server}

在上面的输出中,我们可以看到getOrder和getUser两个Span的开始时间、结束时间和注解信息。我们还可以看到getUser Span的标签信息,其中包括了用户服务的请求路径、请求方法、响应状态码和Span的类型。通过这些信息,我们可以更好地了解整个请求的调用链路和性能情况,方便我们进行性能优化和故障排查。

除了在控制台中输出调用链路信息,我们还可以将这些信息记录到日志文件中,以便更好地跟踪和分析。在Spring Boot应用中,我们可以使用logback等日志框架来记录日志信息。以下是一个logback.xml文件的示例配置:

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/var/log/myapp.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/var/log/myapp.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <logger name="org.springframework.cloud.sleuth" level="DEBUG"/>
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>

在上面的配置中,我们将org.springframework.cloud.sleuth包下的日志级别设置为DEBUG,以便记录Sleuth的调用链路信息。我们还将日志输出到控制台和/var/log/myapp.log文件中,并使用TimeBasedRollingPolicy来进行日志滚动,保留最近7天的日志文件。

0 人点赞