本文主要研究一下skywalking的SamplingService
skywalking-6.6.0/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/sampling/SamplingService.java
@DefaultImplementor
public class SamplingService implements BootService {
private static final ILog logger = LogManager.getLogger(SamplingService.class);
private volatile boolean on = false;
private volatile AtomicInteger samplingFactorHolder;
private volatile ScheduledFuture<?> scheduledFuture;
@Override
public void prepare() throws Throwable {
}
@Override
public void boot() throws Throwable {
if (scheduledFuture != null) {
/**
* If {@link #boot()} invokes twice, mostly in test cases,
* cancel the old one.
*/
scheduledFuture.cancel(true);
}
if (Config.Agent.SAMPLE_N_PER_3_SECS > 0) {
on = true;
this.resetSamplingFactor();
ScheduledExecutorService service = Executors
.newSingleThreadScheduledExecutor(new DefaultNamedThreadFactory("SamplingService"));
scheduledFuture = service.scheduleAtFixedRate(new RunnableWithExceptionProtection(new Runnable() {
@Override
public void run() {
resetSamplingFactor();
}
}, new RunnableWithExceptionProtection.CallbackWhenException() {
@Override public void handle(Throwable t) {
logger.error("unexpected exception.", t);
}
}), 0, 3, TimeUnit.SECONDS);
logger.debug("Agent sampling mechanism started. Sample {} traces in 3 seconds.", Config.Agent.SAMPLE_N_PER_3_SECS);
}
}
@Override
public void onComplete() throws Throwable {
}
@Override
public void shutdown() throws Throwable {
if (scheduledFuture != null) {
scheduledFuture.cancel(true);
}
}
/**
* @return true, if sampling mechanism is on, and getDefault the sampling factor successfully.
*/
public boolean trySampling() {
if (on) {
int factor = samplingFactorHolder.get();
if (factor < Config.Agent.SAMPLE_N_PER_3_SECS) {
boolean success = samplingFactorHolder.compareAndSet(factor, factor + 1);
return success;
} else {
return false;
}
}
return true;
}
/**
* Increase the sampling factor by force,
* to avoid sampling too many traces.
* If many distributed traces require sampled,
* the trace beginning at local, has less chance to be sampled.
*/
public void forceSampled() {
if (on) {
samplingFactorHolder.incrementAndGet();
}
}
private void resetSamplingFactor() {
samplingFactorHolder = new AtomicInteger(0);
}
}
skywalking-6.6.0/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManagerExtendService.java
@DefaultImplementor
public class ContextManagerExtendService implements BootService {
@Override public void prepare() {
}
@Override public void boot() {
}
@Override public void onComplete() {
}
@Override public void shutdown() {
}
public AbstractTracerContext createTraceContext(String operationName, boolean forceSampling) {
AbstractTracerContext context;
int suffixIdx = operationName.lastIndexOf(".");
if (suffixIdx > -1 && Config.Agent.IGNORE_SUFFIX.contains(operationName.substring(suffixIdx))) {
context = new IgnoredTracerContext();
} else {
SamplingService samplingService = ServiceManager.INSTANCE.findService(SamplingService.class);
if (forceSampling || samplingService.trySampling()) {
context = new TracingContext();
} else {
context = new IgnoredTracerContext();
}
}
return context;
}
}
SamplingService在Config.Agent.SAMPLE_N_PER_3_SECS大于0时会注册一个定时任务定时重置samplingFactorHolder为0;它还提供了它还提供了trySampling方法给外部调用,该方法在samplingFactorHolder小于Config.Agent.SAMPLE_N_PER_3_SECS时,执行samplingFactorHolder.compareAndSet(factor, factor + 1);forceSampled方法则在on的前提下执行samplingFactorHolder.incrementAndGet();ContextManagerExtendService的createTraceContext会通过ServiceManager.INSTANCE.findService然后在forceSampling或者samplingService.trySampling()为true时返回TracingContext,其余的返回IgnoredTracerContext
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。