복붙노트

[REDIS] 방법을 잘 내 이벤트 내 응용 프로그램의 하나의 인스턴스에 의해 처리됩니다 만들려면?

REDIS

방법을 잘 내 이벤트 내 응용 프로그램의 하나의 인스턴스에 의해 처리됩니다 만들려면?

우리의 아키텍처에서 우리는 우리가 캐싱 및 이벤트를 게시 사용하십시오 레디 스의 서버가 있습니다.

내 문제는 다음과 같다

데이터베이스 응용 프로그램의 모든 인스턴스가 업데이트되지 않습니다 있는지 만들기위한 어떤 패턴이 있습니까?

해결법

  1. ==============================

    1.당신은 차단 등의 레디 스 키 / 값을 사용할 수 있습니다. 인스턴스가 가입에서 메시지가 나타나면 프로세스가 이미 존재 여부를 확인하기 위해 레디 스에서 LUA 스크립트를 실행합니다.

    당신은 차단 등의 레디 스 키 / 값을 사용할 수 있습니다. 인스턴스가 가입에서 메시지가 나타나면 프로세스가 이미 존재 여부를 확인하기 위해 레디 스에서 LUA 스크립트를 실행합니다.

    서버 구독에서 메시지가 나타납니다 사용은 이미이 메시지 (: XXX GET receiveMessageId처럼 뭔가를) 잠금이 존재하는지 확인하는 스크립트 거래를 레디 스. 거짓과 값이 이미 종료 경우 서버에서 아무것도하지 않습니다. 값과 설정이 존재하지 않는 경우에 true를 돌려줍니다. 그런 다음 서버는 메시지를 처리 ​​할 수 ​​있습니다.

    레디 스가 단일 스레드이기 때문에 메시지가 다른 서버로 촬영하면 다른 모든 서버는 거짓을 얻을 것이다.

    이 키를 제거하려면 다른 서버에서 가져온 메시지가 나타나지 않도록하는 TTL의 큰의 정도를 설정할 수 있습니다.

  2. ==============================

    2.훨씬 간단한 아이디어

    훨씬 간단한 아이디어

    대신 채널에 이벤트를 게시의 1) "CustomerUpdate는"그것이 행동의 유형을 알리는 고유의 통지와 함께 큐에 넣어

    LPUSH CustomerUpdate type1$somework
    

    여기 타입 1 등 이메일, DB에있는 항목을 보낼 수 somework 당신이 처리해야하는 일이다.

    2) 응용 프로그램 논리에서 차단 rpop를 사용합니다.

    BRPOP CustomerUpdate
    

    앱 로직 작업과 작업의 종류를 분할합니다. 그것은 그 등을 할 타입 2 반환하는 경우, 해당 작업을 수행 TYPE1 반환하는 경우. 그런 다음 작업을 수행한다.

    샘플 미리보기 :

    String message = jedis.brpop("CustomerUpdate",1000);
    if(message.startsWith("type1$"))
    sendMail(message.split("$")[1]);
    else if(message.startsWith("type2$"))
    sendAck(message.split("$")[1]);
    

    장점 :

  3. ==============================

    3.나는 CustomerUpdate에 대한 실행 가능한 작업 큐 하나 개 이상의 목록을 설정 것입니다. 대신 (또는뿐만 아니라)을 CustomerUpdate를 게시, 목록에 LPUSH 것이다. 리스트의 각 요소의 값은 업데이트의 매개 변수를 인코딩합니다.

    나는 CustomerUpdate에 대한 실행 가능한 작업 큐 하나 개 이상의 목록을 설정 것입니다. 대신 (또는뿐만 아니라)을 CustomerUpdate를 게시, 목록에 LPUSH 것이다. 리스트의 각 요소의 값은 업데이트의 매개 변수를 인코딩합니다.

    그리고 단순히 필요가 작업을 위해 싸워야하는 핸들러의 각 루프에서 BRPOP를 사용합니다. 이 같은 사용 사례에 대한 설계 시간 제한과 차단 팝업입니다. http://redis.io/commands/brpop

    장점 : 없음 KEYSPACE 알림, 많은 작업 처리기는 별도의 목록으로 필요한 작업을 분리 할 수 ​​있습니다, 인종 않고 팝, 한 번에 여러 목록을 BRPOP 수 있습니다.

    단점 다음 CustomerUpdate가 필요 발행 어떤 변경, 그리고 아마도 아마도 MULTI / EXEC 또는 유사한을 필요로하는 여러 LPUSHs을합니다. 이 부분을 변경할 수 없다면, 당신은 CustomerUpdates에 가입하기 위해 다른 프로세스 (다른 클라이언트)가 필요하고, 작업을 밀어 것입니다.

  4. ==============================

    4.이벤트 데이터를 그 일을하기보다는 메시지에 전송하는 간단한 방법은, 이러한 데이터, 다음 메시지의 첫 번째 수신기는 목록에 LPOP를 실행 만이 이벤트 데이터를 수신 할 들어있는 목록의 이름을 보내 .

    이벤트 데이터를 그 일을하기보다는 메시지에 전송하는 간단한 방법은, 이러한 데이터, 다음 메시지의 첫 번째 수신기는 목록에 LPOP를 실행 만이 이벤트 데이터를 수신 할 들어있는 목록의 이름을 보내 .

    간단히 말해서 :

    그러나 순간부터 당신은 메시지가 처리됩니다 영원히 손실됩니다, 서버에 LPOP을 실행합니다. 예를 들어 연결이 바로 LPOP 후 떨어지면 메시지가 손실됩니다.

    https://github.com/resque/resque 또는 https://github.com/seomoz/qless : 당신이 더 나은 같은 프로젝트에서 살펴 본다 수 있도록 레디 스에서 구현 신뢰할 수있는 메시징은 어렵다

    당신이 그것을 직접 수행하려는 경우 또는, 저자들이 수행 한 접근 방법에 대한 좋은 설명을 줄이 프레젠테이션을 살펴 : https://www.percona.com/news-and-events/percona-university-smart- 데이터 롤리 / 사용 - 레디 스 신뢰성-작업 큐

    PS : 내 추천이 사물의 종류 RabbitMQ 같은 것을 얻을 수있을 것입니다 만.

  5. from https://stackoverflow.com/questions/38569688/how-to-make-sure-my-event-is-handled-by-only-one-instance-of-my-app by cc-by-sa and MIT license