Чи повинен дизель працювати за допомогою актора синхронізації, actix_web :: web :: block або futures-cpupool?


10

Фон

Я працюю над веб-додатком actix, використовуючи дизель через r2d2 і не знаю, як найкраще робити асинхронні запити. Я знайшов три варіанти, які здаються розумними, але не знаю, який із них найкращий.

Потенційні рішення

Синхронізатор

Для одного я міг би використати приклад actix , але він досить складний і вимагає неабиякої роботи котлоагрегату. Я сподіваюся, що існує більш розумне рішення.

Actix_web::web::block

Як інший варіант, я міг би використати функцію actix_web::web::blockдля запиту моїх запитів у майбутнє, але я не впевнений у наслідках для цього.

Чи запит виконується в тій же системі Tokio? З того, що я міг знайти у джерелі, він створює нитку в нижній пуці ниток actix-web . Це проблема?

Якщо я читаю код правильно, r2d2 блокує його потік при отриманні з'єднання, яке б блокувало частину основного пула actix-web. Те саме з запитами до бази даних. Потім це заблокує всі actix-web, якщо я більше запитів, ніж у мене є потоки в цьому пулі? Якщо так, велика проблема.

Ф'ючерси-cpupool

Нарешті, безпечна ставка, яка може мати непотрібні накладні витрати, - це ф'ючерси-cpupool . Основне питання полягає в тому, що це означає додати ще один ящик до мого проекту, хоча мені не подобається ідея про безліч процесорних пулів, що плавають навколо у моїй програмі.

Оскільки і r2d2, і дизель будуть блокувати, тут є дивовижна кількість складних речей.

Найголовніше, не поділяйте цей cpupool нічим, не використовуючи той самий пул r2d2 (оскільки всі створені потоки можуть просто блокувати очікування з'єднання r2d2, блокуючи весь пул, коли робота існує).

По-друге (трохи очевидніше), таким чином, у вас не повинно бути більше з'єднань r2d2, ніж потоки в пулі, і навпаки, оскільки більший буде витрачати ресурси (з'єднання невикористані / потоки постійно блокуються) (можливо, ще один потік, можливо, швидше передача з'єднання за допомогою планувальника ОС, а не планувальника cpupool).

Нарешті, пам’ятайте, яку базу даних ви використовуєте та продуктивність у вас. Запуск єдиного з'єднання r2d2 та однієї нитки в пулі може бути найкращим у важкому додатку sqlite (хоча я рекомендую для цього належну базу даних).

Старі відповіді

Старі рішення, які можуть працювати

https://www.reddit.com/r/rust/comments/axy0hp/patterns_to_scale_actixweb_and_diesel/

По суті, рекомендує Futures-cpupool.

Який найкращий підхід до інкапсуляції, що блокує введення / виведення в майбутньому?

Рекомендує Futures-cpupool для загальних випадків.

Старі рішення, які не працюють

https://www.reddit.com/r/rust/comments/9fe1ye/noob_here_can_we_talk_about_async_and_databases/

Дійсно приємне виправлення старої версії actix-web. Як я можу знайти запити, у них більше немає пульту процесора.


З коментарів у цьому номері , схоже futures-cpupool, рекомендується вирішити відсутність asyncпідтримки у Дизелі.
Джмб

Це більше загальне рішення. Я сподіваюся на щось, що спричинить систему actix. Тим не менш, я зараз заграю у ф'ючерси-cpupool, щоб шукати проблеми.
Логін

Ласкаво просимо до переповнення стека! Схоже, на ваше запитання можуть відповісти відповіді: Який найкращий підхід до інкапсуляції, що блокує введення-виведення в майбутньому? . Якщо ні, то відредагуйте своє запитання, щоб пояснити відмінності. В іншому випадку ми можемо відзначити це питання як уже відповів.
Шепмейстер

Оскільки cpupool також взаємодіє з пулом блокуючих з'єднань в r2d2, я не знаю, як найкраще це вирішити. Я зараз переглядаю це, і незабаром оновлю це.
Логін

Відповіді:


3

Я йду з ф'ючерсами-cpupool. Це найкраще рішення завдяки блокуючому характеру моїх взаємодій.

Використання actix_web :: web :: block є досить пристойним, але використовуватиме спільний пул потоків в actix (і завдяки блокуючим дзвінкам, які я використовую, це може блокувати весь пул потоків і втручатися в інші завдання, надані actix_web).

Краще використовувати futures-cpupool для створення окремої нитки для кожної бази даних лише для взаємодії з базою даних. Таким чином ви групуєте всі завдання, на які потрібно чекати одне одного (коли завдань більше, ніж з'єднань), в один пул, не дозволяючи їм блокувати будь-які інші завдання, які не потребують з'єднання, і потенційно обмежують кількість потоків до кількість підключень (щоб завдання було заплановано лише тоді, коли воно не буде заблоковано).

У тому випадку, коли ви хочете використовувати лише одне підключення до бази даних (або дуже мало), актор синхронізації є досить хорошим варіантом. Він буде діяти як ф'ючерсний cpupool з одним потоком, гарантуючи, що всі завдання виконуються по одному, за винятком того, що він буде використовувати один з базових потоків actix-web, а не окремий (отже, корисний лише для дуже небагато з'єднань) . Я вважаю, що котла занадто великі, щоб його вартувати.


6
прочитавши мої висновки вище - будь ласка , інформацію пут , що мають відношення до відповіді в відповідь , а не питання.
Шепмайстер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.