Gateway
การล็อก Gateway
เหตุผล
- ควรมีโปรเซส Gateway เพียงโปรเซสเดียวที่เป็นเจ้าของไดเรกทอรีสถานะ หากต้องการเรียกใช้ Gateway เพิ่มเติม ให้ใช้โปรไฟล์ ไดเรกทอรีสถานะ การกำหนดค่า และพอร์ตที่แยกจากกัน
- ทำงานต่อได้หลังเกิดข้อขัดข้อง/SIGKILL โดยไม่ทิ้งไฟล์ล็อกที่ค้างอยู่
- ล้มเหลวทันทีพร้อมข้อผิดพลาดที่ชัดเจนเมื่อ Gateway อื่นเป็นเจ้าของพอร์ตอยู่แล้ว
สามชั้น
การเริ่มต้นระบบบังคับใช้ความเป็นเจ้าของตามลำดับสามขั้นตอนดังนี้:
- ล็อกความเป็นเจ้าของสถานะ จะขอล็อกที่ผูกกับไดเรกทอรีสถานะแบบมาตรฐาน Gateway ทุกตัวมีส่วนร่วม รวมถึง Gateway ที่เริ่มต้นด้วย
OPENCLAW_ALLOW_MULTI_GATEWAY=1เพื่อไม่ให้การบำรุงรักษา SQLite ที่ทำลายข้อมูลเกิดภาวะแข่งขันกับเจ้าของที่กำลังทำงานอยู่ - ล็อกการกำหนดค่า จะขอล็อกต่อการกำหนดค่าแบบเดิมและบันทึกพอร์ตรันไทม์ โหมดหลาย Gateway จะข้ามซิงเกิลตันการกำหนดค่านี้ แต่ยังคงใช้ล็อกความเป็นเจ้าของสถานะ
- การผูกซ็อกเก็ต จะผูกตัวรับฟัง HTTP/WebSocket (ค่าเริ่มต้น
ws://127.0.0.1:18789) เป็นตัวรับฟัง TCP แบบเอกสิทธิ์
แต่ละชั้นอาจล้มเหลวได้โดยอิสระและจะโยน GatewayLockError ของตนเอง
ล็อกสถานะและการกำหนดค่า
-
การตรวจสอบว่าล็อกยังทำงานอยู่พิจารณาจาก PID ที่บันทึกไว้ ข้อมูลระบุเวลาเริ่มต้นของโปรเซสบนแพลตฟอร์มเมื่อมี และข้อมูลระบุโปรเซส Gateway เจ้าของที่ผ่านการตรวจสอบแล้วยังคงมีสิทธิ์ขาดระหว่างการเริ่มต้นระบบก่อนที่พอร์ตจะเริ่มรับฟัง
-
ตัวประสานงาน SQLite โดยเฉพาะจะจัดลำดับการตรวจสอบข้อมูลเมตา การเรียกคืนสิทธิ์จากเจ้าของที่ไม่ทำงานแล้ว และการแทนที่ล็อก ธุรกรรมแบบเอกสิทธิ์ของตัวประสานงานจะถูกปล่อยโดยอัตโนมัติหากโปรเซสเจ้าของขัดข้อง
-
หากไฟล์ล็อกหายไปหรือโปรเซสเจ้าของที่บันทึกไว้ไม่ทำงานแล้ว การเริ่มต้นระบบจะเรียกคืนล็อกและดำเนินการต่อ
-
หากล็อกใดล็อกหนึ่งถูกถือครองอยู่ การเริ่มต้นระบบจะลองใหม่เป็นเวลาสูงสุด 5 วินาที (ค่าเริ่มต้น) ก่อนยุติความพยายาม:
text GatewayLockError("Gateway กำลังทำงานอยู่แล้ว (pid <pid>); หมดเวลารอล็อกหลังจาก <ms>ms")
การผูกซ็อกเก็ต
-
เมื่อเกิด
EADDRINUSEการเริ่มต้นระบบจะลองผูกใหม่สูงสุด 20 ครั้ง โดยเว้นช่วงครั้งละ 500ms (รวมประมาณ 10 วินาที) เพื่อรอให้พ้นช่วงTIME_WAITหลังจากโปรเซสเพิ่งสิ้นสุด -
หากพอร์ตยังคงถูกใช้งานหลังจากลองใหม่:
text GatewayLockError("อินสแตนซ์ Gateway อื่นกำลังรับฟังอยู่แล้วบน ws://127.0.0.1:<port>") -
ความล้มเหลวอื่นในการผูก:
text GatewayLockError("ไม่สามารถผูกซ็อกเก็ต Gateway บน ws://127.0.0.1:<port>: <cause>")
เมื่อปิดระบบ Gateway จะปิดเซิร์ฟเวอร์ HTTP/WebSocket และลบไฟล์ล็อกสถานะ และการกำหนดค่าของตน
หมายเหตุด้านการปฏิบัติงาน
- หากพอร์ตถูกใช้งานโดยโปรเซสอื่นที่ไม่ใช่ Gateway ข้อผิดพลาดจะเหมือนกัน ให้คืนพอร์ตหรือเลือกพอร์ตอื่นด้วย
openclaw gateway --port <port> OPENCLAW_ALLOW_MULTI_GATEWAY=1อนุญาตให้มีอินสแตนซ์การกำหนดค่า/รันไทม์หลายอินสแตนซ์ ไม่ใช่การใช้สถานะที่เปลี่ยนแปลงได้ร่วมกัน แต่ละอินสแตนซ์ยังคงต้องมีOPENCLAW_STATE_DIRที่ไม่ซ้ำกัน- เมื่อทำงานภายใต้ตัวควบคุมบริการ โปรเซส Gateway ใหม่ที่พบข้อผิดพลาดใดข้อผิดพลาดหนึ่งข้างต้นจะตรวจสอบ
/healthzของโปรเซสที่มีอยู่ก่อน หากโปรเซสนั้นทำงานเป็นปกติ โปรเซสใหม่จะปล่อยให้โปรเซสเดิมควบคุมต่อไปแทนที่จะล้มเหลว บน systemd โปรเซสจะออกด้วยรหัส78;RestartPreventExitStatus=78ของยูนิตจะป้องกันไม่ให้Restart=alwaysวนซ้ำเมื่อเกิดข้อขัดแย้งด้านล็อกหรือEADDRINUSEหากโปรเซสที่มีอยู่ไม่กลับมาทำงานเป็นปกติ การลองตรวจสอบสถานะจะถูกจำกัดเวลา จากนั้นการเริ่มต้นระบบจะล้มเหลวด้วยข้อผิดพลาดด้านล็อกข้างต้นแทนที่จะวนซ้ำตลอดไป - แอป macOS มีตัวป้องกัน PID แบบเบาของตนเองก่อนสร้างโปรเซส Gateway โดยไฟล์ล็อกและการผูกซ็อกเก็ตข้างต้นเป็นกลไกบังคับใช้จริงขณะรันไทม์
ที่เกี่ยวข้อง
- หลาย Gateway - การเรียกใช้หลายอินสแตนซ์ด้วยพอร์ตที่ไม่ซ้ำกัน
- การแก้ไขปัญหา - การวินิจฉัย
EADDRINUSEและข้อขัดแย้งของพอร์ต