为什么Dubbo这么老的项目还要用Go重写?

诞生于阿里巴巴,2011年开源的dubbo已经走过了10个年头。在2019年,它被用go重写并开源,如今两年过去,已经从当初的v1.0.0版本发展到了v3.0.0,截止目前star数3.8k。
有一次同事问我,为什么dubbo这么老的项目还要用go重写,有什么现实意义吗?
今天就来谈谈我的一些看法。
连接过去和未来
我觉得要回答好这个问题,得从dubbo-go的初衷谈起,github主页上它是这样介绍自己的:
官方给出的中文翻译是
apache dubbo go 语言实现,架起 java 和 golang 之间的桥梁,与 grpc/dubbo 生态互联互通,带领 java 生态享受云原生时代的技术红利。
我再通俗地翻译一下:一个公司或部门内有人用java版dubbo,有人用go,这两者需要通信,于是就有了dubbo-go,用来解决通信问题。
所以第一个问题来了,为什么一个公司用了java,又用了go?
编程语言的抉择
对于编程语言的选择,在商业公司里,我觉得最最主要考虑的点就是效率,至于其他的点都是次要。因为商业公司的主要目的就是盈利,不管什么语言,只要能用最低的成本拿到相等的收益就是好语言。
效率又包含了好几个方面:
开发效率。开发效率高,项目能早日上线,占领市场,也能节约人力成本
运行效率。运行效率高,能省下服务器成本
纵观国内很多商业公司的选择都是如此考虑,比如阿里。
阿里早期是php,选择php的考量点主要是开发效率,但随着业务的发展,php的性能无法支撑,必须得换一个运行效率高的语言。
运行效率高自然想到c/c++,但这两个语言的开发效率低,得在开发效率和运行效率中找到一个平衡点,于是阿里选择了java。
阿里官方在知乎上回答为什么选择java时,主要有以下几点考虑:性能、简单易学、生态丰富、社区活跃
把性能放第一位,简单易学、生态丰富、社区活跃其实也都是说的开发效率,正是有了这些优点,开发效率才高。
当阿里巴巴选择java后,自研了大量的java中间件,培养了大量的java人才,所以其他公司在技术选型时,也参考了阿里巴巴,导致越来越多的公司选择了java。
而选择go也是如此,一些年轻的公司早期可能是php、python等脚本语言,等发展壮大后,不得不面临和阿里一样的问题:性能问题。
在2012年go发布了,大家又多了一个选择,go既有很高的性能,又非常地简单易上手,像字节跳动这类新公司就以go为主。
所以综合来看,选择java或者go都是合理的,存在即合理。
为什么有公司选择了java,又想用go呢?
go语言相比java有启动快,编译速度快、占用内存小、擅长高并发(协程)的特性,所以在已经有java的公司,也会考虑go,只不过目前这类公司占比不多。
某些公司没有强制的技术栈,所以新部门新业务可以摆脱束缚,选择新语言go来进行开发。
小结
综上看来,选择java或选择go都合理,一个公司内两者都选择,也有合理之处,虽然占比不多,但还是有java和go通信的需求。
dubbo在rpc框架中的胜出
公司早期通常是单体服务,在规模达到一定程度,单体应用无法支撑业务发展时,会选择微服务架构,这时就需要一个好用的rpc框架。
能适配java语言的rpc框架中,dubbo是国内最早开源,于2011年开源。
而和他类似的竞品如spring cloud在2014年开源,微博的motan在2017年开源,跨语言的grpc在2015年开源,thrift 2007年开源。
只有thrift 比它早,但thrift只是个rpc框架,dubbo可是包含了开箱即用的服务治理能力,如服务注册与发现、负载均衡、容错、动态配置等等。
可以说早期java的rpc框架没得选。
就算到了rpc框架百花齐放的时代,这么多公司的使用加上阿里的背书,dubbo也有它的一席之地。
小结
当一个公司选择了java编程语言和dubbo框架(这种选择还是挺多的),后来又想尝试go,或者一些新业务、新部门想尝试go时,他们就面临了一个难题,go如何跟java的dubbo通信。
由于dubbo协议是私有协议,用go重新实现一遍的代价还是挺大。于是dubbo-go应运而生,从这个角度看,dubbo-go在连接java和go的通信这条路上还是具有相当大的价值的。
终结与线程池的斗争
如果使用了dubbo框架,很多时候需要一个dubbo网关,关于dubbo网关可以参考我这篇文章:《微服务网关演进之路》。
在这篇文章中,详细介绍了一款dubbo网关的背景、难点、选型、设计、演进以及踩坑经历,其中我花了大篇幅介绍了「与线程池所做的斗争」,在java中,线程是很宝贵的,但dubbo网关如果是同步调用,必须一个请求占用一个线程,这就导致并发上不去,而且线程池打满后,会影响其他请求。
所以解决方案要么是隔离线程池,要么改成异步调用。隔离线程池只解决了请求不相互影响,但并发还是上不去,改成异步调用可以完美解决,但是编码实在是太复杂。
而go的协程可以刚好解决这个问题,go的协程很轻量,调度效率也更高,所以我们可以用简单的代码写出非常高效率的网关。
举个例子可以直观感受一下,nginx的性能大家有目共睹,但如果用java来实现,不知道得堆多少机器才能达到nginx的性能,但百度在反向代理上使用了go写的bfe来代替nginx,可见其性能有多夸张。
小结
所以在dubbo网关上,dubbo-go也提供了一种新的解法,已经有用于线上的dubbo-go网关,开源项目可参考dubbo-go-pixiu。
为dubbo mesh铺路
service mesh也渐渐成为了下一代微服务架构,go在mesh上也绝对是一个闪亮的明星语言,无论是k8s、docker等云原生基础设施都采用go编写,还是go的开发速度以及协程的高并发能力,都使它成为了mesh的首选语言。
基于此,dubbo的mesh化,dubbo-go也为其铺平了道路,但目前dubbo mesh还处于小面积阶段,完整落地的方案并没有开源,从这点上来说,如果某公司想走dubbo mesh化之路,dubbo-go可能也是他们要着重考虑的点之一。
总结
说了这么多,该正面回答dubbo为什么要用go重写,这个问题的答案还是官方给出的那句话:架起 java 和 golang 之间的桥梁。至于为什么要「架起这座桥梁」,参考下图:


如何解读小米突然转换股份?
照明装置的检查项目盘点
什么是惯导模块?惯导模块有什么用?
压力试验机的组成部分
欧瑞博再获“地产数字力 TOP20 科技领军企业”殊荣
为什么Dubbo这么老的项目还要用Go重写?
Cargo如何访问世界上最强大的3D库
东芝为工控设备提供的九款通过UL 508认证的光继电器资料说明
微处理器温度控制模拟计算阶段功能块
福布斯发布第33期年度全球亿万富豪榜,马化腾进入TOP20的理由是什么?(附名单)
DC/DC步降变换器控制器ADP186的引脚功能、工作原理及应用分析
嵌入式系统在电网远程监控中的应用
大数据带给营销的十大主要价值
如何做好服务器安全的监控工作
一起聊聊屏蔽和EMC的故事
GNSS位移监测站的应用领域
苹果和三星的专利之争再起狼烟
美国法院判高通公司必须授权一些专利给芯片竞争对手
“小众逼格派”SUV中的捷豹F-PACE堪称贵族撩妹神器
FPGA在多进制正交扩频通信系统中的应用