it_devops

Elixir Nerves IoT Best Practices ที่ต้องรู้ | SiamCafe Blog

Elixir Nerves IoT Best Practices ที่ต้องรู้ | SiamCafe Blog

Elixir Nerves คืออะไร และทำไมต้องมี Best Practices สำหรับงาน IoT

Elixir Nerves คือเฟรมเวิร์กสำหรับพัฒนาซอฟต์แวร์ฝังตัว (firmware) ที่เขียนด้วยภาษา Elixir บนรากฐานของ BEAM ซึ่งเป็นรันไทม์เดียวกับ Erlang

จุดเด่นคือการที่เราสามารถเขียนโค้ดในลักษณะเดียวกับการพัฒนาเว็บหรือแอปพลิเคชันทั่วไป แล้วนำไปแฟลชลงบนอุปกรณ์ฮาร์ดแวร์ขนาดเล็กอย่าง Raspberry Pi หรือบอร์ดตระกูล BeagleBone ได้โดยตรง ผมใช้งาน Elixir มาช่วงหนึ่งตอนที่ทำระบบดึงข้อมูลราคาและสัญญาณซื้อขาย พบว่าโมเดลการทำงานแบบพร้อมเพียง (concurrency) ของ BEAM เหมาะกับงาน IoT ที่ต้องจัดการอุปกรณ์หลายพันเครื่องพร้อมกันมาก สาเหตุที่ต้องมีแนวปฏิบัติที่ดี เพราะงาน IoT ไม่เหมือนงานเว็บที่เกิดปัญหาแล้วรีสตาร์ทเซิร์ฟเวอร์ได้ทันที อุปกรณ์จำนวนมากถูกติดตั้งในสถานที่เข้าไปแก้ไขยาก เช่น โรงงาน ฟาร์ม หรือตู้คอนโทรลในอาคาร หากไฟร์แวร์มีบั๊กและต้องเดินทางไปแก้ที่หน้างาน ต้นทุนจะสูงมากทั้งเวลาและค่าใช้จ่าย ดังนั้นการวางระบบให้ถูกตั้งแต่ต้นจึงเป็นเรื่องจำเป็น ไม่ใช่ทางเลือก

หัวใจของ Nerves คือการนำหลัก supervision tree ของ Erlang/Elixir มาใช้กับฮาร์ดแวร์ เมื่อส่วนใดของระบบพัง ส่วนที่คอยดูแล (supervisor) จะรีสตาร์ทเฉพาะส่วนนั้น โดยที่ระบบโดยรวมยังทำงานต่อได้ อุปกรณ์จึง "ฟื้นตัวเอง" ได้ในกรณีส่วนใหญ่ นี่คือสิ่งที่ระบบฝังตัวแบบเดิมที่เขียนด้วยภาษาซีทำได้ยากมาก เพราะหากเกิดความผิดพลาดระดับหน่วยความจำ อุปกรณ์จะค้างหรือรีบูตทั้งเครื่อง

ในทางปฏิบัติ แนวปฏิบัติที่ดีของ Nerves แบ่งได้เป็นหลายมิติ ได้แก่ การออกแบบโครงสร้างโปรเจกต์ให้แยก business logic ออกจากส่วนที่จับกับฮาร์ดแวร์ การจัดการอัปเดตไฟร์แวร์แบบระยะไกล (over-the-air update) การเฝ้าระวังสถานะอุปกรณ์ การจัดการความปลอดภัยของการเชื่อมต่อ และการทดสอบบนฮาร์ดแวร์จริงอย่างสม่ำเสมอ บทความนี้จะพาไปดูแต่ละส่วนแบบละเอียด พร้อมตัวอย่างการใช้งานจริงที่ผมนำมาปรับใช้กับระบบงานของตัวเอง เพื่อให้ผู้อ่านนำไปต่อยอดได้ทันทีโดยไม่ต้องเสียเวลาไปเจอปัญหาซ้ำที่คนอื่นเคยเจอมาแล้ว

หลักแรกและสำคัญที่สุดของการเขียนโปรเจกต์ Nerves คือการแยกโค้ดออกเป็นสามชั้นอย่างชัดเจน ชั้นแรกคือตัว firmware ที่บรรจุ logic เฉพาะของอุปกรณ์

ชั้นที่สองคือแอปพลิเคชันที่มี logic ทางธุรกิจซึ่งไม่ขึ้นกับฮาร์ดแวร์ และชั้นที่สามคือไลบรารีที่ใช้ร่วมกัน (shared library) วิธีนี้ทำให้เราสามารถทดสอบ logic ส่วนใหญ่บนเครื่องพัฒนา (โดยใช้ target แบบ host) ได้โดยไม่ต้องแฟลชลงบอร์ดจริงทุกครั้ง ซึ่งช่วยประหยัดเวลาได้มหาศาล เพราะการ build firmware แล้วรอแฟลชลงบอร์ดใช้เวลานานกว่าการรันเทสต์บนเครื่องหลายเท่าตัว

หลักแรกและสำคัญที่สุดของการเขียนโปรเจกต์ Nerves คือการแยกโค้ดออกเป็นสามชั้นอย่างชัดเจน ชั้นแรกคือตัว firmware ที่บรรจุ logic เฉพาะของอุปกรณ์ ชั้นที่สองคือแอปพลิเคชันที่มี logic ทางธุรกิจซึ่งไม่ขึ้นกับฮาร์ดแวร์ และชั้นที่สามคือไลบรารีที่ใช้ร่วมกัน (shared library) วิธีนี้ทำให้เราสามารถทดสอบ logic ส่วนใหญ่บนเครื่องพัฒนา (โดยใช้ target แบบ host) ได้โดยไม่ต้องแฟลชลงบอร์ดจริงทุกครั้ง ซึ่งช่วยประหยัดเวลาได้มหาศาล เพราะการ build firmware แล้วรอแฟลชลงบอร์ดใช้เวลานานกว่าการรันเทสต์บนเครื่องหลายเท่าตัว

แนวปฏิบัติที่แนะนำคือให้ใช้โครงสร้างแบบ umbrella project โดยมีแอปย่อยอย่างน้อยสามตัว ตัวแรกคือ `myappfirmware` ที่มีคอนฟิกเฉพาะของเป้าหมายฮาร์ดแวร์ ตัวที่สองคือ `myappcore` ซึ่งเก็บ logic หลักทั้งหมด และตัวที่สามคือ `myappui` หรือส่วนแสดงผล ถ้ามีส่วนสื่อสารกับเซิร์ฟเวอร์กลาง ควรแยกเป็นอีกตัวหนึ่ง ผลคือเมื่อเขียนเทสต์สำหรับ `myappcore` เราสามารถรันบนเครื่องหลักได้เลย และแก้บั๊กได้เร็วมาก

ตารางต่อไปนี้สรุปการแบ่งชั้นที่ผมใช้จริง

ชั้นชื่อแอปย่อยหน้าที่ทดสอบบนเครื่องพัฒนาได้หรือไม่
โครงข่ายหลักcoreตรรกะธุรกิจ การคำนวณ การจัดการสถานะได้ เต็มรูปแบบ
ส่วนสื่อสารcommการเชื่อมต่อ MQTT/HTTP กับเซิร์ฟเวอร์ได้ (จำลองบริการ)
ส่วนฮาร์ดแวร์hardwareGPIO, I2C, UART, เซนเซอร์ต้องใช้บอร์ดจริง
ไฟร์แวร์firmwareคอนฟิกเป้าหมาย การบูต การอัปเดตต้องแฟลชจริง

การอัปเดตไฟร์แวร์แบบระยะไกลเป็นหัวใจของการดูแลอุปกรณ์ IoT จำนวนมาก หากอุปกรณ์ของคุณกระจายอยู่ตามจังหวัดต่าง ๆ และต้องขับรถไปแก้ทีละเครื่อง

ธุรกิจคงไม่ไหว Nerves มีเครื่องมือสำคัญสองตัวในด้านนี้ คือ Nerves Hub ซึ่งเป็นบริการจัดการอุปกรณ์อย่างเป็นทางการ และแนวทางการอัปเดตแบบ A/B partition ที่ทำให้อุปกรณ์กลับไปเวอร์ชันเดิมได้หากเวอร์ชันใหม่มีปัญหา

การอัปเดตไฟร์แวร์และการจัดการความปลอดภัย

การอัปเดตไฟร์แวร์แบบระยะไกลเป็นหัวใจของการดูแลอุปกรณ์ IoT จำนวนมาก หากอุปกรณ์ของคุณกระจายอยู่ตามจังหวัดต่าง ๆ และต้องขับรถไปแก้ทีละเครื่อง ธุรกิจคงไม่ไหว Nerves มีเครื่องมือสำคัญสองตัวในด้านนี้ คือ Nerves Hub ซึ่งเป็นบริการจัดการอุปกรณ์อย่างเป็นทางการ และแนวทางการอัปเดตแบบ A/B partition ที่ทำให้อุปกรณ์กลับไปเวอร์ชันเดิมได้หากเวอร์ชันใหม่มีปัญหา

หลักการสำคัญคือ "อย่าแฟลชไฟร์แวร์ที่ยังไม่ผ่านการทดสอบขึ้นอุปกรณ์ทุกตัวพร้อมกัน" ควรทำแบบเฟส ๆ ไป เริ่มจากกลุ่มทดสอบ (canary group) สักห้าถึงสิบเปอร์เซ็นต์ของอุปกรณ์ทั้งหมด คอยเฝ้าดูค่าเมตริกเช่น อัตราการรีบูตเอง การเชื่อมต่อขาดหาย หรือค่าที่อุปกรณ์รายงานกลับมาเปลี่ยนผิดปกติ ถ้าทุกอย่างเรียบร้อยภายในยี่สิบสี่ชั่วโมง ค่อยขยายไปยังกลุ่มที่เหลือ วิธีนี้ช่วยจำกัดความเสียหายได้มากหากมีบั๊กหลุดรอด

ด้านความปลอดภัย มีหลักที่ต้องทำเป็นอย่างต่ำดังนี้

เข้ารหัสการสื่อสารทั้งหมด — ใช้ TLS สำหรับการเชื่อมต่อกับเซิร์ฟเวอร์ และตรวจสอบใบรับรองเสมอ อย่าปล่อยการเชื่อมต่อแบบไม่เข้ารหัสแม้ในเครือข่ายภายใน เพราะเครือข่ายในสถานที่ติดตั้งจริงเราควบคุมไม่ได้ จัดการกุญแจและข้อมูลลับอย่างถูกวิธี — ห้ามฝังรหัสผ่านหรือโทเคนลงในโค้ดโดยตรง ให้ใช้กลไก provisioning ของ Nerves ที่ฝังข้อมูลลับตอนสร้างไฟร์แวร์เท่านั้น และเก็บกุญแจไว้ในบริการจัดการข้อมูลลับแยกต่างหาก อัปเดตตัว Nerves และ dependencies เป็นประจำ — ตรวจสอบช่องโหว่ที่รายงานผ่านหน้าเว็บของไลบรารีที่ใช้ และรันคำสั่งตรวจสอบ dependencies เป็นระยะ

อุปกรณ์ IoT ที่ดีคืออุปกรณ์ที่เรา "มองเห็น" สถานะของมันได้ตลอดเวลา หากไม่มีการเฝ้าระวัง เราจะรู้ว่าอุปกรณ์พังก็ต่อเมื่อลูกค้าโทรมาบอก

ซึ่งสายเกินไปเสมอ ระบบการสังเกตการณ์ (observability) ที่ดีประกอบด้วยสามส่วน คือ เมตริก (metrics) บันทึกเหตุการณ์ (logs) และการติดตามการทำงาน (tracing) ในบริบทของ Nerves การเก็บข้อมูลบนอุปกรณ์ต้องคำนึงถึงข้อจำกัดด้านพื้นที่จัดเก็บและแบนด์วิดท์อินเทอร์เน็ต ดังนั้นกลยุทธ์ที่ผมใช้คือเก็บข้อมูลดิบไว้บนอุปกรณ์ชั่วคราว สรุปค่าเฉลี่ยหรือค่าสูงสุดส่งขึ้นเซิร์ฟเวอร์เป็นระยะ และบีบอัดข้อมูลก่อนส่งเสมอ

ประเด็นที่คนมักพลาดคือลืมกำหนดค่าให้อุปกรณ์กลับสู่สถานะปลอดภัยเมื่อเกิดความผิดพลาดร้ายแรง ตัวอย่างเช่น ถ้าอุปกรณ์ควบคุมวาล์วหรือรีเลย์พังกลางทาง ควรออกแบบให้ฮาร์ดแวร์กลับสู่สถานะที่ปลอดภัยโดยอัตโนมัติ ไม่ใช่ค้างอยู่ในสถานะล่าสุดที่อาจเป็นอันตรายได้ แนวคิดนี้ยืมมาจากงานระบบฝังตัวแบบดั้งเดิมและยังใช้ได้ดีมากกับงาน Nerves

การเฝ้าระวัง การเก็บข้อมูล และการสังเกตการณ์ระบบ

อุปกรณ์ IoT ที่ดีคืออุปกรณ์ที่เรา "มองเห็น" สถานะของมันได้ตลอดเวลา หากไม่มีการเฝ้าระวัง เราจะรู้ว่าอุปกรณ์พังก็ต่อเมื่อลูกค้าโทรมาบอก ซึ่งสายเกินไปเสมอ ระบบการสังเกตการณ์ (observability) ที่ดีประกอบด้วยสามส่วน คือ เมตริก (metrics) บันทึกเหตุการณ์ (logs) และการติดตามการทำงาน (tracing) ในบริบทของ Nerves การเก็บข้อมูลบนอุปกรณ์ต้องคำนึงถึงข้อจำกัดด้านพื้นที่จัดเก็บและแบนด์วิดท์อินเทอร์เน็ต ดังนั้นกลยุทธ์ที่ผมใช้คือเก็บข้อมูลดิบไว้บนอุปกรณ์ชั่วคราว สรุปค่าเฉลี่ยหรือค่าสูงสุดส่งขึ้นเซิร์ฟเวอร์เป็นระยะ และบีบอัดข้อมูลก่อนส่งเสมอ

เมตริกพื้นฐานที่ทุกอุปกรณ์ควรรายงานมีดังนี้

  • สถานะการเชื่อมต่อเครือข่ายและคุณภาพสัญญาณ
  • อุณหภูมิของชิปและแรงดันไฟฟ้า
  • การใช้หน่วยความจำและพื้นที่จัดเก็บ
  • จำนวนครั้งที่กระบวนการย่อยถูกรีสตาร์ทโดย supervisor
  • เวลาที่อุปกรณ์ทำงานต่อเนื่องมาแล้วนับแต่บูตครั้งล่าสุด

ค่าที่บอกปัญหาได้ดีที่สุดในระบบ Elixir คือจำนวนครั้งที่กระบวนการถูกรีสตาร์ท ถ้ากระบวนการหนึ่งรีสตาร์ทเป็นสิบครั้งภายในหนึ่งนาที แปลว่ามีบั๊กหรือสภาพแวดล้อมไม่เอื้ออย่างชัดเจน การเก็บค่านี้ส่งขึ้นเซิร์ฟเวอร์ทำให้เราเห็นแนวโน้มก่อนที่อุปกรณ์จะล้มเหลวเต็มรูปแบบ

ด้านการจัดการบันทึกเหตุการณ์ แนะนำให้ใช้ระดับการบันทึกอย่างถูกต้อง ไม่ใช่บันทึกทุกอย่างระดับข้อมูล (info) จนเต็มพื้นที่จัดเก็บ บนอุปกรณ์ที่พื้นที่จำกัด ควรบันทึกระดับข้อผิดพลาด (error) และคำเตือน (warning) ไว้บนอุปกรณ์แบบวนซ้ำ และส่งเฉพาะกรณีสำคัญขึ้นเซิร์ฟเวอร์ทันที ส่วนระดับข้อมูลสำหรับการดีบั๊กให้เปิดเฉพาะตอนที่ต้องการตรวจสอบเท่านั้น

ตัวอย่างการตั้งค่ารายงานสถานะเป็นระยะอย่างง่าย

defmodule MyApp.HealthReporter do use GenServer @interval :timer.minutes(5)

def startlink(opts), do: GenServer.startlink(__MODULE__, opts, name: __MODULE__)

def init(opts) do schedule() {:ok, %{server: opts[:server]}} end

def handle_info(:report, state) do payload = %{ memory: :erlang.memory(:total), uptime: :erlang.statistics(:wall_clock) |> elem(0), restarts: MyApp.Metrics.get(:restarts) } MyApp.Comm.send(state.server, payload) schedule() {:noreply, state} end

จุดแข็งที่สุดของ Nerves อย่างหนึ่งคือระบบ target ที่ให้เราสร้างไฟร์แวร์สำหรับเครื่องพัฒนา (โดยปกติคือ target ชื่อ host)

ได้เช่นเดียวกับการสร้างสำหรับบอร์ดจริง วิธีนี้ทำให้เราเขียนและทดสอบ logic ส่วนใหญ่ได้โดยไม่ต้องแตะฮาร์ดแวร์เลย ทีมงานส่วนใหญ่ที่ทำงานกับ Nerves ใช้วงจรการพัฒนาแบบนี้ เขียนโค้ดและทดสอบบนเครื่องจนเกือบเสร็จ แล้วค่อยทดสอบบนบอร์ดจริงในขั้นตอนสุดท้ายเพื่อยืนยันเรื่องการติดต่อกับเซนเซอร์และฮาร์ดแวร์ที่เกี่ยวข้อง end

โค้ดนี้เป็นตัวอย่างแบบเรียบง่ายที่รายงานสถานะทุกห้านาที ในระบบจริงควรเพิ่มการจัดการกรณีการส่งล้มเหลวโดยเก็บข้อมูลไว้ก่อนแล้วส่งซ้ำเมื่อการเชื่อมต่อกลับมา รวมถึงการตั้งค่าการยืนยันตัวตนให้เรียบร้อยก่อนนำไปใช้

การทดสอบและการพัฒนาบนเครื่องจำลอง

จุดแข็งที่สุดของ Nerves อย่างหนึ่งคือระบบ target ที่ให้เราสร้างไฟร์แวร์สำหรับเครื่องพัฒนา (โดยปกติคือ target ชื่อ host) ได้เช่นเดียวกับการสร้างสำหรับบอร์ดจริง วิธีนี้ทำให้เราเขียนและทดสอบ logic ส่วนใหญ่ได้โดยไม่ต้องแตะฮาร์ดแวร์เลย ทีมงานส่วนใหญ่ที่ทำงานกับ Nerves ใช้วงจรการพัฒนาแบบนี้ เขียนโค้ดและทดสอบบนเครื่องจนเกือบเสร็จ แล้วค่อยทดสอบบนบอร์ดจริงในขั้นตอนสุดท้ายเพื่อยืนยันเรื่องการติดต่อกับเซนเซอร์และฮาร์ดแวร์ที่เกี่ยวข้อง

แนวปฏิบัติที่แนะนำในการทดสอบมีดังนี้

  • เขียนเทสต์หน่วยสำหรับ logic ทั้งหมดในส่วนที่ไม่จับกับฮาร์ดแวร์ ปกติควรครอบคลุมแปดสิบเปอร์เซ็นต์ขึ้นไปของโค้ดทั้งหมด
  • สร้างเลเยอร์สกัด (abstraction layer) รอบการติดต่อกับฮาร์ดแวร์ เช่น นิยามพฤติกรรม (behaviour) ชื่อ `Sensor` ที่มีสองรูปแบบ รูปแบบหนึ่งอ่านค่าจากเซนเซอร์จริง อีกรูปแบบส่งค่าจำลองกลับมา ทำให้ทดสอบได้ทุกสภาพแวดล้อม
  • ทดสอบบนบอร์ดจริงอย่างน้อยหนึ่งครั้งก่อนปล่อยเวอร์ชัน ด้วยการรันชุดทดสอบพื้นฐาน เช่น ตรวจว่าเซนเซอร์อ่านค่าได้ การเชื่อมต่อเครือข่ายสำเร็จ และการรายงานสถานะทำงานถูกต้อง
  • ทดสอบสถานการณ์ผิดปกติ เช่น ตัดการเชื่อมต่ออินเทอร์เน็ตกลางคัน ตัดไฟแล้วบูตใหม่ หรือปล่อยให้อุปกรณ์ทำงานทับซ้อนกันเป็นเวลานาน เพื่อหาปัญหาหน่วยความจำรั่ว

กรณีหน่วยความจำรั่วเป็นปัญหาคลาสสิกของระบบฝังตัว แม้ BEAM จะมีการจัดการหน่วยความจำที่ดี แต่ถ้าโค้ดของเราสะสมข้อมูลไว้ในกระบวนการที่ไม่เคยปล่อย หรือเปิดการเชื่อมต่อแล้วไม่ปิด อุปกรณ์ที่มีหน่วยความจำเพียงห้าร้อยเมกะไบต์จะเต็มภายในไม่กี่วัน วิธีตรวจคือปล่อยอุปกรณ์ทำงานต่อเนื่องอย่างน้อยหนึ่งสัปดาห์แล้ววาดกราฟการใช้หน่วยความจำ ถ้าเส้นกราฟไต่ขึ้นเรื่อย ๆ ไม่มีวันแบน แสดงว่ามีการรั่วไหลต้องรีบแก้

อีกประเด็นสำคัญคือการใช้ CI/CD กับโปรเจกต์ Nerves การสร้างไฟร์แวร์ต้องดาวน์โหลด toolchain และ dependencies ครั้งแรกซึ่งใช้เวลานาน ดังนั้นควรแคชทุกอย่างในระบบรวมศูนย์การทำงานอัตโนมัติ ให้ทุกครั้งที่ผสานโค้ดเข้าสาขาหลัก ระบบจะสร้างไฟร์แวร์ รันเทสต์ และสร้างไฟล์ไฟร์แวร์สำหรับแจกจ่ายอัตโนมัติ วิธีนี้ทำให้ทีมมั่นใจได้ว่าโค้ดบนสาขาหลักพร้อมปล่อยได้ตลอดเวลา และลดข้อผิดพลาดจากการสร้างด้วยมือ

ตัวอย่างการประยุกต์ใช้จริงและบทเรียนจากหน้างาน

เพื่อให้เห็นภาพชัดขึ้น ผมจะเล่ากรณีศึกษาจากระบบเล็ก ๆ ที่ผมช่วยดูแล ซึ่งเป็นระบบเก็บข้อมูลจากเซนเซอร์อุณหภูมิและความชื้นในโกดังสินค้าประมาณสามสิบจุด ใช้ Raspberry Pi Zero 2 พร้อมเซนเซอร์ผ่านบัส I2C อุปกรณ์ทุกตัวรันไฟร์แวร์ Nerves และส่งข้อมูลขึ้นเซิร์ฟเวอร์กลางทุกสองนาที

สิ่งที่เราเรียนรู

คำถามที่พบบ่อย

Elixir Nerves เหมาะกับงาน IoT อย่างไร และต่างจากการเขียนไฟร์แวร์แบบภาษาซีอย่างไร?

Elixir Nerves เป็นเฟรมเวิร์กสำหรับพัฒนาไฟร์แวร์ที่เขียนด้วยภาษา Elixir บนรากฐานของ BEAM ซึ่งเป็นรันไทม์เดียวกับ Erlang จุดเด่นคือเราสามารถเขียนโค้ดในลักษณะเดียวกับการพัฒนาเว็บหรือแอปพลิเคชันทั่วไป แล้วแฟลชลงบนฮาร์ดแวร์ขนาดเล็กอย่าง Raspberry Pi หรือ BeagleBone ได้โดยตรง ความต่างสำคัญจากภาษาซีคือหลัก supervision tree ของ BEAM เมื่อส่วนใดของระบบพัง supervisor จะรีสตาร์ทเฉพาะส่วนนั้นโดยระบบโดยรวมยังทำงานต่อได้ อุปกรณ์จึง "ฟื้นตัวเอง" ได้ในกรณีส่วนใหญ่ ขณะที่ระบบฝังตัวแบบเดิมที่เขียนด้วยภาษาซี หากเกิดความผิดพลาดระดับหน่วยความจำ อุปกรณ์มักค้างหรือรีบูตทั้งเครื่อง นอกจากนี้โมเดล concurrency ของ BEAM ยังเหมาะกับการจัดการอุปกรณ์หลายพันเครื่องพร้อมกันอีกด้วย

ควรโครงสร้างโปรเจกต์ Nerves อย่างไรให้ทดสอบได้ง่ายและรวดเร็ว?

แนวปฏิบัติที่แนะนำคือใช้โครงสร้าง umbrella project โดยแยกโค้ดเป็นสามชั้นอย่างชัดเจน ได้แก่ แอปย่อย `myappfirmware` ที่เก็บคอนฟิกเฉพาะเป้าหมายฮาร์ดแวร์, `myappcore` ที่เก็บ logic หลักทางธุรกิจทั้งหมดซึ่งไม่ขึ้นกับฮาร์ดแวร์, และ `myappui` สำหรับส่วนแสดงผล หากมีส่วนสื่อสารกับเซิร์ฟเวอร์กลางควรแยกเป็นอีกแอปหนึ่ง วิธีนี้ทำให้เราทดสอบ logic ส่วนใหญ่บนเครื่องพัฒนาด้วย target แบบ host ได้โดยไม่ต้องแฟลชลงบอร์ดจริงทุกครั้ง ซึ่งช่วยประหยัดเวลาได้มหาศาล เพราะการ build firmware แล้วรอแฟลชลงบอร์ดใช้เวลานานกว่าการรันเทสต์บนเครื่องหลายเท่าตัว ส่วนที่จับกับฮาร์ดแวร์โดยตรง เช่น GPIO, I2C, UART และเซนเซอร์ จึงเป็นส่วนเดียวที่ต้องทดสอบบนบอร์ดจริง

ควรออกแบบ supervision tree ในโปรเจกต์ Nerves อย่างไรให้ปลอดภัยและเสถียร?

หลักสำคัญคืออย่าให้ทุกอย่างอยู่ใต้ supervisor ตัวเดียว เพราะถ้าส่วนหนึ่งพังบ่อย จะทำให้ส่วนที่เหลือถูกรีสตาร์ทตามไปด้วยโดยไม่จำเป็น ควรแยก supervisor ย่อยตามหน้าที่ เช่น supervisor สำหรับจัดการเซนเซอร์ แยกออกจาก supervisor สำหรับจัดการเชื่อมต่อเครือข่าย แล้วกำหนดกลยุทธ์การรีสตาร์ท (restart strategy) ให้เหมาะกับลักษณะงานของแต่ละส่วน โดยส่วนที่พังได้บ่อยและพังแล้วไม่กระทบส่วนอื่น ให้ใช้แบบ `oneforone` ส่วนที่ต้องพร้อมใช้งานพร้อมกันทั้งชุด ให้ใช้ `restforone` หรือ `oneforall` นอกจากนี้อย่าลืมตั้งค่า `maxrestarts` และ `maxseconds` ให้เหมาะสม เพื่อป้องกันกรณีที่ระบบเกิดลูปรีสตาร์ทไม่สิ้นสุด จนอุปกรณ์กินไฟและเครื่องร้อนโดยที่ไม่มีใครรู้ตัว

ทำไมงาน IoT จึงต้องมี Best Practices ตั้งแต่ต้น ไม่เหมือนงานเว็บทั่วไป?

เหตุผลสำคัญคือลักษณะการติดตั้งและการแก้ไขปัญหาของอุปกรณ์ IoT ที่แตกต่างจากงานเว็บโดยสิ้นเชิง งานเว็บเมื่อเกิดปัญหาสามารถรีสตาร์ทเซิร์ฟเวอร์หรือ deploy โค้ดใหม่ได้ทันที แต่อุปกรณ์ IoT จำนวนมากถูกติดตั้งในสถานที่เข้าไปแก้ไขได้ยาก เช่น โรงงาน ฟาร์ม

แนะนำเพิ่มเติม

🎯 เปิดบัญชี XM Forex → สมัคร

📱 แอป iCafeFX → ดาวน์โหลด

📊 สัญญาณฟรี → รับสัญญาณ

📚 คู่มือเทรด → SiamCafeBook

🤝 สมัคร Partner XM → pipaffiliates.com/c?c=72816&l=th&p=6

คู่มือ Forex ที่เกี่ยวข้อง

อ
XM Legend · เทรดเดอร์ & ผู้สอน Forex 13 ปี

ผู้ก่อตั้ง SiamCafe ตั้งแต่ปี 1997 · เทรดเดอร์สาย Forex มากกว่า 13 ปี ได้รับการยกย่องเป็น XM Legend · แบ่งปันความรู้ Forex, ไอที, AI และการเทรด จากประสบการณ์จริงในตลาดจริง

แหล่งอ้างอิง

  • SiamCafe.net - ชุมชนไอทีไทยตั้งแต่ปี 1997
  • iCafeFX.com - ศูนย์วิเคราะห์ Forex และทองคำ