Apache Camel : Error handlers part II
ตอนที่หนึ่งเราได้พูดถึง Default Error Handler ไปแล้วนะครับมาตอนนี้เราจะพูดถึง DeadLetterChannel กันครับ
Get Chiwa Kantawong (Pea)’s stories in your inbox
Join Medium for free to get updates from this writer.
เอาแบคร่าวๆ ไม่ต้องทฤษฎีจ๋ามากนะครับ ผมไม่ใช่พวกทฤษฎีจ๋าเสียด้วยซิ่ DeadLetterChannel คือ error handler คือการ implements principles ของ Dead Letter Channel EIP. คือถ้า message ไม่สามารถ processed หรือ delivered มันจะถูกส่งไป dead letter queue โดยทันที
ถ้าหากดูตัวอย่างบทความนี้แล้วไม่รู้เรื่อง เรียนเชิญกลับไปอ่านบทความ ตอนแรกก่อนนะครับ
package com.zengcode.camel.kafka.router;
import com.zengcode.camel.kafka.model.EventNotification;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.kafka.KafkaConstants;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@Component
public class MainRouter extends RouteBuilder {
@Autowired
private ProducerTemplate producerTemplate;
@Override
public void configure() throws Exception {
errorHandler(deadLetterChannel("seda://deadLetter").useOriginalMessage());
from("timer://trigger?period=10s")
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
int i = getRandomNumberInRange(1, 100);
producerTemplate.sendBody("direct://start", i);
}
});
from("direct://start")
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
int i = exchange.getIn().getBody(Integer.class);
if (i > 50) {
exchange.getIn().setBody("a");
} else {
exchange.getIn().setBody(i);
}
}
}).to("direct://doSomething");
from("direct://doSomething")
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
int number = exchange.getIn().getBody(Integer.class);
System.out.println("Got number : " + number);
if (number > 20) {
throw new OverNumberException("number is over 20");
}
}
});
from("seda://deadLetter")
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
System.out.println("Error : " + exchange.getIn().getBody());
}
});
}
private static int getRandomNumberInRange(int min, int max) {
if (min >= max) {
throw new IllegalArgumentException("max must be greater than min");
}
return (int)(Math.random() * ((max - min) + 1)) + min;
}
}ผลลัพธ์ก็จะได้ประมาณนี้
/\\ / ___’_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | ‘_ | ‘_| | ‘_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
‘ |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.4.0.RELEASE)Error : a
Error : a
Error : a
Got number : 1
Got number : 25
Error : 25
จะเห็นได้ว่าเมื่อเกิด exception ขึ้น Exchange จะถูกส่งไปยัง “seda://deadLetter”
ซึ่งดูได้จากการ config router
errorHandler(deadLetterChannel("seda://deadLetter"));ซึ่งการใช้งานจริง อาจจะเป็น jms ก็ได้นะครับ แล้วจะทำยังไงกับ message ต่อไปก็แล้วแต่ businese ซึ่งที่ผมเคยทำโดยส่วนใหญ่ก็จะทำ retry process หรือไม่ก็เก็บลง Error Logs ก็แล้วแต่จะเอาไปประยุกต์กันนะครับ สำหรับวันนี้ก็จบแบบง่ายๆ สวยๆ ไปละครับ







