当前位置: 首页 > 编程日记 > 正文

Springboot源码分析之内嵌tomcat源码分析

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)

相关文章:

spring amqp rabbitmq fanout配置

基于spring amqp rabbitmq fanout配置如下&#xff1a; 发布端 <rabbit:connection-factory id"rabbitConnectionFactory" username"guest" password"guest" host"localhost" port"5672"/> <rabbit:template id&qu…

【MATLAB】数组运算

&#xff08;这里这列举笔者不熟悉的&#xff0c;容易忘的数组运算&#xff09; 1、数组的转置 >> a[1 2 3 4 5 6 7]a 1 2 3 4 5 6 7>> bab 1234567 2、对数组的赋值 >> a([1 4])[0 0]a 0 2 3 0 5 6 73、注…

RLCenter云平台配置中心

榕力RLCenter云平台配置中心以图形界面的方式实现对云桌面系统的统一管理&#xff0c;包括用户管理、服务器管理、虚拟机管理、策略管理。可配置U盘类设备的读写权限&#xff0c;避免企业敏感信息泄密。实行数据集中存储&#xff0c;支持用户数据进行备份和恢复。 (1)云桌面性能…

SSL/TLS原理详解

本文大部分整理自网络&#xff0c;相关文章请见文后参考。 关于证书授权中心CA以及数字证书等概念&#xff0c;请移步 OpenSSL 与 SSL 数字证书概念贴 &#xff0c;如果你想快速自建CA然后签发数字证书&#xff0c;请移步 基于OpenSSL自建CA和颁发SSL证书 。 SSL/TLS作为一种互…

SpringBoot源码分析之@Scheduled

Springboot写上注解Scheduled就可以实现定时任务&#xff0c; 这里对其源码做一点分析 Service public class MyScheduled {Scheduled(cron"${time.cron}")void paoapaoScheduled() {System.out.println("Execute at " System.currentTimeMillis());} }…

【MATLAB】矩阵分析之向量和矩阵的范数运算

本片借鉴于 https://blog.csdn.net/u013534498/article/details/52674008 https://blog.csdn.net/left_la/article/details/9159949 向量范数当p1时&#xff0c;即为各个向量的元素绝对值之和 >> norm(x,1)ans 21>> xx 1 2 3 4 5 6>> no…

如何打一个FatJar(uber-jar)

如何打一个FatJar&#xff08;uber-jar&#xff09; FatJar也就叫做UberJar&#xff0c;是一种可执行的Jar包(Executable Jar)。FatJar和普通的jar不同在于它包含了依赖的jar包。 1. maven-jar-plugin 例子 <build><finalName>demo</finalName><plugins&g…

JDK源码分析 NIO实现

总列表&#xff1a;http://hg.openjdk.java.net/ 小版本&#xff1a;http://hg.openjdk.java.net/jdk8u jdk:http://hg.openjdk.java.net/jdk8u/jdk8u60/file/d8f4022fe0cd hotspot:http://hg.openjdk.java.net/jdk8u/jdk8u60/hotspot/file/37240c1019fd 调用本地native方法…

Linux进程ID号--Linux进程的管理与调度(三)

进程ID概述 进程ID类型 要想了解内核如何来组织和管理进程ID&#xff0c;先要知道进程ID的类型&#xff1a; 内核中进程ID的类型用pid_type来描述,它被定义在include/linux/pid.h中 enum pid_type {PIDTYPE_PID,PIDTYPE_PGID,PIDTYPE_SID,PIDTYPE_MAX };12345671234567PID 内核…

【MATLAB】矩阵运算之矩阵分解

矩阵分解&#xff1a;把一个矩阵分解成为矩阵连乘的形式。矩阵的分解函数cholCholesky分解cholinc稀疏矩阵的不完全Cholesky分解lu矩阵LU分解luinc稀疏矩阵的不完全LU分解qr正交三角分解svd奇异值分解gsvd一般奇异值分解schur舒尔分解 在MATLAB中线性方程组的求解主要基于四种基…

Java入门—输入输出流

File类的使用 文件是&#xff1a;文件可认为是相关记录或放在一起的数据的集合。 Java中&#xff0c;使用java.io.File类对文件进行操作 public class FileDemo {public static void main(String[] args) {String path "E:\\pdd";File f new File(path);//判断是文…

Web框架基准测试

Web Framework Benchmarks 这是许多执行基本任务&#xff08;例如JSON序列化&#xff0c;数据库访问和服务器端模板组成&#xff09;的Web应用程序框架的性能比较。每个框架都在实际的生产配置中运行。结果在云实例和物理硬件上捕获。测试实现主要是由社区贡献的&#xff0c;所…

vsftpd用户配置 No.2

在配置ftp虚拟用户的过程中&#xff0c;还有一种配置方式。yum -y install 安装vsftpdcp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bak编辑vsftpd.conf开启下列选项&#xff1a;anonymous_enableNOlocal_enableYESwrite_enableYESlocal_umask022anon_mkdir_write_enab…

【MATLAB】稀疏矩阵(含有大量0元素的矩阵)

1、稀疏矩阵的储存方式 对于稀疏矩阵&#xff0c;MATLAB仅储存矩阵所有非零元素的值及其位置&#xff08;行号和列号&#xff09;。 2、稀疏矩阵的生成 1&#xff09;利用sparse函数从满矩阵转换得到稀疏矩阵函数名称表示意义sparse(A)由非零元素和下标建立稀疏矩阵A。如果A已是…

httpTomcat

Tomcat是web应用服务器的一种 转载于:https://juejin.im/post/5beaf7e451882517165d91d1

memcached(二)事件模型源码分析

在memcachedd中&#xff0c;作者为了专注于缓存的设计&#xff0c;使用了libevent来开发事件模型。memcachedd的时间模型同nginx的类似&#xff0c;拥有一个主进行&#xff08;master&#xff09;以及多个工作者线程&#xff08;woker&#xff09;。 流程图 在memcached中&…

【MATLAB】MATLAB的控制流

1、if-else-end if expressioncommands1 elseif expression2commands2 ... else commandsn end 2、switch-case switch valuecase1 test1%如果value等于test1&#xff0c;执行command1&#xff0c;并结束此结构command1case2 test2command2...case3 testkcommandk otherw…

Linux查看本机端口

查看指定的端口 # lsof -i:port 查看所有端口 # netstat -aptn 安装telnet #yum install -y telnet.x86_64 #telnet ip 端口

Node.js安装

通过nvm安装 下载nvm并执行wget -qO- https://raw.github.com/creationix/nvm/v0.33.11/install.sh | sh将命令输出到终端命令中~/.bashrcexport NVM_DIR"$HOME/.nvm"更新文件source .bashrc通过nvm安装node.jsnvm install 10.13安装的版本是10.13的版本 通过命令查看…

mongodb常用语句以及SpringBoot中使用mongodb

普通查询 某个字段匹配数组内的元素数量的&#xff0c;假如region只有一个元素的 db.getCollection(map).find({region:{$size:1}}) 假如region只有0个元素的 db.getCollection(map).find({region:{$size:0}}) db.getCollection(map).find({region:{$size:1}}).count() db.get…

2002高教社杯---A车灯线光源的优化设计

A题 车灯线光源的优化设计 安装在汽车头部的车灯的形状为一旋转抛物面&#xff0c;车灯的对称轴水平地指向正前方, 其开口半径36毫米&#xff0c;深度21.6毫米。经过车灯的焦点&#xff0c;在与对称轴相垂直的水平方向&#xff0c;对称地放置一定长度的均匀分布的线光源。要求…

从Date类型转为中文字符串

//主方法public static String DateToCh(Date date) {Calendar cal Calendar.getInstance();cal.setTime(date);int year cal.get(Calendar.YEAR);int month cal.get(Calendar.MONTH) 1;int day cal.get(Calendar.DAY_OF_MONTH);return getYear(year) getTenString(month…

第十四课 如何在DAPP应用实现自带钱包转账功能?

1&#xff0c;为什么DAPP生态需要自带钱包功能&#xff1f; 区块链是一个伟大的发明&#xff0c;它改变了生产关系。很多生态&#xff0c;有了区块链技术&#xff0c;可以由全公司员工的"全员合伙人"变成了全平台的”全体合伙人”了&#xff0c;是真正的共享经济模式…

为什么jdk源码推荐ThreadLocal使用static

ThreadLocal是线程私有变量&#xff0c;本身是解决多线程环境线程安全&#xff0c;可以说单线程实际上没必要使用。 既然多线程环境本身不使用static&#xff0c;那么又怎么会线程不安全。所以这个问题本身并不是问题&#xff0c;只是有人没有理解ThreadLocal的真正使用场景&a…

C与C++之间相互调用

1、导出C函数以用于C或C的项目 如果使用C语言编写的DLL&#xff0c;希望从中导出函数给C或C的模块访问&#xff0c;则应使用 __cplusplus 预处理器宏确定正在编译的语言。如果是从C语言模块使用&#xff0c;则用C链接声明这些函数。如果使用此技术并为DLL提供头文件&#xff0c…

【MATLAB】三维图形的绘制mesh

步骤如下&#xff1a; &#xff08;1&#xff09;确定自变量x和y的取值范围和取值间隔 x x1 :dx :x2 , y y1 : dy : y2 &#xff08;2&#xff09;构成xoy平面上的自变量采样“格点”矩阵 ①利用格点矩阵的原理生成矩阵。 xx1:dx:x2; yy1:dy:y2; Xones(size(y))*x; Yy*o…

ORA-01919: role 'PLUSTRACE' does not exist

环境&#xff1a;Oracle 10g,11g.现象&#xff1a;在一次迁移测试中&#xff0c;发现有这样的角色赋权会报错不存在&#xff1a; SYSorcl> grant PLUSTRACE to jingyu; grant PLUSTRACE to jingyu* ERROR at line 1: ORA-01919: role PLUSTRACE does not exist 查询发现这个…

Java反射以及应用

需求&#xff1a;需要通过反射动态获取类的字段类型&#xff0c;然后做特殊处理 Java反射getDeclaredField和getField的区别 getDeclaredFiled 只能获取类本身的属性成员&#xff08;包括私有、共有、保护&#xff09; getField 仅能获取类(及其父类可以自己测试) public属性…

【MATLAB】雅可比矩阵jacobi matrix

参考页面&#xff1a; https://baike.baidu.com/item/%E9%9B%85%E5%8F%AF%E6%AF%94%E7%9F%A9%E9%98%B5/10753754?fraladdin#1 在向量微积分中&#xff0c;雅可比矩阵是一阶偏导数以一定方式排列成的矩阵&#xff0c;其行列式称为雅可比行列式。 由球坐标系到直角坐标系的转…

Laravel:使用Migrations

1、首先利用artisan创建一个可迁移的数据表模板&#xff0c;该命令运行后会在database/migrations目录下生成一个文件 php artisan make:migration create_fees_count_table --createfees_count 2、生成的文件包含up和down两个方法&#xff0c;其中up中是包含了添加表&#xff…