ออกแบบระบบให้คุยข้าม module กันได้ ด้วย Pub/Sub

เมื่อนานมาแล้ว ผมพัฒนา Apps Script ขึ้นมาตัวหนึ่ง เพื่อดึงข้อมูลจาก Reseller API มาตรวจสอบ หากเข้าเงื่อนไขที่กำหนดไว้ script ก็จะส่งอีเมลแจ้งเตือนไปยังทีมงานที่ดูแลข้อมูลชุดนั้น เมื่อเวลาผ่านไปนานเข้า จำนวนข้อมูลที่ต้องตรวจสอบก็เยอะขึ้น และจำนวนอีเมลที่ต้องส่งแจ้งเตือนออกไปก็มากขึ้นเป็นเงาตามตัว จนถึงขีดจำกัดของ script

account ที่ผมใช้รัน script เพื่อดึงข้อมูลจาก Reseller API นั้น เป็น G Suite free editon ซึ่งมีข้อจำกัดในการส่งอีเมลที่ 100 ฉบับต่อวัน ซึ่งในบางวันนั้น จำนวนอีเมลที่ต้องส่งออกก็สูงเกินข้อจำกัดนี้ และการที่ระบบส่งอีเมลไม่ได้ ก็ส่งผลให้ทีมงานที่ทำงานกับอีเมลแจ้งเตือนนี้ ทำงานได้ลำบาก

reseller account ที่ใช้ส่งอีเมลแจ้งเตือน มีข้อจำกัดที่ 100 ฉบับต่อวัน ซึ่งไม่พอกับความต้องการ

ทางออกที่ก้าวข้ามขีดจำกัดนี้ มีอยู่หลายทาง เช่น การเปลี่ยนวิธีการส่งอีเมล แทนที่จะใช้ email service ของ Apps Script ก็สามารถเปลี่ยนไปใช้ SMTP relay อื่นๆ ได้ แต่ก็จะมีองค์ประกอบที่ต้องดูแลเพิ่มเติมเข้ามา

ด้วยความที่บริษัทใช้ G Suite Business อยู่แล้ว และเมื่อดูจาก quota อีเมลก็สามารถส่งได้มากถึง 1,500 ฉบับต่อวัน ซึ่งน่าจะเพียงพอกับการใช้งานไปได้อีกนาน แต่เนื่องจาก API ที่ผมต้องดึงข้อมูลมานั้น ไม่สามารถดึงด้วย business account ของบริษัทได้ ต้องดึงข้อมูลด้วย reseller account (ซึ่งเป็น G Suite free edition) ดังนั้น สิ่งที่ต้องทำเพิ่มคือ ใช้ reseller account เพื่อดึงข้อมูล เสร็จแล้วค่อยใช้ business account มาอ่านข้อมูลนี้และทำหน้าที่ส่งอีเมลออก ซึ่งก็จะเป็นการใช้ quota ของ business account ที่สามารถส่งอีเมลได้มากกว่านั่นเอง

business account ที่ใช้งานอยู่แล้ว มี quota ถึง 1,500 ฉบับต่อวัน สามารถใช้ไปได้อีกยาวๆ

การส่งข้อมูลข้าม account กันนั้น สามารถทำได้หลายวิธี เช่น ตั้ง database ขึ้นมาตัวหนึ่ง แล้วใช้ reseller account ดึงข้อมูลมาเขียนลง database เสร็จแล้วค่อยเอา business account มาอ่าน database แล้วไปทำงานต่อ ถ้าแบบที่ใกล้ตัวหน่อยก็สามารถใช้ spreadsheet เป็นตัวกลางได้เช่นกัน เนื่องจากข้อมูลไม่ได้มีขนาดใหญ่มาก และ schema ของข้อมูลก็ไม่ซับซ้อน

แต่การนำ spreadsheet มาใช้เป็น database ยังมีส่วนที่ต้องทำให้เหมาะสมกับงานอยู่ ทั้งการ update status ของ record นั้นๆ ว่าส่งอีเมลสำเร็จหรือไม่ หรือการคอย maintenance ข้อมูลที่ไม่ใช้แล้วออกจากระบบ เนื่องจากไม่มีความจำเป็นต้องเก็บข้อมูลที่ใช้เสร็จแล้วเอาไว้ และข้อมูลจะได้ไม่เต็ม จนเกิด error ที่ต้องมาตามแก้ไขอีก

เมื่อ Pub/Sub เข้ามาเติมช่องว่างให้เต็ม

Pub/Sub ซึ่งเป็น messeaging service ใน Google Cloud เป็นอีกทางออกหนึ่งที่ค่อนข้างเหมาะเจาะกับกรณีนี้ ด้วยเหตุผลคือ
  • เป็น managed service ไม่ต้องติดตั้งหรือดูแลระบบแต่อย่างใด
  • ใช้ Google account เพื่อเรียกใช้งานได้เลย ไม่ต้องไปสมัครใช้บริการใหม่
  • ระบบมีความเสถียร มั่นใจได้ว่าข้อความที่ส่งต่อไม่หายไปไหน ถ้า publish ข้อความสำเร็จ
  • เมื่อดึงข้อความมาใช้งานแล้ว สามารถ acknowledge ไปที่ Pub/Sub เพื่อป้องกันไม่ให้ข้อความถูกดึงไปใช้ซ้ำได้
  • ไม่ต้องคอย maintenance ข้อความที่ค้างอยู่ในระบบ เนื่องจากข้อความที่ได้รับ ackownledge แล้ว หรือหมดมายุ จะหายไปจากระบบเอง (เทียบกับการที่ต้องคอยดูแล database)
เมื่อเลือก solution ได้แล้ว และเริ่ม implement script ใหม่ ขั้นตอนการทำงานของ script ใหม่จะเป็นดังนี้
  1. trigger reseller account เพื่อดึงข้อมูลจาก Reseller API มาประมวลผล
  2. ใช้ reseller account ในการ publish ข้อมูลที่ต้องมีการแจ้งเตือนอีเมล ไปที่ Pub/Sub topic
  3. trigger business account เพื่อ pull message จาก Pub/Sub subscription และส่งอีเมลแจ้งเตือน
  4. หากทำงานเรียบร้อย จะส่ง acknowledge กลับไปที่ Pub/Sub subscription
dashboard ของ Pub/Sub topics แสดงจำนวนครั้งของการ publish message
dashboard ของ Pub/Sub subscriptions แสดจำนวนและเวลาของ message ในระบบ

จากที่ลองใช้งานมา script ใหม่สามารถรันได้เรียบร้อยดี ไม่ติด limit เรื่องการส่งอีเมลออก และทำให้เห็นว่า Pub/Sub เป็นตัวกลางในการรับส่งข้อมูลเพื่อให้เราออกแบบระบบที่ทำงานแยกเป็นส่วนๆ ได้สะดวกมากขึ้น หากใครมีการพัฒนาระบบและต้องมีการสื่อสารกันในแต่ละ module ลองพิจารณา Pub/Sub ดูครับ อาจจะช่วยให้ระบบแยกส่วนกันได้ง่ายขึ้น



ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

การเรียกใช้งาน Google Apps Script

ป้องกันอีเมลสวมรอย (Email spoofing) ด้วย SPF, DKIM และ DMARC

การเขียน Google Apps Script เพื่อใช้งาน Custom Function