지연 대기열은 이름에서 알 수 있듯이 지연 기능이 있는 메시지 대기열입니다. 그렇다면 어떤 상황에서 이러한 대기열이 필요합니까?
1. 배경
먼저 다음 비즈니스 시나리오를 살펴보겠습니다.
주문이 미결제 상태일 때 적시에 주문을 종료하는 방법
주문 여부를 정기적으로 확인하는 방법 환불 상태가 환불되었습니다. 결제가 성공했습니다
주문이 다운스트림 시스템에서 오랫동안 상태 알림을 받지 못한 경우, 주문 상태를 동기화하는 단계별 전략을 구현하는 방법
시스템에서 알림을 받을 때 최종 결제 성공 상태의 업스트림 시스템에서 알림 실패를 반환하는 경우 진행 방법은 무엇입니까? 비동기 알림은 15초 3분 10분 30분 30분 1시간 2시간 6시간 15시간
1.1 솔루션
가장 간단한 방법은 정기적으로 측정기를 스캔하는 것입니다. 예를 들어, 주문 결제 만료 요구 사항이 상대적으로 높은 경우 만료된 주문을 확인하고 적극적으로 주문을 마감하기 위해 측정기를 2초마다 스캔합니다.단점은 간단하다는 점,단점은 1분마다 테이블을 전역으로 스캔하므로 리소스가 낭비된다는 점. 테이블 데이터의 주문량이 곧 만료될 경우 주문이 지연될 수 있습니다. 폐쇄.
RabbitMq 또는 기타 MQ 수정을 사용하여 지연 대기열을 구현하세요. 장점은 오픈 소스이며 이미 만들어진 안정적인 구현 솔루션이라는 것입니다. 단점은 다음과 같습니다. MQ는 팀 기술 스택이 이미 가지고 있는 경우입니다. MQ라면 괜찮습니다. 지연 대기열을 위한 MQ 배포 비용은 약간 높습니다
Redis의 zset 및 list 기능을 사용하면 redis를 사용하여 지연 대기열을 구현할 수 있습니다RedisDelayQueue
2. 설계 목표
실시간: 일정 기간 동안 2차 오류 허용
고가용성: 독립 실행형 지원, 클러스터 지원
메시지 삭제 지원: 비즈니스 지정된 메시지는 언제든지 삭제됩니다
메시지 신뢰성: 최소 한 번 이상 소비 보장
메시지 지속성: Redis 자체의 지속성 특성에 따라 Redis 데이터가 손실되면 지연된 메시지가 손실된다는 의미이지만, 기본 백업 및 클러스터 보장으로 사용됩니다. MangoDB에 메시지를 유지하기 위한 후속 최적화를 고려할 수 있습니다
3. 설계 계획
설계에는 주로 다음 사항이 포함됩니다.
전체 Redis를 메시지 풀로 사용하고 메시지를 KV 형식으로 저장합니다.
ZSET는 우선순위 대기열 역할을 하며 점수에 따라 우선순위를 유지합니다.
LIST 구조를 사용하여 선입선출 방식으로 소비합니다.
ZSET 및 LIST는 메시지 주소(메시지 풀의 각 KEY에 해당)를 저장합니다.
라우팅 객체를 사용자 정의하여 ZSET 및 LIST 이름을 저장하고 메시지를 ZSET에서 올바른 LIST로 지점 간 방식으로 라우팅합니다.
타이머를 사용하여 라우팅을 유지합니다
TTL 규칙에 따라 메시지 지연을 구현합니다
3.1 디자인 다이어그램
여전히 좋아하는 지연 대기열을 기반으로 코드를 디자인, 최적화 및 구현합니다. Youzan Design
3.2 데이터 구조
ZING:DELAY_QUEUE:JOB_POOL은 모든 지연 대기열 정보를 저장하는 Hash_Table 구조입니다. KV 구조: K=prefix+projectName 필드 = topic+jobId V=CONENT;V클라이언트에서 전달한 데이터는 소비 시 반환됩니다.ZING:DELAY_QUEUE:JOB_POOL是一个Hash_Table结构,里面存储了所有延迟队列的信息。KV结构:K=prefix+projectName field = topic+jobId V=CONENT;V由客户端传入的数据,消费的时候回传
ZING:DELAY_QUEUE:BUCKET지연 대기열 순서 ZSET 설정, K 저장 =ID 및 필요한 실행 타임스탬프(타임스탬프
ZING:DELAY_QUEUE:QUEUELIST 구조에 따라 정렬됨), 각 주제에는 LIST가 있으며 목록에는 현재 소비해야 하는 항목이 저장됩니다. JOB사진은 참고용일 뿐이며, 기본적으로 전체 프로세스의 실행 과정을 설명할 수 있으며, 사진은 기사 끝 부분의 참조 블로그에서 가져왔습니다. Article
3.3 작업 수명 주기새 JOB을 추가하면
ZING:DELAY_QUEUE:JOB_POOL에 데이터 조각이 삽입되어 비즈니스 측면과 소비자를 기록합니다. 옆.
ZING:DELAY_QUEUE:BUCKET은 실행 타임스탬프를 기록하기 위해 레코드도 삽입합니다처리 스레드는
ZING:DELAY_QUEUE:BUCKET으로 이동하여 RunTimeMillis가 있는 실행 타임스탬프를 찾습니다. ratio 이제 시간이 부족하므로 이러한 레코드를 모두 동시에 삭제하면 각 작업의 주제가 무엇인지 분석한 다음 이러한 작업을 TOPIC
ZING:DELAY_QUEUE:QUEUE에 해당하는 목록에 푸시합니다. >각 TOPIC의 LIST에는 LIST에서 일괄적으로 소비할 데이터를 얻기 위한 청취 스레드가 있으며, 획득한 모든 데이터는 이 TOPIC의 소비 스레드 풀로 전달됩니다.소비 스레드 풀 실행은 다음으로 이동합니다.
ZING:DELAY_QUEUE:JOB_POOL데이터 구조를 찾아 콜백 구조에 반환하고 콜백 메서드를 실행합니다. 3.4 디자인 포인트
3.4.1 기본 개념
JOB: 비동기 처리가 필요한 작업은 지연 대기열의 기본 단위입니다.
주제: 동일한 유형의 작업 집합 집합(큐)입니다. 소비자가 구독하려면
3.4.2 메시지 구조
각 JOB에는 다음 속성이 포함되어야 합니다
jobId: 작업의 고유 식별자. 지정된 직무 정보
주제: 직무 유형을 검색하고 삭제하는 데 사용됩니다. 구체적인 업체명으로 이해하시면 됩니다
delay: 작업을 지연시켜야 하는 시간. 단위: 초. (서버에서 이를 절대 시간으로 변환합니다.)
body: 소비자가 특정 비즈니스 처리를 수행하기 위한 Job의 내용, json 형식으로 저장됨
retry: 실패한 재시도 횟수
url: 알림 URL
3.5 디자인 세부사항
3.5.1 빠르게 소비하는 방법ZING:DELAY_QUEUE:QUEUEZING:DELAY_QUEUE:QUEUE
구현하는 가장 간단한 방법은 타이머를 사용하여 스캔하는 것입니다. 두 번째 수준에서는 메시지 실행의 적시성을 보장하기 위해 1S마다 Redis에 요청을 설정하여 대기열에서 사용할 JOB이 있는지 확인할 수 있습니다. 하지만 문제가 발생합니다. 대기열에 소비 가능한 JOB이 없으면 잦은 검색은 의미가 없으며 다행히 LIST에BLPOP 차단 프리미티브가 있습니다. 데이터가 있으면 즉시 반환되고, 데이터가 없으면 데이터가 반환될 때까지 차단되며, 차단 시간 초과를 설정할 수 있으며, 특정 구현 방법 및 전략은 NULL을 반환합니다.3.5.2 타이밍으로 인한 메시지의 반복 처리 및 소비 방지
Redis의 분산 잠금을 사용하여 메시지 처리를 제어함으로써 메시지 반복 처리로 인해 발생하는 문제를 방지합니다
타이머 실행 빈도를 보장하려면 분산 잠금을 사용하세요
4. 핵심 코드 구현4.1 기술 설명기술 스택: SpringBoot, Redisson, Redis, 분산 잠금, 타이머참고: 이 프로젝트는 설계 계획에서 다중 Queue 소비를 구현하지 않았으며 하나의 QUEUE만 열었습니다. 이는 향후 최적화될 예정입니다4.2 핵심 엔터티4.2.1 작업 새 객체 rrreee4.2.2 작업 삭제 개체rrreee4.3 처리 스레드rrreee4.4 소비 스레드rrreee4.5 추가 및 작업 삭제rrreee 5 . 최적화할 콘텐츠
현재 메시지를 저장하는 대기열은 하나뿐입니다. 소비해야 할 메시지가 많이 쌓이면 메시지 알림의 적시성이 영향을 받습니다. 개선 방법은 여러 대기열을 열고 메시지 라우팅을 수행한 다음 처리량을 제공하기 위해 여러 소비자 스레드를 여는 것입니다. 이는 메시지가 향후 MangoDB에 유지될 위험이 있습니다. >6. 소스코드자세한 소스코드는 다음 주소
RedisDelayQueue 구현zing-delay-queue (https://gitee.com/whyCodeData/)에서 확인하세요. zing -project/tree/master/zing-delay-queue)
RedissonStarterredisson-spring-boot-starter(https://gitee.com/whyCodeData/zing-project/tree/master/) zing -starter/redisson-spring-boot-starter)
프로젝트 애플리케이션zing-pay (https://gitee.com/whyCodeData/zing-pay)7. https://tech.youzan.com/queuing_delay/https://blog.csdn.net/u010634066/article/details/98864764더 많은 Redis 지식을 보려면 다음 항목에 주의하세요. redis 입문 튜토리얼 칼럼.
위 내용은 Redis는 지연 대기열을 어떻게 구현합니까? 방법 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!