一、tomcat 目录结构
- bin: 执行目录
- lib:依赖的jar包
- conf:
- catalina.policy:权限相关permission,tomcat 是跑在jvm 上的所以有些默认的权限。
- server.xml:server节点—>service—>executor(线程池)、connector连接器
- connector 连接器 用线程池的话,connector里面的maxThreads 是无效的。
- executor 不设置的话一般默认是200
- web.xml
- DefaultServlet 默认的,加载静态文件html,js,jpg等静态文件
- JspServlet 专门处理jsp
- mime-mapping 文件类型,其实就是tomcat 处理的文件类型。
- logs:
- catalina.xxx.log 若tomcat 出现问题,启动不了,查看这个问题。
- localhost.xxx.log
- webapps : 默认应用程序
二、tomcat 的部署方式
1、隐式部署
打包war 包放在webapps 下。
2、显示部署
这两种方式都可以直接引入tomcat外部目录的项目。
1、通过serve.xml 文件中配置:
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
<Context path="/Demo" docBase="d:/Demo" reloadable="true"></Context>
</Host>
path :访问路径。
docBase:表示项目的真实路径。
通过 url :127.0.0.1:8080/Demo 就可以访问到D盘下面的Demo 项目。
2、通过xml 配置
在tomcat 目录:conf\Catalina\localhost新建test.xml文件,
<!-- test.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="d:/Demo" reloadable="true"></Context>
docBase:表示项目的真实路径。
通过url:127.0.0.1:8080/test 就可以访问到D盘下面的Demo 项目。
三、tomcat 总体架构
server:是服务器的意思,代表整个tomcat服务器,一个tomcat 只有一个server。
service:server中的一个逻辑功能层,一个server可以包含多个service。
connector:称作连接器,是service的核心组件之一,一个service可以有多个connector ,主要是连接客户端请求。
container:service 的另一个核心组件,按照层级有engine,Host,Context,Wrapper四种,一个Service 只有一个engine,其主要作用是执行业务逻辑;
四、请求处理流程
1、监听服务器端口,读取来自客户端的请求。
2、将请求数据按照指定协议进行解析。
3、根据请求地址匹配正确的容器进行处理。
4、将结果返回给客户端。
五、connector解析
connector 使用ProtocolHandler来处理请求的。
ProtocolHandler 包含了三个组件:Endpoint、Processor、Adapter.
- Endpoint:处理底层Socket 的网络连接。
- Processor:将Endpoint 接收到的Socket 封装成request。
- Adapter:充当适配器,用于将request转换为ServletRequest 交给Container进行具体的处理。
六、Container解析
按照层级有engine,Host,Context,Wrapper四种,一个Service 只有一个engine,其主要作用是执行业务逻辑;
- Engine:引擎、只有一个,定义了一个名为Catalina的Engine
- Host:站点、虚拟主机,一个Engine包含多个Host的设计,使得一个服务器实例可以承担多个域名的服务。
- Context:一个应用,默认配置下webapps 下的每个目录都是一个应用
- Wrapper:一个servlet
容器的责任链模式
1、请求被Connector 组件接收,创建Request 和response对象
2、connector 将request和response交给container,依次通过engine的pipeline组件——>host 的pipeline——>context pipeline——>wrapper pipeline ——>wrapper 内部的wrapperValve 创建FilterChain 实例,调用指定的servlet 实例处理请求。在这些传递过程,请求都会经过内部的valve 过滤。
七、Tomcat 启动流程
八、嵌入式tomcat
嵌入式tomcat:非传统的部署方式,将tomcat 嵌入到主程序中进行运行。
优点:灵活部署,任意指定位置,通过复杂的条件判断。
maven 集成tomcat 插件:
<!-- pom.xml 引入插件 -->
<dependency>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version> </dependency>
插件运行:eclipse:选择pom.xml文件,击右键——>选择 Run As——> Maven build 在Goals框加加入以下命令: tomcat7:run
maven集成tomcat 插件,启动的方式就是调用了Tomcat的API来实现的。(Tomcat7RunnerCli 是它启动的引导类,Tomcat7RunnerCli 主要依赖于 Tomcat7Runner)Tomcat本身提供了外部调用的API,org.apache.catalina.startup.Tomcat 类就是供外部调用的tomcat 的入口。
九、手写嵌入式Tomcat
主要类:Tomcat
1、pom.xml 引入插件
<dependency>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</dependency>
2、servlet
package *********;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ResourceBundle;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DemoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.println("!!!!!!!!!!!!!!!!!!!!");
}
}
3、
package *********;
import org.apache.catalina.Context;
import org.apache.catalina.Host;
import org.apache.catalina.Wrapper;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
public class EmbeddedTomcatServer {
public static void main(String[] args) throws Exception{
//把目录的绝对的路径获取到
String classpath = System.getProperty("user.dir");
Tomcat tomcat = new Tomcat();
Connector connector = tomcat.getConnector();
connector.setPort(9091);
//设置Host
Host host = tomcat.getHost();
//我们会根据xml配置文件来
host.setName("localhost");
host.setAppBase("webapps");
//把class加载进来,把启动的工程加入进来了
Context context =tomcat.addContext(host, "/", classpath);
if(context instanceof StandardContext){
StandardContext standardContext = (StandardContext)context;
standardContext.setDefaultContextXml("web.xml 绝对的路径");
//我们要把Servlet设置进去
Wrapper wrapper = tomcat.addServlet("/", "DemoServlet", new DemoServlet());
wrapper.addMapping("/test");
}
//Tomcat跑起来
tomcat.start();
//强制Tomcat server等待,避免main线程执行结束后关闭
tomcat.getServer().await();
}
}
十、相关问题
非阻塞模式(NIO):通道(Channel)、缓冲区(Buffer)、选择器(Selector