_______. _______.___ ___ .______ ____ ____ _______ .______
/ | / | / / | _ / / | ____|| _
| (----` | (----` V / | |_) | / / | |__ | |_) |
> < | / / | __| | /
.----) | .----) | / . | | ----. / | |____ | | ----.
|_______/ |_______/ /__/ __ | _| `._____| __/ |_______|| _| `._____|
SSXRver-это высокопроизводительная сетевая библиотека с высокой токностью, работающая на платформе Linux. Он написан в C ++ 17 и поддерживает протоколы TCP и UDP.
Пожалуйста, попробуйте соответствовать той же среде разработки, что и я. Если вам не нужен модуль базы данных, пожалуйста, измените cmakelists.txt соответственно.
Установка Cmake
# debian/ubuntu
sudo apt-get install cmakeУстановка библиотеки повышения
wget http://sourceforge.net/projects/boost/files/boost/1.72.0/boost_1_72_0.tar.bz2
tar -xvf boost_1_72_0.tar.bz2
cd ./boost_1_72_0
./bootstrap.sh --prefix=/usr/local
sudo ./b2 install --with=allЗапустите ./build.sh в каталоге SSXRver вы можете изменить build.sh, чтобы выбрать генерацию версии отладки или версии релиза (версия релиза по умолчанию)
./build.shСкомпилированный успешно будет генерировать сборку/ каталог, а исполняемый файл находится в соответствующем каталоге версий. Например, когда вы выбираете версию выпуска, исполняемый файл находится в/build/release/ssxrver.
Имитируйте формат conf/ssxrver.json.example, чтобы создать файл конфигурации (обратите внимание, что файл конфигурации не может быть прокомментирован, а не комментирован, а не комментирован). Я объясню параметры каждого файла конфигурации ниже. Я на самом деле устанавливаю значения по умолчанию для многих параметров. Если не настроить, это не повлияет на это.
{
" port " : 4507, # 端口号,不填的话默认4507
" address " : " 127.0.0.1 " , # 绑定的地址
" worker_processes " : 4, # IO 线程数量,不填默认为 4 个
" worker_connections " : -1, # 一个 IO 线程最多支持多少连接, -1 表示最多能创建多少就创建多少,不做限制
" task_processes " : 0, # 任务线程,不填的话默认为 0
" cpu_affinity " : " off " , # cpu 亲和度 ,默认关闭
" http " : { # http 模块
" max_body_size " : 67108864, # 单个 http 包最大支持大小
" root_path " : " /home/randylambert/sunshouxun/ssxrver/html/ " # 文件访问根路径
},
" log " : { # log 模块
" level " : " INFO " , # 输出等级,可填三种等级, DEBUG,INFO,WARN 不填默认为 INFO 等级
" ansync_started " : " off " , # 是否打开异步日志线程,不填默认关闭
" flush_second " : 3, # 异步线程每隔多久持久化一次
" roll_size " : 67108864, # 日志文件滚动大小
" path " : " /home/randylambert/sunshouxun/ssxrver/logs/ " , # 日志文件存放路径
" base_name " : " ssxrver " # 日志文件基础名
},
" mysql " : { # 数据库模块
" mysql_started " : " off " , # 是否打开数据库模块,默认关闭
" address " : " 127.0.0.1 " , # 以下是对应数据库连接信息
" user " : " root " ,
" password " : " 123456 " ,
" database_name " : " ttms " ,
" port " : 0,
" unix_socket " : null,
" client_flag " : 0
},
" blocks_ip " : [ " 122.0.0.2 " , " 198.1.2.33 " ] # 可屏蔽部分恶意 IP
}Запустите исполняемый файл.
./ssxrver -f /配置文件的路径
# 例如
./build/Release/ssxrver -f ./conf/ssxrver.json| Тестовая среда | Ценить |
|---|---|
| Версия прически для операционной системы | Deepin v20.1 Community Edition (1030) |
| Версия ядра | 5.4.70-AMD64-DESKTOP (64-битный) |
| Компиляторная версия | GCC 8.3 |
| Увеличьте версию библиотеки | 1.72 |
| процессор | Intel (r) Core (TM) I7-8750H ЦП при 2,20 ГГц |
| Размер кэша L1 | 32к |
| Размер кэша L2 | 256K |
| Размер кэша L3 | 9216K |
| Скорость жесткого диска | 1,8 Механический жесткий диск TIB 5400 об / мин |
| Жесткий диск чтение и скорость записи | 370 МБ за 3,03 секунды = 122,27 МБ/с |
| Память | 7,6 ГБ |
| Перегородка обмена | 4,7 ГБ |
| Логическое количество ядра | 12 ядер |
Чтобы управлять переменными, перезапустите компьютер перед тестированием, чтобы убедиться, что в тестовой среде нет других приложений с высокой нагрузкой ЦП и высокой нагрузкой ввода -вывода.
Тестовый инструмент - WebBench1.5. Удалите первые данные разминки. Тестовая команда заключается в следующем (100 клиентов были доступны непрерывно в течение 15 секунд).
./webbench -c 100 -t 15 http://127.0.0.1:8081/Тестовые объекты Apache/2.4.38, Nginx/1.14.2, SSXRver.
ПРИМЕЧАНИЕ. Использование Webbench или AB, данные, измеренные этим инструментом измерения давления, могут использоваться только в качестве простой ссылки. Измерение давления-это тест, который требует многоугольного и многоугольного, а не просто запуск команды. Даже во время измерения давления данные вообще не передаются через сеть, а просто обходятся в ядре.
| Сетевая библиотека | Скорость (страницы/мин) | Запрос успех |
|---|---|---|
| SSXRver возвращает ответ, сгенерированный в памяти | 7107414 | 100% |
| SSXrver возвращает статические файлы | 5114376 | 100% |
| Apache/2.4.28 | 2884072 | 100% |
| nginx/1.14.2 | 4728748 | 100% |
Результаты испытаний SSXRver довольно хороши, но, как ни странно, я думал, что данные будут выше, потому что, когда я развивался в первые дни, в то время я не делал много оптимизаций. Когда я вернул ответ, сгенерированный непосредственно в памяти, он измерялся в большинстве почти 8000000 страниц/мин (результаты испытаний 8000000 страниц/мин не были сделаны на снимках экрана, оставив 7550778). В то время nginx/1,14,2 имел максимум 5000000 страниц/мин. Однако, независимо от того, был ли это SSXRver или Nginx/1.14.2, я не смог найти такую высокую ценность. Я не знаю, в чем причина, что привело к такому большому разрыву в конечном результате (это потому, что мой компьютер стареет?  ̄ □  ̄||)
В настоящее время я лично изменю модуль буферного модуля и журнал SSXRver, если у меня будет время.
Прежде всего, самый простой способ изменить буферный модуль-это изменить его на циклический буфер, тем самым эффективно уменьшая количество раз, когда буфер перемещает данные вперед, или непосредственно отказавшись от этой реализации буфера и повторно внедряя буфер высокого уровня.
Во -вторых, текущий модуль журнала записывается в форме потока C ++. Несмотря на то, что он определенно выше производительности, чем использование C ++ непосредственно с iostream, перегрузка журнала в символической форме << все равно приведет к неудобным проблемам управления форматом и производительности, вызванными цепочками вызовов функций. Обе эти проблемы могут быть решены путем внедрения журнала в форме печати.
По причинам времени SSXRver не реализует модуль управления памятью, поэтому практически невозможно написать общий высокопроизводительный модуль управления памятью (лучше перейти непосредственно на Jemalloc или Tcmalloc). Тем не менее, анализируя сценарий библиотеки сетевой библиотеки, все еще немного шансов написать модуль управления памятью с более высокой производительностью в этом сценарии. Если у меня будет время, я посмотрю на реализацию в Nginx и узнаю ее.
Когда я запрашивал информацию, я пришел к выводу, что в C ++ 17 вы можете использовать std :: string_view, чтобы заменить Const String &, что повысит некоторую эффективность. Поэтому я попытался заменить все места, где Const String & в моем проекте на std :: string_view. Однако, когда я наконец использовал perf -top для просмотра измененной нагрузки, я неожиданно обнаружил, что некоторые функции фактически увеличились после того, как я использовал std :: string_view, чтобы заменить его. Я был очень озадачен, почему эта ситуация произошла. По причинам времени я не буду исследовать конкретную причину этой проблемы в настоящее время. У меня есть возможность проверить основную реализацию, чтобы проверить конкретную причину.
При внедрении модуля анализа HTTP я использовал рукописную машину, которая непосредственно соответствует строкам в первой версии. Затем я заменил его на государственную машину, реализованную Ragel. Однако во время недавних тестов я обнаружил, что нагрузка функции анализа HTTP очень преувеличена, достигая 10%. Может ли быть так, что использование Ragel вызвало снижение производительности? (Если анализ заголовка вызовет такую высокую системную нагрузку, то кажется, что HTTP/2.0 все равно значительно улучшит производительность), к сожалению, когда я уже написал рукописную машину, я не проверял нагрузку соответствующей функции анализа. Теперь я не могу получить сравнение данных между ними одновременно, и у меня есть возможность написать эталонный тест.
SSXRver поддерживает простую передачу UDP, но я лично думаю, что структура UDP без контроля за перегрузки, управления трафиком и функций повторной передачи пакетов в основном можно сказать, что не может использоваться нормально. В будущем у меня будет время выучить протоколы QUIC и KCP. Я добавлю знания, связанные с UDP. Я считаю, что более эффективный и гибкий протокол UDP будет все более и более широко использоваться в будущем!
На самом деле, я на самом деле думаю, что лучшая сетевая структура в настоящее время должно заключаться в том, что мультиплексирование мультиплексирования порта плюс несколько потоков (мультипроцессы) связывают один и тот же адрес и порт, а ядро автоматически выполняет балансировку с нагрузкой. В то же время блокируют системы системы через Coroutine Framework + Hook. После использования этой структуры он может обеспечить высокую производительность без использования основного потока для распределения соединений, и нет необходимости впадать в асинхронный обратный вызов.
Кроме того, если вы можете использовать асинхронный механизм ввода -вывода IO_URING, добавленный после ядра Linux 5.1, я считаю, что производительность сервера будет выше. Однако в настоящее время я мало знаю о io_uring, и у меня нет возможности разработать асинхронную сетевую библиотеку ввода -вывода на основе io_uring.