谈最优之前,先排除差的
我所知道的技术搞得差的公司,都有一个特点:技术体系不统一。每个团队各搞各的,语言不一样,架构不一样,部署方式不一样,水平更是参差不齐。
团队之间协作怎么办?大部分情况下服务提供个 Rest 接口,还有的通过数据库互通数据,甚至更夸张的用 FTP 传文件。
最后导致服务无法统一监控,无法构建链路追踪,日志格式都没办法统一,就更别说从中提取有价值的数据了。这种情况下服务治理基本上不可能,建立基本的观测平台也做不到,成本太高。
统一比最优重要
导致这种情况的原因,正是因为最初的妥协和纵容,到后来成了摆脱不掉的「历史包袱」。这些历史包袱还需要不断找人维护,人员越来越多,走的原来越远,最终连重构的可能性都失去了。
这一般源于没有技术自信的 CTO,怕自己所知的那一套不是最优方案,所以宁愿放手让大家自己去尝试,哪种效果最好再大规模应用也不迟。往往到时候才发现走得太远,已经回不了头了。
作为 CTO(或技术负责人),不一定需要知道最优的架构或方案,但一定要坚决防止技术团队各玩各的。
根据我做架构的经验,任何糟糕的架构,都可以演进优化,或者用新的方案逐步替换掉。唯独遇到多种不同的架构,还各有各的问题,这时候要再统一架构难于登天,不如开个新公司重新开始。
次优的选择,要好于多个最优的选择。1 > N。
统一的价值
随便列举几个要统一的东西:
1. 统一语言
Java 语言具有全世界最优的可观测性,可调试性,永远是互联网公司的不二之选。
在统一语言的基础上,可以构建统一的链路追踪,监控指标,动态追踪平台。大家都用 Java,就都可以用 BTrace、Arthas 做线上问题的快速定位。再比如发生问题时,所有人都能理解 NullPointerException
是什么意思。或一旦有什么技术上的优化,可快速应用到所有服务上去。
2. 统一日志
包括统一输出格式、输出方式、日志框架。通过这些,可以为日后搭建日志平台,研发日志分析工具。可以通过日志中埋入 userId、链路 ID 等,跨服务追踪问题。
3. 统一 RPC 调用框架
对 Java 来说,可以闭着眼用 Dubbo 就好了。Dubbo 是对 Java 语言最友好的框架,社区活跃,成熟度高,运维简单。服务的数量级在三五百以下的完全 cover 的住。
绝对不推荐的是 Spring Cloud。
首先,我所知道的任何一个大公司,没有大规模使用 Spring Cloud 的。其次,Spring Cloud 技术栈的组件太多太杂,想要搞懂就已经很难了,大规模使用出现问题要治理起来更复杂。
网上大多数都会分析 RPC 框架的性能优劣什么的。我认为在选型上,性能是最不值得考虑的。更重要的东西反而经常被忽略:
3.1 统一 RPC 接口定义
Dubbo 的接口定义非常友好。在一个公司内,就可以使用同一个项目定义接口,所有服务都将接口定义在一起,统一审批发布。这样可以避免大家对 Dubbo 的理解能力不一致,导致错误的 RPC 接口定义,或者发布一些不兼容的接口变更。
3.2 开发效率
最早使用 Rest 接口做 RPC 调用时,最麻烦的事,就在于对接口,写接口文档,处理接口响应格式。即使大家都用 JSON,对日期的格式可能各有各的想法,或者因为用了不一样的 JSON 库,最终导致一堆莫名其妙的问题,浪费时间。
对 Dubbo 来说,定义了接口直接继承后写代码就好了,调用方和提供方都不用担心序列化的问题。并且对之后换成 gRPC 也留有后路,接口定义改成 proto 就好了。
至于跨语言 RPC 的问题,压根不值得考虑。没有什么情况需要跨语言,当公司的规模大的时候,各方面的设施也在慢慢齐全,再引入另一门语言实际上是一种破坏。
3.3 RPC 接口管理
对 Dubbo 来说,每个接口的提供方调用方都是可以得知的。每个接口可以统计到调用方的次数,要下线或升级接口时,方便通知到服务调用方。
Dubbo 的问题确实有,就是大规模下的性能问题。如果一个接口的提供方有几十个节点,或者某个服务依赖了几十个接口,Dubbo 的模型就有点处理不来了。
比如在系统中有 100 个节点互相依赖,那么每个节点,都需要与其他 99 个节点建立最低 1 条连接,那他们之间就需要建立 99 * 99 条连接。这对系统来说无疑负载很高。更优的架构,当然是通过中间件与节点建立连接,中间件来转发流量,那么理论上整个系统最低只需要 99 * N(中间件的数量) 条连接。是 N x N -> N x M 的优化,连接数不会无限地高。
这种架构同样会带来问题,最显而易见的是内网流量会翻倍。中间件承载了所有南北流量,对性能要求很高,系统整体稳定性也会有所下降。而对中间件的运维监控同样要付出成本。总之是没有最好的架构,解决一个问题,要解决之后带来的更多问题。
4. 统一链路追踪
链路追踪是重要的观测手段,从链路中可以采集到的非常多有价值的数据。
比如在我司统一使用 Skywalking,我们改造了 Skywalking,使之具备配置动态下发,采样外持续追踪的能力,增加采集了线程级别的内存和 CPU,再进一步从链路中分析到了应用的所有行为,从而可以通过监控系统一眼看出问题的根因所在。
想深挖某个技术栈,前提一定是统一。
统一架构的演进法则
统一技术架构,不代表架构僵化,反而有利于架构演进。公司内应该有固定的架构委员会,持续或者定期地,为公司的技术栈和架构保持活力,跟进行业趋势。
本文转载自: 掘金