Смотрим плавность хода с помощью BMW Rheingold

Всем знакома ситуация, когда двигатель немного "троит", но пропусков зажигания нет...

Облачный хостинг VDS за 2 минуты

Настоящий облачный VDS-хостинг от UltraVDS: тестируем производительность

Дельта-синхронизация крипто-дисков

Существуют разные способы зашифровать "облако". Один из них - поместить в облако крипто-диск. В предыдущей статье мы писали, почему это не всегда удобно.

Дельта синхронизация без облака

Ранее мы показывали разные способы синхронизации криптодиска между ПК и Android-устройством.

Каждому сервису - крейсерный ход. Руководство по оптимизации работы сетевых сервисов


Колисниченко Денис (dhsilabs@mail.ru)

Сегодня мы поговорим об оптимизации различных сетевых сервисов - Apache, SSH, ProFTPD. Практически каждый сетевой сервис имеет директивы управления производительностью. Значения по умолчанию рассчитаны на всех - и на домашний компьютер, на котором тот или иной сервис используется только эксперимента ради, и на сервер большого предприятия, доступ к которому получают сотни пользователей одновременно. Ясно, что данные значения не могут быть оптимальными именно для твоего случая. В этой статье мы поговорим, как "выжать" максимальную производительность из вышеуказанных сетевых сервисов.

Оптимизация FTP

Самыми популярными FTP-серверами на наших (да и не только на наших) просторах являются wu-ftpd и ProFTPD, как бы их не ругали за… не будем об этом, сейчас речь идет не о защите, а об оптимизации, поэтому не буду увлекаться. Сервер ProFTPD более современный, чем wu-ftpd, поэтому сегодня поговорим именно о нем (не забывай, нам еще много чего настроить нужно будет, поэтому оба сервера рассмотреть невозможно). Открой файл конфигурации ProFTPD - /etc/proftpd.conf. Первое, что бросается в глаза - это директива ServerType. Она может принимать значения standalone или inetd. По умолчанию используется первое значение, означающее, что сервер будет работать автономно, а не через xinetd. Если кто-то изменил значения на inetd, то установи standalone. В автономном режиме производительность FTP-сервера выше, поскольку он постоянно загружен в память и ждет запроса. В режиме inetd FTP-сервер вызывается суперсервером xinetd по мере поступления запроса. Ясно, что во втором случае для обработки запроса нужно больше времени.

Не кажется ли тебе, что авторизация на сервере занимает много времени? Этот процесс можно существенно ускорить, отключив директивы IdentLookup и UseReverseDNS:

IdentLookups off
UseReverseDNS off 

Первая директива подразумевает использование протокола ident для идентификации клиента. Поскольку данный протокол все равно уже не используется, IdentLookups можно выключить с чистой совестью.

Вторая директива UseReverseDNS позволяет определить доменное имя клиента по его IP-адресу. Поскольку разрешение имени занимает время, то лучше его отключить - так авторизация на сервере будет намного быстрее.

Теперь наш FTP-сервер будет быстрее запускаться и "принимать" пользователей, но мы пока ничем не ускорили его работу. Сейчас мы этим и займемся. Особого внимания заслуживают следующие директивы:

  1. MaxClients число[сообщение] - задает максимальное число одновременно работающих клиентов. Сколько клиентов может одновременно выдержать твой сервер, зависит не только от самого сервера, но и от "ширины" канала (пропускной способности). Чем "шире" канал, тем с большим числом клиентов может справиться сервер.
  2. MaxClientsPerHost число[сообщение] - максимальное число клиентов от одного узла, если ограничение будет превышено, пользователь увидит сообщение, заданное необязательным параметром [сообщение]. На одном компьютере можно запустить несколько FTP-клиентов и каждый FTP-клиент может соединиться с нашим сервером. Вполне может быть, что Вася Пупкин поназапускает столько клиентов, что их количество превысит максимально допустимое число клиентов и другие пользователи не смогут подключиться к серверу. Первое, что приходит в голову, установить значение 1. С одной стороны хорошо, с другой нет. Существуют организации, у которых только один реальный IP, и все пользователи внутренней сети используют этот IP-адрес при работе в Интернете. Представь, что одновременно на ваш сервер захотят зайти два пользователя этой внутренней сети. Если установить значение 1, то работать сможет только 1 пользователь. Поэтому правильнее для ограничения числа клиентов использовать следующую директиву. Но также не нужно думать, что все пользователи какой-то сети одновременно будут работать с твои сервером (если, конечно, ты не знаешь обратного). Это я о том, что большое значение тоже устанавливать не нужно. Лучше всего разреши доступ трем клиентам от одного узла.
  3. MaxClientsPerUser число[сообщение] - максимальное число клиентов от одного пользователя. Вася Пупкин знает только свой пароль, поэтому все клиенты будут регистрироваться под логином Васи Пупкина. Вот здесь можно указать значение 1.
  4. MaxConnectionRate соединений/секунду - позволяет указать количество соединений в секунду. Данный параметр очень сильно зависит от ширины канала, поэтому конкретное значение порекомендовать не могу. Если установить значение 1, то за одну секунду с сервером можно будет установить только 1 соединение.
  5. MaxHostsPerUser число[сообщение] - максимальное количество узлов на одного пользователя. Предположим, что Вася Пупки хочет нас обхитрить. Он раздал свой пароль всем своим знакомым, и теперь они хотят зайти под логином Васи с разных компьютеров. Мы этого не позволим сделать, поскольку установим значение 1 для этого параметра.
  6. MaxInstances число - максимальное число одновременно запускаемых процессов в режиме standalone. Во избежание DoS-атаки, рекомендую установить этот параметр. Его значение опять-таки зависит от ширины канала и возможностей сервера. На своем сервере я установил MaxInstances 30.
  7. MaxLoginAttempts число - сколько раз пользователь может ввести пароль. После последней попытки сервер разорвет соединение. Рекомендуемое значение - 3.
  8. MaxRetrieveFileSize - максимальный размер получаемого файла. Можно не устанавливать, потому как файлы, загружаемые на сервер тобою, будешь контролировать ты сам, а файлы, который загружают пользователи - с помощью следующей директивы. Если никто не "зальет" на сервер файл размером, скажем, в 1 Гб, следовательно, никто не сможет и скачать этот файл.
  9. MaxStoreFileSize - максимальный размер файла, загружаемого на сервер пользователями. Тут все зависит от "ширины" канала и места на диске, даже больше от второго, нежели от первого. Решай сам.

Если у сервера "узкий" канал, можно попробовать несколько улучшить ситуацию с помощью следующих директив:

  1. RateReadBPS байт-в-секунду - задает максимальную скорость чтения информации с сервера в BPS (область действия - сервер, VirtualHost, Global, Anonymous, Directory)
  2. RateReadFreeBytes байт - указанное количество байтов не будет учитываться (область действия - сервер, VirtualHost, Global, Anonymous, Directory)
  3. RateReadHardBPS off | on - ждать ли после исчерпания первых бесплатных байт пока средняя скорость не опустится до RateReadBPS
  4. RateWriteBPS байт-в-секунду - скорость записи информации на сервер в BPS (область действия - сервер, VirtualHost, Global, Anonymous, Directory)
  5. RateWriteFreeBytes байт - то же, что и RateReadFreeBytes, но для записи
  6. RateWriteHardBPS off | on - то же, что и RateReadHardBPS, но для записи
  7. TransferRate - заменяет старые директивы Rate* и позволяет задать максимальную скорость передачи данных (чтения/записи). Использовать директивы Rate* иногда даже предпочтительнее, поскольку можно указать отдельно скорость чтения и скорость записи, что бывает полезно, если сервер подключен по асинхронному каналу.

Также немного времени можно выиграть, если из строки формата протокола удалить модификатор %h (строка протоколирования задается директивой LogFormat). Это имя узла клиента, но как мы знаем для разрешения имени нужно сделать DNS-запрос, а на это нужно время.

Правильно установив вышеуказанные параметры, можно добиться существенного прироста в производительности сервера.

Оптимизация Apache

Оптимизация Apache осуществляется с помощью директив файла конфигурации. Открой файл конфигурации своего Apache (надеюсь, ты знаешь, где он "лежит"? У меня - в /etc/httpd/conf).

В чем же заключается оптимизация? Как и у сервера ProFTPD, у Apache есть директива MacClients, определяющая максимальное количество клиентов, которые могут работать с сервером одновременно. Это не просто число клиентов, это еще и число апачей, одновременно запущенных на твоем сервере (то есть одному соединению соответствует своя копия Апача). Представь, что ты установил значение 30, а зайти на твой сайт (одновременно имеется в виду) хочется, скажем, сразу 35 пользователям. Выходит, 5 пользователей будет "за бортом". С другой стороны, если ты установишь значение с большим запасом, скажем, 150 или даже 200, а на твой сайт одновременно заходят только 5-10 человек, то это будет расточительством системных ресурсов. Зачем тебе 190 "лишних" Апачей? Да, они ничего не делают, но все равно занимают системные ресурсы (процессорное время, оперативную память). Поэтому нужно определить максимальное число пользователей, которое когда-либо было на твоем сервере одновременно. Это можно сделать с помощью того же WebAlizyer или форума PHPBB (или аналогичного), если такой установлен на твоем сервере. Например, на мой форум по до сих пор неведомой мне причине 28 марта одновременно зашло 25 человек. Больше такая ситуация не повторялась. Следовательно, можно установить в качестве значения MaxClients это значение или же это значение с небольшим запасом, скажем, 30 или 35. Ясно, что определенное время нужно поработать с заведомо большим значением директивы MacClients, скажем 100 или 150. Потом нужно смотреть по ситуации - если установленное значение "зашкаливает", то есть ты установил 100 и у тебя несколько дней подряд показывает, что на сайте одновременно было 100 пользователей, то нужно увеличить MaxClients, потому что вероятно, что некоторые пользователи на сайт не попали. Если же MaxClients не было превышено, то его нужно подкорректировать, округлив в большую сторону. Скажем, если у тебя было максимум 42 посетителя, то установи значение 50, если 98, то 100.

Но кроме MaxClients есть еще и другие директивы управления производительностью. Например, StartServers, MaxSpareServers, MinSpareServers. Как уже отмечалось выше, для каждого нового соединения создается новая копия процесса сервера. Директива StartServers задает количество копий, которые будут созданы при запуске исходной копии сервера. При этом исходная копия сервера получает запросы и передает их свободным копиям. Это позволяет равномерно распределить нагрузку между отдельными процессами и повысить производительность сервера, однако на практике все не так хорошо, как хотелось бы. Существенного прироста производительности можно добиться только в случае большой загрузки сервера. По умолчанию запускает пять копий сервера.

Если число поступающих запросов превышает количество запущенных копий сервера, запускаются дополнительные процессы-серверы. Эти процессы не завершаются после обработки своего запроса, а продолжают находиться в памяти. Директива MaxSpareServers позволяет указать максимальное число таких процессов. Если это количество превышено, то лишние процессы завершаются. Если количество «серверов на подхвате» меньше, чем задано директивой MinSpareServers, запускаются дополнительные копии. Для работы этих директив необходимо, чтобы сервер был запущен в автономном режиме.

Директива Timeout задает промежуток времени в секундах, в течение которого сервер продолжает попытки возобновления приостановленной передачи данных. Значение директивы Timeout распространяется не только на передачу, но и на прием данных. Если нужно передавать большие файлы, нужно увеличить данное значение. Но если у тебя самый обычный Web-сервер, на котором не лежат ISO-образы последних дистров, много фильмов и прочих "тяжеловесных" файлов, можно уменьшить значение таймаута до 30 секунд (по умолчанию оно равно 300 секунд). Для чего? Смотри, пользователь подключился к Интернету по модему, он создал соединение с твоим сервером и запросил какой-то файл (скажем index.html), но модем он и в Африке модем - соединение было оборвано, а твой Апач будет ждать целых 300 секунд, пока не "поймет", что клиента давно уже нет "на той стороне". Если уменьшить значение таймаута до 30 секунд, то Апач намного быстрее "одумается".

Немного повысить производительность могут KeepAlive-соединения - так называемые постоянные соединения. Схема обычного соединения: подключились, отправили запрос, получили ответ, отключились. А вот в случае с постоянными соединениями за одно соединение можно отправить несколько запросов и получить ответы. Поскольку процедура подключения/отключения для каждого запроса отсутствует, это позволяет повысить производительность. Включить постоянные соединения можно с помощью директивы KeepAlive, а с помощью KeepAliveTimeout установить таймаут для постоянного соединения. Таймаут для постоянного соединения рекомендуется установить в размере 10-20 секунд.

Чтобы твой Апач заработал еще быстрее, отключи директиву HostnameLookups. Сервер Apache ведет журнал доступа других компьютеров. Если включть данную опцию (on), то в журнал будет записано доменное имя компьютера-клиента. Если эта опция выключена (off), в журнал будет записан IP-адрес клиента. Включение данной опции замедляет работу сервера, так как требуется дополнительное время на ожидание ответа от сервера DNS.

Заставляем Самбу работать быстрее

У Самбы есть файл конфигурации smb.conf. Если его открыть, ты найдешь там параметр wide links. Так вот, если ты установишь его в no, то это будет большой ошибкой с твоей стороны. Если этот параметр установлен в no, то Самба не будет следовать по символическим ссылкам вне экспортируемой области. Чтобы определить, где находится ссылка - в области или вне области, Самба сначала следует по символической ссылки, а затем выполняет так называемый directory path lookup для определения, где завершилась ссылка. Данная операция занимает 6 лишних системных вызовов на каждый файловый lookup, а таких lookup'ов Самба делает очень много. Тесты показывают, что выключение wide links снижает производительность Самбы приблизительно на 30%.

Протокол TCP/IP штука тонкая. Производительность сетевых приложений во многом зависит от того, правильно ли настроен TCP/IP. Samba - настоящее сетевое приложение, которое к тому же работает по протоколу TCP/IP. При использовании TCP/IP, если размер запросов и ответов не фиксирован (как в случае с Samba), рекомендуется применять протокол TCP с опцией TCP_NODELAY. Проверим эту опцию на Samb'е. В файл smb.conf добавь строку:

socket options = TCP_NODELAY

Тесты показывают, что Samba при больших нагрузках работает в 3 раза быстрее, чем без указания этих опций. Если Samba используется в локальной сети (в большинстве случаев так оно и есть) рекомендуется еще указать опцию IPTOS_LOWDELAY:

socket options = IPTOS_LOWDELAY TCP_NODELAY

Хочешь выжать из Samba еще больше? Тогда установи следующие параметры буферизации: SO_RCVBUF=8192 SO_SNDBUF=8192, например:

socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192

Десятикратное ускорение SSH

На страничке https://www.psc.edu/networking/projects/hpn-ssh/ можно скачать патчи (проект HPN-SSH), ускоряющие копирование по SCP в 10 раз! Конечно, патчи применяются к исходниках OpenSSH, которые можно скачать на страничке https://www.openssh.com/portable.html. Но перед тем как устанавливать HPN-SSH, тебе нужно произвести небольшой тюнинг твоего стека TCP/IP. Об этом подробно говориться на страничке https://www.psc.edu/networking/projects/tcptune/

Прибавка производительности достигается за счет изменения размера буферов SSH или за счет отключения шифрования при передаче файлов. Также есть патч, позволяющий вообще отключить шифрование при передаче файла. Ясно, что с точки зрения безопасности это нецелесообразно - зачем тогда вообще использовать SSH? Проще перейти на telnet. Хотя в некоторых случаях его использовать все же можно.

Заставить работать SCP быстрее очень просто: скачиваем и распаковываем исходники, скачиваем патч, применяем его (см. man patch). После этого нужно перекомпилировать OpenSSH. Разумеется, если OpenSSH установлена из RPM, то до всего этого нужно удалить соответствующий RPM-пакет. Причем применить патчи и перекомпилировать OpenSSH нужно как на сервере, так и на клиенте, иначе толку не будет.

На страничке проекта HPN-SSH можно найти несколько патчей. Для большинства пользователей подойдет патч HPN-11, который является точкой оптимума между производительностью и безопасностью. При скачивания патча обрати внимание на его версию - она зависит от версии твоего OpenSSH. Для того, чтобы задействовать патч уже после перекомпиляции OpenSSH, укажи в командной строке параметр -R для scp (или -r для ssh).

Патч HPN-11 with None Cipher вообще отключает шифрование при передаче файлов. Шифруются только имя пользователя и пароль, которые передаются по сети. После успешной аутентификации шифрование отключается вообще, и файлы передаются по сети как есть, то есть в незашифрованном виде. Это довольно опасно, но если передается объемная и не конфиденциальная информация (например, музыка или видео), то этот патч все-таки оправдывает себя. После применения патча активировать его можно с помощью опции -z командной строки (как для ssh, так и для scp). Подробнее об отмене шифрования можно прочитать здесь: https://www.psc.edu/networking/projects/hpn-ssh/none.php

Надеюсь, данная статья поможет тебе оптимизировать сетевые сервисы. Если у тебя есть вопросы, ты можешь задать их на форуме https://dkws.org.ua.