java多事件,在Java Servlet中使用中断器并处理多个事件

I am using the LMAX disruptor in my web application which takes the http request parameters and handle them to the ringbuffer. 3 event-handlers handle and process data, the final one, saves it to the database.

Initialize the ringbuffer once, when the servlet is instantiated. is this right?

public void init() throws ServletException {

Disruptor disruptor = new Disruptor(

CampaignCode.FACTORY, 1024, Executors.newCachedThreadPool());

EventHandler campaignDetailsLoader = new CampaignDetailsLoaderEvent();

EventHandler templateEvent = new TemplateBuildEvent();

EventHandler codeGenerator = new CodeGenerationEventHandler();

EventHandler campaignSaveEventHandler= new CampaignSaveEventHandler();

disruptor.handleEventsWith(templateEvent, campaignDetailsLoader).then(

codeGenerator).then(campaignSaveEventHandler);

this.ringBuffer = disruptor.start();

}

here I put the values straight into the ringbuffer

@Override

protected void doPost(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {

String campaignId = request.getParameter("campaignId");

String campaignType = request.getParameter("campaignType");

if (campaignId != null && !campaignId.isEmpty()) {

long sequence = ringBuffer.next();

CampaignCode campaign = ringBuffer.get(sequence);

campaign.setCampaignId(Long.parseLong(campaignId));

campaign.setCampaignType(campaignType);

ringBuffer.publish(sequence);

}

}

event handlers

public class CampaignDetailsLoaderEvent implements EventHandler {

@Override

public void onEvent(CampaignCode event, long sequence, boolean endOfBatch)

throws Exception {

//load details from db and process

// udpate values to the event object

}

}

public class TemplateBuildEvent implements EventHandler {

@Override

public void onEvent(CampaignCode event, long sequence, boolean endOfBatch)

throws Exception {

// find the template of this type

// set template to the event object

}

}

public class CodeGenerationEventHandler implements EventHandler {

@Override

public void onEvent(CampaignCode event, long sequence, boolean endOfBatch)

throws Exception {

// generate custom dsl code and execute it

// update the output to the event object

//next handler will save it the db

}

}

public class CampaignSaveEventHandler implements EventHandler {

@Override

public void onEvent(CampaignCode event, long sequence, boolean endOfBatch)

throws Exception {

// save the details to db

// done!

}

}

is this the right way to publish to the ringbuffer? do I need to synchronize the "ringBuffer" object? First 2 events run parallel, then the 3rd event. How should I handle this when I have fast publishers and slow consumers? I am using the disruptor 3.1.1, I could not find good usage example of disruptor in a web environment. A simple code implementation, if you have done one, would help me understand this a lot!

解决方案

This implementation is correct given the code requirements you've stated. Best practice is to wrap your publishing code in a try-finally block to ensure that a claimed sequence is always published:

long sequence = ringBuffer.next();

try {

Event e = ringBuffer.get(sequence);

// Do some work with the event.

} finally {

ringBuffer.publish(sequence);

}

It may also be a good idea to explicitly specify in the constructor that you need a multiple-producer Disruptor, but that is already done in the default constructor you've used. You should not synchronize writes to the RingBuffer as the process of claiming and publishing the sequence number is already thread-safe. Note however that there is no guarantee that the order in which events are published to the RingBuffer in concurrent invocations of doPost() will be the same as the order they're received by your web application.

The Disruptor is just a specialized queue and is therefore subject to all the usual problems they have with unbounded growth. If there are no available slots in the buffer, your call to ringBuffer.next() will block until one becomes available. You should both provide sufficient capacity to the RingBuffer to handle bursts of traffic, and consider ways to apply back pressure in the (hopefully rare) case that the buffer is filled.

In your particular use case, if the CodeGeneration or CampaignSave steps are taking a very long time compared to the first two, and can be deferred, it may make sense to use additional Disruptors/RingBuffers to queue up events for those executions.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值