คุณกำลังดูเอกสารประกอบของ Apigee Edge
ไปที่เอกสารประกอบของ Apigee X ข้อมูล
ลักษณะปัญหา
แอปพลิเคชันไคลเอ็นต์จะได้รับรหัสสถานะ HTTP เป็น 502
พร้อมข้อความ Bad Gateway
เป็นการตอบกลับสำหรับการเรียก API
รหัสสถานะ HTTP 502
หมายความว่าไคลเอ็นต์ไม่ได้รับการตอบสนองที่ถูกต้องจากเซิร์ฟเวอร์แบ็กเอนด์ที่ควรดำเนินการตามคำขอจริงๆ
ข้อความแสดงข้อผิดพลาด
แอปพลิเคชันไคลเอ็นต์จะได้รับโค้ดตอบกลับต่อไปนี้
HTTP/1.1 502 Bad Gateway
นอกจากนี้ คุณอาจพบข้อความแสดงข้อผิดพลาดต่อไปนี้
{ "fault": { "faultstring": "Unexpected EOF at target", "detail": { "errorcode": "messaging.adaptors.http.UnexpectedEOFAtTarget" } } }
สาเหตุที่เป็นไปได้
สาเหตุทั่วไปประการหนึ่งของ 502 Bad Gateway Error
คือข้อผิดพลาด Unexpected EOF
ซึ่งอาจเกิดจากสาเหตุต่อไปนี้
สาเหตุ | รายละเอียด | ขั้นตอนที่ให้สำหรับ |
---|---|---|
กำหนดค่าเซิร์ฟเวอร์เป้าหมายไม่ถูกต้อง | ไม่ได้กำหนดค่าเซิร์ฟเวอร์เป้าหมายให้รองรับการเชื่อมต่อ TLS/SSL อย่างถูกต้อง | ผู้ใช้ Edge Public และ Private Cloud |
EOFException จากเซิร์ฟเวอร์แบ็กเอนด์ | เซิร์ฟเวอร์แบ็กเอนด์อาจส่ง EOF อย่างกะทันหัน | ผู้ใช้ Edge Private Cloud เท่านั้น |
กำหนดค่าไม่ถูกต้องสำหรับระยะหมดเวลาของ Keep Alive | กำหนดค่าระยะหมดเวลาของ Apigee และเซิร์ฟเวอร์แบ็กเอนด์ไว้ไม่ถูกต้อง | ผู้ใช้ Edge Public และ Private Cloud |
ขั้นตอนการวินิจฉัยทั่วไป
ในการวินิจฉัยข้อผิดพลาด คุณสามารถใช้วิธีการใดก็ได้ต่อไปนี้
การตรวจสอบ API
วิธีวินิจฉัยข้อผิดพลาดโดยใช้ API Monitoring
เมื่อใช้การตรวจสอบ API คุณจะสามารถตรวจสอบข้อผิดพลาด 502
โดยทำตามขั้นตอนที่อธิบายไว้ในตรวจสอบปัญหา โดยการ
- ไปที่หน้าแดชบอร์ดตรวจสอบ
- เลือกรหัสสถานะ ในเมนูแบบเลื่อนลง แล้วตรวจสอบว่าได้เลือกช่วงเวลาที่ถูกต้องเมื่อเกิดข้อผิดพลาด
502
รายการ - คลิกช่องในเมทริกซ์เมื่อคุณเห็นข้อผิดพลาด
502
จำนวนมาก - ทางด้านขวา ให้คลิกดูบันทึกเพื่อหาข้อผิดพลาด
502
รายการที่อาจมีลักษณะดังต่อไปนี้ - Fault Source คือ
target
- Fault Code คือ
messaging.adaptors.http.UnexpectedEOFAtTarget
เราเห็นข้อมูลต่อไปนี้
ซึ่งแสดงให้เห็นว่าข้อผิดพลาด 502
เกิดจากเป้าหมายเนื่องจาก EOF ที่ไม่คาดคิด
นอกจากนี้ ให้จดบันทึก Request Message ID
สำหรับข้อผิดพลาด 502
เพื่อทำการตรวจสอบเพิ่มเติม
เครื่องมือการติดตาม
วิธีวินิจฉัยข้อผิดพลาดโดยใช้เครื่องมือติดตาม
- เปิดใช้
เซสชันการติดตามและเรียก API เพื่อจำลองปัญหา
502 Bad Gateway
- เลือกคำขอที่ล้มเหลว 1 รายการและตรวจสอบการติดตาม
- ไปยังระยะต่างๆ ของการติดตามและค้นหาตำแหน่งที่ความล้มเหลวเกิดขึ้น
-
คุณควรเห็นการทำงานล้มเหลวหลังจากที่ส่งคำขอไปยังเซิร์ฟเวอร์ปลายทางดังที่แสดงด้านล่าง
-
ระบุค่าของ X-Apigee.fault-source และ X-Apigee.fault-code ในระยะ AX (บันทึกข้อมูล Analytics) ในการติดตาม
หากค่าของ X-Apigee.fault-source และ X-Apigee.fault-code ตรงกับค่าที่แสดงในตารางต่อไปนี้ คุณยืนยันได้ว่าข้อผิดพลาด
502
มาจากเซิร์ฟเวอร์เป้าหมายส่วนหัวการตอบกลับ ค่า X-Apigee.fault-source target
โค้ด X-Apigee.fault-code messaging.adaptors.http.flow.UnexpectedEOFAtTarget
นอกจากนี้ ให้จด
X-Apigee.Message-ID
สำหรับข้อผิดพลาด502
ไว้ตรวจสอบเพิ่มเติม
บันทึกการเข้าถึง NGINX
วิธีวินิจฉัยข้อผิดพลาดโดยใช้ NGINX
นอกจากนี้ คุณยังดูบันทึกการเข้าถึง NGINX เพื่อหาสาเหตุของรหัสสถานะ 502
ได้อีกด้วย ซึ่งจะเป็นประโยชน์อย่างยิ่งหากปัญหาเกิดขึ้นในอดีต หรือหากปัญหาเกิดขึ้นเป็นบางครั้งและคุณไม่สามารถจับภาพการติดตามใน UI ได้ ทำตามขั้นตอนต่อไปนี้เพื่อระบุข้อมูลนี้จากบันทึกการเข้าถึง NGINX
- ตรวจสอบบันทึกการเข้าถึง NGINX
/opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log
- ค้นหาข้อผิดพลาด
502
สำหรับพร็อกซี API ที่ระบุในช่วงเวลาที่เจาะจง (หากปัญหาเกิดขึ้นในอดีต) หรือหาคำขอใดก็ตามที่ยังคงไม่สำเร็จโดยใช้502
- หากมีข้อผิดพลาด
502
ให้ตรวจสอบว่าข้อผิดพลาดดังกล่าวเกิดจากเป้าหมายที่ส่งUnexpected EOF
หรือไม่ หากค่าของ X-Apigee.fault-source และ X- Apigee.fault-code ตรงกับค่าที่แสดงในตารางด้านล่าง ข้อผิดพลาด502
เกิดจากเป้าหมายปิดการเชื่อมต่อโดยไม่คาดคิดส่วนหัวการตอบกลับ ค่า X-Apigee.fault-source target
โค้ด X-Apigee.fault-code messaging.adaptors.http.flow.UnexpectedEOFAtTarget
ต่อไปนี้คือรายการตัวอย่างที่แสดงข้อผิดพลาด
502
ที่เกิดจากเซิร์ฟเวอร์เป้าหมาย
นอกจากนี้ ให้จดรหัสข้อความสำหรับข้อผิดพลาด 502
ไว้เพื่อตรวจสอบเพิ่มเติม
สาเหตุ: เซิร์ฟเวอร์เป้าหมายกำหนดค่าไม่ถูกต้อง
ไม่ได้กำหนดค่าเซิร์ฟเวอร์เป้าหมายให้รองรับการเชื่อมต่อ TLS/SSL อย่างถูกต้อง
การวินิจฉัย
- ใช้การตรวจสอบ API, เครื่องมือติดตาม หรือบันทึกการเข้าถึง NGINX เพื่อระบุรหัสข้อความ โค้ดข้อผิดพลาด และแหล่งที่มาของข้อผิดพลาดสำหรับข้อผิดพลาด
502
- เปิดใช้การติดตามใน UI สำหรับ API ที่ได้รับผลกระทบ
- หากการติดตามคําขอ API ที่ล้มเหลวแสดงข้อมูลต่อไปนี้
- ข้อผิดพลาด
502 Bad Gateway
จะเห็นทันทีที่คำขอโฟลว์เป้าหมายเริ่มต้น error.class
แสดงmessaging.adaptors.http.UnexpectedEOF.
มีความเป็นไปได้สูงว่าปัญหานี้จะเกิดจากการกำหนดค่าเซิร์ฟเวอร์เป้าหมายที่ไม่ถูกต้อง
- ข้อผิดพลาด
- รับการกำหนดเซิร์ฟเวอร์เป้าหมายโดยใช้การเรียก Edge Management API ดังนี้
- หากคุณเป็นผู้ใช้ระบบคลาวด์สาธารณะ ให้ใช้ API นี้
curl -v https://api.enterprise.apigee.com/v1/organizations/<orgname>/environments/<envname>/targetservers/<targetservername> -u <username>
- หากคุณเป็นผู้ใช้ Private Cloud ให้ใช้ API นี้
curl -v http://<management-server-host>:<port #>/v1/organizations/<orgname>/environments/<envname>/targetservers/<targetservername> -u <username>
ตัวอย่างคำจำกัดความ
TargetServer
ที่ผิดพลาด:<TargetServer name="target1"> <Host>mocktarget.apigee.net</Host> <Port>443</Port> <IsEnabled>true</IsEnabled> </TargetServer >
- หากคุณเป็นผู้ใช้ระบบคลาวด์สาธารณะ ให้ใช้ API นี้
-
คําจํากัดความของ
TargetServer
ที่แสดงในภาพเป็นตัวอย่างของการกําหนดค่าที่ผิดพลาดทั่วไปอย่างหนึ่งซึ่งอธิบายไว้ดังนี้สมมติว่าเซิร์ฟเวอร์เป้าหมาย
mocktarget.apigee.net
ได้รับการกำหนดค่าให้ยอมรับการเชื่อมต่อ ที่ปลอดภัย (HTTPS) บนพอร์ต443
อย่างไรก็ตาม หากคุณดูคำจำกัดความเซิร์ฟเวอร์เป้าหมาย จะไม่มีแอตทริบิวต์/แฟล็กอื่นๆ ที่ระบุว่าเป็นการกำหนดค่าสำหรับการเชื่อมต่อที่ปลอดภัย ซึ่งทำให้ Edge ถือว่าคำขอ API ที่ส่งไปยังเซิร์ฟเวอร์เป้าหมายที่เจาะจงเป็นคำขอ HTTP (ไม่ปลอดภัย) ดังนั้น Edge จะไม่เริ่มกระบวนการแฮนด์เชค SSL กับเซิร์ฟเวอร์เป้าหมายนี้เนื่องจากเซิร์ฟเวอร์เป้าหมายถูกกำหนดค่าให้ยอมรับเฉพาะคำขอ HTTPS (SSL) ใน
443
เซิร์ฟเวอร์จะปฏิเสธคำขอจาก Edge หรือปิดการเชื่อมต่อ ด้วยเหตุนี้ คุณจึงได้รับข้อผิดพลาดUnexpectedEOFAtTarget
ในระบบประมวลผลข้อความ ผู้ประมวลผลข้อความจะส่ง502 Bad Gateway
เป็นการตอบกลับไปยังไคลเอ็นต์
ความละเอียด
ตรวจสอบให้แน่ใจเสมอว่าได้กำหนดค่าเซิร์ฟเวอร์เป้าหมายอย่างถูกต้องตามความต้องการของคุณ
สำหรับตัวอย่างที่แสดงให้เห็นด้านบน หากต้องการส่งคำขอไปยังเซิร์ฟเวอร์เป้าหมายที่ปลอดภัย (HTTPS/SSL) คุณต้องใส่แอตทริบิวต์ SSLInfo
โดยตั้งค่าสถานะ enabled
เป็น true
แม้ว่าระบบจะได้รับอนุญาตให้เพิ่มแอตทริบิวต์ SSLInfo
สำหรับเซิร์ฟเวอร์เป้าหมายในคำจำกัดความปลายทางเป้าหมาย แต่เราขอแนะนำให้เพิ่มแอตทริบิวต์ SSLInfo
เป็นส่วนหนึ่งของคำจำกัดความเซิร์ฟเวอร์เป้าหมายเพื่อหลีกเลี่ยงความสับสน
- หากบริการแบ็กเอนด์ต้องใช้การสื่อสาร SSL ทางเดียว ให้ทําดังนี้
- คุณต้องเปิดใช้ TLS/SSL ในคำจำกัดความ
TargetServer
โดยรวมแอตทริบิวต์SSLInfo
ที่มีการตั้งค่าแฟล็กenabled
เป็น "จริง" ดังที่แสดงด้านล่าง<TargetServer name="mocktarget"> <Host>mocktarget.apigee.net</Host> <Port>443</Port> <IsEnabled>true</IsEnabled> <SSLInfo> <Enabled>true</Enabled> </SSLInfo> </TargetServer>
- หากต้องการตรวจสอบใบรับรองของเซิร์ฟเวอร์เป้าหมายใน Edge เราจะต้องใส่ Truststore (ที่มีใบรับรองของเซิร์ฟเวอร์เป้าหมาย) ด้วยดังที่แสดงด้านล่าง
<TargetServer name="mocktarget"> <Host>mocktarget.apigee.net</Host> <Port>443</Port> <IsEnabled>true</IsEnabled> <SSLInfo> <Ciphers/> <ClientAuthEnabled>false</ClientAuthEnabled> <Enabled>true</Enabled> <IgnoreValidationErrors>false</IgnoreValidationErrors> <Protocols/> <TrustStore>mocktarget-truststore</TrustStore> </SSLInfo> </TargetServer>
- คุณต้องเปิดใช้ TLS/SSL ในคำจำกัดความ
- หากบริการแบ็กเอนด์ต้องใช้การสื่อสาร SSL แบบ 2 ทาง ให้ทําดังนี้
- คุณต้องมีแอตทริบิวต์
SSLInfo
ที่มีการตั้งค่าแฟล็กClientAuthEnabled
,Keystore
,KeyAlias
และTruststore
อย่างเหมาะสมตามที่แสดงด้านล่าง<TargetServer name="mocktarget"> <IsEnabled>true</IsEnabled> <Host>www.example.com</Host> <Port>443</Port> <SSLInfo> <Ciphers/> <ClientAuthEnabled>true</ClientAuthEnabled> <Enabled>true</Enabled> <IgnoreValidationErrors>false</IgnoreValidationErrors> <KeyAlias>keystore-alias</KeyAlias> <KeyStore>keystore-name</KeyStore> <Protocols/> <TrustStore>truststore-name</TrustStore> </SSLInfo> </TargetServer >
- คุณต้องมีแอตทริบิวต์
รายการอ้างอิง
การจัดสรรภาระงานในเซิร์ฟเวอร์แบ็กเอนด์
สาเหตุ: EOFException จากเซิร์ฟเวอร์แบ็กเอนด์
เซิร์ฟเวอร์แบ็กเอนด์อาจส่ง EOF (สิ้นสุดไฟล์) อย่างกะทันหัน
การวินิจฉัย
- ใช้การตรวจสอบ API, เครื่องมือติดตาม หรือบันทึกการเข้าถึง NGINX เพื่อระบุรหัสข้อความ โค้ดข้อผิดพลาด และแหล่งที่มาของข้อผิดพลาดสำหรับข้อผิดพลาด
502
- ตรวจสอบบันทึกตัวประมวลผลข้อความ (
/opt/apigee/var/log/edge-message-processor/logs/system.log
) และค้นหาเพื่อดูว่าคุณมีeof unexpected
สำหรับ API ที่เฉพาะเจาะจงหรือไม่ หรือคุณมีmessageid
ที่ไม่ซ้ำกันสำหรับคำขอ API ดังกล่าว คุณก็ค้นหาได้ตัวอย่างสแต็กเทรซข้อยกเว้นจากบันทึกของผู้ประมวลผลข้อความ
"message": "org:myorg env:test api:api-v1 rev:10 messageid:rrt-1-14707-63403485-19 NIOThread@0 ERROR HTTP.CLIENT - HTTPClient$Context$3.onException() : SSLClientChannel[C:193.35.250.192:8443 Remote host:0.0.0.0:50100]@459069 useCount=6 bytesRead=0 bytesWritten=755 age=40107ms lastIO=12832ms .onExceptionRead exception: {} java.io.EOFException: eof unexpected at com.apigee.nio.channels.PatternInputChannel.doRead(PatternInputChannel.java:45) ~[nio-1.0.0.jar:na] at com.apigee.nio.channels.InputChannel.read(InputChannel.java:103) ~[nio-1.0.0.jar:na] at com.apigee.protocol.http.io.MessageReader.onRead(MessageReader.java:79) ~[http-1.0.0.jar:na] at com.apigee.nio.channels.DefaultNIOSupport$DefaultIOChannelHandler.onIO(NIOSupport.java:51) [nio-1.0.0.jar:na] at com.apigee.nio.handlers.NIOThread.run(NIOThread.java:123) [nio-1.0.0.jar:na]"
ในตัวอย่างข้างต้น คุณจะเห็นว่า
java.io.EOFException: eof unexpected
มีข้อผิดพลาดเกิดขึ้นขณะที่ผู้ประมวลผลข้อความพยายามอ่านการตอบกลับจากเซิร์ฟเวอร์แบ็กเอนด์ ข้อยกเว้นนี้หมายถึงจุดสิ้นสุดของไฟล์ (EOF) หรือถึงจุดสิ้นสุดของสตรีมโดยไม่คาดคิดกล่าวคือ ผู้ประมวลผลข้อความส่งคำขอ API ไปยังเซิร์ฟเวอร์แบ็กเอนด์และกำลังรอหรืออ่านการตอบกลับอยู่ แต่เซิร์ฟเวอร์แบ็กเอนด์จะยุติการเชื่อมต่ออย่างกะทันหันก่อนที่ผู้ประมวลผลข้อความจะได้รับการตอบกลับหรืออ่านการตอบกลับทั้งหมดได้
- ตรวจสอบบันทึกเซิร์ฟเวอร์แบ็กเอนด์และดูว่ามีข้อผิดพลาดหรือข้อมูลที่อาจทําให้เซิร์ฟเวอร์แบ็กเอนด์ยุติการเชื่อมต่ออย่างกะทันหันหรือไม่ หากพบข้อผิดพลาด/ข้อมูล ให้ไปที่การแก้ปัญหาแล้วแก้ไขปัญหาที่เหมาะสมในเซิร์ฟเวอร์แบ็กเอนด์
- หากไม่พบข้อผิดพลาดหรือข้อมูลในเซิร์ฟเวอร์แบ็กเอนด์ ให้รวบรวมเอาต์พุตของ
tcpdump
ในตัวประมวลผลข้อความ ดังนี้- หากโฮสต์เซิร์ฟเวอร์แบ็กเอนด์มีที่อยู่ IP เดียว ให้ใช้คำสั่งต่อไปนี้
tcpdump -i any -s 0 host IP_ADDRESS -w FILE_NAME
- หากโฮสต์เซิร์ฟเวอร์แบ็กเอนด์ของคุณมีที่อยู่ IP หลายรายการ ให้ใช้คำสั่งต่อไปนี้
tcpdump -i any -s 0 host HOSTNAME -w FILE_NAME
โดยทั่วไปแล้ว ข้อผิดพลาดนี้เกิดจากเซิร์ฟเวอร์แบ็กเอนด์ตอบกลับด้วย
[FIN,ACK]
ทันทีที่ผู้ประมวลผลข้อความส่งคําขอไปยังเซิร์ฟเวอร์แบ็กเอนด์
- หากโฮสต์เซิร์ฟเวอร์แบ็กเอนด์มีที่อยู่ IP เดียว ให้ใช้คำสั่งต่อไปนี้
-
ลองดูตัวอย่าง
tcpdump
ต่อไปนี้ตัวอย่าง
tcpdump
ที่ถ่ายเมื่อ502 Bad Gateway Error
(UnexpectedEOFAtTarget
) เกิดขึ้น - จากเอาต์พุต TCPDump คุณจะสังเกตเห็นลําดับเหตุการณ์ต่อไปนี้
- ในแพ็กเก็ต
985
ตัวประมวลผลข้อความจะส่งคำขอ API ไปยังเซิร์ฟเวอร์แบ็กเอนด์ - ในแพ็กเก็ต
986
เซิร์ฟเวอร์แบ็กเอนด์จะตอบกลับด้วย[FIN,ACK]
ทันที - ในแพ็กเก็ต
987
ตัวประมวลผลข้อความจะตอบกลับด้วย[FIN,ACK]
ไปยังเซิร์ฟเวอร์แบ็กเอนด์ - ในที่สุดก็ปิดการเชื่อมต่อด้วย
[ACK]
และ[RST]
จากทั้ง 2 ฝั่ง - เนื่องจากเซิร์ฟเวอร์แบ็กเอนด์ส่ง
[FIN,ACK]
คุณจึงได้รับข้อยกเว้นjava.io.EOFException: eof unexpected
ยกเว้นในเครื่องมือประมวลผลข้อความ
- ในแพ็กเก็ต
- ซึ่งอาจเกิดจากปัญหาเครือข่ายในเซิร์ฟเวอร์แบ็กเอนด์ ให้ทีมปฏิบัติการเครือข่ายของคุณตรวจสอบปัญหานี้เพิ่มเติม
ความละเอียด
แก้ไขปัญหาในเซิร์ฟเวอร์แบ็กเอนด์อย่างเหมาะสม
หากปัญหายังคงอยู่และคุณต้องการความช่วยเหลือในการแก้ปัญหา 502 Bad Gateway Error
หรือสงสัยว่าเป็นปัญหาใน Edge โปรดติดต่อทีมสนับสนุนของ Apigee Edge
สาเหตุ: กำหนดค่า Keep ของระยะหมดเวลาไม่ถูกต้อง
ก่อนที่จะวิเคราะห์ว่านี่คือสาเหตุของข้อผิดพลาด 502
หรือไม่ โปรดอ่านแนวคิดต่อไปนี้อย่างละเอียด
การเชื่อมต่อถาวรใน Apigee
โดยค่าเริ่มต้น Apigee (และที่เป็นไปตามมาตรฐาน HTTP/1.1) จะใช้การเชื่อมต่อถาวรเมื่อสื่อสารกับเซิร์ฟเวอร์แบ็กเอนด์เป้าหมาย การเชื่อมต่อแบบถาวรช่วยเพิ่มประสิทธิภาพได้โดยการอนุญาตให้นำการเชื่อมต่อ TLS/SSL ที่สร้างขึ้นแล้วและ (หากมี) มาใช้ซ้ำ ซึ่งจะช่วยลดค่าใช้จ่ายของเวลาในการตอบสนอง ระยะเวลาในการคงการเชื่อมต่อจะต้องถูกควบคุมผ่านพร็อพเพอร์ตี้ระยะหมดเวลาของ Keep Alive (keepalive.timeout.millis
)
ทั้งเซิร์ฟเวอร์แบ็กเอนด์และ Apigee Message Processor จะใช้ระยะหมดเวลาแบบเก็บการทำงานไว้เพื่อเปิดการเชื่อมต่อระหว่างกัน เมื่อได้รับข้อมูลภายในระยะหมดเวลาของ Keep Alive แล้ว เซิร์ฟเวอร์แบ็กเอนด์หรือผู้ประมวลผลข้อมูลข้อความจะปิดการเชื่อมต่อกับอีกเซิร์ฟเวอร์หนึ่งได้
พร็อกซี API ที่ทำให้ใช้งานได้กับเครื่องมือประมวลผลข้อความใน Apigee ตามค่าเริ่มต้นแล้ว การตั้งค่าระยะหมดเวลาของ Keep จะเป็น 60s
เว้นแต่จะมีการลบล้าง เมื่อไม่มีรับข้อมูลของ 60s
แล้ว Apigee จะปิดการเชื่อมต่อกับเซิร์ฟเวอร์แบ็กเอนด์ เซิร์ฟเวอร์แบ็กเอนด์จะยังคงรักษาระยะหมดเวลาให้คงการทำงานไว้
และเมื่อหมดอายุ เซิร์ฟเวอร์แบ็กเอนด์จะปิดการเชื่อมต่อกับเครื่องมือประมวลผลข้อความ
ผลของการกำหนดค่าระยะหมดเวลาของ Keep Alive ที่ไม่ถูกต้อง
หากกำหนดค่า Apigee หรือเซิร์ฟเวอร์แบ็กเอนด์โดยมีระยะหมดเวลาของ Keep Alive ที่ไม่ถูกต้อง จะทําให้เกิดเงื่อนไขการแข่งซึ่งทำให้เซิร์ฟเวอร์แบ็กเอนด์ส่ง End Of File
(FIN)
ที่ไม่คาดคิดเพื่อตอบกลับคําขอทรัพยากร
ตัวอย่างเช่น หากมีการกำหนดค่าระยะหมดเวลาของ Keep alive ภายในพร็อกซี API หรือผู้ประมวลผลข้อมูลข้อความที่มีค่ามากกว่าหรือเท่ากับระยะหมดเวลาของเซิร์ฟเวอร์แบ็กเอนด์ของอัปสตรีม เงื่อนไขเชื้อชาติต่อไปนี้อาจเกิดขึ้นได้ กล่าวคือ หากผู้ประมวลผลข้อความไม่ได้รับข้อมูลใดๆ จนกว่าจะใกล้ถึงเกณฑ์ของเซิร์ฟเวอร์แบ็กเอนด์ที่จะคงระยะหมดเวลาไว้ คำขอจะผ่านเข้ามาและส่งไปยังเซิร์ฟเวอร์แบ็กเอนด์โดยใช้การเชื่อมต่อที่มีอยู่ ซึ่งอาจนำไปสู่ 502 Bad Gateway
เนื่องจากข้อผิดพลาด EOF ที่ไม่คาดคิดตามที่อธิบายไว้ด้านล่าง
- สมมติว่าระยะหมดเวลาของ Keep alive ที่ตั้งค่าทั้งในตัวประมวลผลข้อความและเซิร์ฟเวอร์แบ็กเอนด์คือ 60 วินาที และไม่มีคำขอใหม่จนกว่าจะ 59 วินาทีหลังจากที่ผู้ประมวลผลข้อความที่ระบุส่งคำขอก่อนหน้า
- ตัวประมวลผลข้อความจะดำเนินการต่อและประมวลผลคำขอที่เข้ามาในวินาทีที่ 59 โดยใช้การเชื่อมต่อที่มีอยู่ (เนื่องจากยังไม่หมดเวลาของ Keep Alive) และส่งคำขอไปยังเซิร์ฟเวอร์แบ็กเอนด์
- แต่ก่อนที่คำขอจะมาถึงเซิร์ฟเวอร์แบ็กเอนด์ เกินเกณฑ์ระยะหมดเวลาของ Keep Alive ในเซิร์ฟเวอร์แบ็กเอนด์แล้ว
- คำขอทรัพยากรของผู้ประมวลผลข้อความอยู่ระหว่างดำเนินการ แต่เซิร์ฟเวอร์แบ็กเอนด์พยายามปิดการเชื่อมต่อโดยส่งแพ็กเก็ต
FIN
ไปยังผู้ประมวลผลข้อความ - ขณะที่ผู้ประมวลผลข้อความกำลังรอรับข้อมูล แต่จะได้รับ
FIN
ที่ไม่คาดคิดแทนและการเชื่อมต่อจะสิ้นสุดลง - ซึ่งส่งผลให้เกิด
Unexpected EOF
และจากนั้นผู้ประมวลผลข้อความจะส่ง502
กลับไปยังไคลเอ็นต์
ในกรณีนี้ เราพบว่าเกิดข้อผิดพลาด 502
เนื่องจากมีการกำหนดค่าการหมดเวลาของ Keep Alive ซึ่งก็คือ 60 วินาทีเหมือนกันทั้งในเครื่องมือประมวลผลข้อความและเซิร์ฟเวอร์แบ็กเอนด์ ในทำนองเดียวกัน ปัญหานี้อาจเกิดขึ้นได้หากมีการกำหนดค่าค่าการหมดเวลาของ Keep Alive ในเครื่องประมวลผลข้อความสูงกว่าในเซิร์ฟเวอร์แบ็กเอนด์
การวินิจฉัย
- หากคุณเป็นผู้ใช้ระบบคลาวด์สาธารณะ ให้ทำดังนี้
- ใช้เครื่องมือ API Monitoring หรือ Trace (ตามที่อธิบายไว้ในขั้นตอนการวิเคราะห์ทั่วไป) และตรวจสอบว่าคุณมีการตั้งค่าทั้ง 2 อย่างต่อไปนี้แล้ว
- รหัสข้อผิดพลาด:
messaging.adaptors.http.flow.UnexpectedEOFAtTarget
- แหล่งที่มาของข้อผิดพลาด:
target
- รหัสข้อผิดพลาด:
- โปรดไปที่การใช้ tcpdump เพื่อตรวจสอบเพิ่มเติม
- ใช้เครื่องมือ API Monitoring หรือ Trace (ตามที่อธิบายไว้ในขั้นตอนการวิเคราะห์ทั่วไป) และตรวจสอบว่าคุณมีการตั้งค่าทั้ง 2 อย่างต่อไปนี้แล้ว
- หากคุณเป็นผู้ใช้ Private Cloud ให้ทำดังนี้
- ใช้เครื่องมือติดตามหรือบันทึกการเข้าถึง NGINX เพื่อระบุรหัสข้อความ รหัสข้อผิดพลาด และแหล่งที่มาของข้อผิดพลาดสำหรับข้อผิดพลาด
502
- ค้นหารหัสข้อความในบันทึกของตัวประมวลผลข้อความ
(/opt/apigee/var/log/edge-message-processor/logs/system.log
) - คุณจะเห็น
java.io.EOFEXception: eof unexpected
ตามที่แสดงด้านล่าง2020-11-22 14:42:39,917 org:myorg env:prod api:myproxy rev:1 messageid:myorg-opdk-dc1-node2-17812-56001-1 NIOThread@1 ERROR HTTP.CLIENT - HTTPClient$Context$3.onException() : ClientChannel[Connected: Remote:51.254.225.9:80 Local:10.154.0.61:35326]@12972 useCount=7 bytesRead=0 bytesWritten=159 age=7872ms lastIO=479ms isOpen=true.onExceptionRead exception: {} java.io.EOFException: eof unexpected at com.apigee.nio.channels.PatternInputChannel.doRead(PatternInputChannel.java:45) at com.apigee.nio.channels.InputChannel.read(InputChannel.java:103) at com.apigee.protocol.http.io.MessageReader.onRead(MessageReader.java:80) at com.apigee.nio.channels.DefaultNIOSupport$DefaultIOChannelHandler.onIO(NIOSupport.java:51) at com.apigee.nio.handlers.NIOThread.run(NIOThread.java:220)
- ข้อผิดพลาด
java.io.EOFException: eof unexpected
บ่งบอกว่าผู้ประมวลผลข้อความได้รับEOF
ในขณะที่ยังรออ่านการตอบกลับจากเซิร์ฟเวอร์แบ็กเอนด์ - แอตทริบิวต์
useCount=7
ในข้อความแสดงข้อผิดพลาดข้างต้นบ่งบอกว่าผู้ประมวลผลข้อความได้ใช้การเชื่อมต่อนี้ซ้ำประมาณ 7 ครั้ง และแอตทริบิวต์bytesWritten=159
ระบุว่าผู้ประมวลผลข้อความได้ส่งเพย์โหลดคำขอขนาด159
ไบต์ไปยังเซิร์ฟเวอร์แบ็กเอนด์ แต่ได้รับกลับมา 0 ไบต์เมื่อEOF
ที่ไม่คาดคิดเกิดขึ้น -
ซึ่งแสดงให้เห็นว่าผู้ประมวลผลข้อความได้ใช้การเชื่อมต่อเดิมซ้ำหลายครั้ง และในโอกาสนี้ระบบได้ส่งข้อมูล แต่หลังจากนั้นไม่นานก็ได้รับ
EOF
ก่อนที่จะได้รับข้อมูลใดๆ ซึ่งหมายความว่ามีโอกาสสูงที่ระยะหมดเวลา Keep-alive ของเซิร์ฟเวอร์แบ็กเอนด์จะสั้นกว่าหรือเท่ากับค่าที่ตั้งไว้ในพร็อกซี APIคุณตรวจสอบเพิ่มเติมได้โดยใช้
tcpdump
ตามที่อธิบายไว้ด้านล่าง
- ใช้เครื่องมือติดตามหรือบันทึกการเข้าถึง NGINX เพื่อระบุรหัสข้อความ รหัสข้อผิดพลาด และแหล่งที่มาของข้อผิดพลาดสำหรับข้อผิดพลาด
การใช้ tcpdump
- บันทึก
tcpdump
ในเซิร์ฟเวอร์แบ็กเอนด์ด้วยคำสั่งต่อไปนี้tcpdump -i any -s 0 host MP_IP_Address -w File_Name
- วิเคราะห์
tcpdump
ที่บันทึกไว้ตัวอย่างเอาต์พุต tcpdump มีดังนี้
ในตัวอย่าง
tcpdump
ด้านบน คุณจะเห็นข้อมูลต่อไปนี้- ในแพ็กเก็ต
5992,
เซิร์ฟเวอร์แบ็กเอนด์ได้รับคำขอGET
- ในแพ็กเก็ต
6064
จะตอบสนองด้วย200 OK.
- ในแพ็กเก็ต
6084
เซิร์ฟเวอร์แบ็กเอนด์ได้รับคำขอGET
อีกรายการ - ในแพ็กเก็ต
6154
จะตอบสนองด้วย200 OK
- ในแพ็กเก็ต
6228
เซิร์ฟเวอร์แบ็กเอนด์ได้รับคำขอGET
รายการที่ 3 - ในครั้งนี้ เซิร์ฟเวอร์แบ็กเอนด์จะส่ง
FIN, ACK
ไปยัง Message Processor (แพ็กเก็ต6285
) เพื่อเริ่มการปิดการเชื่อมต่อ
ในตัวอย่างนี้มีการใช้การเชื่อมต่อเดียวกันซ้ำ 2 ครั้งสำเร็จ แต่ในคำขอที่ 3 เซิร์ฟเวอร์แบ็กเอนด์เริ่มปิดการเชื่อมต่อในขณะที่ผู้ประมวลผลข้อความกำลังรอข้อมูลจากเซิร์ฟเวอร์แบ็กเอนด์ ซึ่งแสดงให้เห็นว่าระยะหมดเวลาของ Keep-alive ของเซิร์ฟเวอร์แบ็กเอนด์มีแนวโน้มที่จะสั้นกว่าหรือเท่ากับค่าที่ตั้งไว้ในพร็อกซี API หากต้องการตรวจสอบความถูกต้องนี้ โปรดดูเปรียบเทียบระยะหมดเวลาของ Keep alive ใน Apigee และเซิร์ฟเวอร์แบ็กเอนด์
- ในแพ็กเก็ต
เปรียบเทียบระยะหมดเวลา Keep ใน Apigee และเซิร์ฟเวอร์แบ็กเอนด์
- โดยค่าเริ่มต้น Apigee จะใช้ค่า 60 วินาทีสำหรับพร็อพเพอร์ตี้ระยะหมดเวลาของ Keep alive
-
แต่คุณอาจลบล้างค่าเริ่มต้นในพร็อกซี API ไปแล้วก็ได้ คุณยืนยันได้โดยตรวจสอบคำจำกัดความ
TargetEndpoint
เฉพาะในพร็อกซี API ที่ล้มเหลวโดยมีข้อผิดพลาด502
รายการตัวอย่างการกำหนดค่า TargetEndpoint
<TargetEndpoint name="default"> <HTTPTargetConnection> <URL>https://mocktarget.apigee.net/json</URL> <Properties> <Property name="keepalive.timeout.millis">30000</Property> </Properties> </HTTPTargetConnection> </TargetEndpoint>
ในตัวอย่างข้างต้น ระบบจะลบล้างพร็อพเพอร์ตี้ระยะหมดเวลาของ Keep alive ด้วยค่า 30 วินาที (
30000
มิลลิวินาที) - ถัดไป ให้ตรวจสอบพร็อพเพอร์ตี้ระยะหมดเวลาของ Keep Alive ที่กําหนดค่าไว้ในเซิร์ฟเวอร์แบ็กเอนด์ สมมติว่าเซิร์ฟเวอร์แบ็กเอนด์ได้รับการกําหนดค่าด้วยค่า
25 seconds
- หากคุณเห็นว่าค่าของพร็อพเพอร์ตี้ระยะหมดเวลาของ Keep alive ใน Apigee สูงกว่าค่าของพร็อพเพอร์ตี้ระยะหมดเวลาของ Keep alive ในเซิร์ฟเวอร์แบ็กเอนด์ตามตัวอย่างข้างต้น จึงเป็นสาเหตุที่ทําให้เกิดข้อผิดพลาด
502
ความละเอียด
ตรวจสอบว่าพร็อพเพอร์ตี้ระยะหมดเวลาของ Keep alive ต่ำกว่าเสมอใน Apigee (ในพร็อกซี API และคอมโพเนนต์ตัวประมวลผลข้อความ) เมื่อเทียบกับเซิร์ฟเวอร์แบ็กเอนด์
- กำหนดค่าที่ตั้งค่าให้ระยะหมดเวลาของ Keep Alive ในเซิร์ฟเวอร์แบ็กเอนด์
- กำหนดค่าที่เหมาะสมสำหรับพร็อพเพอร์ตี้ระยะหมดเวลาของ Keep ในพร็อกซี API หรือตัวประมวลผลข้อความเพื่อให้พร็อพเพอร์ตี้ระยะหมดเวลาของ Keep alive ต่ำกว่าค่าที่ตั้งไว้ในเซิร์ฟเวอร์แบ็กเอนด์ โดยใช้ขั้นตอนที่อธิบายไว้ใน การกำหนดค่าระยะหมดเวลาของ Keep alive ในตัวประมวลผลข้อความ
หากยังพบปัญหาอยู่ ให้ไปที่ต้องรวบรวมข้อมูลการวินิจฉัย
แนวทางปฏิบัติแนะนำ
ขอแนะนำเป็นอย่างยิ่งว่าคอมโพเนนต์ที่ดาวน์สตรีมจะมีเกณฑ์การหมดเวลาของ Keep ต่ำกว่าที่กำหนดค่าไว้ในเซิร์ฟเวอร์อัปสตรีมเสมอ เพื่อหลีกเลี่ยงเงื่อนไขการแข่งขันและข้อผิดพลาด 502
ประเภทนี้ ฮอพดาวน์สตรีมแต่ละรายการควรต่ำกว่าอัปสตรีมฮอพแต่ละรายการ แนวทางปฏิบัติที่ดีใน Apigee Edge คือการใช้หลักเกณฑ์ต่อไปนี้
- ระยะหมดเวลาของ Keepalive ของไคลเอ็นต์ควรน้อยกว่าระยะหมดเวลาของเราเตอร์ Edge
- การหมดเวลาของเราเตอร์ Edge ที่ใช้งานอยู่ควรน้อยกว่าระยะหมดเวลาของโปรแกรมประมวลผลข้อความ
- การหมดเวลาของตัวประมวลผลข้อความควรต่ำกว่าระยะหมดเวลาปัจจุบันของเซิร์ฟเวอร์เป้าหมาย
- หากคุณมีการรับส่งข้อมูลอื่นๆ อยู่ด้านหน้าหรือด้านหลัง Apigee ควรใช้กฎเดียวกัน คุณควรปล่อยให้ไคลเอ็นต์เป็นความรับผิดชอบของไคลเอ็นต์ดาวน์สตรีมที่จะต้องปิดการเชื่อมต่อกับอัปสตรีมเสมอ
ต้องรวบรวมข้อมูลการวินิจฉัย
หากปัญหายังคงอยู่แม้ว่าจะทำตามวิธีการข้างต้นแล้ว ให้รวบรวมข้อมูลการวินิจฉัยต่อไปนี้ จากนั้นติดต่อฝ่ายสนับสนุนของ Apigee Edge
หากคุณเป็นผู้ใช้ระบบคลาวด์สาธารณะ โปรดระบุข้อมูลต่อไปนี้
- ชื่อองค์กร
- ชื่อสภาพแวดล้อม
- ชื่อพร็อกซี API
- ใช้คำสั่ง
curl
ให้เสร็จสมบูรณ์เพื่อจำลองข้อผิดพลาด502
ซ้ำ - ไฟล์การย้ายข้อมูลที่มีคำขอซึ่งมีข้อผิดพลาด
502 Bad Gateway - Unexpected EOF
รายการ - หากข้อผิดพลาด
502
ไม่ได้เกิดขึ้นในขณะนี้ ให้ระบุระยะเวลาพร้อมข้อมูลเขตเวลาเมื่อเกิดข้อผิดพลาด502
ในอดีต
หากคุณเป็นผู้ใช้ Private Cloud โปรดระบุข้อมูลต่อไปนี้
- สังเกตข้อความแสดงข้อผิดพลาดสำหรับคำขอที่ไม่สำเร็จ
- ชื่อองค์กร ชื่อสภาพแวดล้อม และชื่อพร็อกซี API ที่คุณพบข้อผิดพลาด
502
รายการ - กลุ่มพร็อกซี API
- ไฟล์การย้ายข้อมูลที่มีคำขอซึ่งมีข้อผิดพลาด
502 Bad Gateway - Unexpected EOF
รายการ - บันทึกการเข้าถึง NGINX
/opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log
- บันทึกตัวประมวลผลข้อความ
/opt/apigee/var/log/edge-message-processor/logs/system.log
- ระยะเวลาที่มีข้อมูลเขตเวลาเมื่อเกิดข้อผิดพลาด
502
Tcpdumps
รวบรวมไว้ในตัวประมวลผลข้อความหรือเซิร์ฟเวอร์แบ็กเอนด์ หรือทั้ง 2 อย่างเมื่อเกิดข้อผิดพลาด