Amazon SQS คืออะไร การแนะนำฟังก์ชันล่าสุดของ AWS

นี่เป็นบทความแปล ที่มีเนื้อหามาจากบทความภาษาญี่ปุ่นของ Classmethod, Inc. ในหัวข้อ「AWS再入門ブログリレー2022 SQS編」 หากผู้อ่านสนใจอ่านเนื้อหาต้นฉบับสามารถอ่านได้ที่ลิ้งค์ "บทความต้นฉบับ" ด้านล่าง เนื้อหาในบทความนี้การอธิบายบางอย่างจะถูกปรับให้เข้าใจง่ายขึ้นทำให้แตกต่างจากต้นฉบับในบางจุด
2022.08.02

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

สวัสดีครับทุกคน อาชิ ครับ

รายการนี้จะเขียนเกี่ยวกับ AWS ปี 2022 ฉบับเบื้องต้น โดยฝ่าย Consulting ของบริษัทเราเอง นี่เป็นบทความที่จะมาเล่าเกี่ยวกับเนื้อหา AWS Service มาเล่าใหม่อีกครั้งว่ามีอะไรถูกอัพเดทอะไรบ้างแล้ว
แบบละเอียด/เจาะลึกตั้งแต่เบสิกพร้อมคำอธิบาย โดยเหล่าสมาชิกที่เคยเขียนบทความเหล่านี้มาแล้ว

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

งั้นก็ไปเริ่มกันเลยครับ Theme ในวันนี้คือ "Amazon SQS" ครับ

Amazon SQS คืออะไร

SQS คือ Fully managed message queuing service ครับ (เกี่ยวกับ message queuing จะอธิบายในหัวข้อต่อไป) ด้วยการที่มันเป็น Fully managed ทำให้เราไม่จำเป็นต้องคอยดูแล Server หรือ Middleware ก็สามารถใช้งานได้ นอกจากนี้ยังมีจุดเด่นที่สามารถใช้ทำงานร่วมกับ AWS Service อื่นได้อีกด้วย

ข้อดีในการใช้งาน Amazon SQS

Security

ใน SQS เราสามารถใช้ IAM เพื่อควบคุม จำกัดสิทธิ์ การ Access ได้ นอกจากนี้ยังสามารถใช้ KMS เพื่อเข้ารหัสไฟล์ในฝั่ง Server ได้ด้วย

Durability

SQS จะลดโอกาสในการศูนย์เสียข้อมูล Message ด้วยการเก็บ Message ไว้ใน Server หลายๆตัว โดย Standard queue จะทำอย่างน้อย 1 ครั้ง และ FIFO queue จะประมวลผลข้อความ 1 ครั้ง ซึ่งสามารถอ่านรายละเอียดเพิ่มได้ในหัวข้อด้านล่าง

Scalability

SQS จะทำการ Scale in / out เองโดยอัตโนมัติ ไม่จำเป็นต้องมีการควบคุม Provisioning ทำให้ลดภาระในการโหลดโดยอัตโนมัติ

reliability

SQS จะทำการล็อก Message ในขณะประมวลผล นั่นทำให้สามารถคงความสม่ำเสมอได้ต่อให้เจอการควบคุมผ่าน หลายๆ Producer / Consumer

Customizability

เราสามารถตั้งค่า Option ต่างๆของ SQS ได้ ยกตัวอย่างเช่น การเพิ่ม Delay ในการส่งข้อความ หรือการตั้งค่าให้เก็บข้อความใหญ่ๆไว้ใน S3 หรือ DynamoDB

ทำความเข้าใจเกี่ยวกับ Message queuing (MQ)

Message queuing คือวิธีอย่างหนึ่งที่ใช้ในการสื่อสารระหว่าง interprocess และ thread communication ข้อมูลที่ถูกเรียกว่า Message จะถูกเก็บไว้ใน queue ที่เป็นโครงสร้างข้อมูลที่ใช้ในการสื่อสาร โดยโครงสร้างของ queue คือ ข้อมูลที่ถูกใส่ไว้ก่อนจะถูกปล่อยออกก่อน(เหมือนการต่อแถว)

การใช้ Message queuing จะมีข้อดีดังต่อไปนี้

Loosely coupled components

การใช้ queue จะทำให้เราสามารถสร้าง System ที่จัดการ component ที่กระจัดกระจายมาเชื่อมกันอยู่ได้ ด้วยการทำเช่นนี้ จะเพิ่ม Maintainability, scalability, reusability ขึ้น และสามารถเชื่อมกันระหว่างภาษาคอมพิวเตอร์ที่ต่างกันได้ด้วย
การที่ component อยู่กระจัดกระจาย จะทำให้เราสามารถปรับเปลี่ยน สเกลต่างๆของ component ที่ต้องการได้ง่ายขึ้น

สามารถประมวลผลแบบ async ได้

ด้วยการเก็บรักษาสิ่งที่อยากประมวลผลไว้ใน queue ขณะหนึ่ง จะทำให้เราสามารถประมวลผลที่ใช้เวลานานแบบ async ได้
ฝั่งที่ส่งข้อมูลให้ queue ก็สามารถเสร็จงานได้เมื่อส่งเสร็จ ทำให้ component อื่นสามารถประมวลผลต่อมาได้

ยกตัวอย่างเช่น ในกรณีที่มีการแปลงวิดีโอที่อัปโหลดใน video streaming service
(แปลงในสามารถ streaming ได้)((Convert))
Endpoint Server จะตอบกลับในตอนที่ได้รับการคำสั่งให้อัพโหลด แล้วส่ง Message ไปที่ queue

Standard queue กับ FIFO queue

SQS มี queue อยู๋ 2 ชนิดคือ Standard และ FIFO

เมื่อเราทำการเปรียบเทียบเป็นจะได้เป็นตารางที่เขียนอยู่ด้านล่างนี้

Standard FIFO
Message order รักษา order ตามลำดับเท่าที่จะทำได้ ใครมาก่อน ออกก่อนแบบสมบูรณ์แบบ
จำนวนในการจัดส่ง อย่างน้อย 1 ครั้ง 1 ครั้ง

นอกจากนี้ ตอนใช้กรุณาระวังเรื่อง quotas ที่แตกต่างออกไปเช่น Message throughput

วิธีการดูว่าควรจะใช้ตัวอะไรคือ ถ้ามีข้อจำกัดในเรื่องของลำดับของ Message หรือ จำนวนในการจัดส่ง แนะนำให้ใช้ FIFO queue

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

ในทางตรงกันข้าม ระบบเบิกถอนของธนาคารที่เข้มงวดเรื่องลำดับในการ Run หรือ Run แบบทับซ้อน ในกรณีนี้ก็แนะนำให้เลือก FIFO

โดยหากสนใจสามารถอ่านเพิ่มเติมได้ที่บทความด้านล่างต่อไปนี้
Best practices for Amazon SQS - Amazon Simple Queue Service

ฟังก์ชันต่างๆที่น่าสนใจ

visibility timeout

ใน SQS นั้น ถึงแม้จะได้รับข้อความ(Message)จาก queue แล้ว แต่ข้อความก็ยังจะหลงเหลืออยู่ใน queue จนกว่าจะถูกลบ พอเป็ยอย่างงั้นแล้วก็จะทำให้เราได้รับข้อความเดิมได้เรื่อยๆ ซึ่ง visibility timeout จะมาแก้ไขปัญหานี้

หลังจากตั้งค่านี้แล้ว เมื่อได้รับข้อความจะทำให้ข้อความเดียวกันได้ไม่สามารถ access ได้อีก ในเวลาที่กำหนด
โดย timeout default จะอยู่ที่ 30 วินาที ขั้นต่ำสุดอยู่ที่ 0 วินาที ขั้นมากสุดอยู่ที่ 12 ชั่วโมง

แต่ทว่า ต่อให้เราใช้ visibility timeout แต่หากเราใช้ standard queue ก็มีโอกาสที่จะได้รับข้อความมากกว่า 2 ครั้ง
หากต้องการรับข้อความ 1 ครั้งจริงๆ แนะนำให้ใช้ FIFO queue ครับ

โดยหากสนใจสามารถอ่านเพิ่มเติมได้ที่บทความด้านล่างต่อไปนี้
Amazon SQS visibility timeout - Amazon Simple Queue Service

dead-letter queues

ใน SQS นั้น ข้อความก็ยังจะหลงเหลืออยู่ใน queue จนกว่าจะถูกลบ ทำให้ในกรณีที่การประมวลผลผิดพลาด เกิดเป็นลูป Recieve → Timeout ที่เกิดจากการ Restore → Recieve ทำให้เราจำเป็นต้องประมวลผลข้อความที่ไม่สามารถประมวลได้ไปเรื่อยๆ

ซึ่งฟังก์ชันที่จะแก้ไขเรื่องนี้ก็คือ dead-letter queues โดยที่เมื่อเราตั้งค่า dead-letter queues แล้วมี Recieve เกิดขึ้นเกินจำนวนที่กำหนด จะย้ายไปที่ queue อื่น อารมณ์ประมาณย้ายข้อความที่ผิดพลาดไปเก็บไว้ในโกดัง

โดยนี้ไม่ใช้ queue พิเศษ เป็นแค่ SQS queue ครับ ทำให้ถ้าเราจะตั้งค่าจำเป็นต้องสร้าง queue เตรียมไว้ก่อนครับ

โดยหากสนใจสามารถอ่านเพิ่มเติมได้ที่บทความด้านล่างต่อไปนี้
Amazon SQS dead-letter queues - Amazon Simple Queue Service

Delay queue

การใช้ Delay queue จะช่วงเพิ่ม Delay ในการส่ง ถึง รับ ข้อความได้

ยกตัวอย่างเช่น การประมวลผลที่ทำงานร่วมกับระบบอื่น แล้วต้องการรอข้อความที่ถูกส่งมาสัก 3 วินาทีแล้วค่อยประมวลผล ก็สามารถใช้ Delay queue ได้ โดยไม่จำเป็นต้องไปเพิ่ม Delay การประมวลผลในส่วนของ Customer

นอกจากนี้ยังมี Message Timer ของ SQS ที่มีโครงสร้างที่คล้ายๆกัน โดยเจ้าตัวนี้จะ Delay ในแต่ละข้อความ ไม่ใช่ในแต่ละ queue ซึ่งก็จะสะดวกในตอนที่เราอยากจะ Delay แต่ละข้อความให้แตกต่างกันได้

โดยหากสนใจสามารถอ่านเพิ่มเติมได้ที่บทความด้านล่างต่อไปนี้
Amazon SQS delay queues - Amazon Simple Queue Service

ลองใช้ดู

เราจะมาลองใช้ SQS ดูกันครับ

เตรียมตัว

ครั้งนี้เราจะใช้ CDK ในการเตรียม queue ครับ

sqs.py

from aws_cdk import (
    Stack,
    CfnOutput,
    aws_sqs as sqs
)
from constructs import Construct


class QueueStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        queue = sqs.Queue(self, "ExampleQueue")

        CfnOutput(self, "QueueURL", value=queue.queue_url)

CDK จะมี high level interface ของ SQS queue เตรียมไว้ให้อยู่แล้ว สะดวกดีครับ
สิทธิการควบคุม หรือ การลงทะเบียน dead-letter queues ก็สามารทำได้ง่ายๆ

หลังจาก Deploy แล้ว QueueURL จะแสดงออกมาใน output โดยเราจะใช้สิ่งนี้ในการ Access queue ครับ

ลอง Access ดู

โดยครั้งนี้เราจะลองส่งข้อความง่ายๆ ในรูปแบบ send → Recieve → Delete กันดูครับ

app.py

import boto3

sqs = boto3.resource('sqs')

URL = 'https://sqs.ap-northeast-1.amazonaws.com/XXXXXX/XXXXXX'
queue = sqs.Queue(URL)


for i in range(5):
    # ส่งข้อความ
    # ถ้าใช้ send_messages จะส่งหลายๆข้อความในเวลาเดียวกันได้
    queue.send_message(
        MessageBody=f'No. {i}'
    )

for i in range(5):
    # รับข้อความ
    # ถ้ากำหนด MaxNumberOfMessages สามารถรับหลายๆข้อความในเวลาเดียวกันได้ Default คือ 1
    # ถ้ากำหนด WaitTimeSeconds จะรอใน queue ว่างก่อน
    message = queue.receive_messages()
    message = message[0]
    print(message.body)

    # หลังจากประมวลผลเสร็จแล้วให้ลบ
    message.delete()

พอลองทดสอบจริงจะได้ผลดังนี้

<ลองทำจริงๆดู

$ python3 sqs.py 
No. 1
No. 4
No. 2
No. 3
No. 0

ลำดับการอัพโหลดไม่ตรงแต่ว่าเราได้รับข้อมูลทุกอย่างครับ

สรุป

เป็นยังไงกันบ้างครับกับ Amazon SQS หากใครยังจำไม่ค่อยได้ว่าเจ้าตัวนี้ทำอะไร ให้ดูชื่อมันว่ามี "Q" อยู่ ซึ่งนี่ก็คือ "คิว" ครับ เป็นตัวที่จะคอยสร้างคิวให้ระหว่าง Component สำหรับผู้ที่ต้องการอ่านบทความต้นฉบับสามารถดูได้ที่หัวข้อด้านล่างนี้ แล้วเจอกันในบทความต่อไป สวัสดีครับ / ต้า

บทความต้นฉบับ

AWS再入門ブログリレー2022 SQS編 | DevelopersIO