2017-11-02 11 views
0

데이터베이스를 공유하는 서버가 여러 개 있습니다. 각 서버에서 텍스트 메시지 로그 항목이 없으면 cron 작업이 5 분간 확인되고 텍스트 메시지가 생성됩니다 로그 항목을 보내고 텍스트 메시지를 보냅니다. 나는 하나의 서버가 먼저 있어야하므로 텍스트 메시지가 여러 번 전송되는 상황이 결코 없을 것이라고 생각했다.여러 서버에서 Laravel cron/queue/workers 설치

음 - 내가 잘못했다, 그 시나리오는 일어나지 않았다

  • A는 - 로그가 존재하는지 확인 - 그것은
  • B하지 않습니다 - 로그가 존재하는지 확인 - 그것은
  • 하지 않습니다 - 로그 생성
  • B - 메시지
  • B 보내 - - 보낼 메시지
  • 로그 생성

    이 문제는 대기열을 도입하기 위해 변경되었으며 문제를 완화시켜야합니다. crons가 여전히 발사하는 동안, 여러 작업이 대기열에 배치되며, 작업자는 다른 시간에 주어진 작업을 선택해야하므로 메시지를 두 번 보내는 것을 방지합니다. 그것뿐만 아니라 존재 끝날 수도 있지만 :

    • 을 - 작업 1
    • B를 선택 - 작업 2
    • 를 데리러 - 로그가 존재하는지 확인 - 그것은
    • B하지 않습니다 - 확인 로그가 존재하는 경우 - 그렇지 않습니다.

    기타 또는 정확히 같은 시간에 동일한 작업을 픽업 할 수 있습니다.

    해결 방법은 하나의 작업자 서버를 실행하는 것입니다. 그런데 여러 서버의 작업이 여러 번 대기하는 상황이 발생했습니다. 첫 번째 시나리오가 끝나면 대기열에 대기 중인지 확인할 수 없습니다.

    여러 서버, 하나의 작업자 서버 설정이 작동하지만, 동일한 작업 (여러 서버에서 들어오는 인스턴스)을 여러 번 사용하고 싶지는 않습니다. 열.

    어쩌면 해결책은 하나의 cron/queue/worker 서버를 사용하는 것이지만 Laravel/multiserver 환경을 설정하지 않은 경험이있을 것입니다.

    나를 위해 다른 문제는 - 이것을 테스트하는 방법입니다. 서로 동기화 된 VM 인스턴스를 회전시킬 수있는 방법이 없으면 로컬로 테스트 할 수 없습니다.

  • 답변

    1

    쉬운 답 :

    확인 할만큼 높은 수준의 데이터베이스 트랜잭션을 사용할 수있는 기존 데이터베이스 항목에 대한 데이터베이스를 확인하는 코드가 같은에서 같은 일을하려고하는 다른 사람들 시간이 차단되고 작업이 완료/완료 될 때까지 대기합니다.

    정말로 천진난 만 한 해결책 (mysql이라고 가정)은 LOCK TABLES entries WRITE;이고 로직이 끝나면 UNLOCK TABLES이됩니다.

    이것은 또한 아무도이 작업을 확인하는 동안 테이블에 액세스 할 수 없음을 의미합니다.5 분마다 작은 시간 동안 테이블에 대한 모든 액세스를 차단할 것이기 때문에 수표가 정말 빨리 바란다.

    WRITE 잠금 :

    • 테이블을 읽고 쓸 수 잠금을 보유 세션.
    • 잠금을 보유한 세션 만 테이블에 액세스 할 수 있습니다. 잠금이 해제 될 때까지 다른 세션에서 액세스 할 수 없습니다.
    • WRITE 잠금이 유지되는 동안 다른 세션 블록에 의한 테이블에 대한 잠금 요청.

    출처 : 정말 지루한 대답은, 그래서 당신은 아마에 ...

    서버 아키텍처 대답 더 관심이 대답로 이동합니다

    https://dev.mysql.com/doc/refman/5.7/en/lock-tables.html :

    대기열에서 시간 간격마다 하나의 작업 만 수행하려는 경우 작업을 처리하는 하나의 시스템 만 있어야합니다. 이는 예약 된 명령에서 작업을 발송하는 전용 기계 하나로 쉽게 수행 할 수 있습니다. (Laravel 5.5에서는 스케줄러에서 작업을 직접 전달할 수있는 기능이 도입되었으므로를 참조하십시오.

    그런 다음 여러 작업자 컴퓨터에서 대기열을 처리 할 수 ​​있으며 그 중 하나만 작업을 집어 실행합니다. 모든 작업이 평소대로 작동하면 두 작업자 컴퓨터가 같은 작업을 동시에 수행하지 않습니다.

    웹 컴퓨터를 작업자 컴퓨터와 분리하여 독립적으로 확장 할 수 있습니다. 나는 웹 트래픽 전용 웹 머신을 선호한다. 큐잉 된 작업의 많은 양이 내 http 응답 시간에 영향을 미치지 않도록 작업을 처리하지는 않는다.

    그래서 다음 설정을 권장합니다.

    1. 스케줄러 - 일정을 실행하고 작업을 발송하는 단일 시스템입니다.
    2. 대기열을 처리하는 작업자 시스템.
    3. 방문자의 트래픽을 처리하는 웹 컴퓨터입니다.

    모든 기계에는 Laravel 응용 프로그램에 대한 동일한 소스 코드가 있습니다. 그들은 또한 동일한 구성을 가질 것입니다. 유일한 기계 유형별로 유일한 생각은 ...

    1. 스케줄러에 crontab에 php artisan schedule:run이 있습니다.
    2. 근로자는 php artisan queue:work을 실행하는 관리자 (또는 비슷한 사람)가 있습니다.
    3. 웹 서버에는 nginx + php-fpm이 있으며 수신 웹 요청을 처리합니다.

    이 설정은 밀어 넣는 기계가 하나뿐이므로 5 분마다 하나의 작업 만 가져옵니다. 이 설정은 작업자가 생성 한 CPU로드가 웹 요청에 영향을 미치지 않는지 확인합니다.

    내 대답에 대한 하나의 문제는 분명합니다. 단일 스케줄러 시스템은 단일 실패 지점입니다. 그것이 죽으면 더 이상 스케줄 된 작업을 대기열로 보내지 않습니다. 이는 서버 모니터링 및 건강 검진과 같은 영역에 영향을 미치며 이는 귀하의 질문 범위를 벗어나며 호스팅 제공 업체에 크게 의존합니다.


    작은 별표에 대해서는; 여러 컴퓨터에서 작업이 실행되는 이상한 시나리오를 구성 할 수 있습니다. 여기에는 제한 시간보다 오래 잠자기 된 작업이 포함되는 동시에 작업 종료에 대한 지원이없는 환경이 있습니다. 이렇게하면 첫 번째 작업자가 작업을 계속 실행할 수 있으므로 (종료 할 수 없기 때문에) 두 번째 작업자는 작업을 시간 초과로 간주하고 다시 시도합니다.

    +0

    주어진 현재의 설정은 "반드시"작동해야하는 여러 작업자를 갖는 것입니다. (대기열이없는 초기 설정은 "두 대의 컴퓨터가 절대적인 동시성을 가질 수있는 설정을 본 적이 없기 때문에"잘 작동해야하지만) - 내 생각을 확인하는 것이 좋다. 나는 5.4를 돌리고 있는데 현재 업그레이드가 불가능하다. 필자가 (Laravel이 아니더라도) 더 익숙한 해결책은 모든 서버의 memcache에 인덱스를 갖고 누가 현재 마스터인지를 파악하는 것입니다. 마스터가 죽으면 새로운 마스터가 임명되고 대기열에 마스터가 있는지 확인합니다. – eithed