tomcat

Servlet中的url-pattern配置

匹配方法只有三种,要么是路径匹配(以“/”字符开头,并以“/*”结尾),要么是扩展名匹配(以“*.”开头),要么是精确匹配,三种匹配方法不能进行组合,不要想当然使用通配符或正则规则。

  如<url-pattern>/user/*.action</url-pattern>是非法的;

  另外注意:<url-pattern>/aa/*/bb</url-pattern>是精确匹配,合法,这里的*不是通配的含义。

当servlet容器接收到浏览器发起的一个url请求后,容器会用url减去当前应用的上下文路径,以剩余的字符串作为servlet映射,假如url是http://localhost:8080/appDemo/index.html,其应用上下文是appDemo,容器会将http://localhost:8080/appDemo去掉,用剩下的/index.html部分拿来做servlet的映射匹配

"/*"和"/"含义并不相同

  • “/*”属于路径匹配,并且可以匹配所有request,由于路径匹配的优先级仅次于精确匹配,所以“/*”会覆盖所有的扩展名匹配,很多404错误均由此引起,所以这是一种特别恶劣的匹配模式,一般只用于filter的url-pattern
  • “/”是servlet中特殊的匹配模式,且该模式有且仅有一个实例,优先级最低,不会覆盖其他任何url-pattern,只是会替换servlet容器的内建default servlet ,该模式同样会匹配所有request。

在使用springmvc时,如果将dispatcherServlet配置为“/*”就会出现问题,此时所有请求都会经过dispatcherServlet(除了精确路径),如果请求的是一个jsp,我们并没有Controllor与之对应,这是dispatcherServlet就会将请求forword到defaultServlet,但defaultServlet是只能处理静态文件,所以经过defaultServlet处理的jsp只能以纯文本的形式返回给客户端,而不会进经过jsp引擎解析。

server.xml配置

 

 1 <?xml version='1.0' encoding='utf-8'?>  
 2 <Server port="8007" shutdown="SHUTDOWN">  
 3   <Listener className="org.apache.catalina.startup.VersionLoggerListener" />  
 4     
 5   <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />  
 6   <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->  
 7   <Listener className="org.apache.catalina.core.JasperListener" />  
 8   <!-- Prevent memory leaks due to use of particular java/javax APIs-->  
 9   <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />  
10   <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />  
11   <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />  
12   
13   <!-- Global JNDI resources  
14        Documentation at /docs/jndi-resources-howto.html  
15   -->  
16   <GlobalNamingResources>  
17     <!-- Editable user database that can also be used by  
18          UserDatabaseRealm to authenticate users  
19     -->  
20     <Resource name="UserDatabase" auth="Container"  
21               type="org.apache.catalina.UserDatabase"  
22               description="User database that can be updated and saved"  
23               factory="org.apache.catalina.users.MemoryUserDatabaseFactory"  
24               pathname="conf/tomcat-users.xml" />  
25   </GlobalNamingResources>  
26   
27   <!-- A "Service" is a collection of one or more "Connectors" that share  
28        a single "Container" Note:  A "Service" is not itself a "Container",  
29        so you may not define subcomponents such as "Valves" at this level.  
30        Documentation at /docs/config/service.html  
31    -->  
32   <Service name="Catalina">  
33     <Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>  
34     <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />  
35     <Engine name="Catalina" defaultHost="localhost">   
36       <Realm className="org.apache.catalina.realm.LockOutRealm">  
37         <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>  
38       </Realm>  
39   
40       <!-- 访问路径:www.zyong.com  -->  
41      <Host name="www.zyong.com"  appBase="webapps" unpackWARs="true" autoDeploy="true">  
42         <Context path="/" docBase="D:\tomcat\webapps\zyong" allowLinking="true" />  
43           
44         <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"  
45                prefix="localhost_access_log." suffix=".txt"  
46                pattern="%h %l %u %t "%r" %s %b" />  
47   
48       </Host>  
49   
50       <!-- 访问路径:www.zhangy.com  -->  
51      <Host name="www.test2.com.cn"  appBase="webapps" unpackWARs="true" autoDeploy="true">  
52         <Context path="/" docBase="D:\tomcat\webapps\zhangy" allowLinking="true" />  
53           
54         <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"  
55                prefix="localhost_access_log." suffix=".txt"  
56                pattern="%h %l %u %t "%r" %s %b" />  
57   
58       </Host>  
59   
60   
61     </Engine>  
62   </Service>  
63 </Server>  
View Code

 

tomcat组件

 

由上图可以看到tomcat由server(tomcat)、service、connector(一个service可以有多个connector,connector直接面对socket,将字节流反序列化成httpRequest对象)、engine(engine用于处理处理请求、响应,engine中又包括host、context、Servlet)等组成。

connector在指定端口监听,连接到来时就可以确定哪个connector服务,connector accept到socket后就会启动一个线程,从socket中读取字节流并反序列化为httpRequest对象;engine通过识别http请求中的host头部,将请求传给对应的host组件;host组件根据请求的上下文,将请求传给对应的context;context的下一级就是Servlet了,web.xml中配置的Servlet的url-pattern这时就起作用了,context根据请求的路径(去掉host和上下文部分)找到对应的Servlet;Servlet调用service进行服务。

 

keep-alive

1  <Connector executor="tomcatThreadPool"
2                port="8080" protocol="HTTP/1.1" 
3  keepAliveTimeout = “30000”
4                connectionTimeout="30000" maxKeepAliveRequests="10" 
5                redirectPort="8443" bufferSize="8192" sockedBuffer="65536" acceptCount="200"/>
keepAliveTimeout就是长连接空闲超时时间(毫秒),connectionTimeout是连接建立超时时间(毫秒),而maxKeepAliveRequests则指定了每个连接最大响应次数,这里设为10即表示处理完10个请求后就关闭该链接。

注意:我们关闭writer或outputStream时,其实并没有关闭socket通路,而只是关闭一个缓冲区,这是连接仍然存在,只有socket.close时才真正的关闭了一端。

 

线程池

在Connector中可以配置executor,executor就是一个线程池(ThreadPoolExecutor),线程池有几个重要参数:coreSize、maxSize、idleTime、threadFactory、blockingQueue,tomcat中的executor也不例外,当线程数大于coreSize且有空闲线程时,这些空闲线程会阻塞在blockingQueue上,当到达idleTime且没有新请求(任务)到来时,这些空闲线程就会自动消亡(这些线程阻塞在blockingQueue的定时poll上,当timeout时自动唤醒,没有从blockingQueue中得到请求任务,worker线程就会退出循环结束运行)。

bio的线程模型比较简单,一个或多个acceptor线程用于serverSocket.accept,多个worker线程(executor)用于处理socket;

nio的线程模型要复杂一些,同样有一个或多个acceptor线程用于serverSocket.accept,一个或多个poller线程用于select,多个worker线程(executor)处理select后的事件。

 

参考:http://www.cnblogs.com/canger/p/6084846.html

   http://tomcat.apache.org/tomcat-8.0-doc/config/http.html

  https://stackoverflow.com/questions/896789/java-is-serversocket-accept-threadsafe

posted @ 2017-10-01 21:15  holoyong  阅读(197)  评论(0编辑  收藏  举报