Springboot源码是内嵌tomcat的,这个和完整的tomcat还是不同。

内嵌tomcat的源码在tomcat-embed-core等3个jar包里

展开tomcat-embed-core的catalina目录

再对照下载的apache-tomcat-9.0.31源码

打开bin目录,看到很多库文件比如catalina.jar

再展开看看类文件

和之前Spring内嵌的tomcat-embed-core的catalina目录文件一致。

所以内嵌的tomcat只用了一部分代码。

内嵌tomcat的配置文件是ServerProperties.java

在org.springframework.boot.autoconfigure.web里,port等配置信息默认取这里的。

调试一下

可以看到最大线程数:maxThreads=200

最大连接数:maxConnections=8192

修改最大线程数和最大连接数

##端口号
server.port=8080
server.tomcat.max-threads=300
server.tomcat.max-connections=10000

已经改了

再看看NIO和APR源码

在TomcatServletWebServerFactory.java

public class TomcatServletWebServerFactory extends AbstractServletWebServerFactoryimplements ConfigurableTomcatWebServerFactory, ResourceLoaderAware {private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;private static final Set<Class<?>> NO_CLASSES = Collections.emptySet();/*** The class name of default protocol used.*/public static final String DEFAULT_PROTOCOL = "org.apache.coyote.http11.Http11NioProtocol";
private String protocol = DEFAULT_PROTOCOL;
protocol读取默认的DEFAULT_PROTOCOL

启动完成输出日志看到确实是NIO:

2020-02-27 12:38:43.264 [main] [INFO ] o.s.boot.web.embedded.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8080 (http)
2020-02-27 12:38:43.277 [main] [INFO ] org.apache.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"]

NIO相对于BIO已经是提升很多, 还可以改为更高效的APR

tomtcat7.0内置BIO,8.0,9.0都是NIO。

这三种模式的不同之处如下:

BIO

【一个线程处理一个请求】。

缺点:【并发量高时,线程数较多,浪费资源】。

Tomcat7或以下,在Linux系统中默认使用这种方式。

NIO

【多路复用】,可以通过【一个线程处理大量的请求】。

Tomcat8在Linux系统中默认使用这种方式。

APR

即Apache Portable Runtime,从操作系统层面解决io阻塞问题。

Tomcat7或Tomcat8在Win7或以上的系统中启动默认使用这种方式。

------------------------------------------------------------------------

Tomcat源码中与connector相关的类位于org.apache.coyote包中,Connector分为以下几类:

Http Connector, 基于HTTP协议,负责建立HTTP连接。它又分为BIO Http Connector与NIO Http Connector两种,后者提供非阻塞IO与长连接Comet支持。默认情况下,Tomcat使用的就是这个Connector。

AJP Connector, 基于AJP协议,AJP是专门设计用来为tomcat与http服务器之间通信专门定制的协议,能提供较高的通信速度和效率。如与Apache服务器集成时,采用这个协议。

APR HTTP Connector, 用C实现,通过JNI调用的。主要提升对静态资源(如HTML、图片、CSS、JS等)的访问性能。现在这个库已独立出来可用在任何项目中。Tomcat在配置APR之后性能非常强劲。

具体地,Tomcat7中实现了以下几种Connector:

org.apache.coyote.http11.Http11Protocol : 支持HTTP/1.1 协议的连接器。

org.apache.coyote.http11.Http11NioProtocol : 支持HTTP/1.1 协议+New IO的连接器。

org.apache.coyote.http11.Http11AprProtocol : 使用APR(Apache portable runtime)技术的连接器,利用Native代码与本地服务器(如linux)来提高性能。

(以上三种Connector实现都是直接处理来自客户端Http请求,加上NIO或者APR)

org.apache.coyote.ajp.AjpProtocol:使用AJP协议的连接器,实现与web server(如Apache httpd)之间的通信

org.apache.coyote.ajp.AjpNioProtocol:SJP协议+ New IO

org.apache.coyote.ajp.AjpAprProtocol:AJP + APR

https://www.cnblogs.com/qq951785919/archive/2013/11/29/3450285.html

------------------------------------

关于  APR介绍

https://ci.apache.org/projects/tomcat/tomcat9/docs/apr.html

介绍

Tomcat可以使用Apache Portable Runtime提供出色的可伸缩性,性能以及与本机服务器技术的更好集成。Apache可移植运行时是一个高度可移植的库,它是Apache HTTP Server 2.x的核心。APR有许多用途,包括访问高级IO功能(例如sendfile,epoll和OpenSSL),操作系统级别的功能(生成随机数,系统状态等)和本机进程处理(共享内存,NT管道和Unix套接字)。

这些功能使Tomcat成为通用的Web服务器,可以更好地与其他本机Web技术集成,并且总体上使Java作为完善的Web服务器平台而不是仅以后端为中心的技术更加可行。

安装

APR支持需要安装三个主要的本机组件:

  • APR库
  • Tomcat使用的APR的JNI包装器(libtcnative)
  • OpenSSL库

APR主页

https://apr.apache.org/

由于本地开发是基于Windows,Windows下需要二进制文件提供给tcnative-1,它是一个静态编译的.dll,其中包括OpenSSL和APR。在下载对应tomcat包,将bin目录下的tcnative-1.dll拷贝到jdk安装目录的bin目录下.

新增配置文件:

import org.apache.catalina.core.AprLifecycleListener;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AprProtocolConfig {@Beanpublic TomcatServletWebServerFactory servletContainer() {TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();tomcat.setProtocol("org.apache.coyote.http11.Http11AprProtocol");tomcat.addContextLifecycleListeners(new AprLifecycleListener());return tomcat;}
}

先初始化TomcatServletWebServerFactory,默认的protocol是NIO

再set为APR

再到TomcatServletWebServerFactory.getWebServer初始化Connector

反射出org.apache.coyote.http11.Http11AprProtocol

完成初始化

ServletWebServerApplicationContext.createWebServer()创建webserver

启动完成输出APR模型:

 [main] [INFO ] org.apache.coyote.http11.Http11AprProtocol - Initializing ProtocolHandler ["http-apr-8080"][main] [INFO ] org.apache.catalina.core.StandardService - Starting service [Tomcat][main] [INFO ] org.apache.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.30]

下面这两篇讲怎么自定义配置实现自动配置

https://blog.csdn.net/qq_34609889/article/details/86714796

https://blog.csdn.net/u014229347/article/details/93641356

下面这篇讲linux下apr库安装

https://juejin.im/post/5b8e3d756fb9a019f82fc40d

tomcat bio nio apr 模式性能测试与个人看法

================

tomcat8.5以后都是NIO,可以在NIO和APR之间选

public Connector(String protocol) {boolean aprConnector = AprLifecycleListener.isAprAvailable() &&AprLifecycleListener.getUseAprConnector();if ("HTTP/1.1".equals(protocol) || protocol == null) {if (aprConnector) {protocolHandlerClassName = "org.apache.coyote.http11.Http11AprProtocol";} else {protocolHandlerClassName = "org.apache.coyote.http11.Http11NioProtocol";}} else if ("AJP/1.3".equals(protocol)) {if (aprConnector) {protocolHandlerClassName = "org.apache.coyote.ajp.AjpAprProtocol";} else {protocolHandlerClassName = "org.apache.coyote.ajp.AjpNioProtocol";}} else {protocolHandlerClassName = protocol;}

再用反射出对象

// Instantiate protocol handlerProtocolHandler p = null;try {Class<?> clazz = Class.forName(protocolHandlerClassName);p = (ProtocolHandler) clazz.getConstructor().newInstance();} catch (Exception e) {log.error(sm.getString("coyoteConnector.protocolHandlerInstantiationFailed"), e);} finally {this.protocolHandler = p;}

===========================

Spring Boot 集成undertow作为web容器

默认是tomcat,也可以启用undertow。

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-undertow</artifactId></dependency>

启动信息里面的tomcat已经被替换为undertow:

2020-03-22 23:25:44.535 [main] [INFO ] io.undertow - starting server: Undertow - 2.0.29.Final
2020-03-22 23:25:44.542 [main] [INFO ] org.xnio - XNIO version 3.3.8.Final
2020-03-22 23:25:44.550 [main] [INFO ] org.xnio.nio - XNIO NIO Implementation Version 3.3.8.Final
2020-03-22 23:25:44.633 [main] [INFO ] o.s.b.w.embedded.undertow.UndertowServletWebServer - Undertow started on port(s) 8080 (http) with context path ''
2020-03-22 23:25:44.635 [main] [INFO ] c.p.springboot.SpringBootLearningApplication - Started SpringBootLearningApplication in 3.209 seconds (JVM running for 3.682)

Springboot源码分析之内嵌tomcat源码分析相关推荐

  1. 深入分析SpringBoot源码如何内嵌Tomcat容器?

    作者:陌北有棵树,Java人,架构师社区合伙人! [一]总述 SpringBoot的诞生,极大的简化了Spring框架的使用过程,提升了开发效率,可以把它理解为一个整合包,使用了SpringBoot, ...

  2. 精尽Spring Boot源码分析 - 内嵌Tomcat容器的实现

    概述 我们知道 Spring Boot 能够创建独立的 Spring 应用,内部嵌入 Tomcat 容器(Jetty.Undertow),让我们的 jar 无需放入 Servlet 容器就能直接运行. ...

  3. SpringBoot入门之内嵌Tomcat配置

    spring boot默认web程序启用tomcat内嵌容器tomcat,监听8080端口,servletPath默认为 / .需要用到的就是端口.上下文路径的修改,在spring boot中其修改方 ...

  4. 将tomcat源码以maven方式运行

    前言 最近在分析tomcat的启动流程,虽然我们可以在idea中查看到tomcat的源代码,但是我们不能在上面做一些代码注释,这就会 非常的不方便,所以我们还是能在本地 运行一份源码,这样非常有利于我 ...

  5. Tomcat源码解析:环境搭建

    下载源码 从github下载tomcat源码 git clone https://github.com/apache/tomcat.git 或者直接fork一份到自己仓库,以便后续添加注释,附上笔者自 ...

  6. Alian解读SpringBoot 2.6.0 源码(六):启动流程分析之创建应用上下文

    目录 一.背景 1.1.run方法整体流程 1.2.本文解读范围 二.创建应用上下文 2.1.初始化入口 2.2.初始化AbstractApplicationContext 2.3.初始化Generi ...

  7. Alian解读SpringBoot 2.6.0 源码(八):启动流程分析之刷新应用上下文(下)

    目录 一.背景 1.1.刷新的整体调用流程 1.2.本文解读范围 二.初始化特定上下文子类中的其他特殊bean 2.1.初始化主体资源 2.2.创建web服务 三.检查监听器bean并注册它们 四.实 ...

  8. Alian解读SpringBoot 2.6.0 源码(三):启动流程分析之命令行参数解析

    目录 一.背景 1.1.run方法整体流程 1.2.本文解读范围 二.默认应用参数解析 2.1.接口ApplicationArguments 2.2.实现类DefaultApplicationArgu ...

  9. Tomcat源码分析--转

    一.架构 下面谈谈我对Tomcat架构的理解 总体架构: 1.面向组件架构 2.基于JMX 3.事件侦听 1)面向组件架构 tomcat代码看似很庞大,但从结构上看却很清晰和简单,它主要由一堆组件组成 ...

最新文章

  1. php拦截器配置,php 类中的各种拦截器
  2. uni上传图片跨域_uni-app的项目实践心得
  3. 如何通过构建以太坊智能合约来销售商品
  4. 1.2 一维数组的定义、赋值和初始化
  5. WinDbg配置与下载
  6. python-web自动化-元素定位
  7. 黑马程序员传智播客 python生成器 学习笔记
  8. 计算机网络防护,计算机网络防护方法与流程
  9. java对音频文件的频谱分析
  10. windows10复制粘贴键突然失效 的一个最简单的解决方法
  11. 格拉姆-施密特正交化
  12. Android 获取照片位置信息
  13. vue3.0+ts+element-plus多页签应用模板:项目搭建
  14. Kafka---如何配置Kafka集群和zookeeper集群
  15. java并查集_一个非常实用而且精妙的算法-并查集(java语言实现)
  16. 2020成电计算机考研
  17. 半导体代理商名录---芯片代理商、MLCC代理商
  18. IDM下载慢 没有权限下载如何解决?
  19. 独家 | 数据化思维、 数字化陷阱和 0.01 突破
  20. 第一次使用炫云云渲染软件该怎么使用?

热门文章

  1. 基于熵权法优劣解距离法_基于优劣解距离法的火电机组单辅机运行状态评估
  2. cmd连接oracle_Oracle -PLSQLDeveloper 13 数据库连接
  3. OpenCV-Python绑定如何工作及如何扩展新模块到Python
  4. 基于Struts2框架的名片管理系统
  5. ZigBee(CC2530)最小系统PCB设计(AD18开发软件)
  6. The Shortest Statement CodeForces - 1051F LCA+最短路
  7. Python实现一元及多元线性回归
  8. android o 全机型推送,氢OS(Android O)官方更新推送 一加两款机型完成适配
  9. 基于Keras的CNN/Densenet实现分类
  10. 剑指offer:面试题06. 从尾到头打印链表