502 EOF เกตเวย์ไม่ถูกต้อง

คุณกำลังดูเอกสารประกอบของ Apigee Edge
ไปที่เอกสารประกอบของ Apigee X
info

ลักษณะปัญหา

แอปพลิเคชันไคลเอ็นต์จะได้รับรหัสสถานะ 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 ไม่ถูกต้อง กำหนดค่าการหมดเวลา Keep-Alive ไม่ถูกต้องใน Apigee และเซิร์ฟเวอร์แบ็กเอนด์ ผู้ใช้ Edge Public และ Private Cloud

ขั้นตอนการวินิจฉัยที่พบบ่อย

หากต้องการวินิจฉัยข้อผิดพลาด คุณสามารถใช้วิธีใดวิธีหนึ่งต่อไปนี้

การตรวจสอบ API

วิธีวินิจฉัยข้อผิดพลาดโดยใช้การตรวจสอบ API

การใช้การตรวจสอบ API ช่วยให้คุณตรวจสอบ ข้อผิดพลาด 502 ได้โดยทำตามขั้นตอนที่อธิบายไว้ใน ตรวจสอบปัญหา โดยการ

  1. ไปที่แดชบอร์ดตรวจสอบ
  2. เลือกรหัสสถานะ ในเมนูแบบเลื่อนลง และตรวจสอบว่าได้เลือกช่วงเวลาที่เหมาะสม เมื่อเกิดข้อผิดพลาด 502
  3. คลิกช่องในเมทริกซ์เมื่อเห็นข้อผิดพลาด 502 จำนวนมาก
  4. ทางด้านขวา ให้คลิกดูบันทึกสำหรับข้อผิดพลาด 502 ซึ่งจะมีลักษณะดังนี้
  5. ในส่วนนี้ คุณจะเห็นข้อมูลต่อไปนี้

    • แหล่งที่มาของข้อบกพร่องคือ target
    • รหัสข้อบกพร่องคือ messaging.adaptors.http.UnexpectedEOFAtTarget

ซึ่งบ่งชี้ว่าข้อผิดพลาด 502 เกิดจากเป้าหมายเนื่องจาก EOF ที่ไม่คาดคิด

นอกจากนี้ ให้จดบันทึกRequest Message IDสำหรับข้อผิดพลาด 502 เพื่อทำการตรวจสอบเพิ่มเติม

เครื่องมือติดตาม

วิธีวิเคราะห์ข้อผิดพลาดโดยใช้เครื่องมือติดตาม

  1. เปิดใช้ เซสชันการติดตาม แล้วเรียกใช้ API เพื่อจำลองปัญหา 502 Bad Gateway
  2. เลือกคำขอที่ล้มเหลวรายการใดรายการหนึ่ง แล้วตรวจสอบการติดตาม
  3. ไปยังส่วนต่างๆ ของการติดตาม และค้นหาตำแหน่งที่เกิดข้อผิดพลาด
  4. คุณควรเห็นความล้มเหลวหลังจากส่งคำขอไปยังเซิร์ฟเวอร์เป้าหมายดังที่แสดงด้านล่าง

    alt_text

    alt_text

  5. กำหนดค่าของ X-Apigee.fault-source และ X-Apigee.fault-code ในระยะ AX (บันทึกข้อมูลวิเคราะห์) ในการติดตาม

    หากค่าของ 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

  1. ตรวจสอบบันทึกการเข้าถึง NGINX
    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log
  2. ค้นหาข้อผิดพลาด 502 สำหรับพร็อกซี API ที่เฉพาะเจาะจงในช่วงระยะเวลาหนึ่ง (หากปัญหาเกิดขึ้นในอดีต) หรือสำหรับคำขอที่ยังคงล้มเหลวด้วย 502
  3. หากมี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

การวินิจฉัย

  1. ใช้การตรวจสอบ API, เครื่องมือติดตาม หรือ บันทึกการเข้าถึง NGINX เพื่อกำหนดรหัสข้อความ รหัสข้อผิดพลาด และแหล่งที่มาของข้อผิดพลาดสำหรับข้อผิดพลาด 502
  2. เปิดใช้การติดตามใน UI สำหรับ API ที่ได้รับผลกระทบ
  3. หากการติดตามคำขอ API ที่ล้มเหลวแสดงข้อมูลต่อไปนี้
    1. 502 Bad Gateway ข้อผิดพลาดจะปรากฏทันทีที่เริ่มคำขอโฟลว์เป้าหมาย
    2. error.class แสดง messaging.adaptors.http.UnexpectedEOF.

      ในกรณีนี้ ปัญหานี้อาจเกิดจากการกำหนดค่าเซิร์ฟเวอร์เป้าหมายไม่ถูกต้อง

  4. รับคำจำกัดความของเซิร์ฟเวอร์เป้าหมายโดยใช้การเรียก Edge Management API ดังนี้
    1. หากคุณเป็นผู้ใช้ระบบคลาวด์สาธารณะ ให้ใช้ API นี้
      curl -v https://api.enterprise.apigee.com/v1/organizations/<orgname>/environments/<envname>/targetservers/<targetservername> -u <username>
    2. หากคุณเป็นผู้ใช้ 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 >
  5. TargetServer ที่แสดงเป็นตัวอย่างของการกำหนดค่าที่ไม่ถูกต้องตามปกติ ซึ่งอธิบายได้ดังนี้

    สมมติว่าเซิร์ฟเวอร์เป้าหมาย mocktarget.apigee.net ได้รับการกำหนดค่า ให้ยอมรับการเชื่อมต่อที่ปลอดภัย (HTTPS) ในพอร์ต 443 อย่างไรก็ตาม หากดูที่ คำจำกัดความของเซิร์ฟเวอร์เป้าหมาย จะไม่มีแอตทริบิวต์/แฟล็กอื่นๆ ที่บ่งชี้ว่า มีไว้สำหรับการเชื่อมต่อที่ปลอดภัย ซึ่งทำให้ Edge ถือว่าคำขอ API ที่ไปยังเซิร์ฟเวอร์เป้าหมายที่เฉพาะเจาะจงเป็นคำขอ HTTP (ไม่ปลอดภัย) ดังนั้น Edge จะไม่ เริ่มกระบวนการแฮนด์เชค SSL กับเซิร์ฟเวอร์เป้าหมายนี้

    เนื่องจากเซิร์ฟเวอร์เป้าหมายได้รับการกำหนดค่าให้ยอมรับเฉพาะคำขอ HTTPS (SSL) ใน 443 ดังนั้นเซิร์ฟเวอร์จะ ปฏิเสธคำขอจาก Edge หรือปิดการเชื่อมต่อ ด้วยเหตุนี้ คุณจึงได้รับข้อผิดพลาด UnexpectedEOFAtTarget ใน Message Processor Message Processor จะส่ง 502 Bad Gateway เป็นการตอบกลับไคลเอ็นต์

ความละเอียด

ตรวจสอบให้แน่ใจเสมอว่าได้กำหนดค่าเซิร์ฟเวอร์เป้าหมายอย่างถูกต้องตามข้อกำหนด

สำหรับตัวอย่างที่แสดงด้านบน หากต้องการส่งคำขอไปยังเซิร์ฟเวอร์เป้าหมายที่ปลอดภัย (HTTPS/SSL) คุณต้องรวมแอตทริบิวต์ SSLInfo โดยตั้งค่าแฟล็ก enabled เป็น true แม้ว่าจะอนุญาตให้เพิ่มแอตทริบิวต์ SSLInfo สำหรับเซิร์ฟเวอร์เป้าหมายในการกําหนดปลายทางเป้าหมายเอง แต่เราขอแนะนําให้เพิ่มแอตทริบิวต์ SSLInfo เป็นส่วนหนึ่งของการกําหนดเซิร์ฟเวอร์เป้าหมายเพื่อหลีกเลี่ยงความสับสน

  1. หากบริการแบ็กเอนด์ต้องใช้การสื่อสาร SSL ทางเดียว ให้ทำดังนี้
    1. คุณต้องเปิดใช้ 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>
    2. หากต้องการตรวจสอบใบรับรองของเซิร์ฟเวอร์เป้าหมายใน 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>
  2. หากบริการแบ็กเอนด์ต้องใช้การสื่อสาร SSL แบบ 2 ทาง ให้ทำดังนี้
    1. คุณต้องมีแอตทริบิวต์ 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 (สิ้นสุดไฟล์) อย่างกะทันหัน

การวินิจฉัย

  1. ใช้การตรวจสอบ API, เครื่องมือติดตาม หรือ บันทึกการเข้าถึง NGINX เพื่อกำหนดรหัสข้อความ รหัสข้อผิดพลาด และแหล่งที่มาของข้อผิดพลาดสำหรับข้อผิดพลาด 502
  2. ตรวจสอบบันทึกของ Message Processor (/opt/apigee/var/log/edge-message-processor/logs/system.log) และค้นหาเพื่อดูว่าคุณ มี eof unexpected สำหรับ API ที่เฉพาะเจาะจงหรือไม่ หรือหากคุณมี messageid ที่ไม่ซ้ำสำหรับคำขอ API คุณก็ค้นหาได้

    สแต็กเทรซของข้อยกเว้นตัวอย่างจากบันทึกของ Message Processor

    "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ข้อผิดพลาดขณะที่ Message Processor พยายามอ่านการตอบกลับจาก เซิร์ฟเวอร์แบ็กเอนด์ ข้อยกเว้นนี้บ่งบอกถึงจุดสิ้นสุดของไฟล์ (EOF) หรือจุดสิ้นสุดของสตรีมที่ มาถึงโดยไม่คาดคิด

    กล่าวคือ Message Processor ส่งคำขอ API ไปยังเซิร์ฟเวอร์แบ็กเอนด์และกำลังรอ หรืออ่านการตอบกลับ อย่างไรก็ตาม เซิร์ฟเวอร์แบ็กเอนด์ได้สิ้นสุดการเชื่อมต่ออย่างกะทันหัน ก่อนที่ Message Processor จะได้รับการตอบกลับหรืออ่านการตอบกลับที่สมบูรณ์ได้

  3. ตรวจสอบบันทึกเซิร์ฟเวอร์แบ็กเอนด์และดูว่ามีข้อผิดพลาดหรือข้อมูลที่อาจ ทำให้เซิร์ฟเวอร์แบ็กเอนด์สิ้นสุดการเชื่อมต่ออย่างกะทันหันหรือไม่ หากพบข้อผิดพลาด/ข้อมูล ให้ไปที่การแก้ปัญหา และแก้ไขปัญหาอย่างเหมาะสมในเซิร์ฟเวอร์แบ็กเอนด์
  4. หากไม่พบข้อผิดพลาดหรือข้อมูลใดๆ ในเซิร์ฟเวอร์แบ็กเอนด์ ให้รวบรวมเอาต์พุต tcpdump ในตัวประมวลผลข้อความโดยทำดังนี้
    1. หากโฮสต์เซิร์ฟเวอร์แบ็กเอนด์มีที่อยู่ IP เดียว ให้ใช้คำสั่งต่อไปนี้
      tcpdump -i any -s 0 host IP_ADDRESS -w FILE_NAME
    2. หากโฮสต์เซิร์ฟเวอร์แบ็กเอนด์มีที่อยู่ IP หลายรายการ ให้ใช้คำสั่งต่อไปนี้
      tcpdump -i any -s 0 host HOSTNAME -w FILE_NAME

      โดยปกติแล้ว ข้อผิดพลาดนี้เกิดจากเซิร์ฟเวอร์แบ็กเอนด์ตอบกลับด้วย [FIN,ACK] ทันทีที่ Message Processor ส่งคำขอไปยังเซิร์ฟเวอร์แบ็กเอนด์

  5. ลองดูtcpdumpตัวอย่างต่อไปนี้

    ตัวอย่าง tcpdump ที่นำมาเมื่อเกิด 502 Bad Gateway Error (UnexpectedEOFAtTarget)

  6. จากเอาต์พุต TCPDump คุณจะเห็นลำดับเหตุการณ์ต่อไปนี้
    1. ในแพ็กเก็ต 985 ตัวประมวลผลข้อความจะส่งคำขอ API ไปยังเซิร์ฟเวอร์แบ็กเอนด์
    2. ในแพ็กเก็ต 986 เซิร์ฟเวอร์แบ็กเอนด์จะตอบกลับทันทีด้วย [FIN,ACK]
    3. ในแพ็กเก็ต 987 Message Processor จะตอบกลับด้วย [FIN,ACK] ไปยังเซิร์ฟเวอร์แบ็กเอนด์
    4. ในที่สุดการเชื่อมต่อจะปิดด้วย [ACK] และ [RST] จากทั้ง 2 ฝั่ง
    5. เนื่องจากเซิร์ฟเวอร์แบ็กเอนด์ส่ง [FIN,ACK] คุณจึงได้รับข้อยกเว้น java.io.EOFException: eof unexpected ใน Message Processor
  7. ซึ่งอาจเกิดขึ้นหากมีปัญหาเกี่ยวกับเครือข่ายในเซิร์ฟเวอร์แบ็กเอนด์ โปรดติดต่อทีมปฏิบัติการเครือข่าย เพื่อตรวจสอบปัญหานี้เพิ่มเติม

ความละเอียด

แก้ไขปัญหาในเซิร์ฟเวอร์แบ็กเอนด์อย่างเหมาะสม

หากยังพบปัญหาอยู่และต้องการความช่วยเหลือในการแก้ปัญหา 502 Bad Gateway Error หรือสงสัยว่าปัญหาเกิดจาก Edge โปรดติดต่อทีมสนับสนุนของ Apigee Edge

สาเหตุ: กำหนดค่าการหมดเวลา Keep-Alive ไม่ถูกต้อง

ก่อนที่จะวินิจฉัยว่านี่คือสาเหตุของข้อผิดพลาด 502 โปรดอ่านแนวคิดต่อไปนี้

การเชื่อมต่อแบบถาวรใน Apigee

โดยค่าเริ่มต้น Apigee (และตามมาตรฐาน HTTP/1.1) จะใช้การเชื่อมต่อแบบถาวร เมื่อสื่อสารกับเซิร์ฟเวอร์แบ็กเอนด์เป้าหมาย การเชื่อมต่อแบบถาวรช่วยเพิ่มประสิทธิภาพ โดยอนุญาตให้ใช้การเชื่อมต่อ TCP และ (หากมี) TLS/SSL ที่สร้างไว้แล้วซ้ำ ซึ่งจะช่วย ลดค่าใช้จ่ายในการตอบสนอง ระยะเวลาที่ต้องคงการเชื่อมต่อจะควบคุมผ่านพร็อพเพอร์ตี้การหมดเวลา Keep-Alive (keepalive.timeout.millis)

ทั้งเซิร์ฟเวอร์แบ็กเอนด์และ Message Processor ของ Apigee ใช้การหมดเวลา Keep-alive เพื่อให้การเชื่อมต่อเปิดอยู่ซึ่งกันและกัน เมื่อไม่ได้รับข้อมูลภายในระยะเวลาการหมดเวลา Keep-Alive เซิร์ฟเวอร์แบ็กเอนด์หรือ Message Processor จะปิดการเชื่อมต่อกับอีกฝ่ายได้

โดยค่าเริ่มต้น พร็อกซี API ที่ติดตั้งใช้งานใน Message Processor ใน Apigee จะมีการตั้งค่าการหมดเวลา Keep-Alive เป็น 60s เว้นแต่จะมีการลบล้าง เมื่อไม่ได้รับข้อมูลสำหรับ 60s Apigee จะ ปิดการเชื่อมต่อกับเซิร์ฟเวอร์แบ็กเอนด์ เซิร์ฟเวอร์แบ็กเอนด์จะรักษาการหมดเวลา Keep-Alive ด้วย และเมื่อหมดเวลาแล้ว เซิร์ฟเวอร์แบ็กเอนด์จะปิดการเชื่อมต่อกับ Message Processor

ผลกระทบของการกำหนดค่าการหมดเวลา Keep-Alive ที่ไม่ถูกต้อง

หาก Apigee หรือเซิร์ฟเวอร์แบ็กเอนด์ได้รับการกำหนดค่าด้วยการหมดเวลา Keep-Alive ที่ไม่ถูกต้อง จะส่งผลให้เกิดภาวะแข่งขันซึ่งทำให้เซิร์ฟเวอร์แบ็กเอนด์ส่ง End Of File (FIN) ที่ไม่คาดคิดเพื่อตอบสนองต่อคำขอทรัพยากร

ตัวอย่างเช่น หากกำหนดค่าการหมดเวลา Keep-Alive ภายใน พร็อกซี API หรือ Message Processor โดยมีค่ามากกว่าหรือเท่ากับการหมดเวลาของ เซิร์ฟเวอร์แบ็กเอนด์ จากต้นน้ำ ภาวะแข่งขัน ต่อไปนี้อาจเกิดขึ้น กล่าวคือ หากตัวประมวลผลข้อความไม่ได้รับข้อมูลใดๆ จนกว่าจะใกล้ถึงเกณฑ์ของระยะหมดเวลาในการเชื่อมต่อที่ใช้งานอยู่ของเซิร์ฟเวอร์แบ็กเอนด์ คำขอจะเข้ามาและส่งไปยังเซิร์ฟเวอร์แบ็กเอนด์โดยใช้การเชื่อมต่อที่มีอยู่ ซึ่งอาจทำให้เกิด 502 Bad Gateway เนื่องจากข้อผิดพลาด EOF ที่ไม่คาดคิดตามที่อธิบายไว้ด้านล่าง

  1. สมมติว่าการหมดเวลา Keep-Alive ที่ตั้งค่าไว้ในทั้ง Message Processor และเซิร์ฟเวอร์แบ็กเอนด์ คือ 60 วินาที และไม่มีคำขอใหม่ เข้ามาจนกว่าจะถึง 59 วินาทีหลังจากที่ Message Processor เฉพาะ ประมวลผลคำขอก่อนหน้า
  2. จากนั้น Message Processor จะประมวลผลคำขอที่เข้ามาในวินาทีที่ 59 โดยใช้การเชื่อมต่อที่มีอยู่ (เนื่องจากยังไม่หมดเวลา Keep-Alive) และส่งคำขอ ไปยังเซิร์ฟเวอร์แบ็กเอนด์
  3. อย่างไรก็ตาม ก่อนที่คำขอจะไปถึงเซิร์ฟเวอร์แบ็กเอนด์ เกณฑ์การหมดเวลา Keep-Alive ได้เกินขีดจำกัดในเซิร์ฟเวอร์แบ็กเอนด์แล้ว
  4. คำขอทรัพยากรของ Message Processor อยู่ระหว่างดำเนินการ แต่เซิร์ฟเวอร์แบ็กเอนด์ พยายามปิดการเชื่อมต่อโดยการส่งแพ็กเก็ต FIN ไปยัง Message Processor
  5. ขณะที่ Message Processor กำลังรอรับข้อมูล แต่กลับได้รับ FIN ที่ไม่คาดคิดแทน และระบบจะสิ้นสุดการเชื่อมต่อ
  6. ซึ่งจะส่งผลให้ Unexpected EOF และต่อมา 502 จะ ส่งคืนไปยังไคลเอ็นต์โดย Message Processor

ในกรณีนี้ เราพบว่าข้อผิดพลาด 502 เกิดขึ้นเนื่องจากมีการกำหนดค่าการหมดเวลา Keep-Alive เดียวกันที่ 60 วินาทีทั้งใน Message Processor และเซิร์ฟเวอร์แบ็กเอนด์ ในทำนองเดียวกัน ปัญหานี้อาจเกิดขึ้นได้เช่นกันหากมีการกำหนดค่าระยะหมดเวลา Keep-Alive ใน Message Processor ให้สูงกว่าในเซิร์ฟเวอร์แบ็กเอนด์

การวินิจฉัย

  1. หากคุณเป็นผู้ใช้ระบบคลาวด์สาธารณะ ให้ทำดังนี้
    1. ใช้เครื่องมือตรวจสอบ API หรือเครื่องมือติดตาม (ตามที่อธิบายไว้ใน ขั้นตอนการวินิจฉัยทั่วไป) และตรวจสอบว่าคุณมีการตั้งค่าทั้ง 2 รายการต่อไปนี้
      • รหัสข้อบกพร่อง: messaging.adaptors.http.flow.UnexpectedEOFAtTarget
      • แหล่งที่มาของข้อบกพร่อง: target
    2. ไปที่การใช้ tcpdump เพื่อตรวจสอบเพิ่มเติม
  2. หากคุณเป็นผู้ใช้ Private Cloud ให้ทำดังนี้
    1. ใช้เครื่องมือติดตามหรือ บันทึกการเข้าถึง NGINX เพื่อระบุรหัสข้อความ รหัสข้อผิดพลาด และแหล่งที่มาของข้อผิดพลาดสำหรับข้อผิดพลาด 502
    2. ค้นหารหัสข้อความในบันทึกของ Message Processor
      (/opt/apigee/var/log/edge-message-processor/logs/system.log)
    3. คุณจะเห็น 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)
    4. ข้อผิดพลาด java.io.EOFException: eof unexpected แสดงว่า Message Processor ได้รับ EOF ขณะที่ยังรออ่านการตอบกลับจากเซิร์ฟเวอร์แบ็กเอนด์
    5. แอตทริบิวต์ useCount=7 ในข้อความแสดงข้อผิดพลาดข้างต้นระบุว่า Message Processor ใช้การเชื่อมต่อนี้ซ้ำประมาณ 7 ครั้ง และแอตทริบิวต์ bytesWritten=159 ระบุว่า Message Processor ได้ส่งเพย์โหลดคำขอ ขนาด 159 ไบต์ไปยังเซิร์ฟเวอร์แบ็กเอนด์ แต่ได้รับข้อมูลกลับมาเป็น 0 ไบต์ เมื่อเกิด EOF ที่ไม่คาดคิด
    6. ซึ่งแสดงให้เห็นว่า Message Processor ใช้การเชื่อมต่อเดียวกันซ้ำหลายครั้ง และในโอกาสนี้ เครื่องมือได้ส่งข้อมูล แต่หลังจากนั้นไม่นานก็ได้รับ EOF ก่อนที่จะได้รับข้อมูลใดๆ ซึ่งหมายความว่ามีโอกาสสูงที่การหมดเวลา Keep-Alive ของเซิร์ฟเวอร์แบ็กเอนด์จะสั้นกว่าหรือเท่ากับที่ตั้งค่าไว้ในพร็อกซี API

      คุณสามารถตรวจสอบเพิ่มเติมได้โดยใช้ tcpdump ตามที่อธิบายไว้ด้านล่าง

การใช้ tcpdump

  1. บันทึก tcpdump ในเซิร์ฟเวอร์แบ็กเอนด์ด้วยคำสั่งต่อไปนี้
    tcpdump -i any -s 0 host MP_IP_Address -w File_Name
  2. วิเคราะห์tcpdumpที่บันทึกไว้

    ตัวอย่างเอาต์พุต tcpdump มีดังนี้

    ในตัวอย่าง tcpdump ด้านบน คุณจะเห็นข้อมูลต่อไปนี้

    1. ในแพ็กเก็ต 5992, เซิร์ฟเวอร์แบ็กเอนด์ได้รับคำขอ GET
    2. ในแพ็กเก็ต 6064 ระบบจะตอบกลับด้วย 200 OK.
    3. ในแพ็กเก็ต 6084 เซิร์ฟเวอร์แบ็กเอนด์ได้รับคำขอ GET อีกรายการ
    4. ในแพ็กเก็ต 6154 อุปกรณ์จะตอบกลับด้วย 200 OK
    5. ในแพ็กเก็ต 6228 เซิร์ฟเวอร์แบ็กเอนด์ได้รับคำขอที่ 3 GET
    6. คราวนี้เซิร์ฟเวอร์แบ็กเอนด์จะส่งคืน FIN, ACK ไปยัง Message Processor (แพ็กเก็ต 6285) ซึ่งเริ่มการปิดการเชื่อมต่อ

    ตัวอย่างนี้ใช้การเชื่อมต่อเดียวกันซ้ำ 2 ครั้งได้สำเร็จ แต่ในคำขอที่ 3 เซิร์ฟเวอร์แบ็กเอนด์จะเริ่มปิดการเชื่อมต่อ ขณะที่ Message Processor รอข้อมูลจากเซิร์ฟเวอร์แบ็กเอนด์ ซึ่งแสดงว่าการหมดเวลา Keep-Alive ของเซิร์ฟเวอร์แบ็กเอนด์มีแนวโน้มที่จะสั้นกว่าหรือเท่ากับค่าที่ตั้งไว้ในพร็อกซี API หากต้องการตรวจสอบ โปรดดูเปรียบเทียบการหมดเวลา Keep-Alive ใน Apigee และเซิร์ฟเวอร์แบ็กเอนด์

เปรียบเทียบการหมดเวลา Keep-Alive ใน Apigee และเซิร์ฟเวอร์แบ็กเอนด์

  1. โดยค่าเริ่มต้น Apigee จะใช้ค่า 60 วินาทีสำหรับพร็อพเพอร์ตี้การหมดเวลา Keep-Alive
  2. อย่างไรก็ตาม คุณอาจลบล้างค่าเริ่มต้นในพร็อกซี 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 มิลลิวินาที)

  3. จากนั้นตรวจสอบพร็อพเพอร์ตี้การหมดเวลา Keep-Alive ที่กำหนดค่าไว้ในเซิร์ฟเวอร์แบ็กเอนด์ สมมติว่า เซิร์ฟเวอร์แบ็กเอนด์ของคุณได้รับการกำหนดค่าด้วยค่า 25 seconds
  4. หากคุณพิจารณาว่าค่าของพร็อพเพอร์ตี้ Keep Alive Timeout ใน Apigee สูงกว่า ค่าของพร็อพเพอร์ตี้ Keep Alive Timeout ในเซิร์ฟเวอร์แบ็กเอนด์ตามตัวอย่างข้างต้น นั่นคือสาเหตุของข้อผิดพลาด 502

ความละเอียด

ตรวจสอบว่าพร็อพเพอร์ตี้การหมดเวลา Keep-Alive ใน Apigee (ในพร็อกซี API และ คอมโพเนนต์ Message Processor) ต่ำกว่าในเซิร์ฟเวอร์แบ็กเอนด์เสมอ

  1. พิจารณาค่าที่ตั้งไว้สำหรับระยะหมดเวลา Keep-Alive ในเซิร์ฟเวอร์แบ็กเอนด์
  2. กำหนดค่าที่เหมาะสมสำหรับพร็อพเพอร์ตี้การหมดเวลา Keep-Alive ใน API Proxy หรือ Message Processor เพื่อให้พร็อพเพอร์ตี้การหมดเวลา Keep-Alive มีค่าต่ำกว่าค่าที่ตั้งไว้ใน แบ็กเอนด์เซิร์ฟเวอร์ โดยใช้ขั้นตอนที่อธิบายไว้ใน การกำหนดค่าการหมดเวลา Keep-Alive ใน Message Processor

หากยังพบปัญหาอยู่ ให้ไปที่ ต้องรวบรวมข้อมูลการวินิจฉัย

แนวทางปฏิบัติแนะนำ

เราขอแนะนำอย่างยิ่งว่าคอมโพเนนต์ดาวน์สตรีมควรมีเกณฑ์การหมดเวลา Keep-Alive ที่ต่ำกว่า ที่กำหนดค่าไว้ในเซิร์ฟเวอร์อัปสตรีมเสมอ เพื่อหลีกเลี่ยงการแข่งขันและ 502ข้อผิดพลาดประเภทนี้ แต่ละฮ็อปลงควรต่ำกว่าแต่ละฮ็อปต้นทาง ใน Apigee Edge แนวทางปฏิบัติแนะนำคือการใช้หลักเกณฑ์ต่อไปนี้

  1. การหมดเวลา Keep-Alive ของไคลเอ็นต์ควรน้อยกว่าการหมดเวลา Keep-Alive ของเราเตอร์ Edge
  2. ระยะหมดเวลา Keep-Alive ของเราเตอร์ Edge ควรน้อยกว่าระยะหมดเวลา Keep-Alive ของ Message Processor
  3. ระยะหมดเวลา Keep-Alive ของ Message Processor ควรน้อยกว่าระยะหมดเวลา Keep-Alive ของเซิร์ฟเวอร์เป้าหมาย
  4. หากคุณมีฮ็อปอื่นๆ ที่อยู่หน้าหรือหลัง 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
  • บันทึกของ Message Processor
    /opt/apigee/var/log/edge-message-processor/logs/system.log
  • ระยะเวลาที่มีข้อมูลเขตเวลาเมื่อเกิดข้อผิดพลาด 502
  • Tcpdumpsที่รวบรวมไว้ในเครื่องมือประมวลผลข้อความหรือเซิร์ฟเวอร์แบ็กเอนด์ หรือทั้ง 2 อย่างเมื่อเกิดข้อผิดพลาด ขึ้น