重新认识TOMCAT

网络编程中BIO/NIO区别

BIO
一种阻塞式的编程技术,阻塞IO,网络编程中的所有API都是阻塞的,例如Socket中的accept, 包括InputStream,OutputStream。表现在只要没有返回信息就一直阻塞线程。比如ServerSocket接受了一个Conn只要只要该连接没有发送数据,处理线程就会一直阻塞,导致的结果就是在同一时刻别的Conn连接是Server端并不会及时识别到。
那么此刻解决这个问题的唯一办法就是在获取到新的Conn时,另开启一个线程去处理IO(阻塞)。别的Conn过来时能够及时识别到,并且开启一个新的线程去处理IO。
这样一个连接,对应一个新线程。 如果大量的Conn到达后,Server端就需要开启很多新线程,这就会导致线程的利用率低,还会占用大量的内存资源。
可见BIO+多线程 并不适合我们的正式环境。更早的tomcat版本就是BIO。
NIO
针对BIO的情况,NIO做的事情就是优化BIO的不足。
用非阻塞,一个公共线程的方式去处理网络请求。可以提高线程的利用率,也可以节省资源。
其中NIO中的三组件: Buffer , Channel,Selector
1 Buffer是为了我们能跟好的操作byte数组。主要属性(capacity,position,limit)(更大的用处是提供了直接内存也叫堆外内存实现0拷贝,从性能提升),具体细节可上网查阅。
2 channel 直接操作buffer,并且封装了IO的API。我们可以直接通过channel操作输入,输出。特别方便。 单纯的使用channel也可改善BIO的处境,基本思路将获取到的Conn放在一个list中,通过循环便利list即可
3 selector 基于事件驱动机制(底层是OS的多路复用机制)更优雅的盖上BIO缺陷。主要思路是在selectot中组册对应的事件,常用的四个事件,connection,accept,read,writer。这样的话,只要有对应的事件发生就会别发现。(selector.select()阻塞操作),去循环遍历selector中的事件(KEY),在通过判断KEY事件的类型进行对应的操作。就可以实现同样的效果。这样做的好处是使用一个线程,提高了线程的利用率。使用的API都是非阻塞的。
NIO循环+非阻塞=BIO多线程+阻塞
在正式环境中使用一个线程难免会有些吃力,就需要用多个线程专门处理accept,多个线程处理IO,多个线程处理Servlet。具体实现可自行百度。 这样的NIO+多线程思想就是Netty框架的雏形。 tomcat8的版本中已经完全摒弃了BIO的实现都采用NIO的实现。

TOMCAT

模式 NIO+Asyn 异步实现
其中只要的属性:
ConnectionTimeOut 超时时间 默认 20s,具体设置需要根据应用程序调节。
maxThread最大处理线程数,默认200,这个线程数并不是越大越好。 理想的计算公式:1+(IO等待时间/计算时间)*cpus,具体合适的参数需要自己调节。
acceptCount等待接受Connection的数量,默认 100。在Tomcat超过接受的最大连接数时,多余的连接会存入os的一个队列进行等待(不同的操作系统有不同的实现—windons 是只会存tcp握手完毕的Conn,—linux除了握手完毕的Conn,还会保存正在握手的Conn 默认128)
maxConnnectionsTomcat允许的最大连接数。NIO默认是1w,apr 8192 。
总共连接数=acceptCount+maxConnnections;
maxConnection调节的情况:
在maxThread > maxConnnections 时,导致更多的Conn被堵在Tomcat外,由于正在执行的线程数太少。线程的利用率低下,CPU的利用率就会很低,浪费CPU资源。 推荐maxConnection的值应该是并发量的120%。这样可以充分利用CPU。
maxThread调节:
正在执行线程数太少会导致导致CPU利用率低。线程数过大就会因为时间片频繁切换从而影响性能。
CPU只会执行计算,可是在执行线程时,有计算,有io等待。io等待并不会利用cpu,就会出现cpu的空档期,cpu就会切换到另外的线程的计算。为了提高CPU的使用率,此时在适当增加线程时正确做法。让CPU更多的执行我们应用中的代码,提高CPU的利用率从而提高吞吐量。
场景带入: 2核服务器, 一个线程只行50ms计算,50ms io等待。 4个线程同时交替执行就会有高的cpu利用率。所以4个线程时理想的选择。cpu的利用率维持在80%-90%是一个好的结果,可以维持一个很高的吞吐量。
同时在使用jmeter并发测试时,出现Error的情况
1 由于请求量大导致超过最大连接数,就会被拒绝。
2 由于接受了大量的请求,程序来不及处理,被囤积在了os的队列或tomcat队列中,超过了tomcat的20s,就会出现错误现象。
总结:
不论是jvm调优,还是Tomcat调优都是在调整参数,改动参数,一般效果不明显。如果可以接受长时间返回,可以维持一个直接运行。 否则就要采用集群分流(一个服务器上集群,只是增加了tomcat数量,接受了更多的请求,增加了线程数,还是共享了同样的CPU数量,对程序并起不到实质的提升,由于吞吐量一样,会导致更多的连接超时返回增加错误率。)–所以还是要在不同的服务器上做集群,这样做实质上是增加了CPU的数量,从而提升吞吐量来提高整个服务的性能。 另外还要看清楚现实,优化代码是王道,通过增加中间件来提升单节点的性能。(中间件的使用是可以减少流量高峰时的CPU使用率,通过借助其他服务器的CPU来实现性能提升。 实质也是增加了CPU的数量)

Tomcat在大量的请求面前也是有down机的风险的,这样就需要用到Nginx做一个限流。 nginx的作用限流,日志记录。 条件允许的情况下可以一台tomcat配一台nginx,可以提高系统稳定性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值