24 คะแนน โดย GN⁺ 2024-09-30 | 2 ความคิดเห็น | แชร์ทาง WhatsApp

ตั้งแต่ Go 1.22 เป็นต้นมา มีการรองรับ routing ที่ดีขึ้นใน standard library

  • ก่อนหน้านี้ต้องจัดการ routing เองแบบ manual แต่ตอนนี้สามารถทำ routing ได้ง่าย ๆ ด้วย mux.HandleFunc
  • สามารถเพิ่ม login middleware เพื่อเสริมความปลอดภัยได้

ข้อควรระวังของ router ที่มีมาในตัว: การ redirect จาก trailing slash

  • หากสร้าง path /records/ คำขอไปที่ /records จะถูก redirect ไปยัง /records/
  • สิ่งนี้อาจทำให้ body ของคำขอ POST ถูกลบออกและเปลี่ยนเป็นคำขอ GET
  • วิธีแก้คือใช้ API endpoint อย่าง POST /records แทน POST /records/

สร้างโค้ด query ฐานข้อมูลอัตโนมัติด้วย sqlc

  • พบเครื่องมือ sqlc ที่ช่วยให้เขียน SQL query ได้โดยไม่ต้องเรียนรู้ ORM
  • เมื่อเขียน SQL query แล้ว ระบบจะ แปลงเป็นโค้ด Go ให้อัตโนมัติ
  • ทำให้เขียน SQL query ที่ต้องการได้ง่าย โดยไม่ต้องอ้างอิงเอกสารของ ORM

เคล็ดลับการปรับแต่ง sqlite

  • ใช้อ็อบเจ็กต์ฐานข้อมูลสำหรับการเขียนโดยเฉพาะ และตั้งค่า db.SetMaxOpenConns(1)
  • หากต้องการเพิ่มความเร็วในการอ่าน ให้ใช้อ็อบเจ็กต์ DB แยกสำหรับงานเขียนและงานอ่าน
  • ตารางสองชุดที่ไม่จำเป็นต้อง JOIN กันสามารถแยกไว้คนละฐานข้อมูลและเชื่อมต่ออย่างอิสระได้

การตั้งค่า GC memory limit ใน Go 1.19

  • เมื่อรันทุกโปรเจกต์ Go บน VM ที่มีหน่วยความจำค่อนข้างน้อย เช่น 256MB หรือ 512MB จะเกิดปัญหาที่แอปพลิเคชันถูกปิดด้วย OOM อยู่เรื่อย ๆ
  • เนื่องจากค่าเริ่มต้นของ garbage collector อนุญาตให้จัดสรรหน่วยความจำได้มากถึง 2 เท่าของขนาด heap ปัจจุบัน
  • ใน Go 1.19 มีการเพิ่มวิธีสั่งให้แอปพลิเคชันรัน GC เมื่อการใช้หน่วยความจำถึงระดับที่กำหนด
  • หลังตั้งค่า GC memory limit เป็น 250MB ความถี่ของการถูกปิดเพราะ OOM ก็ลดลง export GOMEMLIMIT=250MiB

เหตุผลที่เลือกสร้างเว็บไซต์ด้วย Go

  • deploy ได้ง่ายด้วย static binary เพียงไฟล์เดียว
  • มีเว็บเซิร์ฟเวอร์ในตัวที่พร้อมใช้ใน production จึงไม่ต้องตั้งค่า WSGI หรือสิ่งคล้ายกัน
  • toolchain ของ Go ติดตั้งและใช้งานได้ง่าย
  • การส่ง HTTP response ทำได้ง่าย จึงดูแลรักษาโปรเจกต์ได้สะดวก
  • standard library มี net/http มาให้ จึงสร้างเว็บไซต์ได้โดยไม่ต้องติดตั้งไลบรารีเพิ่ม
  • งานระดับระบบก็ทำได้ง่ายเช่นกัน
  • ดูเหมือนว่าทุกอย่างถูกออกแบบมาเพื่อให้จัดการโปรเจกต์ได้ง่าย

ปัญหาที่ยังแก้ไม่ได้

  • ยังมีหลายอย่างใน Go ที่ยังไม่ได้ลองทำมากนัก
    • การ render HTML template
    • การทำระบบล็อกอินจริง
    • การทำ CSRF
  • โดยทั่วไปแล้วไม่ค่อยรู้วิธีทำฟีเจอร์ที่อ่อนไหวด้านความปลอดภัยอย่างถูกต้อง จึงไม่ค่อยเริ่มโปรเจกต์ที่ต้องมี login/CSRF

การได้เห็นฟีเจอร์ใหม่ของ Go เป็นเรื่องที่น่าประทับใจ

  • ฟีเจอร์ Go สองอย่างที่กล่าวถึงในบทความนี้ (GOMEMLIMIT และ routing) เป็นสิ่งที่เพิ่งถูกเพิ่มเข้ามาในช่วงไม่กี่ปีที่ผ่านมา
  • รู้สึกว่าน่าจะต้องใส่ใจกับ release note ของ Go เวอร์ชันใหม่ ๆ ให้มากขึ้น

2 ความคิดเห็น

 
secret3056 2024-09-30

sqlc ดีมากจริงๆ

 
GN⁺ 2024-09-30
ความเห็นจาก Hacker News
  • ภาษา Go ทำให้กลับมาเขียนโค้ดต่อได้แบบไม่มีปัญหา แม้จะทำโปรเจ็กต์อยู่ 5 วันแล้วปล่อยทิ้งไว้ 2 ปี
  • เริ่มเรียนภาษา Go มาหลายปีแล้ว แต่แทบไม่เปลี่ยนแปลงมาก จึงยังคงมีประโยชน์แม้เวลาจะผ่านไปนาน
  • น่าเสียดายที่โพสต์เกี่ยวกับการพัฒนาเว็บด้วยภาษา Go ไม่ได้พูดถึงแพ็กเกจ embed
    • การบันเดิลรีซอร์สแบบสแตติกไว้ในไบนารีเดียวสะดวกมาก
  • ธุรกรรมฐานข้อมูลถูกออกแบบมาให้ล้มเหลวได้ ดังนั้นควรใช้ลูปสำหรับ retry อยู่เสมอ
    • ควรเพิ่ม Context เข้าไปในลูปของทรานแซกชันเพื่อให้สามารถยกเลิกได้
  • sqlc มีข้อจำกัดสำคัญบางอย่างและความไม่สะดวกเล็กน้อย จึงควรตรวจสอบรายการ issue ก่อนใช้งาน
    • ไม่รองรับ dynamic query, ความสัมพันธ์แบบ one-to-many, embedded CTE, composite type เป็นต้น
    • เหมาะกับความต้องการที่เรียบง่าย แต่ถ้างานซับซ้อนควรใช้แนวทางแบบเขียนเองด้วยมือ
  • เมื่อต้องรัน Go ภายในคอนเทนเนอร์ ควรตั้งค่า GOMAXPROCS ให้เหมาะสมเพื่อหลีกเลี่ยง CPU throttling
  • การใช้ GOMEMLIMIT ช่วยให้กังวลเรื่อง GC น้อยลงได้
    • สามารถตั้งค่าอัตโนมัติได้เมื่อใช้ Kubernetes หรือ Docker
  • html/template มีความแปลกและมีปัญหาหลายอย่าง จึงไม่แนะนำให้ใช้
    • เลือกใช้ Templ แทน
  • ดีใจที่มีการพูดถึงเรื่อง routing
    • คุ้นเคยกับ mux มานาน แต่ไม่ได้สังเกตฟีเจอร์ในรีลีสใหม่
  • ใช้ Go ในที่ทำงานใหม่มา 1 เดือนแล้ว แต่ไม่ชอบ
    • Go ดูเหมือนไม่ได้เรียนรู้อะไรจากพัฒนาการของภาษาตลอด 20 ปีที่ผ่านมา
    • ปัญหาเรื่อง nil ทำให้งานง่าย ๆ ก็ซับซ้อนขึ้น
  • เวลาใช้ SQLite ควรใช้พูล writer แบบเธรดเดียวแยกจากพูลสำหรับอ่าน
    • สามารถใช้ BEGIN CONCURRENT เพื่อปรับปรุงการทำงานพร้อมกันได้
  • ชอบความเรียบง่ายของ Go และการที่ไม่ต้องพึ่งพาเฟรมเวิร์ก
    • แค่ใช้ standard library กับไลบรารี third-party ที่ผ่านการพิสูจน์แล้ว ก็สร้างสิ่งที่ยอดเยี่ยมได้
    • Go เหมาะกับการทำเว็บแอปหรือเครื่องมือ CLI
    • ชอบการจัดการ error แบบชัดเจน
    • เป็นแฟน Go มาก