हमारे पास क्लाइंट सर्वर ऐप, 1 सर्वर, लगभग 10 क्लाइंट हैं। वे कस्टम प्रश्नों का उपयोग कर टीसीपी सॉकेट के माध्यम से संवाद करते हैं।पूर्ण जीसी के बाद सॉकेट कनेक्शन धीमा क्यों हुआ?
प्रणाली की गई कई महीनों के लिए सहज बनाए थे, लेकिन कुछ बिंदु पर, शेड्यूल किए गए दैनिक सर्वर पूर्ण जीसी उस के बारे में 50 के दशक ले लिया के बाद, हम पता लगा है कि ग्राहक द्वारा भेजे गए प्रश्नों और प्रतिक्रियाओं के बीच के समय से प्राप्त सर्वर बड़ा था,> 10-20s। कुछ 3 घंटों के बाद सिस्टम ठीक हो गया, सब ठीक हो रहा था।
समस्या की जांच करते समय हमने पाया: दोनों ग्राहकों पर
- कोई कचरा संग्रहण की समस्याओं और सर्वर
- क्वेरी प्रसंस्करण समय पर सर्वर छोटा था।
- सर्वर पर लोड उच्च था।
- नेटवर्क बैंडविड्थ संतृप्त नहीं था।
- पूर्ण जीसी के दौरान कनेक्शन रीसेट नहीं किए गए थे (दैनिक पूर्ण जीसी तब तक एक सामान्य घटना थी)
- मशीन और ओएस हाल ही में सेंटोस 6 (कर्नेल 2.6.32) से सेंटोस 7 (कर्नेल 3.10.0) में बदल गया है। , लेकिन नई कॉन्फ़िगरेशन का विस्तार किया गया था। ओरेकल जेडीके संस्करण भी 1.7.65 से 1.7.75 में बदल गया।
हम सर्वर पर एक धागा डंप ले लिया:
public int read() throws IOException {
return in.read();
}
in
हमारे कोड में एक BufferedInputStream
है:
java.lang.Thread.State: RUNNABLE
at java.io.FilterInputStream.read(FilterInputStream.java:83)
at util.network.BytesBasedSocketConnection$ReadConnectionRunnable.run(BytesBasedSocketConnection.java:293)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
FilterInputStream.read()
निम्नलिखित है।
प्रश्न हैं: पूर्ण जीसी विराम के बाद अधिकांश कनेक्शन क्यों धीमा हो गए? स्टैकट्रैक FilterInputStream.read()
में क्यों समाप्त होता है? क्या यह BufferedInputStream
या सॉकेट इनपुट स्ट्रीम में कहीं खत्म नहीं होना चाहिए? क्या यह सर्वर पर उच्च लोड के लिए पढ़ा जा सकता है?
कोड हम पढ़ने के लिए उपयोग करें:
int constructLength = _socketDIS.readInt();
ByteArrayOutputStream constructBOAS = new ByteArrayOutputStream(constructLength);
for (int i = 0; i != constructLength; i++)
constructBOAS.write(_socketDIS.read());
constructBOAS.close();
byte[] bytes = constructBOAS.toByteArray();
जहां:
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
- locked <0x00007f522cbebca8> (a java.io.BufferedInputStream)
at java.io.DataInputStream.readInt(DataInputStream.java:387)
at util.network.BytesBasedSocketConnection$ReadConnectionRunnable.run(BytesBasedSocketConnection.java:287)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
अद्यतन:
_socketDIS = new DataInputStream(new BufferedInputStream(_socket.getInputStream()));
यहाँ अच्छी तरह से काम कर रहे ग्राहक कनेक्शन से स्टैकट्रेस है
EJP जवाब के बारे में:
कोई EOS शामिल था, कनेक्शन थे, लेकिन वे बहुत धीमी गति से थे
यहां तक कि अगर वहाँ एक EOS मैं नहीं देख सकते हैं कि कोड स्पिन सकता था ईओएस पर,
for
constructLength
मूल्य से घिरा हुआ है। लेकिन फिर भी, सुझाया गया सुधार वैध है।समस्या से स्टैकट्रेस पढ़ने एक
DataInputStream
((_socketDIS.read()
) पर किया किFilterInputStream.read()
से विरासत में मिला है में समाप्त होता है, इसके बाद के संस्करण कोड देखें।DataInputStream
,BufferedInputStream
read()
गुम है। यहांFilterInputStream.read()
मेंin.read()
BufferedInputStream
पर बुलाया गया है, इसकी इसकीread()
विधि परिभाषित है। लेकिन स्टैकट्रैक बीच में बंद हो जाता है,BufferedInputStream.read()
तक नहीं पहुंच रहा है। क्यूं कर?
आह, वास्तव में एक 'अनुसूचित थ्रेडपूलएक्ससेलर' गलत तरीके से उपयोग किया जाता है, लेकिन यह कार्य लगातार चल रहा है, यह सिर्फ सॉकेट से प्रश्न पढ़ता है और उन्हें कतार में रखता है। – dcernahoschi