Фон
Я работаю над приложением actix-web, использующим дизельное топливо через r2d2, и не знаю, как лучше всего выполнять асинхронные запросы. Я нашел три варианта, которые кажутся разумными, но я не уверен, какой из них лучше.
Возможные решения
Актер синхронизации
Например, я мог бы использовать пример actix, но это довольно сложно и требует справедливая сделка шаблона для построения. Надеюсь, есть более разумное решение.
Actix_web::web::block
В качестве другого варианта я мог бы использовать actix_web::web::block
для перенести мои функции запросов в будущее, но я не уверен в последствиях этого для производительности.
Выполняется ли запрос в той же системе Tokio? Из того, что я смог найти в источнике, он создает поток в базовом пуле потоков actix-web. Это проблема?
Если я правильно прочитал код, r2d2 блокирует свой поток при получении соединения, что заблокирует часть основного пула actix-web. То же самое с запросами к базе данных. Тогда это заблокирует весь actix-web, если я сделаю больше запросов, чем у меня есть потоков в этом пуле? Если так, то большая проблема.
Фьючерсы-cpupool
Наконец, безопасный вариант, при котором могут возникнуть ненужные накладные расходы, - это futures-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.
Каков наилучший подход к инкапсуляции блокировки? I / O in future-rs?
Рекомендует Futures-cpupool для общих случаев.
Старые решения, которые не работают
https://www.reddit.com/r/rust/comments/9fe1ye/noob_here_can_we_talk_about_async_and_databases/
Действительно хорошее исправление для старой версии actix-web. Из того, что я могу найти, в запросах больше нет пула процессора.
futures-cpupool
рекомендуемый обходной путь из-за отсутствия поддержкиasync
в Diesel. - person Jmb   schedule 08.11.2019