gpt4 book ai didi

java - 当我运行超过 1 个几乎完全相同的 java servlet 时,为什么我的服务器会崩溃?

转载 作者:行者123 更新时间:2023-11-28 23:33:54 25 4
gpt4 key购买 nike

我在 tomcat 7 VPS 服务器上运行 2 个 java (7) servlet。一个 servlet 返回 json 响应,另一个 servlet 返回 4 行纯 html 代码。

如果我只运行 json 响应 servlet,我每天处理 12+ 百万个请求(每秒约 140 个请求)没有问题。

目前我只在 json servlet 上运行一半的流量(所以每秒大约 70 个请求)。

如果我添加返回 html 的 servlet,当此 servlet 的请求数甚至没有达到每秒 20 次时,服务器响应时间会激增并返回错误。 (因此请求总量约为每秒 90 个)。

但是,如果对 html servlet 的请求下降到每分钟约 2 个,一切都很好。所以看起来 servlet 本身没有任何错误。

我正在运行的两个 servlet 是:

// Loading required libraries
import java.lang.*;
import java.io.*;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import javax.sql.DataSource;
import javax.naming.*;
import java.util.Random;
import java.math.*;
import java.security.*;
import java.sql.*;

/**
* Servlet implementation class test
*/
@WebServlet("/html")
public class html extends HttpServlet{
private static final long serialVersionUID = 12L;

public html() {
super();
// TODO Auto-generated constructor stub
}
private DataSource dataSource;

public void init() throws ServletException {
try {
// Get DataSource
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
dataSource = (DataSource)envContext.lookup("jdbc/testdb");
System.out.println("Obtained Cached Data Source ");

} catch (NamingException e) {
e.printStackTrace();
}
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{

// Get all parameters from request.

String source = null;
String UA = null;
String id = null;
String ip = null;

source = request.getParameter("source");
UA = request.getHeader("User-Agent");
//is client behind something?
ip = request.getHeader("X-FORWARDED-FOR");
if (ip == null) {
ip = request.getRemoteAddr();
}


Connection conn = null;
Statement stmt = null;
int exit = 0;

// Set response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();

try{
// Open a connection
conn = dataSource.getConnection();
stmt = conn.createStatement();
// Execute SQL query
stmt = conn.createStatement();
String sql;
sql = "SELECT data from db";
ResultSet rs = stmt.executeQuery(sql);

rs.next();
String url = rs.getString("url");
String url_src = rs.getString("url_src");



out.println("<html>");
out.println("<body>");
out.println("<a href=\"url\">");
out.println("<img src=\"url_src\"/></a>");
out.println("</body></html>");


long time = System.currentTimeMillis()/1000;

Random randomGenerator = new Random();
int randomInt = randomGenerator.nextInt(250);
String toEnc = ip + time + UA + randomInt; // Value to hash
MessageDigest mdEnc = MessageDigest.getInstance("MD5");
mdEnc.update(toEnc.getBytes(), 0, toEnc.length());
id = new BigInteger(1, mdEnc.digest()).toString(16);// Hashed

sql = "insert request";
stmt.execute(sql);




// Clean-up environment
rs.close();
stmt.close();
conn.close();
}catch(SQLException se){
//Handle errors for JDBC
se.printStackTrace();
}catch(Exception e){
//Handle errors for Class.forName
e.printStackTrace();
}finally{
//finally block used to close resources
try{
if(stmt!=null)
stmt.close();
}catch(SQLException se2){
}// nothing we can do
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}//end finally try
} //end try*/

}
}

第二个 servlet 是:

// Loading required libraries
import java.lang.*;
import java.io.*;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import javax.sql.DataSource;
import javax.naming.*;
import java.util.Random;
import java.math.*;
import java.security.*;
import java.sql.*;

/**
* Servlet implementation class test
*/
@WebServlet("/json")
public class json extends HttpServlet{
private static final long serialVersionUID = 11L;

public json() {
super();
// TODO Auto-generated constructor stub
}
private DataSource dataSource;

public void init() throws ServletException {
try {
// Get DataSource
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
dataSource = (DataSource)envContext.lookup("jdbc/testdb");
System.out.println("Obtained Cached Data Source ");

} catch (NamingException e) {
e.printStackTrace();
}
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{

// Get all parameters from request.

String source = null;
String UA = null;
String id = null;
String ip = null;


source = request.getParameter("source");
UA = request.getParameter("ua");
ip = request.getParameter("clientIP");

Connection conn = null;
Statement stmt = null;
int exit = 0;

// Set response content type
response.setContentType("application/json");
PrintWriter out = response.getWriter();

try{
// Open a connection
conn = dataSource.getConnection();
stmt = conn.createStatement();
// Execute SQL query
stmt = conn.createStatement();
String sql;
sql = "SELECT * from db";
ResultSet rs = stmt.executeQuery(sql);

rs.next();
String url = rs.getString("url");
String url_src = rs.getString("url_src");



String jsonResponse = "{\"url\":\"url\","\"media_url\":\"url_src\"}";
out.println(jsonResponse);

long time = System.currentTimeMillis()/1000;

Random randomGenerator = new Random();
int randomInt = randomGenerator.nextInt(250);
String toEnc = ip + time + UA + randomInt; // Value to hash
MessageDigest mdEnc = MessageDigest.getInstance("MD5");
mdEnc.update(toEnc.getBytes(), 0, toEnc.length());
id = new BigInteger(1, mdEnc.digest()).toString(16);// Hashed

sql = "insert request";
stmt.execute(sql);




// Clean-up environment
rs.close();
stmt.close();
conn.close();
}catch(SQLException se){
//Handle errors for JDBC
se.printStackTrace();
}catch(Exception e){
//Handle errors for Class.forName
e.printStackTrace();
}finally{
//finally block used to close resources
try{
if(stmt!=null)
stmt.close();
}catch(SQLException se2){
}// nothing we can do
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}//end finally try
} //end try*/

}
}

我已经用 JDBC 设置了一个连接池。我有以下 config.xml 文件:

<?xml version='1.0' encoding='utf-8'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- The contents of this file will be loaded for each web application -->
<Context>

<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>

<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->

<!-- Uncomment this to enable Comet connection tacking (provides events
on session expiration as well as webapp lifecycle) -->
<!--
<Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
-->

<Resource name="jdbc/testdb"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/database"
username="username"
password="password"
maxActive="250"
maxIdle="60"
minIdle="30"
maxWait="10000"
poolPreparedStatements="true"
maxOpenPreparedStatements="100"
/>


</Context>

我已经在文件/tomcat/bin/setenv.sh 中设置了环境变量或 JAVA_OPTS:

export CATALINA_OPTS="-Djava.library.path=/usr/local/apr/lib"

NORMAL="-d64 -Xmx1536m -Xms512m -server"
MAX_PERM_GEN="-XX:MaxPermSize=512m"
HEADLESS="-Djava.awt.headless=true"

JAVA_OPTS="$NORMAL $MAX_PERM_GEN $HEADLESS"
export JAVA_OPTS

我的 vps 有 2gb 的内存,4 个 2ghz 的 cpu 内核。我曾尝试更改堆大小或 MaxPermSize,但这似乎并不重要。

有人可以向我解释我在配置上做错了什么吗?我不明白为什么服务器仅用一个 servlet 就可以处理如此多的负载,而当流量被分配给另一个 servlet 时却崩溃了。

谢谢

最佳答案

Hagubear 感谢您提供信息,但问题出在两个 out.println() 语句中。在此线程 [1] 中:Do not use System.out.println in server side code

我发现使用这个是不好的做法。现在我只将它放在 1 个 out.println() 中,服务器运行得更好。

谢谢

关于java - 当我运行超过 1 个几乎完全相同的 java servlet 时,为什么我的服务器会崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26847043/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com