Быстродействие UNIX сокетов

Сравнение скорости работы unix-сокетов. Выполнялась передача большого объема данных от одного процесса другому через unix-сокет. Изменялся размер данных, передаваемых за один вызов write/read (chunk). С каждым размером производилось пять измерений, результат усреднялся.


На графике черная кривая — производительность unix-сокетов, красная и зеленая — для сравнения копирование памяти memcpy в рамках одного процесса и, соответственно, копирование из разделяемой (shared) памяти. Если рост производительности при увеличении "размера пакета" для сокетов не является чем-то не очевидным, то падение производительности операции memcpy при росте значения третьего аргумента функции не тривиально.

Характеристики тестового стенда. Процессор: Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz, память: DDR3 Kingston HyperX KHX1600C9D3P1K2/8G. Ядро: 3.7.10.

Xen: проброс USB устройств

Xen умеет пробрасывать USB-устройства (по отдельности) в гостевые непривилегированные домены. Для этого используется механизм, называемый PVUSB (подозреваю, что сокращение от Para-Virtualized USB), концептуально состояний из модулей usbbk (Xen USB backend driver) и xen_hcd (Xen USB Virtual Host Controller driver). Соответственно, первый модуль съедает устройство в dom0, делая его недоступным для других драйверов, а все URB отправляет через гипервизор в нужный выбранный домен, где их получает перавиртуальный контроллер. Утверждается, что потеря производительности минимальна.

Вся конструкция управляется несколькими командами. Посмотреть, какие устройства доступны:
# xm usb-list-assignable-devices
4-2          : ID 067b:2303 Prolific Technology Inc. USB-Serial Controller
Создать в домене паравиртуальный USB хост контроллер: xm usb-hc-create Domain UsbVer PortNum, где параметры — название домена, версия USB (поддерживаются 1 и 2) и количество USB-портов. После этого, в гостевом домене с помощью lsusb видно появившийся контроллер. Для удаления есть обратная команда xm usb-hc-destroy

Для присваивания устройства есть команда xm usb-attach Domain HostNum PortNum Device, где параметры — название домена, номер хост контроллера (их можно хоть пачку создать), номер порта на виртуальном контроллере, первая колонка выдачи usb-list-assignable-devices. Обратная команда — xm usb-destroy. При этом, в dom0 устройство пропадет на глазах у изумленного драйвера:
[12129.803899] pl2303 ttyUSB0: pl2303 converter now disconnected from ttyUSB0
[12129.803938] pl2303 4-2:1.0: device disconnected
но появится в гостевом домене:
# lsusb
Bus 001 Device 002: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Важное замечание. Если в гостевом домене ничего не появилось, кроме записей в dmesg:
[12332.892117] usb 1-1: new full-speed USB device number 70 using vusb
[12332.892126] usb 1-1: parent hub has no TT
то скорее всего, устройство не поддерживает USB 2.0, к которому его прицепили, нужно сделать другой контроллер с правильным параметром UsbVer.

Кроме того, устройство можно прибить гвоздями в конфигурационном файле домена:
vusb=['usbver=1, numports=4, port_1=4-2']
Список литературы:

Elixir

Больше маргинальных языков в openSUSE. Elixir — основываясь на Erlang, является еще более маргинальным языком.

Брать здесь — http://software.opensuse.org/package/elixir.

gen_bunny для RabbitMQ 3.0


Немного подправил gen_bunny для новых версий клиентской библиотеки amqp_client. Поменялся только вызов amqp_connection:start/1 и связанные с ним записи. Брать здесь: https://github.com/matwey/gen_bunny/tree/amqp_client-3.0.4, пока больше ничего не отваливается, если отвалится — поправлю еще.

Настройка сети в Xen

Сеть в Xen работает по принципу виртуального моста, как рассказывается здесь: http://wiki.xen.org/wiki/Xen_Networking.

Сначала, надо сделать этот самый мост. В /etc/sysconfig/network/ifcfg-br0 надо написать буквально следующее:
BOOTPROTO='dhcp4'
# как для простого интерфейса, можно и статический адрес задать 
BRIDGE='yes'
BRIDGE_FORWARDDELAY='0'
BRIDGE_PORTS='eth0 eth1'
BRIDGE_STP='on'
# если два активных физических интерфейса в мост собраны,
# то пакеты могут и по кругу пойти без Spanning Tree Protocol.
STARTMODE='auto'
ifcfg-eth0 и ifcfg-eth1 лучше просто удалить, чтобы не мешались.

Теперь у нас есть самый настоящий мост, который можно вписывать в параметры конфигураций доменов: http://xenbits.xen.org/docs/4.2-testing/misc/xl-network-configuration.html.

Дальше запускаем домены, и проверяем, что появились их бэкендные интерфейсы:
# brctl show br0
bridge name     bridge id               STP enabled     interfaces
br0             8000.52540035c714       yes             eth0
                                                        eth1
                                                        vif1.0

Дальше настраиваем внутренний интерфейс домена, как это происходит обычно.

Диагностика ядра Linux

Сбои в ядре Linux приводят к возникновению чрезвычайно разнообразных симптомов. Некоторые авторы дают следующую неполную классификацию проблем, с которыми может столкнуться пользователь:
  • kernel oops — проблема при выполнении кода в ядре, например кто-нибудь попытался разыменовать нулевой указатель. С кем из программистов на C такого не случалось?
  • kernel panic — кто-то попытался разыменовать нулевой указатель в обработчике прерываний. После чего ядро уходит в полную несознанку и начинает мигать caps-lock-ом.
  • soft lockup ­— что-то заблокировалось (вероятно наткнувшись на не освобожденную блокировку), несмотря на это прерывания продолжают обрабатываться. Хорошее упражнение — попинговать машину или попытаться зажечь numlock.
  • hard lockup — компьютер жужжит вентиляторами и ни на что не реагирует. Провести какую-то диагностику в этом случае особенно сложно. Проблема может быть вызвана как вышедшим из строя железом, так и неаккуратной обработкой прерываний.
кроме того, можно добавить:
  • hung — индуцированное неправильной блокировкой последовательное попадание всех или большинства процессов системы в состояние TASK_UNINTERRUPTIBLE (известного так-же как D-состояние, по обозначению в top или ps). Согласно книге Р.Лава такой «наводящий ужас» процесс нельзя убить, завершить, и вообще что-то с ним сделать. При этом с точки зрения пространства пользователя программа просто заблокирована на каком-то системном вызове (например ввода-вывода). При попадании в подобное состояние всех критических процессов системы можно получить симптом похожий на soft lockup.
Получить как можно более подробную информацию о сути возникающей проблемы важно как для правильного написания сообщения об ошибке, так и для временного переконфигурирования системы с целью избегания выполнения проблемного кода и повышения её живучести.

К счастью, ядро обладает неким набором средств первичной самодиагностики, пригодным для постановки примерного диагноза. Согласно, видимо всеобщей, философской парадигме, наиболее устойчивыми и надежными являются наиболее простые подсистемы, поэтому сообщения ядра имеет смысл искать в текстовой и последовательной консолях. Конечно, при достаточном уровне везения нужное сообщение будет сброшено syslog-демону, записано на диск, отправлено по сети на удаленный syslog-демон и прочее, но при недостаточном везении монитор (и фотоаппарат на телефоне), клавиатура и COM-порт являются последней надеждой.

printk


Одним из механизмов общения ядра с внешним миром является printk. При неправильной настройке сообщение скорее всего будет просто потеряно как не обладающее значимостью. Для настройки используется /proc/sys/kernel/printk, соответствующий ему параметр sysctl, утилита klogconsole, SysRq-клавиша и т.п. Ядро обладает восемью уровнями важности сообщений, поэтому установка уровня в 8 заведомо напечатает все на консоль.

sysrq


Магическая кнопка включается в /proc/sys/kernel/sysrq или соответствующим ему параметром sysctl. Предлагается просто записать туда 1, несмотря на то, что новые ядра позволяют изысканный контроль над функционалом. В данной ситуации незачем себя ограничивать, хотя для нормальной работы разумно ограничить функционал на случай случайных нажатий. Если осталась рабочая терминальная сессия (например удаленная сессия по ssh), можно использовать как альтернативу, например, echo b > /proc/sysrq-trigger; с последовательной консоли поведение активируется кнопкой 'break'.

Важно помнить, что SysRq-w, например, выдает сообщение с уровнем KERN_INFO, то есть выдача printk должна быть настроена правильно, чтобы можно было что-то увидеть. Полный список команд SysRq.

softlockup_panic


Параметр ядра softlockup_panic или параметр kernel.softlockup_panic для sysctl включают панику ядра при обнаружении soft lockup. Описание внутреннего устройства. Включение паники позволит остановить выполнение системы и проанализировать выдачу, снабженную трассировкой, хотя контроль блокировки исполняется постоянно. Существует аналогичный механизм отслеживания hard lockup для многопроцессорных систем (если остались живые процессоры — есть шанс что сработает), с соответствующим параметром hardlockup_panic. Время срабатывания обычно в пределах одной минуты.

hung_task_timeout_sec


Механизм отслеживания процессов, надолго застрявших в состоянии TASK_UNINTERRUPTIBLE, параметры настраиваются через sysctl и /proc:
  • kernel.hung_task_panic — включает/отключает панику при обнаружении не прерываемого процесса;
  • kernel.hung_task_warnings — счетчик сообщений. Иными словами, если паника отключена, будет сообщено о таком количестве зависших процессов;
  • kernel.hung_task_timeout_secs — сколько секунд процесс должен непрерывно пробыть в TASK_UNINTERRUPTIBLE, чтобы вызвать сообщение. По умолчанию бывает либо выключено (0), либо очень большое число порядка 10 минут.
Сообщения снабжаются трассировкой, которая подсказывает в какой подсистеме происходит сбой.

FastCGI в Lighttpd и Nginx

Сравнение настроек, приводящих к одинаковому результату в Lighttpd и Nginx.

Настройки Lighttpd:
url.rewrite-once += ( "^/testfc$" => "/testfc/", )

fastcgi.server += ( 
        "/testfc" => ((
                        "bin-path" => "/path/to/fcgi/server.py",
                        "socket" => socket_dir + "/viewvc.sock",
                        "max-procs" => 1,
                        "check-local" => "disable",
                        "fix-root-scriptname" => "enable",
        ))
)

Настройки Nginx:
location /testfc/ {
                fastcgi_pass unix:/path/to/fcgi/sock;
                fastcgi_split_path_info ^(/testfc)(.*)$;
                fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param  PATH_INFO $fastcgi_path_info;
                fastcgi_param  PATH_TRANSLATED $document_root$fastcgi_path_info;
                include        fastcgi_params;
        }

Nginx сам запускать приложения не умеет, поэтому об этом нужно заботиться заранее. Например можно использовать изысканное решение с помощью systemd.