2013-08-22 4 views
0

HTTP 요청 매개 변수를 사용하고 링 버퍼로 처리하는 웹 응용 프로그램에서 LMAX 처리기를 사용하고 있습니다. 3 개의 이벤트 핸들러가 데이터를 처리하고 처리하며, 마지막 하나는 데이터 베 이스에 저장합니다. 서블릿이 인스턴스화 될 때 링 버퍼를 한 번 초기화하십시오. 이게 옳은 거니? Java Servlet에서 장애 처리자 사용 및 여러 이벤트 처리

public void init() throws ServletException { 

    Disruptor<CampaignCode> disruptor = new Disruptor<CampaignCode>(
      CampaignCode.FACTORY, 1024, Executors.newCachedThreadPool()); 

    EventHandler<CampaignCode> campaignDetailsLoader = new CampaignDetailsLoaderEvent(); 
    EventHandler<CampaignCode> templateEvent = new TemplateBuildEvent(); 
    EventHandler<CampaignCode> codeGenerator = new CodeGenerationEventHandler(); 
    EventHandler<CampaignCode> campaignSaveEventHandler= new CampaignSaveEventHandler(); 

    disruptor.handleEventsWith(templateEvent, campaignDetailsLoader).then(
      codeGenerator).then(campaignSaveEventHandler); 
    this.ringBuffer = disruptor.start(); 
} 

여기에서 나는

@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); 
    } 
    } 

이벤트 핸들러

public class CampaignDetailsLoaderEvent implements EventHandler<CampaignCode> { 
    @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<CampaignCode> { 
    @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<CampaignCode> { 
    @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<CampaignCode> { 
    @Override 
public void onEvent(CampaignCode event, long sequence, boolean endOfBatch) 
     throws Exception { 
     // save the details to db 
     // done! 
    } 
} 

이이 ringbuffer에 게시 할 수있는 권리 방법입니다

바로 ringbuffer에 값을 넣어? "ringBuffer"객체를 동기화해야합니까? 처음 2 개의 이벤트가 병렬로 실행되고 3 번째 이벤트가 실행됩니다. 빠른 게시자와 느린 소비자가있을 때 어떻게 처리해야합니까? 나는 disruptor 3.1.1을 사용하고 있는데, 나는 웹 환경에서 disruptor의 좋은 사용 예를 찾을 수 없었다. 간단한 코드 구현을하면, 이것을 이해하는 데 도움이 될 것입니다!

답변

1

명시된 코드 요구 사항에 따라이 구현 방법은 정확합니다. 모범 사례에 게시 코드를 래핑하는 시도 - 마침내 주장 순서가 항상 게시되도록 차단 :

long sequence = ringBuffer.next(); 
    try { 
    Event e = ringBuffer.get(sequence); 
    // Do some work with the event. 
} finally { 
    ringBuffer.publish(sequence); 
} 

는 또한 명시 적으로는 다중이 필요 생성자에서 지정하는 것이 좋습니다 수 있습니다 producer Disruptor,하지만 이미 사용 된 기본 생성자에서 이미 완료되었습니다. 이 아니어야합니다.RingBuffer에 대한 쓰기를 동기화하고 시퀀스 번호를 게시하고 게시하는 프로세스가 이미 스레드로부터 안전하기 때문에해야합니다. 그러나 동시 호출에서 RingBuffer에 이벤트가 게시되는 순서는 doPost() 일 때 웹 응용 프로그램에서받은 순서와 동일 할 것이라는 보장은 없습니다.

Disruptor는 특별한 대기열 일 뿐이며 제한없는 성장으로 인해 발생하는 모든 일반적인 문제의 영향을받습니다. 버퍼에 사용 가능한 슬롯이 없으면 ringBuffer.next()에 대한 통화는 사용할 수있을 때까지 차단됩니다. 버스트 트래픽을 처리 할 수있는 충분한 용량을 RingBuffer에 제공하고 버퍼가 채워지는 (경우에 따라 드문 경우) 백 프레셔를 적용하는 방법을 고려해야합니다.

CodeGeneration 또는 CampaignSave 단계가 처음 두 개에 비해 매우 오랜 시간이 걸리고 지연 될 수있는 경우 특정 실행 사례에서 추가 Disruptors/RingBuffers를 사용하여 해당 실행에 대한 이벤트를 대기열에 넣는 것이 좋습니다 .

+0

정말 도움이되었고, 또 하나의 질문이었습니다. 클러스터 된 환경으로 배포 할 때 코드를 변경하지 않아도됩니까? Disruptor를 클러스터하는 방법은 무엇입니까? –