Катринка: https://avatars.mds.yandex.net/get-adfox-content/2774030/210216_market_1523869_4142475_4.898e408d281fc91443310f7ae00d0dfd.jpg/optimize.webp
еще одна
Nginx?
А эти люди не гуглят про c++ webserver (там не про ASP.NET), а делают. Насколько они круты? Тут, круче точно нет.
Приземляемся. Вот тут,
Намекают, что и сервер не очень то и нужен. Даже пых понял:
#А че так можно было?echo "Server running at http://127.0.0.1:8080\n"; $loop->run();
Так что развивается все..
(pyenv) [www@localhost ~]$ curl -X HEAD -I https://avatars.mds.yandex.net/get-adfox-content/2774030/210216_market_1523869_4142475_4.898e408d281fc91443310f7ae00d0dfd.jpg/optimize.webp HTTP/2 200 server: nginx date: Fri, 05 Mar 2021 20:45:14 GMT content-type: image/jpeg content-length: 40042 access-control-allow-origin: * access-control-allow-credentials: true last-modified: Tue, 16 Feb 2021 15:46:03 GMT cache-control: max-age=86400,immutable x-request-id: 308dd2e79af8323e nel: {"report_to": "network-errors", "max_age": 600, "success_fraction": 0.001, "failure_fraction": 0.01} report-to: {"group": "network-errors", "max_age": 600, "endpoints": [ { "url": "https://dr.yandex.net/s3_nel"}]} timing-allow-origin: * (pyenv) [www@localhost ~]$ curl -X HEAD -I -H "user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64);" -H "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" https://avatars.mds.yandex.net/get-adfox-content/2774030/210216_market_1523869_4142475_4.898e408d281fc91443310f7ae00d0dfd.jpg/optimize.webp HTTP/2 200 server: nginx date: Fri, 05 Mar 2021 20:45:46 GMT content-type: image/webp content-length: 17044 access-control-allow-origin: * access-control-allow-credentials: true last-modified: Tue, 16 Feb 2021 15:50:33 GMT cache-control: max-age=86400,immutable x-request-id: 6599f34cff38fb39 nel: {"report_to": "network-errors", "max_age": 600, "success_fraction": 0.001, "failure_fraction": 0.01} report-to: {"group": "network-errors", "max_age": 600, "endpoints": [ { "url": "https://dr.yandex.net/s3_nel"}]} timing-allow-origin:
У меня в основном монга. Пока ее хватает в моих задачах.
Постгрес, в основном в парсерах, ну и кое-какие товарные базы. То, что с asyncio - aiopg (но оно тоже надстройка над psycopg2 ), а в мелких ручных задачах, выборку там какую быстро сделать, то просто:
import psycopg2 conn = psycopg2.connect(database=....
Я в курсе. То, что большой backlog ставил - это только в рамках тестов. Понятно, что в зависимости от доступных ресурсов и их потребления приложением.
По SO_REUSEPORT , спасибо за наводку. Разберусь.
Нет, у меня Nginx +
upstream dododohttp { server unix:/tmp/appd_1.sock fail_timeout=0; server unix:/tmp/appd_2.sock fail_timeout=0; server unix:/tmp/appd_3.sock fail_timeout=0; server unix:/tmp/appd_4.sock fail_timeout=0;}...command=/var/www/aweb/pyenv/bin/python /var/www/aweb/pyenv/pyd/app.py --path=/tmp/appd_%(process_num)s.sock
несколько процессов aiohttp;
В документации прямо сказано, что
В отличие от развертывания с голым Nginx, решению не нужно вручную запускать несколько процессов aiohttp и использовать такой инструмент, как supervisord, для его мониторинга. Но ничего не дается бесплатно: запуск приложения aiohttp под Gunicorn немного медленнее.
А uwsgi у меня pgadmin
danforth , кстати, привет.
Было бы интересно, с теми, кто в теме, порассуждать про оптимальные варианты.
это один из вариантов. В зависимости от ресурсов.
В предыдущем тесте, 2 последних были закоментированы.
а на предыдущем тесте, было numprocs = 2
Ну вот они, все 4. В итоге 512 тоже вариант:
И нормально:
Ресурсыprocessor : 7vendor_id : GenuineIntelcpu family : 6model : 165model name : Intel(R) Core(TM) i3-10100 CPU @ 3.60GHzstepping : 3microcode : 0xe0cpu MHz : 4118.145cache size : 6144 KB[www@localhost supervisord.d]$ sudo cat /proc/meminfoMemTotal: 16066212 kBMemFree: 2226140 kBMemAvailable: 7608288 kBBuffers: 5116 kBCached: 6130460 kBSwapCached: 3636 kB
Если это про это,
Failed requests: 4+ на скрине (Connect: 0, Receive: 0, Length:
то ответы разной длины. Ну, типа
"gen_time": 6.4334869384765625
а может, 16.345345... или 134.88888...
Ошибки, это когда Non-2xx responses: Смоделирую..
Concurrency Level: 800Time taken for tests: 3.727 secondsComplete requests: 10000Failed requests: 732 (Connect: 0, Receive: 0, Length: 732, Exceptions: 0)Non-2xx responses: 9268Total transferred: 194033751 bytesHTML transferred: 192166843 bytesRequests per second: 2683.09 [#/sec] (mean)Time per request: 298.163 [ms] (mean)Time per request: 0.373 [ms] (mean, across all concurrent requests)Transfer rate: 50840.90 [Kbytes/sec] receivedConnection Times (ms) min mean[+/-sd] median maxConnect: 0 6 3.6 6 19Processing: 0 231 805.1 7 3581Waiting: 0 228 802.4 5 3580Total: 0 237 806.5 13 3594
При
web.run_app( init(), path=args.path, port=args.port, access_log=None, print=None, backlog=1024 )
backlog (int) – a number of unaccepted connections that the system will allow before refusing new connections, see socket.listen() for details. 128 by default.
Для начала положите в корень сайта test.php, в нем
Посмотрите в браузере за сколько отрабатывает. Потом добавьте
А зачем в браузере? microtime
<?phpheader('Content-Type:text/plain');ob_start();$t0 = $_SERVER['REQUEST_TIME_FLOAT'];$t1 = microtime(true);echo 'phpversion: ', phpversion(), "\n==== REQUEST_TIME_FLOAT: ", $t0, "\n==== PHP_START_TIME: ", $t1;echo "\n==== SCRIPT_time_after_request (ms): ", ( $t1 - $t0) * 1000;$fn = '/home/www_data/geo/__avito.json';$f = file_get_contents($fn);$t2 = microtime(true);printf( "\n==== SCRIPT_time_after_file_getcontents_%s_%s_byte (ms): ", $fn, strlen($f));echo ( $t2 - $t1) * 1000;$f = json_decode($f);$t3 = microtime(true);printf( "\n==== SCRIPT_time_after_json_decode_obj_count_%s: \n", count($f));echo ' After start (ms):', ( $t3 - $t1) * 1000, "\n";echo ' After file_get_contents (ms):', ( $t3 - $t2) * 1000, "\n";echo "First obj: \n"; print_r($f[0]);echo '???Page gen time (ms):', ( microtime(true) - $t1) * 1000, "\n~~~\n";$tpl = "\n%s, Координаты: [ %s, %s ]\n";foreach($f as $v){ printf($tpl, $v->name, $v->Location->Longitude, $v->Location->Latitude);}$out = ob_get_contents();ob_end_clean();echo '!!!!!!!Page gen time (ms):', ( microtime(true) - $t1) * 1000, "\n-------------\n";echo $out;
Красненьким на скрине + код. json приложен.
Уупс, соврал. В данном случае
ab -n 20000 -c 500 -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0" http://audodo.aio1/
Юзер агент который заставит апп отработать по полной - и сессия, и токен, и все данные и логи для аналитики запишутся..
И пофиг.. Лучше, скрин
ab -n 20000 -c 500 -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0" http://sndl.local/
покажите и htop при этом.
А чего там рассказывать? Как сказал бы ТС, "приляпываю" потихоньку кучу либ🤣
from aiohttp import web, __version__from aiojobs.aiohttp import setupimport aioredisfrom motor.motor_asyncio import AsyncIOMotorClientfrom jinja2 import FileSystemLoaderfrom aiohttp_jinja2 import setup as aiohttp_jinja2_setup....async def create_aiodb(app): dsn = CNF['mongo'] app['dbname'] = dsn.split('/')[-1] app['db_engine'] = AsyncIOMotorClient(dsn)[app['dbname']]async def on_startup(app): await create_redis_pool(app) await create_aiodb(app)app.on_startup.append(on_startup) app.on_cleanup.append(on_cleanup)app.on_shutdown.append(on_shutdown)app.on_response_prepare.append(on_resp_prep)"""где то потом, в данном случае, если юзер мышкой повозил, то post xhr, ну там понять его реальность,в свете нынешних ботоатак на сайты, и, заодно, определить георгафию пользователя"""coll = self.request.app['db_engine'].ru_geoself.request['out']['nearby'] = []async for doc in coll.find( query, {'cid':1, 'regId':1, 'name':1, 'location':1, 'region':1} ) .limit(6): self.request['out']['nearby'].append(doc)return json_response(request['out'])
В итоге, имеем.
26 уже приляпял (requrements.txt)
aiohttpaiojobsaiohttp_jinja2jinja2motoraiosqliteaioredisaiohttp_sessionaiostalkpyexcelpillowpymorphy2[fast]pymorphy2-dicts-rugensimpasslibbs4lxmlrequestspyexcel-xlsxpyexcel-xlspyyamlrecordclassuvloopcryptographybasicauthxxhash
И ещё буду🤓
Правда изучать приходится, мотор, там, аио - нудно и скучно. Тестировать, разные варианты смотреть, по нагрузкам, потребляемым ресурсам и т.д. Нудятина типа такого, как чтобы RPS много, а load average и пр. RES мало.
backlog=10240
Здорово помогают штучки типа раз, два.( контролируемый способ планирования фоновых задач + beanstalkd) Здорово снижает время генерации документа, за счет того что часть задач может выполняться уже после отрузки документа.
Лог задач beanstalkd заканчивается такой строкой (после ab -n 20000)
Task 20000 (JobId: 77658) done!--2021-02-20 12:51:06.820591~
Которые запускаюся в свою очередь
await spawn(request, coro(request))# где в коро естьif 'talk_job' in request: await add_job(request['talk_job'])
До внедрения этих штучек, РПС был примерно 400-500, а сейчас 900+ на типичной индекс паги ( для реального юзера чуть меньше, юзер агент апачбенч в списке ботов, ряд операции для ботов не выполняется. Сессия там и т.д. )