Lottery 클래스란
Illuminate\Support\Lottery는 확률 기반의 조작을 유창한 API로 표현할 수 있는 유틸리티 클래스입니다. “100 요청에 1번만 처리를 실행한다”, “일부 요청만 상세 로그를 기록한다”와 같은 패턴을 심플하게 기술할 수 있습니다.
구현은
src/Illuminate/Support/Lottery.php에 있습니다. Laravel은 이 클래스를 Session GC나 캐시 락의 prune 등, 프레임워크 내부에서도 활용하고 있습니다.기본적인 사용법
정수 비율로 확률 지정하기
Lottery::odds($chances, $outOf)로 “chances 회 당첨”이라는 확률을 지정합니다.
소수로 확률 지정하기
$outOf를 생략하고 0.0~1.0의 소수를 전달하면, 그대로 확률로 사용됩니다.
콜백 없이 진위값 반환하기
winner / loser를 설정하지 않은 경우,choose()는 당첨이면 true, 낙첨이면 false를 반환합니다.
여러 번 실행하기
choose($times)에 횟수를 전달하면 결과의 배열이 반환됩니다.
Callable로서 전달하기
Lottery 인스턴스는 __invoke를 구현하고 있으므로, callable을 받는 API에 직접 전달할 수 있습니다.
실전적인 유스케이스
1. 캐시 prune(100회에 1번만 실행)
기한이 지난 레코드 삭제 등, 매번 실행할 필요가 없는 유지보수 처리에 최적입니다.2. 텔레메트리·샘플링(일부 요청만 상세 로그)
전체 요청을 로그에 남기면 비용이 높은 경우, 샘플링에 사용할 수 있습니다.3. A/B 테스트적인 동작
사용자를 확률적으로 2개의 코드 패스로 나눕니다.4. Scheduler의 보조로 정기 태스크를 랜덤 실행
여러 서버에서 중복 실행을 피하면서, 어떤 태스크를 랜덤하게 실행하고 싶을 때 사용할 수 있습니다.Laravel 프레임워크 내에서의 확률적 패턴
Laravel은 프레임워크 내부에서도 확률적인 유지보수 처리를 널리 사용하고 있습니다. 일부 구현은Lottery 클래스가 추가되기 전에 작성되었기 때문에 random_int()를 직접 사용하고 있지만, 같은 사상에 기반합니다.
1
Session: 가비지 컬렉션
Illuminate\Session\Middleware\StartSession::configHitsLottery()는 config/session.php의 lottery 설정을 사용해 random_int로 확률 판정하여 GC를 실행합니다.2
DatabaseLock: 기한 만료 락 prune
Illuminate\Cache\DatabaseLock::acquire()는 락 획득 때마다 동일한 비율 패턴으로 기한 만료 락을 삭제합니다.3
DB::whenQueryingForLongerThan — Lottery 클래스를 전달하는 예
Lottery 인스턴스는 callable로 전달할 수 있으므로, 슬로우 쿼리 감지 콜백에 직접 사용할 수 있습니다.테스트 시의 이용
랜덤성이 있는 코드의 테스트에는Lottery가 제공하는 테스트용 API를 사용합니다.
Lottery::alwaysWin() — 항상 당첨시키기
Lottery::alwaysLose() — 항상 낙첨시키기
Lottery::fix() — 결과를 시퀀스로 고정하기
여러 번의 호출 결과를 true/false의 배열로 제어할 수 있습니다.
Lottery::setResultFactory() — 커스텀 팩토리 주입하기
더 세밀한 제어가 필요한 경우에는 커스텀 팩토리를 사용합니다.
패키지 개발에서의 활용
서비스 프로바이더에의 등록
패키지의 서비스 프로바이더에 유지보수 처리를 넣는 경우,Lottery를 사용해 부하를 분산시킵니다.
설정값에서 odds 읽어들이기
확률을 설정 파일에서 변경 가능하게 하면, 사용자가 조정하기 쉬워집니다.Middleware에서의 샘플링
API 레퍼런스
관련 페이지
Macroable 트레이트
기존 클래스에 새로운 메서드를 추가하는 확장 패턴을 배웁니다.
Conditionable 트레이트
when() / unless()를 사용한 조건 분기 체인의 설계를 배웁니다.