Vert.x与Netty的区别

虽然Vert.x是基于Netty的更高级封装,但它们解决的问题是不太一样的。可以认为Vert.x是Netty的超集,它利用Netty的Eventloop为开发者提供了更友好的编程模型。

Netty解决了如何支撑大量连接的问题

Netty作为一个网络I/O工具,使用起来随时都能清晰的感受到你在操作网络,在操作字节等这些与业务不太相关的东西。很明显,Netty解决的同高吞吐的网络I/O问题,而不是编程问题。我们在使用Netty时,通常都会编写一些ChannelHandler, 先对请求进行解码,封装成任务再投递到我们自己的业务线程池中跑业务,然后再编码响应,调用writeAndFlush()发送响应对客户端。然而,我们的业务线程池中会跑的任务,往往还是那些会阻塞线程的数据库查询、网络I/O等操作,在执行这些操作时,当前的业务线程一直在等I/O完成也会浪费业务线程池的资源。在这种情况下,使用Netty其实只解决了如何用少量线程支撑起大量连接的问题,你连接是建立起来了,但是你的业务处理逻辑并没有因此而变的更快(吞吐量更高)

我们可以再思考一下,平时用的Tomcat这种Servlet容器,其网络I/O也是NIO实现的,那跟Netty其实差不了太多。在你使用同步Servlet的情况下,区别也就在于Servlet有一些规范导致它会笨重一些,然后在调用XXXXStream返回响应时需要block当前线程,而Netty则会先判断当前是否处在指定NIO线程中,如果不是则封装成事件投递到任务队列中等待执行,这样就不会block当前业务线程了。

Vert.x进一步解决了业务编程/工程实现问题

Vert.x在Netty的基础上,提供了对一个工程上对程序员更加友好的封装。

Vert.x鼓励你将JDBC调用、Redis查询、文件I/O等所有可能会导致线程阻塞的操作全都异步化以进一步压榨CPU利用率。为了实现这一点,Vert.x官方就提供了很多常见服务的异步化实现,如jdbc-client, redis-client, mongodb-client, web-client等,用起来就跟node.js一样,都是在发起操作时注册一个回调,当处理完成后回调方法就会得到执行。

与此同时,Vert.x还提供了很多好用的异步协调工具,如CompositeFeature,允许你将多个异步调用组合起来,当满足一定条件时再触发另一个回调,这正是当你尝试用Netty将业务逻辑异步化时Netty所欠缺的组件。

不仅如此,在工程上面Vert.x还提供了"一站式"的工程解决方案, 如Event Bus, 允许你将Verticle部署到多台服务器上(集群),每个实例通过Event Bus通信,甚至还有针对时下流行的微服务架构而准备的注册中心Vert.x Service Discovery, 断路器Vert.x Circuit Breaker等。

在这角度上看,Vert.x是Netty的超集,更加注重解决工程问题,而不仅仅是单纯的网络I/O问题。笔者就曾在业务上遇到过一个需要大量调用HTTP接口的场景。如果使用传统的线程池,则不太可能单实例下支撑起每秒万级的并发数,如果使用Netty,则需要编写大量跟I/O更加接近的"底层"代码,比较繁琐。最后使用Vert.x解决了问题,代码非常简洁,而且性能一样很猛。

那么Vert.x有没有什么劣势?到现在为止,笔者只感受到了一个劣势,就是Vert.x对二进制协议的解析不够友好。因为封装程度较高,导致对二进制协议的解析不够灵活,有时候甚至要使用取巧的方法来实现。因此,如果你是在做以二进制协议为基础的服务端就用,还是不推荐Vert.x,老老实实用Netty吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章