这是我试图解决的问题,也许JRE中的错误请投票重新打开这个问题。如果你没有足够的能力去理解某些问题,这是非常自私的方法来标记某些主题。
Java版
java版“1.7.0_45” Java(TM)SE运行时环境(版本1.7.0_45-b18) Java HotSpot(TM)64位服务器VM(内置24.45-b08,混合模式)
以下两个版本的代码都会产生相同的崩溃。
客户端计算机使用在Windows Server 2003 64位,使用Oracle 10g数据库和Hibernate 3.0上运行的服务器缓存来调用部署在Tomcat 7中的Servlet。
当我尝试将负载加载到Servlet上进行负载测试时,我编写了以下两个方法,这两个方法只是创建一个线程并调用Synchronous方法,但是没有任何堆栈跟踪日志我的进程在Eclipse中。
我不知道崩溃的原因如果我创建500个线程然后它在487崩溃并且如果我创建1000个线程然后它在874崩溃。我不知道真正的原因是什么。我已经配置了StuckThreadDetectionValve来检测长时间运行的线程。
https://stackoverflow.com/a/7484800/185022
我将在这里分享所有更新。如果你知道可能出错的话,请至少给我一个提示。
**两个代码都会产生相同的崩溃**
代码1:
public class TokenTest {
static int count = 0;
public static void main(String[] args) {
try {
System.out.println("Start " + new Date());
final ApplicationServiceClient app = WSClient.getClient("http://192.168.1.15:81/az-server", ApplicationServiceClient.class);
final int max = 50;
ExecutorService executor = Executors.newFixedThreadPool(max);
for (int i = 1; i <= max; i++) {
executor.execute(new Runnable() {
public void run() {
try {
System.out.print(++count +",");
app.verifyToken("7056451004350030976"); //Network Synchronous Operation, calls a Servlet that is deployed in another Server Machine, Using Tomcat 7.0
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
executor.shutdown();
while (!executor.isShutdown()) {
System.out.println("END " + new Date());
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
代码2:
public class TokenTest {
static int count = 0;
public static void main(String[] args) {
try {
System.out.println(new Date());
final ApplicationServiceClient app = WSClient.getClient("http://192.168.1.15:81/az-server", ApplicationServiceClient.class);
final int max=250;
for (int i = 1; i <= max; i++) {
Thread t = new Thread() {
public void run() {
app.verifyToken("7056451004350030976");//Network Synchronous Operation
System.out.print(count++);
System.out.print(", ");
if (count >= max)
System.out.println("\n" + new Date());
}
};
t.start();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
注意: 该服务器托管在另一台Windows Server 2003 64位计算机上。
更新 它只是终止了我在Eclipse中的Java进程,如果我给出类似于5000的值,那么它就会停留在2800上,并且没有任何事情发生,也不会终止我的进程。这是一个控制台快照。
更新*
感谢S.Yavari。他走向了正确的方向。在Tomcat上配置Stuck_Thread_Detection_Valve并中断线程Stuck Threads
我能够在服务器上生成500K客户端负载而没有任何问题,并在开始新请求之前提供睡眠100 miliseconds
。< / p>
以下是代码:
public class StageOne {
final ApplicationServiceClient appClient = WSClient.getClient(Main.url, ApplicationServiceClient.class);
final SecureWebServiceClient secureClient = WSClient.getClient(Main.url, SecureWebServiceClient.class);
final static List<Long> times = new Vector<Long>();
String token = "";
public String authenticateClient() {
token = appClient.authenticateClient("az_y", "az", "0");
// System.out.println("Registration Response: " + token);
return token;
}
private void getDefaultDepartmentName() {
String deptname = appClient.getDefaultDepartmentName();
// System.out.println("Department: " + deptname);
}
private void getLocation() {
List<String> location = appClient.listLocation();
// System.out.println("Location: " + location);
}
private void registerClient_() {
secureClient.setToken(token);
String respon = secureClient.registerClient("Buddy AZ", "443", "njuy", "1");
// System.out.println(respon);
}
static int count = 0;
public static void main(String[] args) {
int pool = 500000;
final ExecutorService execotors = Executors.newFixedThreadPool(pool);
for (int i = 0; i < pool; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
execotors.execute(new Runnable() {
@Override
public void run() {
long startTime = System.nanoTime();
StageOne one = new StageOne();
one.authenticateClient();
one.getDefaultDepartmentName();
one.getLocation();
one.registerClient_();
long EndTime = System.nanoTime();
// System.out.println("Time in Seconds ("+ (++count) +")" + TimeUnit.NANOSECONDS.toSeconds(EndTime - startTime));
times.add(TimeUnit.NANOSECONDS.toSeconds(EndTime - startTime));
}
});
}
execotors.shutdown();
while (!execotors.isShutdown()) {
try {
Thread.sleep(10);
} catch (Exception e) {
// TODO: handle exception
}
}
Collections.sort(times);
long sum = 0;
for (int i = 0; i < times.size(); i++) {
sum += times.get(i);
}
long result = sum / Math.max(1, times.size());
System.out.println("Min Response Time: " + times.get(0));
System.out.println("Average Response Time: " + result);
System.out.println("Max Response Time: " + times.get(times.size() - 1));
}
}
答案 0 :(得分:3)
我认为这只是一个线程问题。使用此代码:
public class Test2 {
public static final Object LOCK = new Object();
static int count = 0;
public static void main(String[] args) {
try {
System.out.println(new Date());
final ApplicationServiceClient app = WSClient.getClient("http://192.168.1.15:81/az-server", ApplicationServiceClient.class);
final int max=250;
for (int i = 1; i <= max; i++) {
Thread t = new Thread() {
public void run() {
synchronized (LOCK) {
app.verifyToken("7056451004350030976");
}
System.out.print(count++);
System.out.print(", ");
if (count >= max)
System.out.println("\n" + new Date());
}
};
t.start();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
此方法(verifyToken
)必须是线程安全的,否则在线程中使用此方法会遇到很多问题。
答案 1 :(得分:1)
在代码1中,代码没有崩溃。它按设计工作。该代码似乎没有任何问题。