文章目录:
tomcat挂起不接收请求
将进程中的javaw.exe关掉,重启tomcat试试。
再不行的话直接找到tomcat安装包D:\apache-tomcat-6.0.32\conf下的server.xml文件,打开xml,找到8005(
Connector port="8005" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" /
)
把8005修改下再重启就绝对没问题了
tomcat 接收get请求一定会处理成功吗
一般来说,access_log中有,说明tomcat已经接收到请求了,而你日志中并没有,那么你首先应该尝试在你处理该路径请求的程序代码中断点调试,看看是否到了你自己的代码、你的代码是否能够正常运行结束;然后再检查你的log4j之类的日志配置,特别是用AOP做日志的前提下是否切到了你的这个方法代码。
总之,一般tomcat是不会出问题的,重点检查你自己
tomcat 和 apache 整合后利用Tomcat 进行URL重写
楼上回答没看清人家的提问。。。。
在conf/server.xml里面,host元素底下,加上下面的语句
Context path="" docBase="E:/work/map2/WebRoot" reloadable="true" /
docbase是你的项目路径
这样的话,访问IP地址,出现的就是你的项目,而不是黄色的tomcat默认画面了
考一个server.xml的详解给你
1. Server port="8005" shutdown="SHUTDOWN"
2. !--属性说明
3. port:指定一个端口,这个端口负责监听关闭Tomcat的请求
4. shutdown:向以上端口发送的关闭服务器的命令字符串
5. --
6. Listener className="org.apache.catalina.core.AprLifecycleListener" /
7. Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" /
8. Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /
9. Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/
10.
11. GlobalNamingResources
12.
13. Environment name="simpleValue" type="java.lang.Integer" value="30"/
14.
15. Resource name="UserDatabase" auth="Container"
16. type="org.apache.catalina.UserDatabase"
17. description="User database that can be updated and saved"
18. factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
19. pathname="conf/tomcat-users.xml" /
20.
21. /GlobalNamingResources
22. !--
23. 每个Service元素只能有一个Engine元素.元素处理在同一个Service中所有Connector元素接收到的客户请求
24. --
25. Service name="Catalina"
26. !--属性说明
27. name:Service的名称
28. --
29.
30.
31.
32. !--
33. Connector元素:由Connector接口定义.Connector元素代表与客户程序实际交互的给件,
34. 它负责接收客户请求,以及向客户返回响应结果.
35. --
36. Connector port="80" maxHttpHeaderSize="8192"
37. maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
38. enableLookups="false" redirectPort="8443" acceptCount="100"
39. connectionTimeout="20000" disableUploadTimeout="true" /
40. !--属性说明
41. port:服务器连接器的端口号,该连接器将在指定端口侦听来自客户端的请求
42. enableLookups:如果为true,则可以通过调用request.getRemoteHost()进行DNS查询来得到远程客户端
43. 的实际主机名;若为false则不进行DNS查询,而是返回其ip地址
44. redirectPort:服务器正在处理http请求时收到了一个SSL传输请求后重定向的端口号
45. acceptCount:当所有可以使用的处理请求的线程都被用光时,可以放到处理队列中的请求数,超过这个数
46. 的请求将不予处理,而返回Connection refused错误
47. connectionTimeout:等待超时的时间数(以毫秒为单位)
48. maxThreads:设定在监听端口的线程的最大数目,这个值也决定了服务器可以同时响应客户请求的最大数目.默认值为200
49. protocol:必须设定为AJP/1.3协议.
50. address:如果服务器有两个以上IP地址,该属性可以设定端口监听的IP地址,默认情况下,端口会监听服务器上所有IP地址.
51. minProcessors:服务器启动时创建的处理请求的线程数,每个请求由一个线程负责
52. maxProcessors:最多可以创建的处理请求的线程数
53. minSpareThreads:最小备用线程
54. maxSpareThreads:最大备用线程
55. debug:日志等级
56. disableUploadTimeout:禁用上传超时,主要用于大数据上传时
57. --
58.
59.
60. Connector port="8009"
61. enableLookups="false" redirectPort="8443" protocol="AJP/1.3" /
62.
63.
64. Engine name="Catalina" defaultHost="localhost"
65. !--属性说明
66. name:对应$CATALINA_HOME/config/Catalina中的Catalina
67. defaultHost:对应Host元素中的name属性,也就是和$CATALINA_HOME/config/Catalina/localhost中的localhost
68. 缺省的处理请求的虚拟主机名,它至少与其中的一个Host元素的name属性值是一样的
69. debug:日志等级
70. --
71.
72. Realm className="org.apache.catalina.realm.UserDatabaseRealm"
73. resourceName="UserDatabase"/
74. !--
75. 由Host接口定义.一个Engine元素可以包含多个Host元素.
76. 每个Host的元素定义了一个虚拟主机.它包含了一个或多个Web应用.
77. --
78. Host name="localhost" appBase="webapps"
79. unpackWARs="true" autoDeploy="true"
80. xmlValidation="false" xmlNamespaceAware="false"
81. !--属性说明
82. name:在此例中一直被强调为$CATALINA_HOME/config/Catalina/localhost中的localhost
83. 虚拟主机名
84. debug:是日志的调试等级
85. appBase:默认的应用路径,也就是把应用放在一个目录下,并在autoDeploy为true的情况下,可自动部署应用此路径相对于 $CATALINA_HOME/ (web applications的基本目录)
86. unpackWARs:设置为true,在Web应用为*.war是,解压此WAR文件.
87. 如果为true,则tomcat会自动将WAR文件解压;否则不解压,直接从WAR文件中运行应用程序.
88. autoDeploy:默认为true,表示如果有新的WEB应用放入appBase 并且Tomcat在运行的情况下,自动载入应用
89. --
90.
91. Context path="/demm" docBase="E:\\projects\\demm\\WebRoot" debug="0" reloadable="true"
92. /Context
93. !--属性说明
94. path:访问的URI,如:是我的应用的根目录,访问此应用将用:进行操作,此元素必须.
95. 表示此web application的URL的前缀,用来匹配一个Context。请求的URL形式为*
96. docBase:WEB应用的目录,此目录必须符号Java WEB应用的规范.
97. web application的文件存放路径或者是WAR文件存放路径
98. debug:日志等级
99. reloadable:是否在程序有改动时重新载入,设置成true会影响性能,但可自动载入修改后的文件.
100. 如果为true,则Tomcat将支持热部署,会自动检测web application的/WEB-INF/lib
101. 和/WEB-INF/classes目录的变化,自动装载新的JSP和Servlet,我们可以在不重起
102. Tomcat的情况下改变web application
103. --
104. /Host
105.
106. /Engine
107.
108. /Service
109.
110. /Server
tomcat是怎样接收http请求的
在默认的配置中tomcat采用Http11Protocol这个类来处理接收到的请求,
Http11Protocol又调用JIoEndpoint类实现对数据的接收,
JIoEndpoint类调用Http11Processor类实现对数据的解析。
当然还可以采用jno的方式接收请求,它的特点是处理并发请求效率高。原因是采用jno处理socket,不用为每个socket都分配线程。
因为jno中增加了选择器selector,它可以监视各个TCP连接,把准备好的TCP连接交给上层来处理。
这个还是得操作系统支持这种监视TCP连接的特性,在一个不支持此特定的操作系统上用jno也是枉然,
关于tomcat采用jno方式接收请求,还需用业余时间好好了解下。
具体说明一下JIoEndpoint类,它是怎样接收数据的。
在init()方法中
serverSocket = serverSocketFactory.createSocket(port, backlog, address);
创建serverSocket监听8080端口,说明了tomcat原来是用socket来接收请求的。
然后启动了Acceptor线程
这个线程的run方法:
Socket socket = serverSocketFactory.acceptSocket(serverSocket);
再看serverSocketFactory.acceptSocket的实现
public Socket acceptSocket(ServerSocket socket)
throws IOException {
return socket.accept();
}
一个典型的socket应用方式。serverSocket监听请求。
再接收到socket后,处理这个socket。这个socket就是浏览器或其他客户端与服务器建立的TCP连接。在这个连接中,传输了http协议格式的内容。
protected boolean processSocket(Socket socket) {
try {
if (executor == null) {
getWorkerThread().assign(socket);
} else {
executor.execute(new SocketProcessor(socket));
}
} catch (Throwable t) {
// This means we got an OOM or similar creating a thread, or that
// the pool and its queue are full
log.error(sm.getString("endpoint.process.fail"), t);
return false;
}
return true;
}
如果有jdk的线程池,就采用jdk自带的线程池处理它。如果没有就用JIoEndpoint类中实现的简易线程池处理。
默认的情况下没有配置jdk线程池,于是采用简易线程池处理。
简易线程池是JIoEndpoint类的内部类WorkerStack以及Worker实现的。
worker是一个线程,处理socket,同时加入了生产者
WorkerStack包含worker的数组以及对这个数组的处理。
getWorkerThread()是从WorkerStack中拿一个已经启动的worker线程出来。
重点讲述worker。
assign(socket) 调用worker的assign方法。
以下是worker的三个重要方法以及一个重要的变量available
protected boolean available = false;
synchronized void assign(Socket socket) {
// Wait for the Processor to get the previous Socket
while (available) {
try {
wait();
} catch (InterruptedException e) {
}
}
// Store the newly available Socket and notify our thread
this.socket = socket;
available = true;
notifyAll();
}
private synchronized Socket await() {
// Wait for the Connector to provide a new Socket
while (!available) {
try {
wait();
} catch (InterruptedException e) {
}
}
// Notify the Connector that we have received this Socket
Socket socket = this.socket;
available = false;
notifyAll();
return (socket);
}
public void run() {
// Process requests until we receive a shutdown signal
while (running) {
// Wait for the next socket to be assigned
Socket socket = await();
if (socket == null)
continue;
// Process the request from this socket
if (!setSocketOptions(socket) || !handler.process(socket)) {
// Close socket
try {
socket.close();
} catch (IOException e) {
}
}
// Finish up this request
socket = null;
recycleWorkerThread(this);
}
}
首先worker线程是运行着的,它执行到await()的时候,available为false,这时等待,不再继续执行。
调用assign的时候,available为false,不执行wait,方法继续执行,获得了一个socket,然后通知这个线程可以继续执行了。
于是在await()方法中,开始继续执行,返回Socket socket,run方法继续执行处理这个socket.
处理完毕后,再次调用await(),available为false,再次等待。直到再次assign唤醒它。
这样一个线程可以为多个socket服务。
先总结到这里。线程同步,如果写不好。就用jdk自带的线程池吧。
h (Throwable t) { // This means we got an OOM or similar creating a thread, or that // the pool and its queue