Для изучения нового языка программирования я использую следующий подход. Сначала я читаю учебник по этому языку программирования, в котором объясняются синтаксис, идиомы, философия и принципы работы языка. После этого я пишу небольшой пет-проект на этом языке программирования. На пет-проекте я немного практикуюсь с новым языком, с его стандартными библиотеками и популярными фреймворками.
Чтобы погрузиться сильнее в язык, вместо пет-проекта я начинаю писать свои библиотеки для работы с базами данных (ORM), JSON, акторами, MVC веб-фреймворком, логированием и т.д. Библиотеки, которые вряд ли будут кому-то нужны, но они помогут мне лучше понять язык программирования. На удивление, с языком Rust я добрался до написания своего веб-сервера. Раньше такого не было. Думаю, это из-за того, что Rust — это язык системного программирования и грех на нём не попробовать заняться оптимизацией перформанса.
В итоге я столкнулся с тем, что Rust не имеет аналогов Nginx, Lighttpd, Caddy, HAProxy, Apache, Tomcat, Jetty и т.д. Все эти веб-сервера написаны на C, Go, Java и т.д. Имеются только веб-фреймворки: Actix, Axum, Rocket, Hyper и т.д.
В целом я прикинул, что обычно я использую Nginx для следующих целей:
1. TLS для доменов
2. Проксирование запросов на бэкэнд
3. Раздача статических файлов
В итоге решил написать свою реализацию веб-сервера на Rust.
Сервер поддерживает конфигурационный файл в формате KDL Document Language. Вот примеры «Cbltfile» конфигурационного файла для веб-сервера Cblt:
Файл сервер
"*:80" { root "*" "/path/to/folder" file_server }
Файл сервер & Проксирование
"127.0.0.1:8080" { reverse_proxy "/test-api/*" "http://10.8.0.3:80" root "*" "/path/to/folder" file_server }
TLS поддержка
"example.com" { root "*" "/path/to/folder" file_server tls "/path/to/your/domain.crt" "/path/to/your/domain.key" }
Сейчас Cblt веб-сервер можно запустить двумя способами: через Cargo или Docker.
Cargo
cargo run --release
Docker
docker build -t cblt:0.0.3 . docker run -d -p 80:80 --restart unless-stopped --name cblt cblt:0.0.3
На текущий момент я добился приемлемой скорости работы для проксирования статических файлов.
Провёл тест с Apache Benchmark (ab) для 300 запросов с 100 одновременными соединениями. Загрузка изображения размером 5 МБ с example.com/logo_huge.png.
ab -c 100 -n 300 http://example.com/logo_huge.png
Percent |
Cblt |
Nginx |
Caddy |
50% |
1956 |
1941 |
1768 |
75% |
2101 |
2065 |
1849 |
100% |
2711 |
2360 |
2270 |
Cblt
igumn@lenovo MINGW64 ~/cblt (main) $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0589d8f26d91 cblt:0.0.1 "./cblt" 2 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp cblt igumn@lenovo MINGW64 ~/cblt (main) $ ab -c 100 -n 300 http://example.com/logo_huge.png This is ApacheBench, Version 2.3 <$Revision: 1913912 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking example.com (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Finished 300 requests Server Software: Server Hostname: example.com Server Port: 80 Document Path: /logo_huge.png Document Length: 5122441 bytes Concurrency Level: 100 Time taken for tests: 6.020 seconds Complete requests: 300 Failed requests: 0 Total transferred: 1536745500 bytes HTML transferred: 1536732300 bytes Requests per second: 49.83 [#/sec] (mean) Time per request: 2006.721 [ms] (mean) Time per request: 20.067 [ms] (mean, across all concurrent requests) Transfer rate: 249283.62 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.3 0 2 Processing: 1293 1926 262.3 1956 2711 Waiting: 1 118 139.1 63 645 Total: 1293 1926 262.3 1956 2711 Percentage of the requests served within a certain time (ms) 50% 1956 66% 2027 75% 2101 80% 2127 90% 2213 95% 2394 98% 2544 99% 2597 100% 2711 (longest request)
Nginx
igumn@lenovo MINGW64 ~/cblt/benchmark/nginx (main) $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 37fbf1dac42b nginx_srv "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp nginx_srv igumn@lenovo MINGW64 ~/cblt/benchmark/nginx (main) $ ab -c 100 -n 300 http://example.com/logo_huge.png This is ApacheBench, Version 2.3 <$Revision: 1913912 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking example.com (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Finished 300 requests Server Software: nginx/1.27.2 Server Hostname: example.com Server Port: 80 Document Path: /logo_huge.png Document Length: 5122441 bytes Concurrency Level: 100 Time taken for tests: 6.043 seconds Complete requests: 300 Failed requests: 0 Total transferred: 1536804300 bytes HTML transferred: 1536732300 bytes Requests per second: 49.65 [#/sec] (mean) Time per request: 2014.267 [ms] (mean) Time per request: 20.143 [ms] (mean, across all concurrent requests) Transfer rate: 248359.28 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.3 0 2 Processing: 1387 1940 168.4 1941 2360 Waiting: 1 115 84.5 98 301 Total: 1387 1940 168.4 1941 2360 Percentage of the requests served within a certain time (ms) 50% 1941 66% 2024 75% 2065 80% 2088 90% 2152 95% 2201 98% 2263 99% 2317 100% 2360 (longest request)
Caddy
igumn@lenovo MINGW64 ~/cblt (main) $ ab -c 100 -n 300 http://example.com/logo_huge.png This is ApacheBench, Version 2.3 <$Revision: 1913912 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking example.com (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Finished 300 requests Server Software: Caddy Server Hostname: example.com Server Port: 80 Document Path: /logo_huge.png Document Length: 5122441 bytes Concurrency Level: 100 Time taken for tests: 5.440 seconds Complete requests: 300 Failed requests: 0 Total transferred: 1536804000 bytes HTML transferred: 1536732300 bytes Requests per second: 55.14 [#/sec] (mean) Time per request: 1813.469 [ms] (mean) Time per request: 18.135 [ms] (mean, across all concurrent requests) Transfer rate: 275858.99 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.3 0 2 Processing: 1264 1749 191.1 1767 2270 Waiting: 1 96 104.7 67 467 Total: 1265 1749 191.1 1768 2270 Percentage of the requests served within a certain time (ms) 50% 1768 66% 1821 75% 1849 80% 1877 90% 1955 95% 2152 98% 2226 99% 2241 100% 2270 (longest request)
В планах также провести тесты для проксирования бэкенда, в общем reverse_proxy на производительность не тестировал еще.
Может в этот раз мой мини-проект кого-то заинтересует? И это увлечение вырастет в что-то большее?
Если интересно глянуть код или поконтрибутить, вот ссылка на репозиторий: https://github.com/evgenyigumnov/cblt
ссылка на оригинал статьи https://habr.com/ru/articles/857306/
Добавить комментарий