สร้างระบบแจ้งเตือนแบบยืดหยุ่นด้วย Lambda: เมื่อทุกการเคลื่อนไหวสำคัญ
สวัสดีครับเพื่อน ๆ นักพัฒนา! วันนี้ผมอยากจะชวนคุยเรื่องการสร้างระบบแจ้งเตือนที่มันยืดหยุ่นและพร้อมรับมือกับทุกสถานการณ์ที่คาดไม่ถึงนะครับ หลายคนคงเคยเจอประสบการณ์ที่ระบบแจ้งเตือนล่มบ้าง ช้าบ้าง เวลาที่ User เข้ามาเยอะๆ หรือมีอีเวนต์สำคัญๆ เกิดขึ้นพร้อมกันใช่มั้ยครับ? คือจะบอกว่ามันน่าปวดหัวมากๆ เลยนะ
ในยุค 2024 แบบนี้ ที่ทุกอย่างต้องเร็ว ต้องตอบสนองทันที การพึ่งพาระบบแจ้งเตือนแบบเดิมๆ ที่รันบนเซิร์ฟเวอร์ตัวเองตลอดเวลา (แบบที่ต้องไปตั้ง cronjob ยิงสคริปต์งี้) มันอาจจะไม่ค่อยตอบโจทย์แล้วล่ะครับ คือมันมีค่าใช้จ่ายเรื่องเซิร์ฟเวอร์ที่ต้องเปิดทิ้งไว้ตลอด แถมยังต้องมานั่งกังวลเรื่องการ Scale อีก พอ user เยอะขึ้นก็ต้องมานั่งเพิ่มเซิร์ฟเวอร์ วุ่นวายสุดๆ
วันนี้เราจะมาลองดูแนวคิดการสร้างระบบแจ้งเตือนด้วย Lambda function กันครับ คือมันไม่ได้แค่ลดค่าใช้จ่ายนะ แต่มันทำให้ระบบของเราเนี่ย "พร้อม" เสมอที่จะส่งการแจ้งเตือน ไม่ว่าจะเกิดอะไรขึ้น แค่มีอีเวนต์มามันก็ทำงานเอง ไม่ต้องไปเปิดเครื่องทิ้งไว้ให้เปลืองตังค์เลย พูดง่ายๆ คือเราเขียนโค้ด "การแจ้งเตือน" แล้วโยนให้ Lambda จัดการที่เหลือครับ
ทำไม Lambda ถึงเหมาะกับ Notification?
จริงๆ หัวใจสำคัญของ Lambda ที่เอามาใช้กับ Notification ได้ดีคือ “Event-Driven” ครับ คือมันไม่ได้รันตลอดเวลา แต่จะรันเมื่อมี "เหตุการณ์" อะไรบางอย่างเกิดขึ้นเท่านั้น พออีเวนต์มา Lambda ก็ตื่นขึ้นมาทำงาน ส่งแจ้งเตือนเสร็จก็หลับไป ประหยัดงบสุดๆ แถมยัง Scalable แบบอัตโนมัติ คือถ้ามีอีเวนต์มาเป็นล้านพร้อมกัน Lambda ก็แค่สร้าง Instance เพิ่มให้เองครับ ไม่ต้องห่วงเครื่องล่มเลย
ลองมาดูตัวอย่างง่าย ๆ กันนะครับ ว่าจะหน้าตาประมาณไหน
# ตัวอย่างแนวคิดการรับอีเวนต์และส่งแจ้งเตือน (เป็น pseudocode นะครับ ไม่ใช่โค้ดจริง)
def handle_new_order_event(event_data):
user_id = event_data.get('user_id')
order_id = event_data.get('order_id')
product_name = event_data.get('product_name')
# ตรงนี้คือส่วนที่ Lambda จะทำงานเมื่อมีอีเวนต์ 'new_order' เข้ามา
if user_id and order_id and product_name:
message = f"ขอบคุณสำหรับการสั่งซื้อ {product_name} รหัส #{order_id} จาก cii3.net ครับ!"
# ส่งการแจ้งเตือนไปให้ user (อาจจะผ่าน Email, SMS, Push Notification)
send_notification_to_user(user_id, message)
print(f"ส่งแจ้งเตือนให้ User ID: {user_id} เรียบร้อย")
else:
print("ข้อมูลอีเวนต์ไม่ครบถ้วน ไม่สามารถส่งแจ้งเตือนได้")
โค้ดข้างบนเนี่ย มันจะถูก deploy เป็น Lambda function ครับ แล้วเราก็ไปตั้งค่าให้มัน Trigger อัตโนมัติเมื่อมีอีเวนต์ 'new_order' เกิดขึ้น เช่น เวลาลูกค้ากดสั่งซื้อของบนเว็บ cii3.net ก็ยิงอีเวนต์มาที่ Lambda ได้เลยครับ
ส่งแจ้งเตือนจริงจังหน่อยสิ!
มาดูตัวอย่างการส่งแจ้งเตือนจริงๆ ผ่านบริการอย่าง AWS SNS (Simple Notification Service) ซึ่งเป็นบริการของ AWS เองที่ใช้ส่งแจ้งเตือนแบบ Mass scale ได้ครับ
import json
import boto3
# สร้าง client สำหรับ SNS
sns_client = boto3.client('sns')
def lambda_handler(event, context):
try:
# สมมติว่า event ที่เข้ามาคือข้อมูลจาก SQS หรือ Kinesis Stream ที่มีข้อมูล order
for record in event['Records']:
message_body = json.loads(record['body']) # ดึงข้อมูลจาก Body ของ record
user_id = message_body.get('user_id')
product_name = message_body.get('product_name')
order_id = message_body.get('order_id')
if user_id and product_name and order_id:
notification_message = (
f"เรียนคุณ {user_id}, คำสั่งซื้อ #{order_id} สำหรับ {product_name} ที่ cii3.net "
f"ได้รับการยืนยันแล้วครับ! เตรียมรับสินค้าได้เลย"
)
# เปลี่ยน 'arn:aws:sns:REGION:ACCOUNT_ID:YOUR_TOPIC_NAME' เป็น ARN ของ SNS Topic ของคุณ
sns_client.publish(
TopicArn='arn:aws:sns:ap-southeast-1:123456789012:OrderConfirmations', # ตัวอย่าง ARN
Message=notification_message,
Subject=f"ยืนยันคำสั่งซื้อ #{order_id} จาก cii3.net"
)
print(f"ส่งแจ้งเตือน SNS สำหรับ Order ID: {order_id} เรียบร้อยแล้ว")
else:
print(f"ข้อมูลไม่สมบูรณ์: {message_body}")
except Exception as e:
print(f"มีข้อผิดพลาดเกิดขึ้น: {e}")
# อาจจะส่งไปที่ CloudWatch Logs หรือ Sentry เพื่อเก็บ Log Error
raise e # Re-raise เพื่อให้ Lambda รู้ว่ามี error
โค้ดนี้จะรับ Event จากแหล่งข้อมูล เช่น SQS (Simple Queue Service) ซึ่งคอยรับข้อมูลคำสั่งซื้อที่เข้ามา แล้ว Lambda ก็จะไปหยิบข้อมูลเหล่านั้นมาประมวลผลและยิงข้อความผ่าน SNS ไปยังผู้ใช้งานครับ คือถ้ามีข้อผิดพลาดตอนส่งแจ้งเตือน SNS มันก็จะมีระบบ retry ให้เราด้วยนะครับ ไม่ต้องห่วง
เรื่องความปลอดภัย และ PDPA ล่ะ?
แน่นอนครับ! การส่งแจ้งเตือนมักจะเกี่ยวข้องกับข้อมูลส่วนตัวของผู้ใช้ (ชื่อ, เบอร์โทร, อีเมล) เราต้องระวังเรื่องความปลอดภัยมากๆ เลยนะครับ
- การเข้ารหัสข้อมูล: ข้อมูลที่วิ่งผ่านระบบควรจะถูกเข้ารหัสตลอดเส้นทาง ทั้งตอน In Transit (ตอนส่ง) และ At Rest (ตอนเก็บ) พวกบริการของ Cloud อย่าง AWS SNS หรือ SQS มันจะจัดการเรื่องนี้ให้เราส่วนใหญ่ แต่ก็ควร double check config อีกทีนะครับ
- Access Control: กำหนดสิทธิ์การเข้าถึง Lambda function หรือ Topic ของ SNS ให้รัดกุมที่สุด ให้เฉพาะ service ที่จำเป็นจริงๆ เท่านั้นที่เข้าถึงได้ครับ ใช้ IAM Role ที่มีสิทธิ์เท่าที่จำเป็น (least privilege)
- Security Log: ทุกกิจกรรมที่ Lambda ทำ เช่น การส่งแจ้งเตือนสำเร็จ หรือมี Error อะไร ควรถูกบันทึกลง Security Log (เช่น CloudWatch Logs ของ AWS) ครับ เพื่อให้เราสามารถตรวจสอบย้อนหลังได้ว่าเกิดอะไรขึ้นบ้าง ใครเข้าถึงข้อมูลตอนไหน ถ้ามีเหตุการณ์น่าสงสัยจะได้ตามรอยได้ง่ายๆ นะครับ และควรมีระบบแจ้งเตือนเมื่อเกิด Error ด้วย (เช่น ส่งเข้า Slack หรือ PagerDuty)
- การจัดการข้อมูลส่วนบุคคล (PDPA): อันนี้สำคัญมากๆ นะ! ก่อนจะส่งแจ้งเตือนอะไร ต้องแน่ใจว่าได้ขอ "ความยินยอม" จากผู้ใช้งานเรียบร้อยแล้วนะครับ เช่น ตอนที่ User สมัครสมาชิกบน
cii3.netก็ควรมี Checkbox ให้เขากดยินยอมรับข่าวสารหรือโปรโมชั่น ถ้าเขาไม่ยินยอม ก็ห้ามส่งเด็ดขาดนะ! ข้อมูล Log ที่มีข้อมูลส่วนบุคคลก็ควรมีการเข้ารหัสหรือปกปิดข้อมูลบางส่วนถ้าไม่จำเป็นต้องเห็นทั้งหมด
สรุปนะคร๊าบ!
การใช้ Lambda function สำหรับระบบแจ้งเตือน มันช่วยให้เราสร้างระบบที่ทั้ง Scalable, ประหยัด และเชื่อถือได้มากขึ้นเยอะเลยครับ ไม่ต้องกังวลเรื่องการตั้งเซิร์ฟเวอร์ หรือการ Scale อีกต่อไป ขอให้ทุกท่านสนุกกับการสร้างสรรค์ระบบที่เจ๋งๆ นะครับ!