예약푸시 기능을 일반적으로는 redis zset을 이용해서 구현을 많이 한다.
예약시간으로 소트된 푸시대상을 zset에서 꺼내서 전송하는 방식이다. 그리고 예약푸시의 취소기능은 해당 zset에서 해당 예약푸시 대상을 제거하는 방식으로 구현을 한다.
여기서 문제가 하나있는데, 취소기능을 구현하려면, zset하나만으로는 안되고, 해당 payload를 저장하고 있는 별도의 set구조가 하나더 필요하다. 조금 복잡해지는 감이 있다.
최근에 temporal이라는 오픈소스를 알게됬고, 이 예약푸시 기능을 temporal을 이용하면, 훨씬 간단해진다는것을 알았다.
Workflow.sleep(Duration.ofSeconds(3))
이 명령어 한줄이면 예약푸시는 끝난다...
Workflow.await(delay) { cancelled }
그리고 취소도 엄청나게 간단하다..ㅎㄷㄷㄷ
위에 sleep, await는 실제로 thread를 블록하는 thread.sleep가 아닌, temporal에서 제공하는 비동기 sleep, await이다.
따라서 thread가 블록되는일이 없다.
그리고 훨씬 코드가 읽기 쉽다.
예약시간까지 sleep하다가 푸시를 보내라!! 라고 하면 예약 푸시가 되는 구조니, 논리적으로도 맞고,
구현또한 비즈니스 흐름과 맞게 흘러간다.
실제로 temporal 도커로 설치하고, 샘플 코드를 간단히 구현해서, 1만개 worker를 만들어서 동작해봤는데, 잘동작한다.
temporal에서 제공하는 인터페이스에 맞게 Activity를 구현하고,
해당 Activity를 WorkFlow라는 실행흐름설정을 하여, Temporal에 Worker로 등록을 하면,
내가 원하는 시간에 해당 비즈니스 로직을 실행시켜준다.
그리고 더욱 좋은 기능은,
바로, 시스템이 중간에 셧다운되거나, 배포등으로 에러가 발생해도, Activity단위로, 이미 실행한 결과를 상태로 저장을 하고있기때문에, 자동으로 재처리를 수행해준다. (이미 실행된 Activity의 결과는 재사용 방식)
이 기능때문에,
중간에 잡이 죽거나,
배치잡이 죽었을때,
재처리를 별도로 해줘야하는등의 부가적인 프로세스가 필요없게 된다.
단지, 설정한 타임아웃안에 서버가 다시 잘동작하면, Temporal에서 자동으로 재처리로 처리를 해준다.
미쳤다...
좀더 일찍 알았으면,
푸시 기능을 Temporal로 구현을 했으면 좀더 간단하게 구현을 했을것이라는 안타까움이 있지만,
실제로 많이 쓰는 Redis방식으로 경험을 하게 만든것도 좋은 경험이기에 아쉬움을 달랜다. (실제 같이 설계해서, 팀원이 만듬)
다음에 기회가 된다면,
푸시, 리워드, DR등에 적용할수있다고 판단되면, 적용을 해봐야겠다는 생각을 한다.
생각보다, 코드로 구현하기 어려운 기능이 바로, 특정 시간에 특정조건으로 트러거되는 기능등이 상당히 까다롭고, 귀찮고, 난이도가 있다.
(주기적으로 조건을 확인하고 동작하게 만드는 배치잡을 만들거나, 카프카 트러거로 동작하게 만드는게 일반적)
이부분을 단순화한다면, 시스템의 단순화에 많은 도움이 된다.
* Temporal에 Fsm을 적절하게 섞어서 설계를 하면, 정말 확장성있는 DR, PUSH, REWARD 기능을 설계할수있지 않을까 생각이된다.
'MY개발생각' 카테고리의 다른 글
| [개발생각] LMAX Disruptor에 대해서 (0) | 2026.09.10 |
|---|---|
| [개발생각] AI사용에 대한 전략 (0) | 2026.09.06 |
| [개발생각] 성능테스트에 대해서.. (0) | 2026.09.03 |
| [개발생각] Kotlin JDSL사용을 해야 했어.... (0) | 2026.08.23 |
| [개발생각] 미션 보상 기능을 코틀린 DSL 사용하면.. (0) | 2026.08.22 |
