🔀
← Apache Camel

Apache Camel 101

บทเรียนวันที่ 2: EIPs & Resilient Routing

Day 2 Advanced Integration

จัดการเส้นทางข้อมูลซับซ้อนและการรับมือข้อผิดพลาดอย่างมืออาชีพ

เรียนรู้การใช้ Enterprise Integration Patterns (EIPs) เช่น Splitter, Aggregator, Content-Based Router พร้อมระบบกู้คืนระบบล่ม (Resilient Routing & DLQ)

1. ทฤษฎีและสถาปัตยกรรม (Enterprise Integration Patterns)

รูปแบบมาตรฐานในการจัดเส้นทาง แปลง และกรองข้อมูลองค์กรตั้งแต่ปี 2007

1.1 EIP สำคัญที่ใช้งานบ่อยในระบบองค์กร

  • Splitter Pattern: แยกแยะข้อมูล Collection หรือ JSON Array ขนาดใหญ่ ให้กลายเป็น Message รายย่อยทีละชิ้นเพื่อประมวลผลคู่ขนาน
  • Aggregator Pattern: ทำงานตรงข้ามกับ Splitter โดยรวบรวม Message ย่อยหลาย ๆ ชิ้นกลับเป็นชุดเดียวกันตาม Correlation ID พร้อมกำหนดเงื่อนไขตัดรอบ (เช่น ครบ 100 รายการ)
  • Content-Based Router (choice / when / otherwise): สวิตช์ตรวจสอบค่าใน Header หรือ Body แล้วส่งต่อไปยัง Endpoint ปลายทางที่ถูกต้อง
  • Message Filter: กรองคัดเลือกเฉพาะ Message ที่ตรงตามเงื่อนไขให้ไหลผ่าน Route ต่อไป ส่วนที่ไม่ตรงจะถูกละทิ้ง
  • Message Translator (Unmarshal / Marshal): แปลงโครงสร้างข้อมูลระหว่างระบบ เช่น แปลง JSON เป็น Object หรือ XML เป็น SQL

1.2 Error Handling & Resilient Routing

ระบบ Integration ที่ดีต้องมีความทนทานสูง (Resilient):

  • Dead Letter Channel (DLC): เมื่อประมวลผลล้มเหลวและ Retry ครบโควตา จะย้ายข้อความเสียไปยัง Dead Letter Queue (DLQ) ทันที
  • Redelivery Policy & Exponential Backoff: พยายามส่งซ้ำโดยเว้นระยะห่างทวีคูณ (เช่น 1s, 2s, 4s) เพื่อลดภาระระบบปลายทาง
  • Circuit Breaker Pattern: ตัดการเชื่อมต่อชั่วคราวเมื่อปลายทางล่มบ่อย ป้องกันไม่ให้ปัญหารามลามทั้งระบบ (Cascading Failure)

1.3 แผนภาพจำลองการทำงาน EIP & Error Handling

ภาพจำลองการแยกข้อมูล Batch Orders และส่งเข้า DLQ เมื่อเกิดข้อผิดพลาด

เมื่อรับ Batch Orders เข้ามา ➔ ใช้ Splitter แตกรายการ ➔ ใช้ Content-Based Router แยกภูมิภาค (TH / Global) ➔ หากพังครบ 3 ครั้ง ส่งเข้า DLQ

📦
Batch Orders (Kafka)
➔ [Splitter] ➔
🔀
Content-Based Router
region == 'TH' ➔ DB_TH / Other ➔ DB_Global
➔ (Fail 3x) ➔
⚠️
Dead Letter Queue (DLQ)

2. ตัวอย่างโค้ดจริง (Java & YAML DSLs)

โจทย์: Split Batch Orders + Routing + Retry & DLQ

📁 OrderEipRoute.java
import org.apache.camel.builder.RouteBuilder;

public class OrderEipRoute extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        onException(Exception.class)
            .maximumRedeliveries(3)
            .redeliveryDelay(1000)
            .backOffMultiplier(2)
            .handled(true)
            .to("kafka:orders-dlq");

        from("kafka:batch-orders")
            .split(body())
                .choice()
                    .when(header("region").isEqualTo("TH"))
                        .to("sql:INSERT INTO orders_th (id, amount) VALUES (:#id, :#amount)")
                    .otherwise()
                        .to("sql:INSERT INTO orders_global (id, amount) VALUES (:#id, :#amount)")
                .end();
    }
}

🏋️‍♂️ โจทย์ฝึกปฏิบัติประจำวันที่ 2 (Hands-on Drill)

ฝึกออกแบบ Route ด้วยเงื่อนไขและระบบกู้คืนข้อผิดพลาด

  1. สร้าง Route รับข้อมูลจาก kafka:transactions
  2. ใช้ Message Filter คัดเลือกเฉพาะธุรกรรมที่มี header.amount > 50000 เท่านั้น
  3. ตั้งค่า Redelivery Policy แบบ Retry 3 ครั้ง ครั้งละ 2 วินาที
  4. เมื่อ Retry ครบแล้วยังล้มเหลว ให้ย้ายข้อมูลไปเก็บที่ kafka:failed-transactions-dlq

📝 แบบทดสอบทบทวนบทเรียนวันที่ 2 (ตอบปุ๊บ รู้ผลปั๊บ)

เลือกคำตอบที่คุณคิดว่าถูกต้อง ระบบจะแสดงผลลัพธ์และคำอธิบายทันที