ShardingSphere与链路追踪

举报
周杰伦本人 发表于 2022/11/29 17:43:02 2022/11/29
【摘要】 ShardingSphere与链路追踪本篇文章源码基于4.0.1版本ShardingSphere的功能非常强大,它不仅与注册中心、配置中心相结合的很好,它还支持链路追踪,了解过链路追踪技术的肯定对TraceId、Span这些概念有所了解,TraceId可以看做一个全局的id,用来定位一条请求的来和去,途经的服务有哪些,而span可以看做是这个链路中调用这个服务的开始和结束的这个阶段。sha...

ShardingSphere与链路追踪

本篇文章源码基于4.0.1版本

ShardingSphere的功能非常强大,它不仅与注册中心、配置中心相结合的很好,它还支持链路追踪,了解过链路追踪技术的肯定对TraceId、Span这些概念有所了解,TraceId可以看做一个全局的id,用来定位一条请求的来和去,途经的服务有哪些,而span可以看做是这个链路中调用这个服务的开始和结束的这个阶段。

sharding-opentracing模块是ShardingSphere与链路追踪整合的部分,模块中给出了一些测试示例,在使用的时候首先调用ShardingTracer的init()方法进行初始化操作

我们不妨看一下这一部分,

初始化跟踪器

ShardingTracer的init()方法:

    public static void init() {
        String tracerClassName = System.getProperty(OPENTRACING_TRACER_CLASS_NAME);
        Preconditions.checkNotNull(tracerClassName, "Can not find opentracing tracer implementation class via system property `%s`", OPENTRACING_TRACER_CLASS_NAME);
        try {
            init((Tracer) Class.forName(tracerClassName).newInstance());
        } catch (final ReflectiveOperationException ex) {
            throw new ShardingException("Initialize opentracing tracer class failure.", ex);
        }
    }
  1. 从系统的环境变量中获取跟踪器的类名,常量的值是org.apache.shardingsphere.opentracing.tracer.class,如果设置Skywalking的话就设置这个key的值为org.apache.skywalking.apm.toolkit.opentracing.SkywalkingTracer,也就是类的全限定名
  2. 检测类名是否为空
  3. 调用init()方法,这里传入的参数是根据类名通过反射创建的实例,这个init()方法就是调用GlobalTracer的register()方法注册跟踪器。GlobalTracer类的成员变量就是Tracer,注册的实质就是设置Tracer的值,GlobalTracer这个类使用了单例模式

Span的操作

sharding-opentracing模块中一个hook的包,这个包中有三个类OpenTracingParsingHook、OpenTracingRootInvokeHook和OpenTracingSQLExecutionHook

解析Hook

OpenTracingParsingHook用于生成sql解析过程中链路数据span,接口是ParsingHook,start()方法中构建span,设置tag标签,finishSuccess()方法是成功了结束span方法,finishFailure()方法是解析失败设置错误信息给span,span完成的方法

使用示例:

private final ParsingHook parsingHook = new SPIParsingHook();
    
    @BeforeClass
    public static void registerSPI() {
        NewInstanceServiceLoader.register(ParsingHook.class);
    }
    
    @Test
    public void assertExecuteSuccess() {
        parsingHook.start("SELECT * FROM XXX;");
        parsingHook.finishSuccess(mock(SQLStatement.class));
        MockSpan actual = getActualSpan();
        assertThat(actual.operationName(), is("/ShardingSphere/parseSQL/"));
    }

路由Hook

OpenTracingRootInvokeHook用于生成sql路由过程中链路数据span

使用示例:

    private final RootInvokeHook rootInvokeHook = new SPIRootInvokeHook();
    
    @BeforeClass
    public static void registerSPI() {
        NewInstanceServiceLoader.register(RootInvokeHook.class);
    }
    @Test
    public void assertRootInvoke() {
        rootInvokeHook.start();
        assertTrue(ShardingExecuteDataMap.getDataMap().containsKey(OpenTracingRootInvokeHook.ACTIVE_SPAN_CONTINUATION));
        rootInvokeHook.finish(1);
    }

Sql执行Hook

OpenTracingSQLExecutionHook用于生成SQL执行过程中的数据链路span

    private final SQLExecutionHook sqlExecutionHook = new SPISQLExecutionHook();
    
    @BeforeClass
    public static void registerSPI() {
        NewInstanceServiceLoader.register(SQLExecutionHook.class);
    }
    @Test
    public void assertExecuteSuccessForTrunkThread() {
        DataSourceMetaData dataSourceMetaData = mock(DataSourceMetaData.class);
        sqlExecutionHook.start("success_ds", "SELECT * FROM success_tbl;", Arrays.<Object>asList("1", 2), dataSourceMetaData, true, null);
        sqlExecutionHook.finishSuccess();
    }

这里所有的Hook实例的加载都是用来JDK的SPI机制,三个Hook方法都有响应的开始span和结束span的方法实现,使用的时候也大致相同

总结

这篇文章我们将了ShardingSphere与链路追踪技术的相结合,主要是怎么进行初始化配置的Tracer跟踪器和在SQL解析路由和执行过程中的span的操作、链路跟踪。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。