《深入拆解Tomcat&Jetty》总结八:通用模块

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_41594698/article/details/101212525

13 Logger组件:日志框架及实战

默认情况下,Tomcat 使用自身的JULI 作为 Tomcat 内部的日志处理系统。
JULI 的日志门面采用了 JCL;而 JULI 的具体实现是构建在 Java 原生的日志系统java.util.logging之上的

13.1 Java原生日志

java.util.logging组件:
在这里插入图片描述
Logger:用来记录日志的类。
Handler:规定了日志的输出方式,如控制台输出、写入文件。
Level:定义了日志的不同等级。
Formatter:将日志信息格式化,比如纯文本、XML。

JULI 对日志的处理方式与 Java 自带的基本一致,但是 Tomcat 中可以包含多个应用,而每个应用的日志系统应该相互独立;
而Java 的原生日志系统是每个 JVM 有一份日志的配置文件,这不符合 Tomcat 多应用的场景,所以 JULI 重新实现了一些日志接口,主要是通过FileHandler,这是一个在特定位置写文件的工具类,通过每个web应用注册一个FileHandler即可实现隔离

14 Manager组件:Session管理机制解析

Tomcat 中主要由每个 Context 容器内的一个 Manager 对象来管理 Session,默认实现类为StandardManager

Tomcat 为了避免把一些实现细节暴露出来,还有基于安全上的考虑,定义了 Request 的包装类,叫作 RequestFacade

14.1 创建

Request 对象中持有 Context 容器对象,而 Context 容器持有Session 管理器 Manager,这样通过 Context 组件就能拿到 Manager 组件,最后由Manager 组件来创建 Session;
Session在Tomcat中为StandardSession,为HttpSession的具体实现类(HttpSession是Servlet规范定义的接口);
创建出来后 Session 会被保存到一个ConcurrentHashMap 中(< String,Session >);

StandardSession对外暴露的是StandardSessionFacade 外观类,保证了 StandardSession 的安全,避免了程序员调用其内部方法进行不当操作

14.2 清理

容器组件会开启一个 ContainerBackgroundProcessor 后台线程,调用自己以及子容器的 backgroundProcess 进行一些后台逻辑的处理,Session就是在这里被清理的:
在这里插入图片描述
StandardContext重写了backgroundProcessor方法,调用 StandardManager 的 backgroundProcess完成 Session 的清理工作

清理策略:backgroundProcess 默认是每隔 10 秒调用一次,但是Session 的清理动作不能太频繁,因为需要遍历 Session 列表,会耗费 CPU 资源,所以backgroundProcess 方法中做了取模处理,backgroundProcess 调用 6 次,才执行一次Session 清理,也就是说 Session 清理每 60 秒执行一次。
使用isValid方法来判断Session是否过期,过期才清理

14.3 事件通知

按照 Servlet 规范,在 Session 的生命周期过程中,要将事件通知监听者,Servlet 规范定义了 Session 的监听器接口HttpSessionListener

遍历 Context 内部的 LifecycleListener,并且判断是否为HttpSessionListener 实例,如果是的话则调用 HttpSessionListener 的 sessionCreated方法进行事件通知。

扫描二维码关注公众号,回复: 7592030 查看本文章

14.4 总结

在这里插入图片描述
Servlet 规范中定义了 HttpServletRequest 和 HttpSession 接口,Tomcat 实现了这些接口,但具体实现细节并没有暴露给开发者,因此定义了两个包装类,RequestFacade 和StandardSessionFacade。

通过 Manager 来管理 Session ,默认实现是 StandardManager。
StandardContext 持有 StandardManager 的实例,并存放了 HttpSessionListener 集合,Session 在创建和销毁时,会通知监听器。

15 Cluster组件:集群通信原理

如何在集群中的多个节点之间保持数据的一致性,比如会话(Session)信息?

有两种方式:

一种是把所有 Session 数据放到一台服务器或者一个数据库中,集群中的所有节点通过访问这台 Session 服务器来获取数据。

另一种方式就是在集群中的节点间进行 Session 数据的同步拷贝;
这里又分为两种策略:
第一种是将一个节点的 Session 拷贝到集群中其他所有节点;
第二种是只将一个节点上的 Session 数据拷贝到另一个备份节点。

Tomcat如何知道集群中有哪些成员:通过组播实现

组播是一台主机向指定的一组主机发送数据报包

组播通信过程:
每一个Tomcat 节点在启动时和运行时都会周期性(默认 500 毫秒)发送组播心跳包,同一个集群内的节点都在相同的组播地址和端口监听这些信息;
在一定的时间内(默认 3 秒)不发送组播报文的节点就会被认为已经崩溃了,会从集群中删去。
因此通过组播,集群中每个成员都能维护一个集群成员列表。

通过 SimpleTcpCluster 类来进行会话复制

默认情况下 Session 管理组件 DeltaManager 会在节点之间拷贝 Session;
DeltaManager 采用 all-to-all 的工作方式,即集群中的节点会把Session 数据向所有其他节点拷贝,而不管其他节点是否部署了当前应用。
当集群节点数比较少时,比如少于 4 个,all-to-all可以考虑;
但是当集群中的节点数量比较多时,数据拷贝的开销成指数级增长,这种情况下可以考虑 BackupManager,BackupManager 只向一个备份节点拷贝数据,只要这两个节点不同时崩溃,Session数据就不会丢失,数据拷贝的开销也较少

猜你喜欢

转载自blog.csdn.net/qq_41594698/article/details/101212525
今日推荐