Tôi có một máy chủ trò chơi JAVA sử dụng 1 luồng cho mỗi kết nối TCP. (Tôi biết nó xấu nhưng tôi sẽ phải giữ nó theo cách này bây giờ). Trên một (3.2GHz 6cor máy x2, RAM 24GB, Windows Server 2003 64bits) và đây là một phần của mã:BufferedReader.read() ăn 100% của CPU
public void run()
{
try
{
String packet = "";
char charCur[] = new char[1];
while(_in.read(charCur, 0, 1)!=-1 && Server.isRunning)
{
if (charCur[0] != '\u0000' && charCur[0] != '\n' && charCur[0] != '\r')
{
packet += charCur[0];
}else if(!packet.isEmpty())
{
parsePlayerPacket(packet);
packet = "";
}
}
}catch(Exception e)
{
e.printStackTrace();
}
finally
{
try{
kickPlayer();
}catch(Exception e){e.printStackTrace();};
Server.removeIp(_ip);
}
}
Sau khoảng 12 giờ hoặc nhiều máy chủ thời gian hoạt động (và khoảng 3.000 người chơi kết nối) các máy chủ bắt đầu ăn 100% của tất cả 12 CPU cho đến khi tôi tự khởi động lại ứng dụng JAVA. Vì vậy, trò chơi bắt đầu tụt hậu verry xấu và người chơi của tôi bắt đầu phàn nàn.
Tôi đã thử profiling ứng dụng và đây là những gì tôi đã đưa ra:
Vì vậy, tôi đoán rằng vấn đề xuất phát từ đây:
while(_in.read(charCur, 0, 1)!=-1 && Server.isRunning)
biết rằng biến "_in" là một đầu đọc của đầu vào socket: (_in = new BufferedReader (new InputStreamReader (_socket.getInputStream()))).
Tại sao trên trái đất _in.read() mất quá nhiều CPU sau một thời gian chờ máy chủ dài?
Tôi đã thử đặt một Thread.sleep (1); và nhiều hơn nữa bên trong vòng lặp while, nhưng không làm bất cứ điều gì, tôi đoán vấn đề nằm bên trong phương thức BufferedReader.read().
Có ai có bất kỳ ý tưởng nào về điều gì có thể gây ra điều này không ?? Và làm thế nào để khắc phục nó?
Tôi ngạc nhiên vì điều này thay vì thực tế là bạn đang sử dụng nối chuỗi trong một vòng lặp. Và * tại sao * bạn chỉ đọc một nhân vật duy nhất tại một thời điểm? –
các gói là các chuỗi nhỏ verry như: "AB123". vì vậy nó không quan trọng. – Reacen
Cho đến khi bạn kết thúc được gửi một chuỗi lớn bởi ai đó tung ra một cuộc tấn công DDOS vào bạn. Thật dễ dàng để đọc nhiều ký tự và * cũng * để sử dụng StringBuilder ... tại sao không làm như vậy? –