上一讲讲解过NIO的框图,可以看来,NIO通道是目前Tomcat7以后的默认的通道的推荐配置,在Tomcat6和以前的配置中,BIO是主流的配置:

只需要修改protocol协议部分即可,而后续还有APR协议,NIO2.0的协议,都是修改这个字段。

对于BIO的整体框图,基本和NIO保持类似,整体流程变化不大:




1.Http11Protocol
与NIO一样,这个Http11Protocol是默认的BIO的http1.1协议的处理类,Tomcat除了有NIO,BIO,其实还有两个通道:

APR是高性能通道,NIO2是基于纯异步IO的通道,这个会在后面的Tomcat中进行讲解。

Http11Protocol类中,依然持有Endpoint和handler的引用:

只不过,BIO对应的Endpoint是JIOEndpoint,对应的handler是Http11ConnectionHandler。

2.JIoEndpoint
JIoEndpoint是BIO的端点类,它和NIO一样,也是维护着线程池,只不过因为没有Selector.select,没有SocketChannel的通道的注册,所以相比NIO模式,没有Poller线程是非常容易理解的,反倒是NIO的三个线程不容易理解,BIO可以看做就是基于Socket进行操作。

首先,初始化的JIoEndpoint的时候,会调用bind方法绑定Serversocket到对应的端口:

bind方法是初始化构造JIoEndpoint的重要步骤,他的主要作用就是建立ServerSocketFactory。
根据SSL信道或者是普通的http的信道,Tomcat都实现了ServerSocketFactory,
普通的http通道的ServerSocketFactory就是DefaultServerSocketFactory类,其工厂方法就是创建ServerSocket,很简单:

对于SSL通道的ServerSocketFactory是JSSEServerSocketFactory,这个类创建的是SSLServerSocket:


其次,JIoEndpoint启动的时候,会将Acceptor线程和工作线程池启动起来:

除此之外,还启动了一个专门的线程,这个线程就是检查异步请求的Timeout的,后续会有专门的介绍针对于Tomcat的异步请求。

工作线程池,使用的就是JDK自带的ThreadPoolExecutor:

可以从线程的堆栈看到,对应的http-bio-8443-exec-n 这种线程都是工作的线程池:

如果在tomcat中没有指定工作线程池的设置,那么都走的是JDK自带的ThreadPoolExecutor的默认值。

3.Acceptor线程
Acceptor线程的主要作用和NIO一样,如果没有网络IO数据,该线程会一直serversocket.accept进行阻塞住。
当有数据的时候,首先将socekt数据设置Connector配置的一些属性,然后将该接力棒传递给工作线程池:

最后一步processSocket方法,非常简单:

直接调用工作线程池,将SocketProcessor作为工作任务传入到工作线程池中,进行执行。

这一步相比NIO的架构,缺少了NIO通道中的PollerEvent一个缓存的队列,NIO中有这样的一个队列是因为需要从Acceptor到Poller线程,中间传递需要一个缓存的地方,而可以看到上述的BIO中的代码,如果工作线程池已经满载了,会根据JDK的ThreadPoolExecutor的策略是缓存,还是直接拒绝,或者是timeout等待,只不过BIO将这块的策略决断交给了ThreadPoolExecutor来做了。

对于Acceptor线程中还有一个重要的作用,就是控制连接的个数,这个在NIO通道的分析中没有讲解,这里看一下
Acceptor线程在while轮询的时候,每一次最开始都会检查一下当前的最大的连接数超出没有,
如果超出了,直接按照上图的序列调用LimitLatch进行锁定。
我们发现,实际上LimitLatch也是模仿JDK中的读写锁,内部持有一个Sync的类,这个类继承了JDK中隐藏功与名的AQS队列,这个AQS队列还是比较著名的,去年在分析JDK源码的时候,多次在n个并发类中都看到过他的踪迹,其实现中几乎全部是CAS锁的实现。

4.SocketProcessor工作任务
SocketProcessor是工作任务,用于传入到工作线程池中,输入就是Acceptor传过来的socketWapper包装:

如果是SSL交互的话,Tomcat开放了握手的这个环节,但是并没有对应的实现,这个是因为SSL下的握手实现在SUN的包中做的,JDK提供的SSLServerSocket的接口已经隐藏了这个细节,我们可以从handshake这个第二步看到:

Tomcat中直接就可以拿到SSLSession,这个类可以获得相当于SSL已经是握手成功了,否则就会出现失败。
对于为什么保留beforeHandShake和handshake这两个步骤,是为了和NIO通道中的SSLEngine交互的接口做个兼容而已。
暂且不用管它,最重要的步骤就是第3步,也就是handler.process这一步,通过Http11ConenctionHandler进行处理http协议,并疯转出Response和Request两个对象,传递给后端的容器。

总结
后续的流程基本上和NIO通道一样,总结一下,BIO的结构因为缺少了selector和轮询,相比NIO少了一部分的内容,整体上就是使用的ServerSocket来进行通信的,一线程一请求的模式,代码看起来清晰易懂,但是,由于BIO的模型比较落后,在大多数的场景下,不如NIO,而现在Tomcat新版本也是NIO是默认的配置。


b.BIO连接器整体框图的更多相关文章

  1. j.APR连接器整体框图(含SSL实现分析)

    APR连接器的思路和bio,nio的整体架构也是类似的,可以看到下面的整体框图: 第一个区别是,对于从Acceptor线程中的socket解析这块,无论是nio还是bio都是在Acceptor线程内直 ...

  2. c.BIO连接器与NIO连接器的对比

    前面两节,我们分别看了BIO和NIO的两种模式Tomcat的实现方式. BIO的方式,就是传统的一线程,一请求的模式,也就是说,当同时又1000个请求过来,如果Tomcat设置了最大Accept线程数 ...

  3. d.BIO连接器与NIO连接器的对比之二

    前面在Tomcat中讲解了两个通道,BIO和NIO,我们这里来通过两端程序,简单模拟两个通道,找找异同点: BIO: 1. public class SocketServer {    public ...

  4. 基于Hi3559AV100的视频采集(VDEC-VPSS-VO)整体框图设计

    下面给出基于Hi3559AV100的视频采集整体设计,具体设计将在后续给出: 图形采集端整体设计 Hi3559AV100软件程序按结构划分可分为4层,第一层是硬件驱动层,第二层是操作系统层,第三层是媒 ...

  5. h.SSL协议栈整体分解

    1.SSL整体框图 SSL协议是应用层次(http协议)和TCP层级的一个可选的位置,可以从下面的图中非常清楚看到该层次: 绿色的框图就是这个SSL./TLS的位置,最右面的SSL/TLS图可以进一步 ...

  6. Vertx.vertx()初始框图和模块

    Vertx.vertx()实例 一.构造方法 1. VertxImpl构造方法 选择 transports protocol , default select 模型 if (options.getPr ...

  7. Tomcat 七 HTTP 连接器

    摘要 本文尝试翻译Tomcat官方文档Apache Tomcat 7连接器,不足之处敬请指正.该文先介绍了Tomcat7 HTTP连接器的属性,包括:公共属性.标准实现.Java TCP套接字属性.B ...

  8. Linux文件IO与通用块层的请求合并

    本文参考https://mp.weixin.qq.com/s/Imt4BW-zoHPpcOpcKZs_AQ, 公众号“Linux阅码场” 请求合并就是将进程内或者进程间产生的在物理地址上连续的多个IO ...

  9. Tomcat SSL的安装及配置中遇到问题

    配置tomcat服务器利用SSL进行加密. 一.生成密钥库 具体生成方式就不讲了,tomcat支持的keystore的格式有JKS,PKCS11和PKCS12 JKS是jdk /bin目录下keyto ...

随机推荐

  1. ADO,NET 实体类 和 数据访问类

    啥也不说,看代码. --SQl中 --建立ren的数据库,插入一条信息 create database ren go use ren go create table xinxi ( code ) pr ...

  2. codevs1137 计算系数

    1137 计算系数 2011年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 给定一 ...

  3. SQL Server 存储过程(转载)

    SQL Server 存储过程 Transact-SQL中的存储过程,非常类似于Java语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句.这 ...

  4. ContentProvider官方教程(8)自定义MIME

    MIME Type Reference Content providers can return standard MIME media types, or custom MIME type stri ...

  5. 深入javascript作用域链到闭包

    我之前用过闭包,用过this,虽然很多时候知道是这么一回事,但是确实理解上还不够深入.再一次看javascript高级程序设计这本书时,发现一起很多疑难问题竟然都懂了,所以总结一下一些理解,难免有错, ...

  6. Codeoforces 558 B. Duff in Love

    //   B. Duff in Love time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  7. HDU 4441 Queue Sequence(splay)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4441 题意:一个数列,三种操作:(1)插入:找到没在当前数列中的最小的正整数i,将其插在位置p之后,并 ...

  8. Android 获取存储空间

    package com.example.getMem; import java.io.File; import android.os.Build;import android.os.Bundle;im ...

  9. SQL查看一张表中是否存在记录

    今天在QQ群众讨论到一个问题,记录下下来,一边以后用的时候可以翻阅 总结除了三种方法 --方法1,,这一种方法不行,,错误的认识了,@@ROWCOUNT,,,唉,,学艺不精,,丢人啊 SELECT T ...

  10. mysql查询中通配符的使用

    mysql查询中通配符的使用     在mysql查询中经常会使用通配符,并且mysql的通配符和pgsql的存在区别(稍候再讨论),而且mysql中还可以使用正则表达式. SQL模式匹配: “_” ...