같은 자원(계좌, 주문, 재고, 배치 작업 등)을 여러 프로세스나 여러 서버가 동시에 건드리면 경합이 생깁니다. 언어 내장 뮤텍스나 세마포어는 한 프로세스 안에서만 유효합니다 — 프로세스가 여러 개거나 여러 대의 서버에 나뉘어 있으면 프로세스 경계를 넘어서는 상호배제 수단이 따로 필요합니다.
Ticketing은 바로 이 문제, 즉 프로세스·서버 경계를 넘는 분산 상호배제를 위한 락 서버와 클라이언트 모음입니다. 클라이언트는 TCP로 락 서버에 접속해 이름 있는 키(key)를 획득(acquire)하고, 임계 구역을 지난 뒤 반납(release)합니다.
처음부터 고정폭 바이너리 필드로 설계되어, 파싱 과정 없이 오프셋으로 바로 읽습니다 — 요청마다 드는 오버헤드가 최소입니다.
락을 획득할 때마다 서버는 단조 증가하는 u64 펜싱 토큰을 함께 내려줍니다. 보호 대상 리소스가 이 토큰의 단조성을 검증하도록 만들면, lease 만료 뒤 뒤늦게 깨어난 클라이언트가 더 낮은 토큰으로 접근하는 것을 거부할 수 있습니다. 그 결과 락 서버 자체가 매 순간 완벽히 일관적이지 않아도 안전을 지킬 수 있습니다 — 이는 특히 페일오버 구간에서 중요합니다.
서버 1대만으로도 동작하지만(싱글 모드), 무정지 운영이 필요하면 최소 2대로 클러스터를 구성합니다. 클러스터는 합의(쿼럼)가 아니라 우선순위 기반으로 액티브 하나를 선출하고 나머지는 실시간 복제를 받는 스탠바이가 됩니다. 액티브가 죽거나(재기동 포함) graceful 종료되면 스탠바이가 이어받습니다. 자세한 동작은 동작 원리 페이지를 참고하세요.
같은 바이너리 프로토콜 위에 다양한 언어의 클라이언트를 제공합니다: Rust, Java/Kotlin, JavaScript/TypeScript, Python, C#, Go, Ruby, C/C++. 언어마다 그 생태계에 자연스러운 방식으로 API를 노출합니다 — 예를 들어 async/await 계열 언어는 비동기로, Go/Ruby/C는 블로킹 + 백그라운드 스레드로. 프로토콜은 모든 언어에서 바이트 단위로 동일합니다. 언어별 설치 방법과 예제는 라이브러리 페이지에서 확인하세요.