1 web容器
tomcat :http服务器 + Servlet容器
2 http协议
请求行 、请求头、请求正文
cookie session
版本 1.0 1.1 2.0
3 servlet容器
public interface Servlet { void init(ServletConfig config) throws ServletException; ServletConfig getServletConfig(); void service(ServletRequest req, ServletResponse res)throws ServletException, IOException; String getServletInfo(); void destroy(); }
扩展:
filter 过滤器
listener 监听器
4 tomcat系统架构
connector:
处理 Socket 连接,负责网络字节流与 Request 和 Response 对象的转化。
container:
加载和管理 Servlet,以及具体处理 Request 请求。
connector:
Tomcat 支持的 I/O 模型有:
-
NIO:非阻塞 I/O,采用 Java NIO 类库实现。
-
NIO2:异步 I/O,采用 JDK 7 最新的 NIO2 类库实现。
-
APR:采用 Apache 可移植运行库实现,是 C/C++ 编写的本地库。
Tomcat 支持的应用层协议有:
-
HTTP/1.1:这是大部分 Web 应用采用的访问协议。
-
AJP:用于和 Web 服务器集成(如 Apache)。
-
HTTP/2:HTTP 2.0 大幅度的提升了 Web 性能。
connector功能, 设计高内聚低耦合
-
网络通信。 EndPoint
-
应用层协议解析。 Processor
-
Tomcat Request/Response 与 ServletRequest/ServletResponse 的转化。 Adapter
Container 容器,分层架构
设计模式: 模版、观察者、组合模式(父子关系)
IO知识点!
IO模型 : 阻塞、非阻塞
序列化协议、server线程模型、反射动态代理
处理过程 :accept select read decode process encode write
角色: Acceptor Selector Processor
处理模型
tomcat 骨架
io模型:
I/O 模型是为了解决内存和外部设备速度差异的问题。我们平时说的 阻塞或非阻塞 是指应用程序在 发起 I/O 操作时,是立即返回还是等待 。而 同步和异步 ,是指应用程序在与内核通信时, 数据从内核空间到应用空间的拷贝,是由内核主动发起还是由应用程序来触发。
两步: 等待数据准备好,数据从内核空间拷贝到用户空间
同步
异步
阻塞
非阻塞
异步
NioEndpoint:
高并发就是能快速地处理大量的请求,需要合理设计线程模型让 CPU 忙起来,尽量不要让线程阻塞,因为一阻塞,CPU 就闲下来了。另外就是有多少任务,就用相应规模的线程数去处理。我们注意到 NioEndpoint 要完成三件事情:接收连接、检测 I/O 事件以及处理请求,那么最核心的就是把这三件事情分开,用不同规模的线程去处理,比如用专门的线程组去跑 Acceptor,并且 Acceptor 的个数可以配置;用专门的线程组去跑 Poller,Poller 的个数也可以配置;最后具体任务的执行也由专门的线程池来处理,也可以配置线程池的大小。
Nio2Endpoint
Apr
堆外内存:
Tomcat 中的 AprEndpoint 就是通过 DirectByteBuffer 来接收数据的,而 NioEndpoint 和 Nio2Endpoint 是通过 HeapByteBuffer 来接收数据的。
零拷贝 - sendfile:
线程池的优化
池化的目的是为了避免频繁地创建和销毁对象,减少对系统资源的消耗。
定制ThreadPoolExecutor 重写execute
定制任务队列TaskQueue 重写offer
WebSocket双端通信
优化点:池化技术
对象池技术可以减少频繁创建和销毁对象带来的成本,实现对象的缓存和复用。如果你的系统需要频繁的创建和销毁对象,并且对象的创建代价比较大,这种情况下,一般来说你会观察到 GC 的压力比较大,占用 CPU 率比较高,这个时候你就可以考虑使用对象池了。
高性能、高并发
IO、线程模型
系统调用
池化、0拷贝
锁优化 :原子变量 和 CAS
并发容器
类加载
ClassLoader:
findClass 、defineClass 、loadClass(双亲委派)
目的是为了优先加载 Web 应用目录下的类,然后再加载其他目录下的类
总结一下以上步骤,WebAppClassLoader 加载类的时候,故意打破了JVM 双亲委派机制,绕开了 AppClassLoader,直接先使用 ExtClassLoader 来加载类。
- 保证了基础类不会被同时加载。
- 由保证了在同一个 Tomcat 下不同 web 之间的 class 是相互隔离的。
Servlet 异步
tomcat 调优
IO模型、线程池
连接数
acceptCount 、maxConnection 、maxThread