Что такое демон в программировании
Перейти к содержимому

Что такое демон в программировании

  • автор:

Процесс разработки и тестирования демонов

Сегодня мы поговорим о «низкоуровневых» кирпичиках нашего проекта — о демонах.

Хоть это и не очевидно, но практически весь функционал сайта во многом зависит от работы этих программ. Игра в “Знакомства”, поиск новых лиц, центр внимания, обмен сообщениями, статусы, геолокация и многие другие вещи завязаны на тот или иной демон. Так что можно сказать, что они помогают людям по всему миру общаться и находить новые знакомства. Одновременно на сайте могут работать и взаимодействовать между собой несколько десятков демонов. Их корректное поведение является очень важной задачей, поэтому мы решили покрывать основной функционал демонов автотестами.

В Badoo этим занимается специальный отдел. И сегодня мы расскажем о том, как у нас проходит процесс разработки этой критически важной части сайта и выполнение автотестов. Эта область достаточно специфичная и материала много, поэтому мы подготовили структурированный обзор всего процесса, чтобы разобраться в нем смогли все, кому интересно.

В качестве VCS у нас используется Git, для непрерывной интеграции — TeamCity, а в роли баг-трекера выступает JIRA. Для тестирования мы используем PHPUnit. Разработка демонов, как и остального сайта, ведется по принципу «фича ― ветка». Для того чтобы понять, что это, мы рассмотрим проекции нашего flow на Git и на JIRA.

Git flow

Работу в Git схематично можно описать картинкой:

Для работы над задачей от master-ветки форкают отдельную ветку task_n, в которой ведется вся разработка. Затем эта ветка и, возможно, несколько других сливаются в так называемый branch build_n.n.n (или просто билд), и только он уже попадает в master.

JIRA flow

Процесс в JIRA сложнее и включает в себя больше этапов. На рисунке ниже изображены основные из них.

Open -> In progress
Статус Open говорит о том, что задача есть, но к ней еще не приступили. Когда программист начинает работать и отправляет первые изменения на наш git-сервер (там появится ветка, содержащая в имени task_n, идентификатор в JIRA), происходит несколько событий. Во-первых, статус задачи становится In progress, а во-вторых, наша TeamCity создает отдельную сборку для этой ветки, которая запускается каждый раз при новом «пуше» разработчика. Благодаря стараниям релиз-инженеров и разработчиков, артефакты из сборки скопируются на машины нашей среды разработки, после этого запустятся все регрессионные тесты, а результат прогона отобразится в веб-интерфейсе TeamCity. Когда разработчик посчитает, что он закончил работу над задачей, он переводит тикет с ней в статус On Review.

On Review
Здесь задача проходит доскональное изучение со стороны коллеги. Если его взгляд не нашел к чему придраться, тикет переводится в статус In Branch QA.

In Branch QA
На этом этапе задача попадает к тестировщику. Он первым делом смотрит на результат прогона регрессионных тестов — вдруг какие-то из них теперь не проходят. В этом случае есть два варианта: либо все нормально, это результат нового поведения и надо актуализировать регрессионные тесты, либо демон работает не так, как ожидается, тогда задача возвращается к разработчику. Если необходима доработка тестов, QA-инженер берется за дело вплотную. Он покрывает новое поведение демона тестами, попутно исправляя старые, если это необходимо.

To Merge -> In Build
Когда разработчик и тестировщик считают, что сборка из ветки task_n работает стабильно и ожидаемо, в JIRA нажимается кнопка To Merge. В этот момент TeamCity «мержит» ветку разработчика в ветку build_n.n.n и запускает его сборку. Задача снова попадает к тестировщику, но уже со статусом In Build.

Дело в том, что при мерже могут возникнуть неожиданные конфликты: пока ветка была на тестировании, в билдовую могли добавиться несовместимые изменения. При возникновении такой ситуации задача переводится на программиста для ручного мержа в билд. Другой проблемой могут быть падающие регрессионные тесты или, в самом плохом случае, невозможность запустить демон. Это решается откатом задачи из билдовой ветки с возвращением тикета разработчику. Но если нужны незначительные изменения для решения проблемы, то задача остается и появляется патч в самом билде.
Когда тесты проходят, а демон стабилен, QA-инженер присваивает задаче статус In Build OK и она возвращается к разработчику. Билд демона с измененным поведением становится основным в среде разработки devel и проходит испытание боем.

In Build OK -> On Production
В какой-то момент в билдовой ветке накапливается много нужных изменений или появляются критически важные задачи, и разработчик решает, что пора двигать билд на продакшн. Нажимается кнопка Finish Build, и новая версия демона, благодаря нашим доблестным админам, начинает работать на машинах, отвечающих за настоящую работу нашего сайта. В это время билд мержится в master-ветку и создается новый билд с именем build_m.m.m, в который будут попадать все новые изменения. Ну, а тикету программиста поставят статус On Production.

Объединив две проекции всего процесса разработки, получим цикл, показанный ниже.

Подробнее о наших процессах разработки и плотной интеграции JIRA, TeamCity и Git можно прочитать в наших статьях тут, тут и тут.

Выполнение автотестов

Объект тестирования
Для начала давайте определимся с тем, что именно мы тестируем.
В нашем случае программа в общем виде представляет из себя некий бинарный файл, запускающийся из терминала. В качестве аргументов ему могут быть переданы различные параметры, влияющие на его работу: конфигурационные файлы («конфиги»), порты, лог-файлы, папки со скриптами и т.д. Чаще всего это как минимум конфиг, и строка запуска в этом случае будет выглядеть так:

После запуска демон ожидает подключения на нескольких портах (сокет-файлах), по которым происходит общение с внешним миром. Формат может быть разным, начиная от текста или JSON’а и заканчивая protobuf’ом. Обычно поддерживается сразу пара из них. Также у некоторых демонов есть возможность сохранять свои данные на диск, а потом загружать их при запуске. Для разработки в основном используется C и C++, но с недавних пор добавились Golang и Lua.

В общем виде выполнение автотестов можно разбить на несколько этапов:

  1. Подготовка тестового окружения.
  2. Запуск и исполнение тестов.
  3. Чистка тестового окружения.

Подготовка тестового окружения
После запуска тестов сначала исполняется та часть кода, которая определена в конструкторах setUpBeforeClass и setUp. Как раз на данном этапе и подготавливается окружение: сначала читаются параметры запуска, о которых мы расскажем отдельно, потом выбирается нужная версия бинарного файла, создаются временные папки, конфиги и различные файлы, которые могут понадобиться для работы, а также подготавливаются БД, если они нужны. Все создаваемые объекты содержат уникальный идентификатор в имени, который выбирается один раз в конструкторе и дальше используется повсеместно. Это позволяет избежать конфликта при одновременном запуске тестов у нескольких разработчиков и тестировщиков.

Часто бывает так, что демон во время работы общается с другими демонами — он может принимать или отдавать данные, получать или посылать команды от своих сородичей. В этом случае мы используем тестовые заглушки («моки») или запускаем реальных демонов. Когда все необходимое создано, запускается экземпляр демона с нашим конфигом и работающий в нашем окружением.

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

Запуск и исполнение
Большинство тестов можно описать алгоритмом:

В качестве send request может выступать один или несколько запросов, приводящих к какому-то определенному состоянию. Действия внутри get response — получение ответа, чтение записей в БД, чтение файла. Под assert же подразумевается большой спектр действий: это и валидация ответа, и оценка состояния демона, и проверка данных, пришедших в соседние демоны, и сравнение записей в БД, и даже проверка создания снапшотов с правильными данными.

Но вышеупомянутым алгоритмом наши тесты не ограничиваются — мы стараемся по возможности охватить различные стороны жизни нашего подопытного. Поэтому с ним могут происходить случайный неприятности: он может несколько раз перезапускаться, данные в запросах могут быть обрезанными или содержать некорректную информацию, в конфиг могут попасть невалидные настройки, собеседники демона могут не отвечать или загадочным образом исчезать.

На данный момент самой сложной и интересной (на мой взгляд) является область тестирования межпрограммного взаимодействия «демон — демон». В основном это связано с тем, что процесс общения зависит от многих факторов: внутренней логики, внешних запросов, времени, настроек в конфиге и т.д. Совсем весело становится, когда наш объект может общаться с несколькими разными демонами.

Чистка тестового окружения
Как бы не закончились тесты, после себя нужно чистить. В первую очередь мы закрываем коннекты, останавливаем демон и всех связанных с ним моков или соседних демонов. Затем удаляются все созданные во время тестов файлы и папки, если они не нужны, и подчищаются БД.

Проблемным местом здесь является чистка после фатальных ошибок — в некоторых случаях могут оставаться временные файлы (бывает, даже демон продолжает работать).

На весь описанный процесс тестирования накладывается определенная особенность — распределение по разным машинам. Обычным сценарием сейчас является запуск тестов на одном сервере, а старт демона на другом. Ну, или на другом сервере в контейнере docker’а.

Unix2019a/Фоновые процессы (демоны)

Демон (daemon, dæmon, божество) — программа в ОС семейства Unix, запускаемая самой системой и работающая в фоновом режиме без прямого взаимодействия с пользователем.

Демоны обычно запускаются во время загрузки системы. Типичные задачи демонов: серверы сетевых протоколов (HTTP, FTP, электронная почта и др.), управление оборудованием, поддержка очередей печати, управление выполнением заданий по расписанию и т.д. В техническом смысле демоном считается процесс, который не имеет управляющего терминала. Чаще всего (но не обязательно) предком демона является init — корневой процесс UNIX.

В системах Windows аналогичный класс программ называется службой (Services).

Название «демон» появилось ещё до Unix, в 1960-x годах в системе Project MAC. Названо в честь демона Максвелла из физики, занимающегося сортировкой молекул в фоновом режиме. Демон также является персонажем греческой мифологии, выполняющим задачи, за которые не хотят браться боги.

https://amdy.su/wp-admin/options-general.php?page=ad-inserter.php#tab-8

Типичным демоном является cron, использующийся для периодического выполнения заданий в определённое время. Регулярные действия описываются инструкциями, помещенными в файлы crontab и в специальные каталоги.

Процесс init

init (сокращение от initialization) — система инициализации в Unix-подобных системах, которая запускает все остальные процессы.

  • Первый пользовательский процесс, работает как демон и обычно имеет PID 1.
  • Запускается непосредственно ядром системы.
  • Является пра-родителем всех пользовательских (userspace) процессов системы.
  • Согласно Filesystem Hierarchy Standard, располагается по пути /sbin/init.

runlevels

Уровень выполнения (runlevel) — степень загрузки операционной системы. Вот как происходит инициализация системы: процесс init запускается и анализирует файл /etc/inittab. Следует отметить, что в BSD-подобных системах схема несколько отличается.

Пример файла /etc/inittab:

По умолчанию в системе использовано 7 уровней инициализации:

  • 0 — остановка системы
  • 1 — загрузка в однопользовательском режиме
  • 2 — загрузка в многопользовательском режиме без поддержки сети
  • 3 — загрузка в многопользовательском режиме с поддержкой сети
  • 4 — не используется
  • 5 — загрузка в многопользовательском режиме с поддержкой сети и графического входа в систему
  • 6 — перезагрузка

Вы можете подумать, речь идёт о каких-то уровнях, через которые система проходит в процессе загрузки. Это не так. Представляйте себе уровень запуска как некую точку, в которую переходит система, загружаясь.

В большинстве Unix/Linux систем, узнать текущий уровень инициализации можно командами:

$ runlevel $ who -r

Набрав init n в терминале (с правами суперпользователя), где n — номер уровня инициализации, можно переключиться в любой из вышеперечисленных уровней.

Стартовые скрипты для каждого уровня находятся в каталогах с /etc/rc0.d до /etc/rc6.d, где цифра после rc соответствует номеру уровня инициализации.

Обычно скрипты не дублируются для каждого уровня. В каталогах rcX просто ставятся симлинки на скрипты в /etc/init.d.

Сами скрипты в /etc/init.d обычно пишутся по шаблону и должны уметь принимать параметр start|stop|restart.

В именовании используется такая логика.

  • S — скрипты для запуска (start)
  • K — скрипты для остановки (stop)
  • Номер задаёт порядок выполнения: чем меньше номер, тем раньше запускается скрипт.

Для автоматизации создания этих линков с правильными именами есть специальные утилиты. Например, в RedHat и Fedora используется программа chkconfig, в Debian — update-rc.d.

Есть также специальный скрипт /etc/rc.local, который выполняется во всех многопользовательских уровнях.

Современные альтернативы init

Сейчас существует множество систем, призванных заменить собой классический init.

Главный недостаток традиционного init — он запускал процессы последовательно, ожидая завершения предыдущего перед запуском следующего. Поэтому были разработаны альтернативные решения:

Что такое демон в программировании

Peer-to-peer (P2P) is a decentralized communications model in which each party has the same capabilities and either party can .

CAPWAP (Control and Provisioning of Wireless Access Points) is a protocol that enables an access controller to manage a .

Network performance monitoring (NPM) is the process of measuring and monitoring the quality of service of a network.

PCI compliance is adherence to the set of policies and procedures developed to protect credit, debit and cash card transactions .

The Payment Card Industry Data Security Standard (PCI DSS) is a widely accepted set of policies and procedures intended to .

In computing, a logon is a procedure that enables an entity to access a secure system such as an operating system, application, .

A ledger database is somewhat modern and commonly refers to a type of database that uses cryptographic techniques, including .

A SIPOC (suppliers, inputs, process, outputs, customers) diagram is a visual tool for documenting a business process from .

Public data is information that can be shared, used, reused and redistributed without restriction.

The employee Net Promoter Score (eNPS) is a metric used by employers to assess employee loyalty.

A talent pipeline is a pool of candidates who are ready to fill a position.

Recruitment process outsourcing (RPO) is when an employer turns the responsibility of finding potential job candidates over to a .

RFx (request for x) encompasses the entire formal request process and can include request for bid (RFB), request for information .

Customer engagement is the way a company creates a relationship with its customer base to foster brand loyalty and awareness.

Phygital (physical plus digital) is a marketing term that describes blending digital experiences with physical ones. As customer .

Что такое демоны (daemons) в Linux?

В этой статье мы рассмотрим, что такое демоны (и их примеры) в Linux, а также версии происхождения термина «daemon».

Что такое демоны?

Демоны (англ. «daemons») — это работающие в фоновом режиме служебные программы (или процессы), целью которых является мониторинг определенных подсистем ОС и обеспечение её нормальной работы. Например, демон принтера контролирует возможности печати, демон сети контролирует и поддерживает сетевые коммуникации и т.д.

Демоны являются аналогом служб (services) в Windows: они выполняют определенные действия в заранее определенное время или в ответ на определенные события. Существует множество различных демонов, работающих в Linux, каждый из которых создан специально для наблюдения за своей собственной маленькой частью системы. Из-за того, что демоны выполняют основную часть своей работы в фоновом режиме и не находятся под прямым контролем пользователя, бывает трудно определить предназначение того или иного демона.

Так как демон — это процесс, который выполняется в фоновом режиме и обычно находится вне контроля пользователя, то у него нет управляющего терминала.

Процесс — это запущенная программа. В определенный момент времени процесс может либо выполняться, либо ожидать, либо быть «зомби».

В Linux существует три типа процессов:

Процессы переднего плана (или «интерактивные процессы») — это те процессы, которые запускаются пользователем в терминале.

Фоновые процессы (или «автоматические процессы») — это объединенные в список процессы, не подключенные к терминалу; они не ожидают пользовательского ввода данных.

Демоны (англ. «daemons») — это особый тип фоновых процессов, которые запускаются при старте системы и продолжают работать в виде системных служб; они не умирают.

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

Когда завершается загрузка системы, процесс инициализации системы начинает создавать демоны с помощью метода fork(), устраняя необходимость в терминале (именно это подразумевается под «отсутствием управляющего терминала»).

Я не буду вдаваться в подробности работы метода fork(), отмечу лишь, что, хотя существуют и другие методы, традиционный способ создания дочернего процесса в Linux заключается в создании копии существующего процесса (посредством своеобразного «ответвления»), после чего выполняется системный вызов exec() для запуска другой программы.

Примечание: Термин «fork» не был взят с потолка. Он получил свое название от метода fork() из Стандартной библиотеки языка программирования Си. В языке Си данный метод предназначен для создания новых процессов.

Примеры демонов в Linux

Наиболее распространенный способ идентификации демона в Linux — это поиск процесса, имя которого заканчивается буквой d. Есть много способов увидеть работающих демонов. Их можно отследить в списках процессов через такие команды, как: ps , top , htop , а также pstree .

Команда pstree показывает процессы, запущенные в настоящее время в нашей системе, и отображает их в виде древовидной диаграммы. Откройте терминал и введите следующую команду:

Вывод команды pstree — это довольно хорошая иллюстрация того, что происходит с нашей системой. Перед нами появился список всех запущенных процессов, среди которых можно заметить и несколько демонов: cupsd, dbus-daemon, kdekonnectd, packagekitd и некоторые другие.

Вот несколько «популярных» примеров демонов, которые могут работать в вашей системе:

systemd — это системный демон, который (подобно процессу init) является родителем (прямым или косвенным) всех других процессов, и имеет PID=1.

rsyslogd — используется для регистрации системных сообщений. Это более новая версия syslogd, имеющая несколько дополнительных функций.

udisksd — обрабатывает такие операции, как: запрос, монтирование, размонтирование, форматирование или отсоединение устройств хранения данных (жесткие диски, USB-флеш-накопители и пр.).

logind — крошечный демон, который различными способами управляет входами пользователей в систему.

sshd — демон, отвечающий за управление службой SSH. Используется практически на любом сервере, который принимает SSH-соединения.

ftpd — управляет службой FTP. Протокол FTP (сокр. от англ. «File Transfer Protocol») является широко используемым протоколом для передачи файлов между компьютерами, где один компьютер действует как клиент, другой — как сервер.

crond — демон планировщика заданий, зависящих от времени. С его помощью можно выполнять обновление программного обеспечения, проверку системы и пр.

Версии происхождения термина «daemon»

Есть несколько версий происхождения термина «daemon»:

Научная версия: Использование термина «daemon» в вычислительной технике произошло в 1963 году. Project MAC (сокр. от англ. «Project on Mathematics and Computation») — это проект по математике и вычислениям, созданный в Массачусетском технологическом институте. Именно здесь термин «daemon» вошел в обиход для обозначения любого системного процесса, отслеживающего другие задачи и выполняющего предопределенные действия в зависимости от их поведения. Процессы были названы термином «daemons» в честь демона Максвелла.

Примечание: Демон Максвелла — это результат мысленного эксперимента. В 1867 году Джеймс Клерк Максвелл представил себе разумное и изобретательное существо, способное наблюдать и направлять движение отдельных молекул в заданном направлении. Цель мысленного эксперимента состояла в том, чтобы показать возможность противоречия второму закону термодинамики.

Талисман BSD: В операционных системах BSD есть свой талисман — красный чертёнок (этакая игра слов «daemon/demon»). BSD-демона зовут Beastie (Бисти), и его часто можно увидеть с трезубцем, который символизирует системный вызов fork(), активно используемый программами-демонами.

Примечание: «Бисти» по звучанию напоминает BSD (произносится как «Би-Эс-Ди»). При этом beastie является уменьшительной формой от слова beast (зверь).

Теологическая версия: Сторонники данной версии считают, что первоначальной формой произношения слова «daemon» было «daimon», что обозначает (по одной из версий) ангела-хранителя. В то время как «daemon» — помощник, «demon» — злой персонаж из Библии.

Примечание: Также «daemon» иногда произносится как «day-mon» или как рифма к слову «diamond».

Аббревиатура: Некоторые пользователи утверждают, что термин «daemon» является аббревиатурой от «Disk and Execution Monitor».

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *