เนื่องจากระบบ SEOTcs อัปเดตอัลกอริธึมการให้คะแนน SEO เมื่อวันที่ 24 พฤศจิกายน ปัญหาที่กวนใจฉันจึงเกิดขึ้น ข้อผิดพลาดต่อไปนี้มักจะถูกรายงานระหว่างการดำเนินการงานข้อมูล Java:
"2011-12-03 18:00:32 DefaultHttpClient [INFO] ข้อยกเว้น I/O (java.net.SocketException) ตรวจพบเมื่อประมวลผลคำขอ: รีเซ็ตการเชื่อมต่อโดยเพียร์: ข้อผิดพลาดในการเขียนซ็อกเก็ต
2011-12-03 18:00:32 DefaultHttpClient [ข้อมูล] กำลังลองคำขออีกครั้ง”...
ด้วยเหตุนี้ ฉันจึงค้นหาเว็บไซต์บางแห่งในภาษาจีนและภาษาอังกฤษ ค้นหาทุกมุมที่ฉันพบ และพบสาเหตุที่ทำให้สถานการณ์นี้เกิดขึ้น ข้อยกเว้นของ Java นี้อาจเกิดขึ้นทั้งฝั่งไคลเอ็นต์และฝั่งเซิร์ฟเวอร์ สองเหตุผล:
1. หากซ็อกเก็ตที่ปลายด้านหนึ่งปิด (หรือปิดอยู่ หรือปิดเนื่องจากการออกที่ผิดปกติ) ปลายอีกด้านหนึ่งจะยังคงส่งข้อมูล และแพ็กเก็ตข้อมูลแรกที่ส่งไปจะทำให้เกิดข้อยกเว้นนี้ (เชื่อมต่อรีเซ็ตโดยเพียร์)
2. ปลายด้านหนึ่งออก แต่การเชื่อมต่อไม่ปิดเมื่อออก หากปลายอีกด้านหนึ่งอ่านข้อมูลจากการเชื่อมต่อ ข้อยกเว้น (รีเซ็ตการเชื่อมต่อ) จะถูกส่งออกไป พูดง่ายๆ ก็คือ เกิดจากการอ่านและเขียนหลังจากการเชื่อมต่อถูกตัดการเชื่อมต่อ
ดังนั้นฉันจึงคิดว่ามันสามารถแก้ไขได้โดยการตั้งค่าการหมดเวลาของซ็อกเก็ต:
แต่หลังจากตั้งค่าแล้วสถานการณ์ก็ยังเหมือนเดิม
ปัญหานี้กวนใจฉันมาหลายวันแล้ว และฉันได้คิดและทำการทดสอบเปรียบเทียบทุกวันเพื่อค้นหาโค้ดที่ทำให้เกิดปัญหานี้ ฉันอดไม่ได้ที่จะคิดภายใต้สมมติฐานของคีย์เวิร์ดจำนวนเท่ากันว่าทำไม ไม่มีข้อผิดพลาดในข้อมูลการจัดอันดับการสืบค้นแบบแบตช์ก่อนหน้านี้ แต่มีการรายงานข้อผิดพลาดบ่อยครั้งเมื่อเร็ว ๆ นี้ เว็บไซต์อินเทอร์เฟซที่ร้องขอนั้นบล็อก IP เซิร์ฟเวอร์ของเราหรือไม่ เหตุผลนี้ไม่เพียงพอ ต้องเกิดจากการไม่สามารถปล่อยการเชื่อมต่อได้อย่างถูกต้องที่ไหนสักแห่งในโปรแกรม!
ภายใต้การแนะนำของแนวคิดนี้ หลังจากทำงานหนักและฝึกฝนมาหลายวัน ในที่สุดวันนี้ฉันก็ค้นพบแก่นแท้ของปัญหา ซึ่งเกิดจากวิธีจับเวลา! สถานการณ์เป็นเช่นนี้ ในช่วงไม่กี่วันที่ผ่านมา ฉันได้ทริกเกอร์งานแบตช์บางอย่างด้วยตนเอง และพบว่าเมื่อค่าการจัดอันดับตัวกรองเป็น 100 ข้อผิดพลาด java.net.SocketException: การรีเซ็ตการเชื่อมต่อใน java จะถูกโยนทิ้งต่อไป และหน้าจอ รีเฟรชนั้นทรงพลังเป็นพิเศษ หลังจากเปรียบเทียบโค้ดตัวจับเวลานี้อย่างระมัดระวัง
ในที่สุดฉันก็รู้ทันทีว่า ใช่! มีปัญหาที่นี่ให้ฉันวิเคราะห์ด้วยตัวเอง:
ค่าฟังก์ชัน ค่าที่ส่งกลับเป็นค่าวิกฤต แต่ในวิธีการจับเวลาของฉัน มีการตัดสินว่าหากค่าที่ส่งคืนเป็นค่าวิกฤต มันจะบังคับให้ดำเนินการวิธีนั้นต่อภายใน 10 วินาที และวิธีนี้คือ หากต้องการรับข้อมูลเฉพาะของซอร์สโค้ดในเพจ การดำเนินการแต่ละครั้งของวิธีนี้จะใช้เวลาหลายสิบมิลลิวินาที ซึ่งเทียบเท่ากับการสร้างการเชื่อมต่อซ็อกเก็ตภายในเวลานี้ แต่เนื่องจากจะส่งกลับค่าวิกฤตเสมอ ดังนั้นวิธีนี้จึงจะดำเนินการอย่างต่อเนื่อง สร้างการเชื่อมต่อซ็อกเก็ตภายใน 10 วินาทีเพื่อรับข้อมูล หากวิธีนี้ใช้เวลาประมาณ 80ms ในการดำเนินการในแต่ละครั้ง (หลังการทดสอบ เวลาดำเนินการของแต่ละวิธีคือประมาณ 80ms) ใน 10 วินาทีภายในเวลานี้ 10*1000/80 = การเชื่อมต่อซ็อกเก็ต 125 จะถูกสร้างขึ้นนั่นคือการเชื่อมต่อซ็อกเก็ต 12.5 จะถูกสร้างขึ้นต่อวินาที นอกจากนี้ เนื่องจากนี่คือโปรแกรมกรอง ค่าวิกฤตหลายค่าจะปรากฏขึ้นพร้อมกันอย่างต่อเนื่อง ดังนั้น ในไม่กี่วินาที จำนวนซ็อกเก็ต การเชื่อมต่อไปยังหน้าเว็บไซต์เดียวกันจะทะยานสูงมากถึงหลายร้อยหรือหลายพันครั้ง ทำให้จำนวนการเชื่อมต่อคำขอที่รอการประมวลผลสูงเกินไป:
เหตุใดคุณจึงใช้วิธีจับเวลานี้เพื่อดำเนินการวิธีการหลายครั้งตั้งแต่แรก เหตุผลก็คือเพื่อให้ได้ค่าข้อมูลที่คงที่ แต่ตอนนี้เมื่อฉันมาคิดดูแล้ว ผลกระทบด้านลบนั้นมีค่าใช้จ่ายสูงมากและไม่สามารถประเมินผลดังกล่าวต่ำเกินไปได้ แต่หลังจากวิเคราะห์และทดสอบอย่างครอบคลุมหลายวัน ในที่สุดผู้กระทำผิดก็ถูกค้นพบ หลังจากปัญหาได้รับการแก้ไข จิตใจของฉันก็โล่งใจและฉันก็นอนหลับได้อย่างสงบ - -