我参与阿里巴巴 ASoC-Seata 的一些感悟
作者 | 侯志
来源|阿里巴巴云原生公众号
看一看日历
这个不同寻常的 2020 年,马上就要结束了。
这一年,有幸参与阿里巴巴组织 ASoC 活动,有一段让我难忘的不平凡经历。
这一年,却已可以称为是国际开源实习发展历程中不平凡的一年。
参与的起因
初心
Beginner's mind
唯有守得住初心,才能日益精进。
我先来说说 Seata 这个项目的 idea 是怎么来的。一直就有参与开源项目的打算,一个事物的兴起必定或大或小引发一定的问题,微服务就是这样,分布式事务概念泛化的同时,也带来了一个技术问题,微服务架构下分布式数据一致性该如何保证?这几年涌现出不少分布式事务框架,比如 ByteTCC、TCC-transaction、EasyTransaction 以及最近很火爆的 Seata。想要破解罪恶,就必须接近它,甚至成为它。我是去年 8 月份从 GitHub 开始关注 Seata 项目的,初步熟悉后,我觉得它的设计理念非常好,并对它产生了浓厚的兴趣,那个时候就萌发了我要成为这个项目的贡献者。偶然的机会看到 Seata issue,发现了 ASoC 这个活动。
参与的过程
有期待,更美好
Expect better
在参与活动之前我就先从官方文档开始了解过 Seata ,并根据自己的了解,做了一些简单的梳理。看 Seata 源码,继续深入研究,更多的是关注于 SqlParser 模块,在这个过程中,我发现 SqlParser 模块是用 Druid 实现,(Druid 不过多介绍),且 Seata 对于 SqlParser 部分解析功能受限于 Druid,为了方便用户使用,Seata 更加灵活使用数据库语言解析, 有必要扩展一种新的 SqlParser 方案。由于之前有了解过 Antlr,感觉其更加灵活、拓展性更强、层次清晰更易维护。例如 Hive 和 Spark 使用 Antlr 生成词法语法解析器,Twitter 使用 Antlr 来解析用户输入的查询内容,Oracle 把 Antlr 的功能内嵌在 SQL 开发 IDE 中,NetBeans IDE 使用 Antlr 解析 C ++ 语言,也有公司使用 Antlr 来从文件中抽取信息等等...
Antlr 无疑是 Seata SqlParser 另一个更好的选择。于是我想把 Antlr 带到 Seata 中。
迷惑
Confuse
在开发任务期间,Antlr 模块是一个 feature 的实现,涉及 Seata 关于数据库语言解析的一块(有前辈开发者使用 Druid 去处理相关数据库语言数据,因此我进行了 Druid 源码深入研究,基本类似于使用 Antlr 实现一种轻量级别的 Druid),而整个实现过程,太多的地方需要确定,包括实现数据库种类、Antlr 源文件、Antlr 模块划分,以及明确上下游 API 接口等等。在实现解析数据库每种语法语句的时候,比如 Mysql 新增语法,使用 Antlr Visitor 模式,并不兼容查询、修改、删除语法,不断打翻之前的代码,不断调试,甚至导致 Antlr 源文件变动(Antlr 官方提供的源文件过大,改动很头疼)。最终采用 Antlr 两种解析模式去解析。Listener 针对于查询、修改,删除语法包括批量操作,最终问题得以解决。
顿悟
Epiphany
字符串流重写 LA 遍历方法。这里使用 Antlr v4.0.0 字符串流重写 LA 遍历方法,否则大小写转换出错,调用 MySqlLexer 进行词法分析、CommonTokenStream 符号分析、MySqlParser 执行语法规则分析,调用我们自定义的 InsertSpecificationSql,visit 去遍历 Ast 树,把解析出的信息用 MySqlContext 展示。过程很简单,但是在实际过程中可能会遇到很多问题,比如新增语法、查询语法、修改语法、删除语法以及它们语法规则是否有通用性、实现的方法是否可以公用;不同的 sql 语法,是否同一个方法能支持;批量 sql 的话,怎么去处理等等问题。
在解析 mysql 原生 sql 语句时候,遇到这样一个问题,解析出的 sql 明明是对的,Ast 视图树中也正确,但是返回给客户会出现下面这种情况:
原生 sql 居然把空格都给省略掉,一开始我先执行 Ast 树,查询解析结果,发现没有问题,一激灵我想到不是有词法关键词吗,分析时候肯定是基于 Mysql 关键字的,然后把使用到 Mysql 关键词的字符加了空格,重写生成文件,发现是没有问题的。但这词法太多了吧,我都改掉解析会不会出现问题?果真好多解析出现了问题,导致 Seata 生成前后镜像出现问题。遇到事情不能急躁,冷静...它不是有 Ast 树吗,我在它遍历 Ast 树的时候给它加上空格不就好了吗?这样原生的词法文件根本不需要动,也不会引起后续问题,我赶紧阅读起了 Antlr java 源码,功夫不负有心人,果真找到了解决办法,我重写了 visitTerminal 方法:
收获与体会
*思维-编程能力*
Thinking-programming ability
参与 Seata 过程中在社区认识了很多优秀的开发者,这些开发者很多是值得我去学习的,有不理解的地方我的前辈导师包括社区朋友都热心帮我解决。每个阶段完成后,都会有一个小的总结,还参与了 PR Code Review,学习到了开源项目常用的设计模式、SPI 和结构设计等。可以说是学到了优秀的编码习惯和思维方式。
参与到开源项目中并贡献自己的一份力量并没有想象中的难,凡事不要太着急,一步一步、脚踏实地的稳步前进,每天都要有点收获就会不断的成长,开源项目中的大牛很多,参与开源会使自己变得更加谦卑,还会让自己的思维变得更开阔,不会局限于自我。
出色完成工作所带来的成就感,实在是种难以言喻的宝贵体验。还有什么更好的选择能比加入开源项目带来更为广阔的平台?为开源项目作出贡献能够让你体会到从无到有构建成果的满足感,并因此得到承认与感激。必须承认的是,拥有开源软件贡献经历能够让我们的简历变得光彩照人。而朋友们恰好都在使用这款软件,由此带来的激励效果要远远超过每天枯燥完成的业务应用代码。这种感觉很赞,真的很赞。
导师的帮助-*Mentor's help*
季敏(slievrly)前辈是我的导师,从学习 Seata 到第一次提交 Seata pr 期间,前辈总是很耐心地回答我的每一个问题,即使是在他比较忙的时候。有时会自己会问一些比较白痴的问题,他总是细心的给我指点迷津、点出问题所在以及为什么会导致这个问题;有时遇到一些技术方向的问题时,前辈也会给出具有指导性的意见。可以说,一直是他推着我前进,因此在这里感谢前辈的耐心指导,同时也感谢社区张嘉伟大佬、陈健斌大佬、钟正涛大佬在我的编程之夏之旅中提供的帮助。
总结
目前 Seata 已经是 Github 上一个大热的项目,Seata 社区非常活跃,并且在快速更新迭代。项目的技术思想是好的,分布式事务的模式也不止一种,使用方便、高效。本文主要讨论了 Seata 结合 antlr 实现 sqlparser 方面的相关内容,如果有对 Seata 项目或是对 sqlparser 方面、antlr 领域熟悉感兴趣的朋友,期待你们加入 Seata 社区一起交流学习!相信 Seata 会成为万众瞩目的分布式事务解决方案。
版权声明: 本文为 InfoQ 作者【阿里巴巴云原生】的原创文章。
原文链接:【http://xie.infoq.cn/article/fbdd635d3bda5dcd9b4774588】。文章转载请联系作者。
评论