Rust에서 비동기 프로그래밍은 즉시 완료되지 않을 수 있는 잠재적으로 장기 실행 작업을 나타내는 퓨처 개념에 의존합니다. 이러한 퓨처에는 실행 및 완료를 유도하는 메커니즘이 필요합니다. 이때 비동기 실행기가 사용됩니다.
비동기 실행기는 이러한 퓨처를 관리하고 실행하는 역할을 합니다. 퓨처를 예약하고 진행 상황을 폴링하며 궁극적으로 완료를 유도할 수 있는 환경을 제공합니다. 비동기 작업의 복잡성을 처리하여 코드가 응답성이 높고 효율적으로 유지되도록 하는 오케스트레이터라고 생각하면 됩니다.
Rust는 각각 고유한 장점과 특성을 가진 다양한 비동기 실행기를 제공합니다.
비동기 실행기
Rust 서비스의 실행기 선택은 워크로드의 특성에 크게 좌우됩니다. Tokio는 강력한 비동기 런타임이지만 모든 시나리오에 최적의 솔루션은 아닐 수 있습니다.
주로 순차 작업을 실행하는 서비스의 경우 Tokio와 같은 비동기 런타임을 도입하면 상당한 성능 향상을 제공하지 않고 불필요한 오버헤드가 발생할 수 있습니다. 이러한 경우 단일 스레드 실행기가 더 적합하고 가벼운 선택일 수 있습니다. 이 접근 방식은 코드베이스를 간소화하고 리소스 소비를 줄입니다.
작업자 스레드 구성
본질적으로 동시 또는 비동기 작업이 있는 서비스를 처리할 때는 Tokio와 같은 비동기 런타임의 기능을 활용하는 것이 중요합니다. 이러한 시나리오에서 성능을 극대화하려면 시스템에서 사용할 수 있는 CPU 코어 수와 일치하는 작업자 스레드 수를 사용하도록 런타임을 구성합니다. 이렇게 하면 런타임이 워크로드를 효율적으로 분산하고 사용 가능한 처리 능력을 최대한 활용할 수 있습니다.
작업자 스레드를 구성할 때는 전반적인 시스템 환경을 고려하세요. 여러 서비스가 동일한 가상 머신에서 활발하게 실행 중인 경우 서비스당 작업자 스레드 수를 조정하여 CPU 과도한 사용을 방지하고 모든 활성 프로세스 간에 공정한 리소스 할당을 보장합니다.
작업 차단
비동기 런타임 내의 작업자 스레드가 장기 실행 또는 동기 작업으로 인해 차단되지 않도록 하는 것이 중요합니다. 작업자 스레드를 차단하면 런타임이 수신 작업을 처리하고 응답성을 유지하는 기능이 심각하게 저해될 수 있습니다.
작업자 스레드에서 실행되는 함수가 차단 작업을 실행해야 하는 경우 tokio::spawn_blocking을 사용합니다. 이 함수는 차단 작업을 이러한 작업을 위해 특별히 설계된 별도의 스레드 풀로 오프로드하여 비동기 작업자 스레드의 중단을 방지하고 서비스의 전반적인 응답성을 보장합니다.