📚 第九章:Tomcat 源码阅读与扩展
目录
- [9.1 启动入口分析](#9.1 启动入口分析)
- [9.2 核心类分析](#9.2 核心类分析)
- [9.3 Coyote 通信模块](#9.3 Coyote 通信模块)
- [9.4 Container 生命周期与 Pipeline/Valve 机制](#9.4 Container 生命周期与 Pipeline/Valve 机制)
- [9.5 自定义 Valve 实现](#9.5 自定义 Valve 实现)
- [9.6 自定义 Filter 实现](#9.6 自定义 Filter 实现)
- [9.7 源码调试技巧](#9.7 源码调试技巧)
- [9.8 本章小结](#9.8 本章小结)
9.1 启动入口分析
9.1.1 Bootstrap 启动类
Bootstrap 类结构
java
// Bootstrap 启动类
public final class Bootstrap {
private static final String CATALINA_HOME_PROP = "catalina.home";
private static final String CATALINA_BASE_PROP = "catalina.base";
private Object catalinaDaemon = null;
private ClassLoader commonLoader = null;
private ClassLoader catalinaLoader = null;
private ClassLoader sharedLoader = null;
public static void main(String args[]) {
Bootstrap bootstrap = new Bootstrap();
bootstrap.init();
bootstrap.start();
}
public void init() throws Exception {
// 1. 设置系统属性
setCatalinaHome();
setCatalinaBase();
// 2. 创建类加载器
initClassLoaders();
// 3. 设置线程上下文类加载器
Thread.currentThread().setContextClassLoader(catalinaLoader);
// 4. 创建 Catalina 实例
Class<?> startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
Object startupInstance = startupClass.getConstructor().newInstance();
// 5. 设置 Catalina 属性
String methodName = "setParentClassLoader";
Class<?> paramTypes[] = new Class[1];
paramTypes[0] = Class.forName("java.lang.ClassLoader");
Object paramValues[] = new Object[1];
paramValues[0] = sharedLoader;
Method method = startupInstance.getClass().getMethod(methodName, paramTypes);
method.invoke(startupInstance, paramValues);
catalinaDaemon = startupInstance;
}
public void start() throws Exception {
if (catalinaDaemon == null) {
init();
}
Method method = catalinaDaemon.getClass().getMethod("start", (Class[]) null);
method.invoke(catalinaDaemon, (Object[]) null);
}
}
启动流程分析
java
// 启动流程
public void init() throws Exception {
// 1. 设置系统属性
setCatalinaHome();
setCatalinaBase();
// 2. 创建类加载器
initClassLoaders();
// 3. 设置线程上下文类加载器
Thread.currentThread().setContextClassLoader(catalinaLoader);
// 4. 创建 Catalina 实例
Class<?> startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
Object startupInstance = startupClass.getConstructor().newInstance();
// 5. 设置 Catalina 属性
String methodName = "setParentClassLoader";
Class<?> paramTypes[] = new Class[1];
paramTypes[0] = Class.forName("java.lang.ClassLoader");
Object paramValues[] = new Object[1];
paramValues[0] = sharedLoader;
Method method = startupInstance.getClass().getMethod(methodName, paramTypes);
method.invoke(startupInstance, paramValues);
catalinaDaemon = startupInstance;
}
9.1.2 Catalina 启动类
Catalina 类结构
java
// Catalina 启动类
public class Catalina {
private Server server = null;
private boolean await = false;
private String configFile = "conf/server.xml";
public void start() throws Exception {
if (getServer() == null) {
load();
}
if (getServer() == null) {
log.fatal("Cannot start server. Server object is not configured.");
return;
}
long t1 = System.nanoTime();
// 启动服务器
getServer().start();
long t2 = System.nanoTime();
if(log.isInfoEnabled()) {
log.info("Server startup in " + ((t2 - t1) / 1000000) + " ms");
}
// 注册关闭钩子
if (await) {
await();
}
}
public void load() throws Exception {
// 1. 创建服务器
if (getServer() == null) {
loadFromArgs();
}
// 2. 启动服务器
getServer().init();
}
public void stop() throws Exception {
if (getServer() == null) {
return;
}
getServer().stop();
}
}
服务器创建过程
java
// 服务器创建过程
public void loadFromArgs() throws Exception {
// 1. 创建服务器
Server server = new StandardServer();
// 2. 设置服务器属性
server.setPort(8005);
server.setShutdown("SHUTDOWN");
// 3. 创建服务
Service service = new StandardService();
service.setName("Catalina");
// 4. 创建连接器
Connector connector = new Connector("HTTP/1.1");
connector.setPort(8080);
service.addConnector(connector);
// 5. 创建引擎
Engine engine = new StandardEngine();
engine.setName("Catalina");
engine.setDefaultHost("localhost");
// 6. 创建主机
Host host = new StandardHost();
host.setName("localhost");
host.setAppBase("webapps");
engine.addChild(host);
// 7. 添加引擎到服务
service.setContainer(engine);
// 8. 添加服务到服务器
server.addService(service);
// 9. 设置服务器
setServer(server);
}
9.2 核心类分析
9.2.1 StandardServer 分析
StandardServer 类结构
java
// StandardServer 类
public class StandardServer extends LifecycleMBeanBase implements Server {
private Service services[] = new Service[0];
private int port = 8005;
private String shutdown = "SHUTDOWN";
private String address = "localhost";
@Override
protected void startInternal() throws LifecycleException {
// 1. 设置状态
setState(LifecycleState.STARTING);
// 2. 启动服务
for (Service service : services) {
service.start();
}
// 3. 设置状态
setState(LifecycleState.STARTED);
}
@Override
protected void stopInternal() throws LifecycleException {
// 1. 设置状态
setState(LifecycleState.STOPPING);
// 2. 停止服务
for (Service service : services) {
service.stop();
}
// 3. 设置状态
setState(LifecycleState.STOPPED);
}
@Override
public void addService(Service service) {
service.setServer(this);
Service results[] = new Service[services.length + 1];
System.arraycopy(services, 0, results, 0, services.length);
results[services.length] = service;
services = results;
}
}
服务管理
java
// 服务管理
public class StandardServer extends LifecycleMBeanBase implements Server {
private Service services[] = new Service[0];
@Override
public void addService(Service service) {
service.setServer(this);
Service results[] = new Service[services.length + 1];
System.arraycopy(services, 0, results, 0, services.length);
results[services.length] = service;
services = results;
}
@Override
public void removeService(Service service) {
int j = -1;
for (int i = 0; i < services.length; i++) {
if (services[i] == service) {
j = i;
break;
}
}
if (j >= 0) {
Service results[] = new Service[services.length - 1];
int n = 0;
for (int i = 0; i < services.length; i++) {
if (i != j) {
results[n++] = services[i];
}
}
services = results;
}
}
}
9.2.2 StandardService 分析
StandardService 类结构
java
// StandardService 类
public class StandardService extends LifecycleMBeanBase implements Service {
private String name = null;
private Server server = null;
private Container container = null;
private Connector connectors[] = new Connector[0];
private Executor executor = null;
@Override
protected void startInternal() throws LifecycleException {
// 1. 设置状态
setState(LifecycleState.STARTING);
// 2. 启动执行器
if (executor != null) {
executor.start();
}
// 3. 启动连接器
for (Connector connector : connectors) {
connector.start();
}
// 4. 启动容器
if (container != null) {
container.start();
}
// 5. 设置状态
setState(LifecycleState.STARTED);
}
@Override
protected void stopInternal() throws LifecycleException {
// 1. 设置状态
setState(LifecycleState.STOPPING);
// 2. 停止容器
if (container != null) {
container.stop();
}
// 3. 停止连接器
for (Connector connector : connectors) {
connector.stop();
}
// 4. 停止执行器
if (executor != null) {
executor.stop();
}
// 5. 设置状态
setState(LifecycleState.STOPPED);
}
}
连接器管理
java
// 连接器管理
public class StandardService extends LifecycleMBeanBase implements Service {
private Connector connectors[] = new Connector[0];
@Override
public void addConnector(Connector connector) {
connector.setService(this);
Connector results[] = new Connector[connectors.length + 1];
System.arraycopy(connectors, 0, results, 0, connectors.length);
results[connectors.length] = connector;
connectors = results;
}
@Override
public void removeConnector(Connector connector) {
int j = -1;
for (int i = 0; i < connectors.length; i++) {
if (connectors[i] == connector) {
j = i;
break;
}
}
if (j >= 0) {
Connector results[] = new Connector[connectors.length - 1];
int n = 0;
for (int i = 0; i < connectors.length; i++) {
if (i != j) {
results[n++] = connectors[i];
}
}
connectors = results;
}
}
}
9.2.3 StandardEngine 分析
StandardEngine 类结构
java
// StandardEngine 类
public class StandardEngine extends ContainerBase implements Engine {
private String defaultHost = null;
private Service service = null;
@Override
protected void startInternal() throws LifecycleException {
// 1. 设置状态
setState(LifecycleState.STARTING);
// 2. 启动子容器
for (Container child : findChildren()) {
child.start();
}
// 3. 设置状态
setState(LifecycleState.STARTED);
}
@Override
protected void stopInternal() throws LifecycleException {
// 1. 设置状态
setState(LifecycleState.STOPPING);
// 2. 停止子容器
for (Container child : findChildren()) {
child.stop();
}
// 3. 设置状态
setState(LifecycleState.STOPPED);
}
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
// 1. 获取主机名
String hostname = request.getServerName();
if (hostname == null) {
hostname = getDefaultHost();
}
// 2. 查找主机
Host host = findChild(hostname);
if (host == null) {
host = findChild(getDefaultHost());
}
// 3. 调用主机
if (host != null) {
host.invoke(request, response);
} else {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
}
}
}
9.3 Coyote 通信模块
9.3.1 Http11NioProtocol 分析
Http11NioProtocol 类结构
java
// Http11NioProtocol 类
public class Http11NioProtocol extends AbstractHttp11Protocol<NioChannel> {
private NioEndpoint endpoint = null;
@Override
protected AbstractEndpoint.Handler<NioChannel> getHandler() {
return new Http11ConnectionHandler(this);
}
@Override
protected AbstractEndpoint<NioChannel> getEndpoint() {
if (endpoint == null) {
endpoint = new NioEndpoint();
endpoint.setProtocol(this);
}
return endpoint;
}
@Override
protected void configureEndpoint(AbstractEndpoint<NioChannel> endpoint) {
super.configureEndpoint(endpoint);
if (endpoint instanceof NioEndpoint) {
NioEndpoint nioEndpoint = (NioEndpoint) endpoint;
nioEndpoint.setSelectorTimeout(getSelectorTimeout());
nioEndpoint.setPollerThreadCount(getPollerThreadCount());
nioEndpoint.setPollerThreadPriority(getPollerThreadPriority());
}
}
}
连接处理器
java
// 连接处理器
public class Http11ConnectionHandler extends AbstractConnectionHandler<NioChannel, Http11NioProcessor> {
private final Http11NioProtocol protocol;
public Http11ConnectionHandler(Http11NioProtocol protocol) {
this.protocol = protocol;
}
@Override
protected Http11NioProcessor createProcessor() {
Http11NioProcessor processor = new Http11NioProcessor(this);
processor.setAdapter(getAdapter());
return processor;
}
@Override
protected void processSocket(SocketWrapperBase<NioChannel> socketWrapper, SocketEvent event, boolean dispatch) {
try {
if (socketWrapper == null) {
return;
}
NioChannel socket = socketWrapper.getSocket();
if (socket == null) {
return;
}
// 处理套接字事件
if (event == SocketEvent.OPEN_READ) {
processSocketRead(socketWrapper);
} else if (event == SocketEvent.OPEN_WRITE) {
processSocketWrite(socketWrapper);
} else if (event == SocketEvent.CONNECT) {
processSocketConnect(socketWrapper);
} else if (event == SocketEvent.DISCONNECT) {
processSocketDisconnect(socketWrapper);
}
} catch (Exception e) {
log.error("Error processing socket", e);
}
}
}
9.3.2 NioEndpoint 分析
NioEndpoint 类结构
java
// NioEndpoint 类
public class NioEndpoint extends AbstractJsseEndpoint<NioChannel> {
private Selector selector = null;
private Acceptor<SocketChannel> acceptor = null;
private Poller[] pollers = null;
private int pollerThreadCount = 1;
private int pollerThreadPriority = Thread.NORM_PRIORITY;
private long selectorTimeout = 1000L;
@Override
protected void startInternal() throws Exception {
// 1. 创建选择器
selector = Selector.open();
// 2. 创建轮询器
pollers = new Poller[pollerThreadCount];
for (int i = 0; i < pollerThreadCount; i++) {
pollers[i] = new Poller();
pollers[i].setName("http-nio-8080-Poller-" + i);
pollers[i].setPriority(pollerThreadPriority);
pollers[i].setDaemon(true);
pollers[i].start();
}
// 3. 创建接受器
acceptor = new Acceptor<SocketChannel>();
acceptor.setName("http-nio-8080-Acceptor-0");
acceptor.setPriority(acceptorThreadPriority);
acceptor.setDaemon(true);
acceptor.start();
// 4. 设置状态
setState(LifecycleState.STARTED);
}
@Override
protected void stopInternal() throws Exception {
// 1. 设置状态
setState(LifecycleState.STOPPING);
// 2. 停止接受器
if (acceptor != null) {
acceptor.stop();
}
// 3. 停止轮询器
if (pollers != null) {
for (Poller poller : pollers) {
poller.stop();
}
}
// 4. 关闭选择器
if (selector != null) {
selector.close();
}
// 5. 设置状态
setState(LifecycleState.STOPPED);
}
}
接受器实现
java
// 接受器实现
public class Acceptor<U> extends AbstractEndpoint.Acceptor<U> {
@Override
public void run() {
while (endpoint.isRunning()) {
try {
// 1. 接受连接
U socket = endpoint.serverSocketAccept();
// 2. 设置非阻塞模式
if (socket instanceof SocketChannel) {
((SocketChannel) socket).configureBlocking(false);
}
// 3. 注册到轮询器
endpoint.getPoller0().register(socket);
} catch (Exception e) {
log.error("Error accepting connection", e);
}
}
}
}
轮询器实现
java
// 轮询器实现
public class Poller implements Runnable {
private final Selector selector;
private final AtomicBoolean running = new AtomicBoolean(true);
public Poller() throws IOException {
this.selector = Selector.open();
}
@Override
public void run() {
while (running.get()) {
try {
// 1. 等待事件
int keyCount = selector.select(selectorTimeout);
if (keyCount > 0) {
// 2. 处理就绪的通道
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
// 3. 处理 I/O 事件
processKey(key);
}
}
} catch (Exception e) {
log.error("Error in poller", e);
}
}
}
private void processKey(SelectionKey key) {
if (key.isReadable()) {
// 处理读事件
processSocketRead(key);
} else if (key.isWritable()) {
// 处理写事件
processSocketWrite(key);
}
}
}
9.4 Container 生命周期与 Pipeline/Valve 机制
9.4.1 Container 生命周期
Lifecycle 接口
java
// Lifecycle 接口
public interface Lifecycle {
void addLifecycleListener(LifecycleListener listener);
void removeLifecycleListener(LifecycleListener listener);
LifecycleListener[] findLifecycleListeners();
void start() throws LifecycleException;
void stop() throws LifecycleException;
LifecycleState getState();
String getStateName();
}
生命周期状态
java
// 生命周期状态
public enum LifecycleState {
NEW(false, null),
INITIALIZING(false, "before_init"),
INITIALIZED(false, "after_init"),
STARTING_PREP(false, "before_start"),
STARTING(true, "configure_start"),
STARTED(true, "after_start"),
STOPPING_PREP(true, "before_stop"),
STOPPING(false, "configure_stop"),
STOPPED(false, "after_stop"),
FAILED(false, null),
DESTROYING(false, "before_destroy"),
DESTROYED(false, "after_destroy"),
MUST_STOP(true, null),
MUST_DESTROY(false, null);
}
9.4.2 Pipeline/Valve 机制
Pipeline 接口
java
// Pipeline 接口
public interface Pipeline {
Valve getBasic();
void setBasic(Valve valve);
void addValve(Valve valve);
void removeValve(Valve valve);
Valve[] getValves();
Valve getFirst();
Valve getLast();
}
Valve 接口
java
// Valve 接口
public interface Valve {
Valve getNext();
void setNext(Valve valve);
void invoke(Request request, Response response) throws IOException, ServletException;
String getInfo();
}
标准 Pipeline 实现
java
// 标准 Pipeline 实现
public class StandardPipeline implements Pipeline {
private Valve first = null;
private Valve basic = null;
private Container container = null;
@Override
public void addValve(Valve valve) {
if (valve == null) {
return;
}
if (first == null) {
first = valve;
valve.setNext(basic);
} else {
Valve current = first;
while (current.getNext() != basic) {
current = current.getNext();
}
current.setNext(valve);
valve.setNext(basic);
}
}
@Override
public void removeValve(Valve valve) {
if (valve == null) {
return;
}
if (first == valve) {
first = valve.getNext();
} else {
Valve current = first;
while (current != null && current.getNext() != valve) {
current = current.getNext();
}
if (current != null) {
current.setNext(valve.getNext());
}
}
}
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
if (first != null) {
first.invoke(request, response);
} else if (basic != null) {
basic.invoke(request, response);
}
}
}
9.5 自定义 Valve 实现
9.5.1 自定义 Valve 接口
自定义 Valve 实现
java
// 自定义 Valve 实现
public class CustomValve extends ValveBase {
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
// 1. 记录请求信息
String requestURI = request.getRequestURI();
String remoteAddr = request.getRemoteAddr();
long startTime = System.currentTimeMillis();
// 2. 调用下一个阀门
getNext().invoke(request, response);
// 3. 记录响应信息
long endTime = System.currentTimeMillis();
long responseTime = endTime - startTime;
log.info("Request: {} from {} took {}ms", requestURI, remoteAddr, responseTime);
}
@Override
public String getInfo() {
return "CustomValve/1.0";
}
}
注册自定义 Valve
java
// 注册自定义 Valve
@Configuration
public class ValveConfig {
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory() {
@Override
protected void postProcessContext(Context context) {
// 添加自定义阀门
context.addValve(new CustomValve());
}
};
}
}
9.5.2 访问日志 Valve
访问日志 Valve 实现
java
// 访问日志 Valve 实现
public class AccessLogValve extends ValveBase {
private String directory = "logs";
private String prefix = "access_log";
private String suffix = ".txt";
private String pattern = "%h %l %u %t \"%r\" %s %b";
private boolean resolveHosts = false;
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
// 1. 调用下一个阀门
getNext().invoke(request, response);
// 2. 记录访问日志
logAccess(request, response);
}
private void logAccess(Request request, Response response) {
try {
// 1. 格式化日志
String logEntry = formatLogEntry(request, response);
// 2. 写入日志文件
writeLogEntry(logEntry);
} catch (Exception e) {
log.error("Error logging access", e);
}
}
private String formatLogEntry(Request request, Response response) {
StringBuilder logEntry = new StringBuilder();
// 解析模式
String[] patterns = pattern.split(" ");
for (String pattern : patterns) {
if (pattern.equals("%h")) {
logEntry.append(request.getRemoteAddr()).append(" ");
} else if (pattern.equals("%l")) {
logEntry.append("- ");
} else if (pattern.equals("%u")) {
logEntry.append(request.getRemoteUser() != null ? request.getRemoteUser() : "-").append(" ");
} else if (pattern.equals("%t")) {
logEntry.append("[").append(new Date().toString()).append("] ");
} else if (pattern.equals("\"%r\"")) {
logEntry.append("\"").append(request.getMethod()).append(" ").append(request.getRequestURI()).append(" ").append(request.getProtocol()).append("\" ");
} else if (pattern.equals("%s")) {
logEntry.append(response.getStatus()).append(" ");
} else if (pattern.equals("%b")) {
logEntry.append(response.getContentLength()).append(" ");
}
}
return logEntry.toString();
}
}
9.6 自定义 Filter 实现
9.6.1 自定义 Filter 接口
自定义 Filter 实现
java
// 自定义 Filter 实现
@Component
public class CustomFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化过滤器
log.info("CustomFilter initialized");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 1. 前置处理
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// 2. 设置响应头
httpResponse.setHeader("X-Custom-Header", "Custom Value");
// 3. 调用下一个过滤器
chain.doFilter(request, response);
// 4. 后置处理
log.info("Request processed: {}", httpRequest.getRequestURI());
}
@Override
public void destroy() {
// 销毁过滤器
log.info("CustomFilter destroyed");
}
}
注册自定义 Filter
java
// 注册自定义 Filter
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<CustomFilter> customFilter() {
FilterRegistrationBean<CustomFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new CustomFilter());
registration.addUrlPatterns("/*");
registration.setName("CustomFilter");
registration.setOrder(1);
return registration;
}
}
9.6.2 安全 Filter 实现
安全 Filter 实现
java
// 安全 Filter 实现
@Component
public class SecurityFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// 1. 检查请求来源
String remoteAddr = httpRequest.getRemoteAddr();
if (!isAllowedAddress(remoteAddr)) {
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
// 2. 设置安全头
httpResponse.setHeader("X-Content-Type-Options", "nosniff");
httpResponse.setHeader("X-Frame-Options", "DENY");
httpResponse.setHeader("X-XSS-Protection", "1; mode=block");
httpResponse.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
// 3. 调用下一个过滤器
chain.doFilter(request, response);
}
private boolean isAllowedAddress(String remoteAddr) {
// 检查 IP 地址是否在允许列表中
return true; // 简化实现
}
}
9.7 源码调试技巧
9.7.1 调试环境配置
远程调试配置
bash
# 远程调试参数
export JAVA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"
调试参数说明
| 参数 | 说明 | 值 |
|---|---|---|
| -Xdebug | 启用调试模式 | 固定值 |
| -Xrunjdwp | 启用 JDWP 协议 | 固定值 |
| transport | 传输方式 | dt_socket |
| server | 服务器模式 | y |
| suspend | 启动时是否挂起 | n |
| address | 调试端口 | 5005 |
9.7.2 断点设置技巧
关键断点位置
java
// 关键断点位置
public class DebugPoints {
// 1. Bootstrap 启动
public static void main(String args[]) {
// 断点:Bootstrap.main()
Bootstrap bootstrap = new Bootstrap();
bootstrap.init();
bootstrap.start();
}
// 2. Catalina 启动
public void start() throws Exception {
// 断点:Catalina.start()
if (getServer() == null) {
load();
}
getServer().start();
}
// 3. 请求处理
public void invoke(Request request, Response response) throws IOException, ServletException {
// 断点:Container.invoke()
// 处理请求逻辑
}
// 4. Servlet 调用
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
// 断点:Servlet.service()
// 处理业务逻辑
}
}
9.7.3 日志调试技巧
调试日志配置
properties
# 调试日志配置
org.apache.catalina.level = DEBUG
org.apache.coyote.level = DEBUG
org.apache.tomcat.level = DEBUG
org.apache.catalina.startup.level = DEBUG
org.apache.catalina.core.level = DEBUG
org.apache.catalina.session.level = DEBUG
org.apache.catalina.connector.level = DEBUG
org.apache.catalina.valves.level = DEBUG
自定义调试日志
java
// 自定义调试日志
public class DebugLogger {
private static final Logger log = LoggerFactory.getLogger(DebugLogger.class);
public void logRequest(Request request, Response response) {
if (log.isDebugEnabled()) {
log.debug("Request: {} {} from {}",
request.getMethod(),
request.getRequestURI(),
request.getRemoteAddr());
}
}
public void logResponse(Request request, Response response) {
if (log.isDebugEnabled()) {
log.debug("Response: {} {} in {}ms",
response.getStatus(),
response.getContentLength(),
System.currentTimeMillis() - request.getStartTime());
}
}
}
9.8 本章小结
关键要点
-
启动入口分析:
- Bootstrap 启动类的作用和实现
- Catalina 启动类的生命周期管理
- 服务器创建和初始化过程
-
核心类分析:
- StandardServer 的服务管理
- StandardService 的连接器管理
- StandardEngine 的请求路由
-
Coyote 通信模块:
- Http11NioProtocol 的协议处理
- NioEndpoint 的 I/O 事件处理
- 连接器和轮询器的工作机制
-
Container 生命周期:
- Lifecycle 接口的状态管理
- Pipeline/Valve 机制的工作原理
- 标准 Pipeline 的实现方式
-
自定义组件:
- 自定义 Valve 的实现和注册
- 自定义 Filter 的实现和配置
- 安全 Filter 的实现技巧
-
源码调试技巧:
- 远程调试环境配置
- 关键断点设置位置
- 调试日志配置技巧
学习建议
-
源码阅读:
- 从启动入口开始阅读
- 理解核心类的职责和关系
- 掌握关键流程的实现细节
-
实践练习:
- 实现自定义 Valve
- 开发自定义 Filter
- 调试 Tomcat 启动过程
-
扩展开发:
- 基于 Tomcat 开发自定义组件
- 实现性能监控和诊断功能
- 开发安全防护组件
下一步学习
在下一章中,我们将深入探讨 Tomcat 的性能测试与实战案例,了解如何使用各种工具进行性能测试,分析测试结果,以及在实际项目中的应用案例。
相关资源: