还在用tomcat吗

前言

tomcat一度是web容器的标准,但是tomcat的并发量只有200-400之间,即便现在有了AIO模式,也没提升太多,所以现在大部分都是使用netty作为高性能服务器框架,在dubbo,vert.x,getway等开源项目中都使用了,为什么netty深受开发者喜爱呢

netty对java有着很多改进,并适配了不同版本,不用升jdk版本就实现了相关jdk给你,.netty也封装了java的 nio,简化了代码操作.netty本身也提供了很多附加给你,黑白名单,安全认证等,极大方便了网络的开发

IO模型

阻塞非阻塞
同步BIONIO,多路复用,信号驱动(事件分发)
异步 aio

首先这个问题绕不开io,java有bio,nio,多路复用io,aio

  • 同步:发起一个请求调用后,被调用这处理完请求之前,调用不返回
  • 异步:异步就是发起一个调用之后,立即得到被调用者的会员表示已接收到的请求,但是被调用者并没有返回结果,此时我们可以处理其他请求,被调用者通常依靠时间,会吊灯机制来通知调用者返回结果
  • 阻塞:急速发起一个请求,调用者一直等待请求结果返回,也就是当前线程会被挂起,无从事其他任务,只有当条件就绪才能继续
  • 非阻塞:发起一个请求,调用者不用一直等着返回结果,可以先去干其他的事情

多路复用:使用linux底层的sleect,poll,epoll非阻塞api进行调用

信号驱动:类似事件进行机制,向linux发送系统需要调用信号,系统返回调用信号准备结果,期间主线程还是能接收其他请求过来.当调用信号成功后,等待数据从内核态复制到用户态,最终完成

在java的nio当中,当线程读取数据的时候,没有数据可读取的时候,会立即返回-1给线程,此时线程就知道现在没有多余数据可以读了,线程就可继续往下执行.但是在bio中,一旦没有数据可读取,此时不会返回结果给线程,而是一直阻塞在那里,线程也就无法继续执行代了

nio解决了线程阻塞的问题,就是一旦没有数据可读,就可以往下执行,但是还是有个问题,就是虽然现在没有数据可以读,那么你怎么知道接下来会不会有读写呢?所以一般都是类似于死循环这种模式去读, 读不到就进行下一循环.虽然不是阻塞,但是还是基本上属于一个线程对一个sockt的读写模式

对io多路复用,整体大概是这样的,就是一个或几个线程可以管理一堆socket,socket一旦有读写请求,就会通知你,然后就可以进行io读写操作了.这些都是在操作系统层面.在java中野有这种模型的API封装,比如selector,SocketChannel, ,SocketChannel 可以往 Selector 注册, 一个 Selector 可以管理一堆 SocketChannel ,其实底层最后都是基于操作系统的机制操作的。io多路复用的意思也就是 多个socket 复用一个或多个线程。

所以一般都是nio+io多路复用一起使用的.当一个线程A来管理一堆socket,不断的去选择又可以进行读写操作的socket(Selector的select方法就是干这个事情的),一旦发现有读写(上面说过操作系统会通知你哪些socket有读操作),就将socket交给其他线程去处理,其他线程去处理完了,发现没有读写了,因为是nio所以不会阻塞,可以继续执行,由于有通知机制,所以这个线程不需要一直循环去判断有没有数据需要读取,因为一旦这个socket将来还有数据,还是会通知哒线程A,线程A会再次交给子线程处理.基于这种模型,可以实现一定数量的线程就可以完成一大堆socket的io读写操作

参考你还在用tomcat? out了 - 知乎 (zhihu.com)

undertow

在springboot空间中,使用最多的是tomcat,这是springboot默认的容器技术,而且是内嵌式的tomcat

同时springboot也支持Undertow容器,我们可以很方便的用Undertow替换tomcat.而Undertow的性能和内存使用方面都优于tomcat

在高并发系统中,tomcat相对来说比较弱,在相同机器的配置下,模拟相等的请求数,Undertow在想你和内存方面都是最优的.而且Undertow新版本默认支持链接,这将会进一步提高它的并发吞吐能力

Jetty

Jetty更轻量级,这是对于tomcat而言的.由于tomcat除尊新javaservlet规范之外,自身还扩展大量jee特性,以满足企业应用的需求,所以toomcat是重量级的,而配置较Jetty复杂许多

Jetty更灵活,体现在其可插拔性和扩展性,更易于开发者对于Jetty本身进行二次开发,定制适合自身需求的webSErver.相比之下,重量级的Tomcat原本支持过多特征,要对齐瘦身的成本远大于丰富Jetty的成本。

在支持大规模企业级应用时,Jetty也许便需要扩展,在这场景下Tomcat便是更优的。

Jetty创建连接环境需要三个步骤

  1. 创建一个队列线程池,用于处理每个建立连接产生的任务,这个线程池可以由用户来指定,和tomcat类似
  2. 创建serverSocket,用于准备接受客户端的socket请求,以及客户端用来包装这个socket的一些辅助类
  3. 创建一个或多个监听线程,以用来监听端口访问是否有连接

相比于tomcatjetty的逻辑更加简单,牵涉到的类更少,执行的代码量也就更少了

具体看Jetty与Tomcat综合比较 - kaleidoscopic - 博客园 (cnblogs.com)

Netty

netty和tomcat最大的区别在于通信协议,tomcat是基于http协议的,他的实质是一个http协议的web容器,但是netty不一样,他能通过变成自定义各种协议,因为netty能通过codec自己来编码/解码字节流,完成类似redis访问的功能,这就是netty和tomcat最大的不同

有人说netty的性能一定比tomcat性能搞,其实不然,tomcat从6.x就只吃了nio性能模式,并且侯后续还有arp模式 ,通过jni调用apache网络库的模式,相比于旧的bio模式,并发性能得到了很大的提高,特别是arp模式,而netty是否比tomcat性能更高,则要取决于netty程序作者的技术实力了

netty收到青睐的原因有三

  1. 并发高
  2. 传输快
  3. 封装好

netty是一款基于NIO,开发的网络通信框架,对比与BIO,并发性能得到了很多大的提高

Vert.x

vert.x是一个轻量级的高性能JVM应用平台,基于它可以开发各种移动,web和企业应用程序。一个主要特点是可以用多种语言编程应用,如java,js,ruby,python等。它是基于netty和NIO2编写的

当前业界草鱼c10k问题,当并发超过10000+以上时,传统技术会引发暂停,移动设备或视频,声音类似微信这样的实时聊天,都是属于长任务链接long-lived

童丞tomcat会在100个并发长请求(这个请求要做喝多长事务)下堵塞,而vertx将长任务委托给另一个线程来执行,从而不会堵塞当前的线程,与nodejs的原理很类似

NettyJetty
实质网络通信框架NIOWeb容器
针对SocketServlet
协议TCP/IPHTTP
应用即时通信HTTP服务
Last modification:May 20, 2022
如果觉得我的文章对你有用,请随意赞赏