Spring Cloud各个微服务之间为什么要用http交互?难道不慢吗?
先说结论:性能在大规模工程化的时候,或者技术成为流行趋势的时候,永远不是第一顺位的选择。
拿编程语言来说,Java/Golang 一般认为没有Rust/C++快,如果想更快可以直接ASM。但是实际上90%的业务系统,特别是大规模业务系统基本上都是Java来实现的。大型银行核心业务之前的技术栈都是COBOL或C,目前都在转Java了。证券保险类的业务也是这个大趋势。为什么这样呢,一般情况高性能的东西会具有更大的复杂度,一个大型系统如果用汇编语言来写,复杂度和协作程度要严重很多倍,生产率就下降了。
拿出门旅行来说,飞机比较快,战斗机更快,目前还是火车/大巴/自驾为主要方式。开车比电动车和自行车快,但是我在小区附近活动的时候,自行车还是最佳方式。为啥,足够用,足够灵活,性价比高,这往往是比性能更重要的指标。
拿通信协议来说,HTTP肯定比TCP慢,HTTP协议本身有一个变长的头,TCP不需要这个东西,但是反过来,HTTP这个头可以用来做很多扩展性的东西,用TCP就需要一些自己定义一个类似的头,这么来看,TCP的复杂度就上升了。而且HTTP协议作为RCP的底层,一般搭配的JSON数据序列化格式,这个也比一般基于TCP的二进制方式慢一点。但是反过来,1s序列化20万次,跟1s序列化22万次,虽然性能相差了10%,但是我们一次RCP请求里,相对于几ms的网络,几ms的数据库处理,10-200ms这个区间的RT来看,HTTP和JSON序列化的这点性能损失,在99%的场景下可以直接作为误差忽略掉。这就是Spring Cloud/gRPC 之类的使用HTTP协议的原因。
实际上就算在4层网络协议,TCP也不是最快的,UDP更快,之前我们一直说UDP不可靠,实际上稍微封装一下,就可以实现可靠的UDP。
HTTP本身也在发展,从HTTP1.0到keep alive的HTTP 1.1,到后面的HTTP2.0的二进制和复用改进,到HTTP3.0/QUIC 可以基于UDP来实现,就非常快,并且解决了一些TCP的性能问题。并且近些年,HTTP协议作为底层是TCP的一个7层网协议,已经支持一些类似TCP的骚操作了,比如websocket,可以看做是通过一个upgrade指令,借用了HTTP下的TCP通道来实现通信双方的双向二进制通信。Spring对websocket支持的也挺好。
所以有个老话说,脱离场景谈性能都是耍流氓。kimmking:性能也不是万能的,只是我们做出技术选择时的一个指标。