问题描述:
最近在使用 node 构建一个数据处理系统,涉及到的模块较多,因此打算采用微服务架构,目前使用了一个微服务框架 Seneca,采用 tcp 进行通信。
Seneca 微服务主要负责和db通信、以及数据处理计算(不是很耗时的计算)。
这里大部分数据处理计算的工作都可以延时完成,但是前端 http 的返回和其中的一部分工作比如数据库查询工作有关,所以需要等待某些微服务模块有返回结果了(或返回部分结果了)再返回给前端。 于是我通过ab测试发现:采用 Seneca 的方式比原来各个模块写在一起直接引入的方式,效率要低好多,比较坏的情况下,甚至平均响应时间是原来的 1.5 倍。 这个也不难理解,毕竟会有通信的开销,还可能因为采用了 Seneca 造成其他的隐形成本。
我现在有点迷茫,采用了微服务的话,可以使模块之间解藕,对开发有一定方便,但是却会降低效率,感觉有些得不偿失。 我对微服务的理解也并不深刻,只是觉得能在代码维护上给这种单体系统带来好处,另外就是微服务的单个服务方便扩容。
是不是我的使用方式不对?还是说微服务本来就有降低效率这个问题?各位是如何解决的呢?希望能指点一二。
这里大部分数据处理计算的工作都可以延时完成,但是前端 http 的返回和其中的一部分工作比如数据库查询工作有关,所以需要等待某些微服务模块有返回结果了(或返回部分结果了)再返回给前端。
你不拆分,不也一样要等待数据库查询返回?
于是我通过ab测试发现:采用 Seneca 的方式比原来各个模块写在一起直接引入的方式,效率要低好多,比较坏的情况下,甚至平均响应时间是原来的 1.5 倍。 这个也不难理解,毕竟会有通信的开销,还可能因为采用了 Seneca 造成其他的隐形成本。
无度量不优化,不要凭空猜测,你有没有打点去进一步分析下,到底耗时在哪一步?
@atian25 拆分之前的话,是响应函数直接去连数据库,而加了微服务之后,是响应函数先要去和微服务通信,然后微服务模块去查数据库,有结果了再通信返回结果。
ab测试这块,我目前做的是做对比测试,在请求返回函数中只把单个数据处理函数替换掉(微服务初始化过程等不涉及),处理数据的耗时是相同的,但是一个是自己处理一个是在微服务那边。 多出的时间,我认为是花在通信上了,的确没有深入 Seneca 内部去打点。 另外,使用微服务的话压测的结果长时间的链接也变多了(数据库是没问题的)
1.5 倍是比较笼统的结果,由于数据处理系统接收的数据太大,一小时可能就有几百万条,所以对处理数据时间要求比较高… 我是担心微服务通信的成本在这里被放大,不知道自己的担心是不是多余。。
微服务本来就是高成本的玩意。不说通讯了,就这么多容器开在机子上就很费资源。 但是想要符合程序设计美学,低成本,还方便水平扩展的后端服务设计思想基本不存在。而微服务除了成本较高外,基本达到了另外两点。 有钱就放心用,流量来了拿机器磕就完事,还省事。
来自酷炫的 CNodeMD
同一个内网下机器间通信在3ms范围内,排除微服务架构之间的协议握手,延时10ms级别应该也可以接受。但是像你这个情况,建议先排查下自己机器内网的rt,还是这样的话可以考虑换个框架了。
@royalrover 通讯成本有很多个方面,万一哪个二货设计了一个返回数据超过2M的接口,假设1秒20000人访问,网卡就要吞吐40G/s,你慌不慌。
@zy445566 不是微服务也可以有这种二货啊
https://github.com/notadd/notadd 我们在开源一套微服务架构。 并且在生产环境已经有使用。欢迎一起开发
微服务本身维护成本较高,并且是有性能损失的。 网络通信这块,rpc 基于TCP协议的,都是长连接,性能损失不至于有那么大。但是肯定是有性能损失的。
@zuohuadong 谢谢,我会开始关注
@aircloud 除了打点分析外,这样空猜测是没有意义的。
从我们大规模使用的数据来看,网络 RT 这个一般很小,RPC 序列化这里是一个核心优化点。(但一般你们业务量级很少需要扣这点,性能也不可能到 1.5 去的)
@zuohuadong 单测都没耐性加,就急着往外推了?
@ImHype 缺的东西还不少,微服务的服务发现,服务治理,服务熔断也没实现。 目前也只是 alpha 用作单机测试。 不得不说,node 这块确实缺失生态。 如果有兴趣的话,欢迎一起提交代码;
@zuohuadong 干嘛不直接用k8s。没必要跟JAVA一样什么都自己实现吧
@zy445566 肯定是要基于 k8s 来搞,目前主要工作在服务层,我们想提供开箱即用的体验
@zuohuadong 666
来自酷炫的 CNodeMD
我想我明白你的意思,我们的也是微服务。主要问题应该是微服务之间存在数据关联,需要相互调用,主要是之前本来可以SQL查询的变成了API调用,这样的话导致主要的服务或者说是最频繁被依赖的那个service压力增大,也就是之前是数据库压力转变成了该service的压力,从而不得不堆机器。