Springboot实现微服务监控

  1. org.apache.skywalking:apm-toolkit-trace:

    • 用途: 这是 Apache SkyWalking 的一个工具包,用于追踪和监控微服务架构的应用。它提供了一种简单的方式来为 Java 应用程序插入追踪逻辑,帮助开发者收集应用执行的性能数据。
    • 功能: 包括分布式追踪、性能分析、错误监控等。开发者可以通过这个工具包将追踪数据发送到 SkyWalking 的后端服务,后端服务会对这些数据进行处理和可视化。
  2. com.alibaba.arms.apm:arms-sdk:

    • 用途: 这是阿里巴巴的 APM SDK,目的是为了监控和分析应用的性能,尤其是在分布式应用和微服务架构中。它提供了一套完整的 API,用于记录性能数据和上下文信息。
    • 功能: 包括事务追踪、业务监控、错误日志收集等,可以帮助开发者理解业务请求的流转情况和性能瓶颈。

总的来说,这两个依赖库都是为了帮助开发者监控和优化应用程序的性能,不同的是它们分别来源于不同的开源项目。使用这些工具可以使开发者更准确地了解和提高应用的运行效率。

1. 引入依赖

xml 复制代码
<dependency>
    <groupId>com.alibaba.arms.apm</groupId>
    <artifactId>arms-sdk</artifactId>
    <version>1.7.5</version>
</dependency>
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <version>8.7.0</version>
    <scope>provided</scope>
</dependency>

2 .TraceCtx抽象类

主要用于实现分布式追踪(Tracing)的上下文管理。分布式追踪是一种记录请求在微服务或不同系统之间流动的方式,用来分析和监控系统的性能和行为。

  • 该类采用了工厂模式(Factory Pattern),根据环境动态选择合适的追踪上下文实现。
java 复制代码
public abstract class TraceCtx {

	private static TraceCtx traceCtx;

	static {
		if (ClassUtils.isPresent("com.alibaba.arms.tracing.Tracer", null)) {
			traceCtx = new ArmsTraceCtx();
		} else
			if (ClassUtils.isPresent("org.apache.skywalking.apm.toolkit.trace.TraceContext", null)) {
			traceCtx = new SkywalkingTraceCtx();
		} else {
			traceCtx = new PseudoTraceCtx();
		}
	}

	public static TraceCtx get() {
		return traceCtx;
	}

	public abstract String traceId();

	public abstract String spanId();

	public abstract String segmentId();

	public abstract void tag(String key, String value);

	public abstract void putCorrelation(String key, String value);

	public abstract Runnable traceRunnable(Runnable r);

	public abstract <V> Callable<V> traceCallable(Callable<V> c);
}
2.1. ArmsTraceCtx实现类

用于与阿里巴巴的 ARMS(应用性能管理与服务监控)工具集成,提供分布式追踪的上下文管理功能。

java 复制代码
import com.alibaba.arms.sdk.v1.async.TraceCallable;
import com.alibaba.arms.sdk.v1.async.TraceRunnable;
import com.alibaba.arms.tracing.Span;
import com.alibaba.arms.tracing.Tracer;

import java.util.concurrent.Callable;

public class ArmsTraceCtx extends TraceCtx {

	@Override
	public String traceId() {
		Span span = Tracer.builder().getSpan();
		return span.getTraceId();
	}

	@Override
	public String spanId() {
		return "Arms-1";
	}

	@Override
	public String segmentId() {
		Span span = Tracer.builder().getSpan();
		return span.getRpcId();
	}

	@Override
	public void tag(String key, String value) {
		Span span = Tracer.builder().getSpan();
		span.setTag(key, value);
	}

	@Override
	public void putCorrelation(String key, String value) {
	}

	@Override
	public Runnable traceRunnable(Runnable r) {
		return TraceRunnable.asyncEntry(r);
	}

	@Override
	public <V> Callable<V> traceCallable(Callable<V> c) {
		return TraceCallable.asyncEntry(c);
	}
}
2.2. SkywalkingTraceCtx实现类

用于与 Apache SkyWalking 进行集成的类,它用于处理和管理分布式追踪上下文(Trace Context)。

java 复制代码
import org.apache.skywalking.apm.toolkit.trace.ActiveSpan;
import org.apache.skywalking.apm.toolkit.trace.CallableWrapper;
import org.apache.skywalking.apm.toolkit.trace.RunnableWrapper;
import org.apache.skywalking.apm.toolkit.trace.TraceContext;


import java.util.concurrent.Callable;

public class SkywalkingTraceCtx extends TraceCtx {

	@Override
	public String traceId() {
		return TraceContext.traceId();
	}

	@Override
	public String spanId() {
		return TraceContext.spanId() + "";
	}

	@Override
	public String segmentId() {
		return TraceContext.segmentId();
	}

	@Override
	public void tag(String key, String value) {
		ActiveSpan.tag(key, value);
	}

	@Override
	public void putCorrelation(String key, String value) {
		TraceContext.putCorrelation(key, value);
	}

	@Override
	public Runnable traceRunnable(Runnable r) {
		return RunnableWrapper.of(r);
	}

	@Override
	public <V> Callable<V> traceCallable(Callable<V> c) {
		return CallableWrapper.of(c);
	}
}
2.3. PseudoTraceCtx实现类

用于模拟或占位的追踪上下文实现,可以用于测试或验证代码逻辑而不依赖于实际的追踪系统。

java 复制代码
import java.util.concurrent.Callable;

public class PseudoTraceCtx extends TraceCtx {

    @Override
    public String traceId() {
        return "Pseudo-1";
    }

    @Override
    public String spanId() {
        return "Pseudo-1";
    }

    @Override
    public String segmentId() {
        return "Pseudo-1";
    }

    @Override
    public void tag(String key, String value) {
    }

    @Override
    public void putCorrelation(String key, String value) {
    }

    @Override
    public Runnable traceRunnable(Runnable r) {
        return r;
    }

    @Override
    public <V> Callable<V> traceCallable(Callable<V> c) {
        return c;
    }

}

3. 线程工厂

java 复制代码
public class NamedThreadFactory implements ThreadFactory {

    protected static final AtomicInteger POOL_SEQ = new AtomicInteger(1);
    protected final AtomicInteger mThreadNum;
    protected final String mPrefix;
    protected final boolean mDaemon;

    public NamedThreadFactory() {
        this("pool-" + POOL_SEQ.getAndIncrement(), false);
    }

    public NamedThreadFactory(String prefix) {
        this(prefix, false);
    }

    public NamedThreadFactory(String prefix, boolean daemon) {
        this.mThreadNum = new AtomicInteger(1);
        this.mPrefix = prefix + "-thread-";
        this.mDaemon = daemon;
    }

    public Thread newThread(Runnable runnable) {
        String name = this.mPrefix + this.mThreadNum.getAndIncrement();
        Thread ret = new Thread(runnable, name);
        ret.setDaemon(this.mDaemon);
        return ret;
    }
}

4. 线程池参数

java 复制代码
@Data
@Configuration
@ConfigurationProperties(prefix = "thread.pool")
public class ThreadPoolProperties {

    private PoolVo poolVo = new PoolVo();

    @Data
    @Configuration
    public class PoolVo {
        private boolean enabled = true;
        private String namePrefix = "ol-threadPool";
        private int coreSize = 200;
        private int maxSize = 200;
        private long keepAliveSeconds = 600;
        private int queueSize = 100;
    }
}

5. 线程池配置类

java 复制代码
@Slf4j
@Configuration
public class ThreadPoolConfig {

    @Autowired
    private ThreadPoolProperties threadPoolProperties;

    @ConditionalOnProperty(value = "thread.pool.poolVo.enabled", havingValue = "true")
    @Bean(name = "oldThreadPoolExecutor")
    public ThreadPoolExecutor olRvdcThreadPoolExecutor() {
        ThreadPoolProperties.PoolVo poolVo = threadPoolProperties.getPoolVo();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(poolVo.getCoreSize(), poolVo.getMaxSize(), poolVo.getKeepAliveSeconds(), TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory(poolVo.getNamePrefix()),
                new ThreadPoolExecutor.AbortPolicy());
        log.info("======================= ThreadPool initialize success. =======================");
        return threadPoolExecutor;
    }
}

6. 使用示例

java 复制代码
@RestController
public class DemoController {

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @GetMapping("/test")
    public void test() {
        Runnable runnable = TraceCtx.get().traceRunnable(() -> {
                for (int i = 0; i < 10; i++) {
                    System.out.println("i = " + i);
                }
        });
        System.out.println(runnable);
        threadPoolExecutor.execute(runnable);
    }
}
相关推荐
freejackman6 小时前
Java从0到1---基础篇
java·开发语言·后端·idea
无心水7 小时前
20、Spring陷阱:Feign AOP切面为何失效?配置优先级如何“劫持”你的设置?
java·开发语言·后端·python·spring·java.time·java时间处理
0xDevNull7 小时前
Java 21 新特性概览与实战教程
java·开发语言·后端
Gse0a362g7 小时前
Go - Zerolog使用入门
开发语言·后端·golang
Renhao-Wan7 小时前
Docker 核心原理详解:镜像、容器、Namespace、Cgroups 与 UnionFS
java·后端·docker·容器
EFCY1MJ908 小时前
ASP.NET MVC 1.0 (五) ViewEngine 深入解析与应用实例
后端·asp.net·mvc
小江的记录本8 小时前
【RabbitMQ】RabbitMQ核心知识体系全解(5大核心模块:Exchange类型、消息确认机制、死信队列、延迟队列、镜像队列)
java·前端·分布式·后端·spring·rabbitmq·mvc
小江的记录本9 小时前
【RocketMQ】RocketMQ核心知识体系全解(5大核心模块:架构模型、事务消息两阶段提交、回查机制、延迟消息、顺序消息)
linux·运维·服务器·前端·后端·架构·rocketmq
却话巴山夜雨时i9 小时前
Java大厂面试:从Spring Boot到微服务的深度剖析
java·spring boot·spring cloud·微服务·分布式事务·大厂面试
zs宝来了9 小时前
Dubbo SPI 机制:ExtensionLoader 原理深度解析
微服务·dubbo·spi·源码解析·extensionloader