---
read_when:
    - การเรียกใช้หรือดีบักกระบวนการ Gateway
    - การตรวจสอบการบังคับใช้ให้มีเพียงอินสแตนซ์เดียว
summary: 'การป้องกัน Gateway แบบซิงเกิลตัน: การล็อกไฟล์ร่วมกับการผูก WebSocket/HTTP'
title: การล็อก Gateway
x-i18n:
    generated_at: "2026-07-16T19:08:38Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 32
    provider: openai
    source_hash: f5ac6d42c437b481c68a23a0aa4c00aeac9131acd76f3516ce3e949f325e265b
    source_path: gateway/gateway-lock.md
    workflow: 16
---

## เหตุผล

- ควรมีโปรเซส Gateway เพียงโปรเซสเดียวที่เป็นเจ้าของไดเรกทอรีสถานะ หากต้องการเรียกใช้ Gateway เพิ่มเติม ให้ใช้โปรไฟล์ ไดเรกทอรีสถานะ การกำหนดค่า และพอร์ตที่แยกจากกัน
- ทำงานต่อได้หลังเกิดข้อขัดข้อง/SIGKILL โดยไม่ทิ้งไฟล์ล็อกที่ค้างอยู่
- ล้มเหลวทันทีพร้อมข้อผิดพลาดที่ชัดเจนเมื่อ Gateway อื่นเป็นเจ้าของพอร์ตอยู่แล้ว

## สามชั้น

การเริ่มต้นระบบบังคับใช้ความเป็นเจ้าของตามลำดับสามขั้นตอนดังนี้:

1. **ล็อกความเป็นเจ้าของสถานะ** จะขอล็อกที่ผูกกับไดเรกทอรีสถานะแบบมาตรฐาน Gateway ทุกตัวมีส่วนร่วม รวมถึง Gateway ที่เริ่มต้นด้วย `OPENCLAW_ALLOW_MULTI_GATEWAY=1` เพื่อไม่ให้การบำรุงรักษา SQLite ที่ทำลายข้อมูลเกิดภาวะแข่งขันกับเจ้าของที่กำลังทำงานอยู่
2. **ล็อกการกำหนดค่า** จะขอล็อกต่อการกำหนดค่าแบบเดิมและบันทึกพอร์ตรันไทม์ โหมดหลาย Gateway จะข้ามซิงเกิลตันการกำหนดค่านี้ แต่ยังคงใช้ล็อกความเป็นเจ้าของสถานะ
3. **การผูกซ็อกเก็ต** จะผูกตัวรับฟัง 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](/th/gateway/multiple-gateways) - การเรียกใช้หลายอินสแตนซ์ด้วยพอร์ตที่ไม่ซ้ำกัน
- [การแก้ไขปัญหา](/th/gateway/troubleshooting) - การวินิจฉัย `EADDRINUSE` และข้อขัดแย้งของพอร์ต
