0

一些背景

我正在做一个项目,我们有一个从 1999 年开始用 Java EE 1.4 编写的过时的非常简单的书店 Web 应用程序。但是,目的是对其进行现代化改造,以便在 Amazon AWS 等云环境中运行。我们决定从头开始重写它,使用 Spring 框架、Hibernate 和 c3p0 进行连接池。

除了 Web 应用程序,我们还有一个用于 Web 应用程序的压力工具,称为 RBE(远程浏览器模拟器)。您只需告诉 RBE 您想要多少用户,他就会为每个用户创建一个线程。每个线程随机生成 url,只要用户浏览页面(我们定义用户浏览站点 180 秒),它就会这样做。之后,它关闭了一个线程,就是这样。对于每个请求,它需要 HTML 页面源,解析出 jsessionid,然后继续下一个 url。

问题

当我为 400 个用户(即每秒 400 个请求)运行 RBE 时,我很快得到以下异常:

java.net.SocketException: Connection reset by peer
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:382)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:241)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:228)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:431)
    at java.net.Socket.connect(Socket.java:527)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:158)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:388)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:523)
    at sun.net.www.http.HttpClient.<init>(HttpClient.java:227)
    at sun.net.www.http.HttpClient.New(HttpClient.java:300)
    at sun.net.www.http.HttpClient.New(HttpClient.java:317)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:970)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:911)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:836)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1172)
    at rbe.EB.getHTML(EB.java:423)
    at rbe.EB.run(EB.java:324)

过了一会儿,当 RBE 尝试浏览其他子页面时,我得到:

java.net.ConnectException: Operation timed out
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:382)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:241)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:228)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:431)
    at java.net.Socket.connect(Socket.java:527)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:158)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:388)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:523)
    at sun.net.www.http.HttpClient.<init>(HttpClient.java:227)
    at sun.net.www.http.HttpClient.New(HttpClient.java:300)
    at sun.net.www.http.HttpClient.New(HttpClient.java:317)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:970)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:911)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:836)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1172)
    at rbe.EB.getHTML(EB.java:423)
    at rbe.EB.run(EB.java:324)

EB.java:423)(发生异常的地方)的代码是:

BufferedReader in = new BufferedReader( new InputStreamReader(connection.getInputStream() ) );

我的my.cnf配置:

[mysqld]
log=/var/log/mysqld.log
max_connections = 200
log-slow-queries = /var/log/mysqld_slow_queries.log
log-error = /usr/local/mysql/data/mysql-error.log
back-log = 200 
key_buffer_size=16M
max_allowed_packet=100M
interactive_timeout=30
wait_timeout=30

Tomcat相关设置server.xml

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" acceptCount="500" />

我还做了一个测试,并以 2 秒的延迟提供静态 html 文件,并且没有对数据库进行任何迭代。我做了这个测试,看看 Tomcat 是否不能处理 400 个并发请求。Tomcat 成功通过了这个测试。

400并发访问mysql的瓶颈是什么?这对 MySQL 来说太多了吗?

4

1 回答 1

0

您的 my.cnf 声明 max_connections = 200。这可能是个问题。

顺便说一句,400 个请求。很多。

于 2013-08-29T12:12:04.967 回答