배경
r2d2를 통해 디젤을 사용하는 actix-web 응용 프로그램을 작성 중이며 비동기 쿼리를 가장 잘 만드는 방법을 잘 모르겠습니다. 합리적인 것처럼 보이는 세 가지 옵션을 찾았지만 어느 것이 가장 적합한 지 확실하지 않습니다.
잠재적 인 솔루션
싱크 액터
우선 actix 예제를 사용할 수는 있지만 상당히 복잡하고 많은 양의 상용구가 필요합니다. 더 합리적인 해결책이 있기를 바랍니다.
Actix_web::web::block
또 다른 옵션으로를 사용하여 actix_web::web::block
쿼리 기능을 미래에 래핑 할 수 있지만 성능의 영향을 확신하지 못합니다.
그런 다음 쿼리가 동일한 Tokio 시스템에서 실행됩니까? 소스에서 찾을 수있는 것으로부터 기본 actix-web threadpool에 스레드가 생성 됩니다. 그게 문제입니까?
코드를 올바르게 읽으면 r2d2가 연결을 가져올 때 스레드를 차단하여 핵심 actix-web 풀의 일부를 차단합니다. 데이터베이스 쿼리와 동일합니다. 그런 다음 해당 풀에 스레드가있는 것보다 더 많은 쿼리를 수행하면 모든 actix-web을 차단합니까? 그렇다면 큰 문제입니다.
선물 CPU 풀
마지막으로 불필요한 오버 헤드가있을 수있는 안전한 내기는 futures-cpupool 입니다. 주요 문제는 내 프로젝트에 다른 상자를 추가한다는 것을 의미하지만 내 응용 프로그램에서 여러 개의 CPU 풀이 불필요하게 떠 다니는 아이디어는 마음에 들지 않습니다.
r2d2와 디젤이 모두 차단되므로 여기에는 놀라운 일이 많이 있습니다.
가장 중요한 것은이 cpupool을 동일한 r2d2 풀을 사용하지 않는 것과 공유하지 마십시오 (만약 작성된 모든 스레드가 r2d2 연결 대기를 막고 작업이있을 때 전체 풀을 잠글 수 있음).
두 번째로 (좀 더 분명히), 풀의 스레드보다 r2d2 연결이 더 크지 않아야하며 그 반대의 경우 더 큰 리소스가 낭비됩니다 (사용하지 않는 연결 / 스레드가 지속적으로 차단됨) cpupool 스케줄러가 아닌 OS 스케줄러에 의한 연결 핸드 오버).
마지막으로, 사용중인 데이터베이스와 성능을 염두에 두십시오. 풀에서 단일 연결 r2d2와 단일 스레드를 실행하는 것은 쓰기 무거운 sqlite 응용 프로그램에서 가장 좋습니다 (그러나 적절한 데이터베이스를 권장합니다).
이전 답변
작동 할 수있는 오래된 솔루션
https://www.reddit.com/r/rust/comments/axy0hp/patterns_to_scale_actixweb_and_diesel/
본질적으로 Futures-cpupool을 권장합니다.
미래의 R에서 차단 I / O를 캡슐화하는 가장 좋은 방법은 무엇입니까?
일반적인 경우 Futures-cpupool을 권장합니다.
작동하지 않는 오래된 솔루션
https://www.reddit.com/r/rust/comments/9fe1ye/noob_here_can_we_talk_about_async_and_databases/
오래된 actix-web 버전에 대한 정말 좋은 수정입니다. 내가 찾을 수있는 것에서 더 이상 요청에 CPU 풀이 없습니다.
futures-cpupool
에async
대한 지원 이 부족한 경우 권장되는 해결 방법 인 것 같습니다 .