Tomcat连接器和NIO-ServerSocketChannel

ServerSocketChannel

面向流的侦听套接字的可选通道。

通过调用此类的open方法创建服务器套接字通道。 无法为任意预先存在的ServerSocket创建通道。 新创建的服务器套接字通道已打开但尚未绑定。 尝试调用未绑定的服务器套接字通道的accept方法将导致抛出NotYetBoundException 。 可以通过调用此类定义的bind方法之一来绑定服务器套接字通道。

accept

public abstract SocketChannel accept() throws IOException

接受与此通道套接字的连接。

如果此通道处于非阻塞模式,则如果没有挂起连接,则此方法将立即返回null 。 否则它将无限期地阻塞,直到新连接可用或发生I / O错误。

无论此通道的阻塞模式如何,此方法返回的套接字通道(如果有)都将处于阻塞模式。

serverSocket.bind()方法将ServerSocket类绑定到指定的地址,而ServerSocketChannel类也有bind() 方法,该方法public final ServerSocketChannel bind(SocketAddress local)的作用是将通道的套接字绑定到本地地址并侦听连接。

public abstract ServerSocketChannel bind(SocketAddress local; int backlog)方法的作用是将通道的套接字绑定到本地地址并侦听连接,通过使用参数backlog来限制客户端连接的数量。

public abstract Socket Channel accept()方法的作用是接受此通道套接字的连接。如果此通道处于非阻塞模式,那么在不存在挂起的连接时,此方法将直接返回nul否则,在新的连接可用或者发生I/O错误之前会无限期地阻塞它。无论此通道的阻塞模式如何,此方法返回的套接字通道(如果有)将处于阻塞模式。

调用 ServerSocketChannel的 public final Selectable Channel configure Blocking( boolean block)方法即可。 public final Selectable Channel configure Blocking( boolean block)方法的作用是调整此通道的阻塞模式,传入tue是阻塞模式,传人 false是非阻塞模式。

可以把这个 Socketchannel通道注册到选择器中实现I/O多路复用,另外, Socketchannel通道使用缓冲区进行数据的读取操作

返回此通道所支持的操作

public final int validOps()方法的作用是返回一个操作集,标识此通道所支持的操作。因为服务器套接字通道仅支持接受新的连接,所以此方法返回 SelectionKey. OP ACCEPT

SocketChannel支持OP_CONNECT、OP_READ、OP_WRITE

bind

public abstract ServerSocketChannel bind​(SocketAddress local, int backlog) throws IOException

将通道的套接字绑定到本地地址并配置套接字以侦听连接。

此方法用于在套接字和本地地址之间建立关联。 一旦建立关联,则套接字保持绑定直到通道关闭。

backlog参数是套接字上的最大挂起连接数。 它的确切语义是特定于实现的。 特别地,实现可以施加最大长度或者可以选择忽略参数altogther。 如果backlog参数的值为0或负值,则使用特定于实现的默认值。

Selector对象

由于Selector类是抽象类,需要调用 open方法获得 Selector对象。

Selector类的public static Selector open方法的作用是打开1个选择器,使 Selectablechannel能将自身注册到这个选择器上。

执行注册操作与获得SelectionKey对象
Selectable Channel类的public final SelectionKey register( Selector sel, Int ops)方法的作用是向给定的选择器注册此通道,返回一个选择键( SelectionKey)。

参数sel代表要向其注册此通道的选择器,参数ops代表 register方法的返回值 SelectionKey的可用操作集,操作集是在 SelectionKey类中以常量的形式进行提供的:

OP_ACCEPT:用于套接字接受操作的操作集位
OP_CONNECT:用于套接字连接操作的操作集位
OP_READ:用于读取操作的操作集位
OP_WRITE:用于写入操作的操作集位

如果想把通道注册到选择器中,就必须将通道设置成非阻塞模式

Tomcat的Poller对象

Poller(轮训器):实现Runnable接口,构造函数为this.selector = Selector.open();由一个SynchronizedQueue构成

Tomcat的Acceptor对象

实现了runable接口

Acceptor跑在一个单独的线程里,它在一个死循环里调用 accept方法来接收新连接,一旦有新的连接请求到来,accept方法返回一个 Channel 对象,接着把 Channel对象交给 Poller 去处理。

Poller 的本质是一个 Selector,也跑在单独线程里。Poller在内部维护一个 Channel数组,它在一个死循环里不断检测 Channel的数据就绪状态,一旦有 Channel可读,就生成一个 SocketProcessor任务对象扔给 Executor去处理。

Tomcat Connector总结

1、一个connector组件 可分为 protocolHandler 和 Adapter ,protocolHandler 用于处理 网络请求 , Adapter 将内部request , response 适配成 servlet的HttpServletReqeust , HttpServiceResponse

2、protocolHandler主要处理 网络连接 和 应用层协议 ,包含了两个重要部件 EndPoint 和 Processor, EndPoint 是用来实现 TCP/IP 协议数据读写的,本质调用操作系统的 socket 接口 , Processor用于处理socket, 转换应用层协议 ,封装内部 request 和 response

3、adapter 用于 内部 request 和 response 转换 成sevlet 规范的 HttpServletReqeust , HttpServiceResponse

4、EndPoint 一图以避之

 5、

Processor 用来实现 HTTP 协议,Processor 接收来自 EndPoint 的 Socket,读取字节流解析成 Tomcat Request 和 Response 对象,并通过 Adapter 将其提交到容器处理,Processor 是对应用层协议的抽象

 参考:tomcat的原理-组件connector - 简书

Tomcat - Request请求处理过程:Connector | Java 全栈知识体系

一个web请求访问tomcat会经过如下组件:

  1. accptor: 接收网络请求,发送事件给poller组件。
  2. poller: 接收I/O事件, 丢给业务线程池。
  3. processor: 处理socket。
  4. adapter :适配 httpServletReqeust 和 httpServletResponse
  5. 交给container 执行pipline。

 SpringBoot支持的并发量

主要看其对Tomcat的设置。有最大线程数和最大连接数。

并发量指连接数还是线程数?连接数!

200个线程如何处理10000条连接? 

Tomcat有两种处理连接的模式,一种是BIO,一个线程只处理一个Socket连接,另一种就是NIO,一个线程处理多个Socket连接。由于HTTP请求不会太耗时,而且多个连接一般不会同时来消息,所以一个线程处理多个连接没有太大问题。

为什么不开几个线程?

多开线程的代价就是,增加上下文切换的时间,浪费CPU时间,另外还有就是线程数增多,每个线程分配到的时间片就变少。多开线程≠提高处理效率。

那增大最大连接数呢?

增大最大连接数,支持的并发量确实可以上去。但是在没有改变硬件条件的情况下,这种并发量的提升必定以牺牲响应时间为代价。

tomcat7以下的版本都是BIO,就是一个请求是一个独立的线程。不能适用高并发的场景。

在8以上的版本,默认都是NIO

文档:深度解读Tomcat中的NIO模型 - 简书

NIO只是优化了网络IO的读写,如果系统的瓶颈不在这里,比如每次读取的字节说都是500b,那么BIO和NIO在性能上没有区别。NIO模式是最大化压榨CPU,把时间片都更好利用起来。对于操作系统来说,线程之间上下文切换的开销很大,而且每个线程都要占用系统的一些资源如内存,有关线程资源可参照这篇文章《一台java服务器可以跑多少个线程》。因此,使用的线程越少越好。而I/O复用模型正是利用少量的线程来管理大量的连接。在对于维护大量长连接的应用里面更适合用基于I/O复用模型NIO,比如web qq这样的应用。所以我们要清楚系统的瓶颈是I/O还是CPU的计算。

文档:Java NIO与IO的区别和比较 - 简书 

终于有一篇文章把java nio讲透彻,再也不怕面试被提问 - 墨天轮

Spring Boot中内置Tomcat最大连接数、线程数与等待数 实践调优_HD243608836的博客-CSDN博客_springboot tomcat 默认连接数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: nio-multipart 是一个用于处理 Multipart 请求的依赖。Multipart 请求是一种 HTTP 请求格式,允许在单个请求中传输多种类型的数据,包括文本、文件、图像等。nio-multipart 提供了处理这种请求格式的工具和功能。 使用 nio-multipart,开发人员可以轻松地解析和处理 Multipart 请求。它提供了一种简单而灵活的方式,可以从请求中提取不同的数据部分,并以可读的格式进行操作。无论是处理上传的文件、解析数据字段还是获取请求的属性,nio-multipart 都提供了便捷的方法。 该依赖还支持文件上传,并提供了一套完整的 API 来处理上传的文件。使用 nio-multipart,开发人员可以轻松地接收上传的文件,并对其进行验证、存储和处理。它还支持上传文件的大小限制、文件类型验证等常见的文件处理需求。 nio-multipart 还提供了处理编码类型的支持。开发人员可以使用 nio-multipart 来处理不同的编码类型,例如表单数据的 URL 编码或二进制数据的 base64 编码。它还提供了编码类型之间的转换,以便开发人员可以方便地在不同的编码类型之间进行转换。 总而言之,nio-multipart 是一个用于处理 Multipart 请求的依赖,它提供了解析、处理和操作 Multipart 请求的功能,包括数据字段的提取、文件上传的支持和编码类型的处理等。使用 nio-multipart,开发人员可以更加便捷地处理复杂的请求格式,提高开发效率。 ### 回答2: NIO-Multipart是一个Java库工具,它提供了一种使用非阻塞I/O(NIO)实现的提供文件上传和处理多部分表单数据的方法。在Web应用程序开发中,常常需要处理用户提交的文件和表单数据,而NIO-Multipart可以帮助开发人员轻松地实现这些功能。 具体来说,NIO-Multipart提供了以下功能和依赖: 1. 文件上传:NIO-Multipart可以将客户端上载的文件保存到服务器的指定位置。它提供了一种简便的方法来访问上传的文件和相关的表单数据。 2. 处理多部分表单数据:NIO-Multipart可以解析提交的多部分表单数据,包括普通的表单字段和文件字段。它可以将这些数据提取出来,并以易于使用的方式提交给开发人员进行处理。 3. 依赖:NIO-Multipart依赖于Java的NIO库,使用其提供的非阻塞I/O(NIO)功能来处理文件上传和表单数据。 使用NIO-Multipart库,开发人员可以轻松处理和管理文件上传和多部分表单数据。通过利用非阻塞I/O(NIO)的优势,可以实现高效的文件传输和数据处理,提升了Web应用程序的性能和用户体验。 总之,NIO-Multipart是一种用于处理文件上传和多部分表单数据的Java库工具,它依赖于Java的NIO库,提供了一种使用非阻塞I/O实现的方法。 ### 回答3: nio-multipart是Java中的一个依赖库,用于处理基于NIO的多部分请求(multipart requests)。 首先,多部分请求是一种HTTP请求类型,允许在单个请求中传输多个文件和文本数据。它通常用于文件上传功能,在Web应用程序中非常常见。 nio-multipart提供了一种简单和高效的方式来解析和处理多部分请求。它基于Java的NIO(New I/O)库开发,该库提供了更快和更强大的I/O操作功能。 使用nio-multipart,我们可以轻松地从多部分请求中提取文件和文本数据,并对它们进行处理。它提供了易于使用的API,用于读取和解析请求的各个部分。我们可以访问每个部分的内容、类型、大小等信息,以便根据需要进行处理。 另外,nio-multipart还可以处理大文件上传,并在处理过程中节省内存。它使用NIO的特性,将请求数据分成一系列块,逐个处理而不是将整个文件加载到内存中。这种方式可以减少内存使用量,并提高性能和吞吐量。 综上所述,nio-multipart是一个用于处理基于NIO的多部分请求的依赖库。它简化了多部分请求的解析和处理过程,并提供了高效处理大文件上传的方法。它可以在Web应用程序中广泛使用,提高开发效率和性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值