当前位置: 首页 > 科技观察

MicroserviceTax和更简单的GrpcMock

时间:2023-03-11 23:12:16 科技观察

现在规模不大的公司基本上都在用微服务,后端工程师在大大小小的公司打零工都会遇到。因为是微服务,在做开发的时候:依赖太多,没有稳定的环境,服务跑不起来,服务要走网络,稳定性问题很难解决。上下游必须解耦。上游每修改一次,下游就会出现故障,出现各种奇形怪状的问题。每个痛点都会涉及到。看到很多相关的解决方案,比如环境问题,之前分享过https://tilt.dev/;稳定性问题,直接上谷歌三部曲https://sre.google/books/;上下游与队列解耦后,上游不稳定的业务事件导致下游故障,可以通过数据校验平台和schemaregistry来缓解。我们在这里只触及了表面,每一个都需要额外的努力来规避。对于正在迁移到微服务的公司来说,这些只是众多问题中的一小部分。对于想要使用微服务的公司,你需要了解微服务税的概念:它是你为获得分布式应用架构的实质性收益而付出的成本。K8s、可观察性基础设施、监控和底层框架,都是除了研发成本之外,还需要额外的成本。幸运的是,现在有了CNCF,我们不用再交一些微服务税,可以直接使用现成的基础设施(虽然这所谓的免费午餐不是很好吃。在众多问题中,最重要的是是框架的问题,对于Go语言的生态,目前还没有像java生态的springcloud一样最被大家认可的解决方案,框架在微服务技术架构中起着承上启下的作用:必须是负责对接公司内的基础设施,对业务方尽量屏蔽这些基础设施的差异,业务研发只需要写逻辑,其他问题不需要关心,另一方面框架本身应该也协助业务减少重复代码的编写次数,比如根据协议IDL生成协议/控制层代码,根据协议IDL生成相关接入功能代码ding到用户预定义的SQL都是众所周知的例子。看起来没什么技术含量,但是为什么现在市面上的框架都有灾难般的体验呢?连那些大公司的开源框架都满是垃圾代码和bug?我和我的同事们仔细分析了这个问题。主要原因是:大公司的框架开发,在不写业务的公司基本都是推广和考核,与框架的用户体验没有直接关系。框架开发人员故意隐藏对他们不利的信息和数据。第一点比较容易理解。大多数写框架的人,可能一行业务代码都没有写过,也没有做过。自然地,很难理解业务受苦的地方。没有同理心,就很难把事情做好。如果你连用户研究都不愿意做,那结果就是自高自大。第二点,大中型公司的考核体系,对于框架组,常用于考核规模和绩效数据指标,如:框架覆盖率、框架与业内其他同类解决方案的优势,以及看似高深的技术点(看你怎么吹),不会评估框架本身的用户体验。可以关注一下贵公司是否会收集公司框架的nps问卷。如果没有,那么大概率是没有考核的。之前在国内的一个巨头公司,因为框架研发组的老大级别很高,所以大家在内网都不敢吐槽,只好跑到脉脉去谈。第三点也是从第二点推导出来的。公司评估这些绩效指标。如果性能指标出现问题,对于框架研发人员的绩效和考核是非常不利的。因此,一些数据是内部测量的。做完就不放了,就是故意对用户隐瞒。这其实不难理解。比如一些hack的性能优化,需要结合业务场景进行严谨的分析,才能知道是否合适。研发人员这样做一般是为了避免在公司内部出现问题,但是在宣传的时候,他们会刻意隐瞒这些优化限制,导致公司外部的人被相应的宣传误导,而跟进走弯路。所以这就是为什么我建议大家在使用大公司的开源技术方案时,应该多自己做性能测试。好像扯了一些废话,还是要说点干货的。最近接受了Ant原质量同事的教育,了解到在领域做自动化测试时对服务外部依赖的mock需求:如上图,自动化测试脚本对下面的服务发起测试测试,希望看被测服务是否能处理各种外部依赖正常/异常的过程,此时希望被测服务的外部服务(即serv_a、serv_b、serv_c)的返回结果可以在不影响被测代码的情况下更改依赖。在java中,有jvm-Sandbox这个神器,可以方便的隔离测试,动态修改类实现,但是在Go中,这个需求并不容易实现。刚好公司目前正在大规模推行go-zero,所以我们和go-zero社区的同学合作,想了一些办法来解决这个问题。接下来修改对外服务的行为,这让我们想起了一些日常工作中使用的代理服务,所以我们在中间添加一个代理。该代理可以与自动化测试脚本进行交互,脚本可以设置相应的服务、请求和响应匹配规则,可以实现casebycase请求响应匹配/隔离,即可以动态测试serv_a、serv_b、serv_c服务被嘲笑。因为公司默认使用grpc,所以目前市面上所有的mock都需要用户提供pb,没办法动态设置。对grpc比较熟悉的同学都知道grpcurl工具为我们提供了describe功能。我们可以使用grpcdesc查看服务的定义。当然,前提是服务开启了反射。如果可以通过反射获取服务定义,我们就不需要再要求用户提供原始的pb定义了。