Sitemap
Chiwa Kantawong (Pea)

Chiwa Kantawong (Pea)

Software Engineering บนดาวเคราะห์ใบนึง Youtube : https://www.youtube.com/@ThaiJavaZone

Apache Camel : Error handlers part II

2 min readMay 22, 2018

ตอนที่หนึ่งเราได้พูดถึง 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 โดยทันที

Press enter or click to view image in full size

ถ้าหากดูตัวอย่างบทความนี้แล้วไม่รู้เรื่อง เรียนเชิญกลับไปอ่านบทความ ตอนแรกก่อนนะครับ

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 ก็แล้วแต่จะเอาไปประยุกต์กันนะครับ สำหรับวันนี้ก็จบแบบง่ายๆ สวยๆ ไปละครับ

--

--

Chiwa Kantawong (Pea)
Chiwa Kantawong (Pea)

Written by Chiwa Kantawong (Pea)

Software Engineering บนดาวเคราะห์ใบนึง Youtube : https://www.youtube.com/@ThaiJavaZone