tomcat源码接收请求_tomcat处理请求

hacker|
116

文章目录:

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自带的线程池吧。

1条大神的评论

  • avatar
    访客 2022-07-04 下午 02:29:12

    h (Throwable t) { // This means we got an OOM or similar creating a thread, or that // the pool and its queue

发表评论