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

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

  • автор:

Понимаем сленг программистов: мини-словарь для начинающих разработчиков

Понимаем сленг программистов: мини-словарь для начинающих разработчиков главное изображение

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

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

Бесплатные курсы по программированию в Хекслете

  • Освойте азы современных языков программирования
  • Изучите работу с Git и командной строкой
  • Выберите себе профессию или улучшите навыки

А

Адаптив — адаптивный дизайн, адаптация интерфейса к использованию на разных экранах.

Аджайл — от англ. Agile. Общий термин, который описывает ценности и принципы гибкой разработки программного обеспечения, а также практические подходы к разработке. Понятие Agile стало популярным после публикации Манифеста гибкой разработки программного обеспечения в 2001 году.

Айдишник — id, идентификатор.

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

Апишка — API, программный интерфейс приложения или интерфейс прикладного программирования.

Апрув, апрувнуть — от англ. Approve. Одобрение, одобрить, утвердить.

Аутсорс — аутсорсинг, передача компанией части операционной деятельности другой компании.

Б

Баг — от англ. Bug — жучок, клоп. Ошибка в программе.

Бахнуть — что-то быстро сделать, изменить или дополнить функциональность приложения.

Бета — бета-версия, приложение на стадии публичного тестирования.

Бот — сокращение от «робот». Ботом называют программу, которая автоматизирует интерфейс. Пример — автоответчик в чате.

Бэкап, бэкапить — резервная копия или процесс создания резервной копии приложения.

Бэкенд — от англ. Back-end. Программно-аппаратная или серверная часть приложения.

Бэклог — от англ. Backlog. Перечень рабочих задач команды разработчиков, упорядоченный по приотритету.

В

Ворнинг — от англ. Warning — предупреждение. Предупреждающее сообщение в интерфейсе.

Войтивайти — шуточное выражение, обозначает процесс переквалификации далекого от IT-сферы специалиста в разработчика.

Выкатить — сделать доступным для пользователей. Например, «выкатили новую версию сайта» значит сделали новую версию сайта доступной для пользователей.

Выпадашка — выпадающее меню, то же, что и «дропдаун».

Г

Галера — компания, в которой платят низкие зарплаты и не ценят разработчиков.

Гит — система контроля версий Git или сервис GitHub.

Г****окод — плохой, некачественный код. Объяснение термина есть в статье нашего студента.

Градиент — плавный переход из одного цвета в другой.

Грумить — от англ. Grooming. Приводить в порядок, «причесывать».

Д

Движок — в веб-разработке так называют системы управления контентом.

Дебажить — устранять ошибки, баги.

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

Джун, джуниор — от англ. Junior. Младший разработчик. Специалист без опыта или с минимальным опытом работы.

Дезигнер — презрительно-снисходительное название дизайнера.

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

Драй — от англ. DRY, don’t repeat yourself. Принцип программирования, предлагающий избегать повторений кода.

Дропдаун — выпадающее меню, то же, что и «выпадашка».

Дропнуть — от англ. Drop. Удалить, отключить, сбросить или обнулить что-либо.

Ж

Жаба — язык программирования Java.

Жабаскрипт — язык программирования JavaScript.

З

Залить — загрузить. Например, «залить файлы на сервер».

Запилить — сделать что-то, добавить какую-то функциональность.

Змея — язык программирования Python.

И

Исходник — файлы, в которых находится исходный код приложения, или сам исходный код.

Итерация — повторение. «Мы сделали несколько итераций» — мы повторили шаг несколько раз.

Бесплатные курсы по программированию в Хекслете

  • Освойте азы современных языков программирования
  • Изучите работу с Git и командной строкой
  • Выберите себе профессию или улучшите навыки

К

Колл — от англ. Call. Созвон, онлайн-конференция, онлайн-совещание.

Коммит, коммитить — от англ. To commit — совершать. В контексте работы над приложением — сохранять код в репозитории.

Копипаста — от англ. Copy-Paste. Скопированный откуда-то код.

Костыль — код, который нужен, чтобы исправить несовершенство ранее написанного кода.

Л

Легаси — от англ. Legacy. Морально устаревший код, который не обновляется, но используется. Или код, который разработчик получил по наследству от предыдущих разработчиков.

Либа — от англ. Library — библиотека. Речь идет о библиотеках кода, например, React.

Линтер — общее нарицательное название программ, которые анализируют код и предупреждают разработчика об ошибках.

Лист — от англ. List — список.

Локалка — локальный. Например, локальный сервер или сеть.

М

Мидл — от англ. Middle — средний. Уровень разработчика, следующий за джуниором. Опыт и уровень знаний миддла позволяет ему самостоятельно решать серьезные задачи.

Мёржить — от англ. Merge, сливать. Речь идет об объединении или слиянии веток кода.

Меншить — от англ. Mention — упоминание. Упоминанать в чатах или соцсетях. «Менши меня, когда будет готово» значит «упомяни меня, когда будет готово».

Н

Навбар — навигационный блок на сайте или в интерфейсе программы.

Накатить — внести изменения, задеплоить новую версию приложения. Противоположное термину «откатить».

О

Опенсорс, опен-сорс — от англ. Open Source. Программное обеспечение с открытым исходным кодом.

Откатить — удалить изменения, вернуть предыдущую версию приложения. Противоположное термину «накатить».

Ось — операционная система.

П

Падаван — ироничное название стажера или джуниора.

Пилот — пробная (пилотная) версия продукта.

Питон — язык программирования Python.

Подвал — то же, что и «футер». Элемент структуры страницы, который находится в нижней части и содержит служебную информацию — контакты, ссылки на соцсети, публичная оферта и т. д.

Поплыла вёрстка — некорректное отображение страницы в браузере.

Продакшн или продакшен (продакшн-код) — обозначение кода для рабочей версии приложения.

Пушить — использовать команду push, публиковать что-то.

Пэхапэ — язык программирования PHP, то же, что и «пыха».

Пыха — язык программирования PHP, то же, что и «пэхапэ».

Р

Рекурсия — описание процесса с помощью самого процесса. Например, выражение «рекурсивный вызов функции» описывает ситуацию, в которой функция вызывает сама себя.

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

Релокация — перевод сотрудника или бизнеса в другое место внутри страны или за границу.

Репа — репозиторий, хранилище данных. Например, код программы можно хранить в репозитории на GitHub.

Ридми — файл Readme, в котором содержится информация о программе.

Ругаться, например, линтер ругается — сообщения об ошибках в коде, работе сервиса и так далее.

С

Сабж — от английского Subject — тема, предмет. «По сабжу» — по теме обсуждения.

Свитчнуть, свичнуть — переключить. От английского switch.

Сетка — модульная сетка, используется для дизайна и верстки страниц.

Сеньор, синьор — от англ. Senior — старший разработчик.

Сорец (Сорцы) — от англ. Source. Исходный код.

Стек — изначально абстрактный тип данных. В разговорной речи используется для обозначения списка технологий, которые использует разработчик или компания. Пример: «Наш стек — HTML/CSS, JavaScript, React».

Софт — от англ. Software — программное обеспечение.

Софт-скиллы — от англ. Soft skills — знания и качества специалиста, прямо не связанные с профессиональной деятельностью. Примеры: коммуникабельность, проактивность.

Спринт — короткий промежуток времени (до 4 недель), в течение которого scrum-команда выполняет определенный объем работы.

Читайте также: Как джуну найти работу и где лучше начинать карьеру в IT: советы от Хекслета

Т

Таска — от англ. Task. Задание, задача.

Темплейт — от английского Template — шаблон.

Тестировщик — специалист по тестированию программного обеспечения.

Тимлид — от английского Team Lead — руководитель команды. Координатор группы программистов.

У

Убить — удалить что-то. Например, «убить профиль» означает удалить профиль.

Ф

Фидбек — от англ. Feedback — обратная связь.

Фиксить, пофиксить — от англ. Fix. Чинить, починить, исправить.

Фича — функция, возможность. От англ. Feature.

Фреймворк — от англ. Framework — каркас. Инструмент разработки, набор типовых шаблонных решений, упрощающих работу программиста. Примеры: Laravel, Bootstrap.

Фронтенд — от англ. Front-end — клиентская часть приложения.

Х

Хатэмээль, хатээмэль — HTML, язык гипертекстовой разметки.

Хардкодить — статически прописывать в коде данные, которые должны вычисляться динамически. Плохая практика, антипаттерн в программировании.

Хацкер, кулхацкер — ироничное название начинающего специалиста, который считает себя опытным программистом. От английского Hacker и Cool Hacker.

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

Хотфикс — от англ. Hotfix. Срочное исправление критических ошибок, уязвимостей или недоработок в программе.

Ц

Цэмээс, цээмэс — от англ. CMS — Content Management System, система управления контентом.

Цээсэс — от англ. CSS — Cascading Style Sheets, каскадные таблицы стилей.

Ч

Чекать, чекнуть, прочекать — от англ. Check. Проверять, проверить.

Ю

Юзать — от английского To use — использовать.

Я

Ява — язык программирования Java.

Яваскрипт — язык программирования JavaScript.

ЯП — язык программирования.

Бесплатные курсы по программированию в Хекслете

  • Освойте азы современных языков программирования
  • Изучите работу с Git и командной строкой
  • Выберите себе профессию или улучшите навыки

Продвинутые абстракции Kubernetes: Job, CronJob

Что такое Job и CronJob в Kubernetes, для чего они нужны, а для чего их использовать не стоит.
Эта статья — выжимка из лекции вечерней школы «Слёрм Kubernetes».

Job: сущность для разовых задач

Job (работа, задание) — это yaml-манифест, который создаёт под для выполнения разовой задачи. Если запуск задачи завершается с ошибкой, Job перезапускает поды до успешного выполнения или до истечения таймаутов. Когда задача выполнена, Job считается завершённым и больше никогда в кластере не запускается. Job — это сущность для разовых задач.

Когда используют Job

При установке и настройке окружения. Например, мы построили CI/CD, который при создании новой ветки автоматически создаёт для неё окружение для тестирования. Появилась ветка — в неё пошли коммиты — CI/CD создал в кластере отдельный namespace и запустил Job — тот, в свою очередь, создал базу данных, налил туда данные, все конфиги сохранил в Secret и ConfigMap. То есть Job подготовил цельное окружение, на котором можно тестировать и отлаживать новую функциональность.

При выкатке helm chart. После развёртывания helm chart с помощью хуков (hook) запускается Job, чтобы проверить, как раскатилось приложение и работает ли оно.

Таймауты, ограничивающие время выполнения Job

Job будет создавать поды до тех пор, пока под не завершится с успешным результатом. Это значит, что если в поде есть ошибка, которая приводит к неуспешному результату (exit code не равен 0), то Job будет пересоздавать этот под до бесконечности. Чтобы ограничить перезапуски, в описании Job есть два таймаута: activeDeadlineSeconds и backoffLimit.

activeDeadlineSeconds — это количество секунд, которое отводится всему Job на выполнение. Обратите внимание, это ограничение не для одного пода или одной попытки запуска, а для всего Job.

Например, если указать в Job, что activeDeadlineSeconds равен 200 сек., а наше приложение падает с ошибкой через 5 сек., то Job сделает 40 попыток и только после этого остановится.

backoffLimit — это количество попыток. Если указать 2, то Job дважды попробует запустить под и остановится.

Параметр backoffLimit очень важен, потому что, если его не задать, контроллер будет создавать поды бесконечно. А ведь чем больше объектов в кластере, тем больше ресурсов API нужно серверам, и что самое главное: каждый такой под — это как минимум два контейнера в остановленном состоянии на узлах кластера. При этом поды в состоянии Completed или Failed не учитываются в ограничении 110 подов на узел, и в итоге, когда на узле будет несколько тысяч контейнеров, докер-демону скорее всего будет очень плохо.

Учитывая, что контроллер постоянно увеличивает время между попытками запуска подов, проблемы могут начаться в ночь с пятницы на понедельник. Особенно, если вы не мониторите количество подов в кластере, которые не находятся в статусе Running.

Удаление Job

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

В Kubernetes есть специальный TTL Controller, который умеет удалять завершенные Job вместе с подами. Вот только он появился в версии 1.12 и до сих пор находится в статусе alpha, поэтому его необходимо включать с помощью соответствующего feature gate TTLAfterFinished.

ttlSecondsAfterFinished — указывает, через сколько секунд специальный TimeToLive контроллер должен удалить завершившийся Job вместе с подами и их логами.

spec:
ttlSecondsAfterFinished: 100

Манифест

Посмотрим на пример Job-манифеста.

В начале указаны название api-группы, тип сущности, имя и дальше — спецификация.

В спецификации указаны таймауты и темплейт пода, который будет запускаться. Опции backoffLimit: 2 и activeDeadlineSeconds: 60 значат, что Job будет пытаться выполнить задачу не более двух раз и в общей сложности не дольше 60 секунд.

template— это описание пода, который будет выполнять задачу; в нашем случае запускается простой контейнер busybox, который выводит текущую дату и передаёт привет из Kubernetes.

Практические примеры

kubectl apply -f job.yaml

И посмотрим, что получилось.

Видим, что контейнер поднялся и завершился в статусе Completed. В отличие от приложений, которые всегда работают и имеют статус Running.

Статистику по Job можно посмотреть следующей командой.

kubectl get job

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

Ненужный Job обязательно надо удалять. Потому что, если мы не удалим его руками, Job и под будут висеть в кластере всегда — никакой garbage collector не придёт и не удалит их.

Если у вас запускаются по 10-20 заданий в час, и никто их не удаляет, они копятся и в кластере появляется много абстракций, которые никому не нужны, но место занимают. А как я уже говорил выше, каждый под в состоянии Completed — это, как минимум, два остановленных контейнера на узле. А докер демон начинает притормаживать, если на узле оказывается несколько сотен контейнеров, и не важно, работают они или остановлены.

Команда для удаления:

kubectl delete job hello

Что будет, если сломать Job

Job, который выполняется без проблем, не очень интересен. Давайте мы над ним немного поиздеваемся.

Поправим yaml: добавим в темплейт контейнера exit 1. То есть скажем Job’у, чтобы он завершался с кодом завершения 1. Для Kubernetes это будет сигналом о том, что Job завершился неуспешно.

containers:
— name: hello
image: busybox
args:
— /bin/sh
— -c
— date; echo Hello from the Kubernetes cluster; exit 1
restartPolicy: Never

Применяем и смотрим, что происходит: один контейнер создался и упал с ошибкой, затем ещё и ещё один. Больше ничего не создаётся.

В статистике подов видим, что создано три пода, у каждого статус Error. Из статистики Job следует, что у нас создан один Job и он не завершился.


Если посмотреть описание, то увидим, что было создано три пода, и Job завершился, потому что был достигнут backoffLimit.

Обратите внимание! В yaml лимит равен 2. То есть, если следовать документации, Job должен был остановиться после двух раз, но мы видим три пода. В данном случае «после выполнения двух раз» значит 3 попытки. Когда мы проделываем то же самое на
интенсиве
с сотней студентов, то примерно у половины создаётся два пода, а у оставшихся три. Это надо понять и простить.

Проверка ограничения по времени

Сделаем бесконечный цикл и посмотрим, как работает ограничение по времени — activeDeadlineSeconds.

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

containers:
— name: hello
image: busybox
args:
— /bin/sh
— -c
— while true; do date; echo Hello from the Kubernetes cluster; sleep 1; done
restartPolicy: Never

Под запустился.

Если посмотреть в логи, то увидим, что каждую секунду у нас появляется новый «Hello» — всё как надо.

Через 60 секунд под оказывается в статусе Terminating (иногда это происходит через ± 10 сек).

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

В нашем случае приложение — это простой bash-скрипт с бесконечным циклом, реагировать на сигнал некому. Kubernetes ждёт время, которое задано в параметре graceful shutdown. По дефолту — 30 секунд. То есть если за 30 секунд приложение на sigterm не среагировало, дальше посылается sigkill и процесс с pid 1 внутри контейнера убивается, контейнер останавливается.

Спустя чуть более 100 секунд под удалился. Причем ничего в кластере не осталось, потому что единственный способ остановить что-то в контейнере — это послать sigterm и sigkill. После этого приходит garbage collector, который удаляет все поды в статусе Terminating, чтобы они не засоряли кластер.

В описании Job мы увидим, что он был остановлен, так как активность превысила допустимую.

Поле restartPolicy

При проверке backoffLimit поды у нас перезагружались. При этом в манифесте указан параметр
restartPolicy: Never
. Но когда мы смотрели, как работает опция backoffLimit, поды перезагружались. Здесь нет противоречия: если вы посмотрите на весь yaml-файл, то заметите, что этот параметр относится не к Job, а к спецификации контейнера, который запускается внутри пода.

Этот параметр говорит kubelet, что делать с контейнером после того, как он был завершён с ошибкой. По умолчанию стоит политика Always, то есть если у нас контейнер в поде завершился, kubelet этот контейнер перезапускает. Причем, все остальные контейнеры в поде продолжают работать, а перезапускается только упавший контейнер.

Это политика по умолчанию, и если её применить в Job, то Job-контроллер не сможет получить информацию о том, что под был завершён с ошибкой. С его точки зрения под будет очень долго выполняться, а то, что kubelet перезапускает упавший контейнер, Job-контроллер не увидит.

Раздел Suspend — временная приостановка CronJob. В данном случае указано значение False. Это значит, что CronJob выполняется. Можно отредактировать манифест и поставить опцию True, и тогда он не будет выполняться, пока мы его снова не запустим.

Active — сколько Job’ов создано, Last Schedule — когда последний раз исполнялся.

Теперь можно посмотреть статистику по Job’ам и подам.

kubectl get job

Видно, что создан один Job.

kubectl get pod

Под создан, он выполнил полезную работу.

Что получается: CronJob создал Job, Job создал под, под отработал, завершился — всё здорово.

Ещё раз посмотрим на CronJob:

Last Schedule был 19 секунд назад. Если посмотреть на Job, то увидим, что у нас появился следующий Job и следующий под.

Возникает вопрос: а что будет, если CronJob отработает хотя бы пару недель? Неужели у нас в кластере будет столько же Job’ов и подов в статусе Completed, сколько в этой паре недель минут?

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

Снова откроем манифест и посмотрим, что было добавлено:

k get cronjobs.batch hello -o yaml


Появились опции failedJobHistorLimit со значением 1 и successfulJobHistoryLimit со значением 3. Они отвечают за количество Job’ов, которые остаются одновременно в кластере. То есть CronJob не только создаёт новые Job’ы, но и удаляет старые.

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

И на сладкое — про startingDeadlineSeconds

В параметре startingDeadlineSeconds указывают количество секунд, на которое можно просрочить запуск Job. Если по каким-то причинам Job не создался и с момента, когда его надо было создать, прошло больше секунд, чем указано в этом параметре, то он и
не будет создан. А если меньше, то хоть и с опозданием, Job будет создан.

Тут есть небольшая ловушка, если concurrencyPolicy разрешают одновременное создание Job, то при большом значении параметра startingDeadlineSeconds возможен одновременный запуск десятков пропущенных Job одновременно. Для уменьшения всплеска нагрузки в код Kubernetes захардкожены лимиты и запрещающие процедуры:

Если параметр startingDeadlineSeconds не указан в манифесте:

CronJob контроллер при создании Job смотрит на время последнего запуска — значение LastscheduleTime в status: и считает, сколько времени прошло с последнего запуска. И если это время достаточно велико, а точнее за этот промежуток времени CronJob должен был отработать 100 раз или больше, но у нее этого не получилось:

  • например конкурент полиси стоит форбид, крон запускается раз в минуту, и один из запусков подзавис и работал 2 часа, то есть 120 минут;
  • или у нас один мастер в кластере, который упал на пару часов.

И еще более странное:

Если установлен параметр startingDeadlineSeconds, то поведение немного меняется. 100 пропущенных запусков должны уложиться в количество секунд, указанных в этом параметре. т. е. если в расписании стоит выполняться раз в минуту, а startingDeadlineSeconds меньше 6000 секунд, тогда CronJob будет работать всегда, но в этом случае при политике Allow возможен одновременный запуск множества Job.

И наконец, любопытный side-эффект:

Если установить опцию startingDeadlineSeconds равной нулю, Job’ы вообще перестают создаваться.

Если вы используете опцию startingDeadlineSeconds, указывайте её значение меньше, чем интервал выполнения в расписании, но не ноль.
Применяйте политику Forbid. Например, если было пропущено 5 вызовов и наступило очередное время исполнения, то контроллер не будет 5 раз запускать пропущенные задачи, а создаст только один Job. Это логичное поведение.

Особенность работы CronJob

A cron job creates a job object about once per execution time of its schedule. We say «about» because there are certain circumstances where two jobs might be created, or no job might be created. We attempt to make these rare, but do not completely prevent them. Therefore, jobs should be idempotent.

Вольный перевод на русский:

CronJob создаёт объект Job примерно один раз на каждое время исполнения по расписанию. Мы говорим «примерно», потому что иногда бывают случаи, когда создаются два Job’а одновременно или ни одного. Мы делаем всё, чтобы сделать подобные случаи как можно более редкими, но полностью избежать этого не получается. Следовательно, Job’ы должны быть идемпотентны.

Идемпотентны — должны выполняться на одной и той же среде несколько раз и всегда возвращать одинаковый результат.

В общем, используйте CronJob на свой страх и риск.

В качестве альтернативы CronJob можно использовать под, в котором запущен самый обычный crond. Без выкрутасов. Старый добрый cron работает без проблем, и мы всегда знаем, что задачи будут выполнены один раз. Надо только побеспокоиться, чтобы внутри пода с кроном не выполнялись одновременно несколько задач.

Изучить продвинутые абстракции и попрактиковаться в работе с Kubernetes можно с помощью видеокурса Kubernetes База. В октябре 2020 мы обновили курс, подробности здесь.

Job — шаблон проектирования для новичков и опытных Go программистов

Я начал программировать на Go после достаточно продолжительного периода программирования на PHP. Полагаю судя по последним тенденциям мой случай далеко не единичный. Go в целом набирает популярность среди Web разработчиков.

Итак, я в мире сусликов. А что делает прожженный до мозга костей PHP программист оказавшись там? Правильно, он продолжает «пыхтеть» — в силу своей профессиональной деформации — но уже на Go, со всеми вытекающими отсюда последствиями.

Признаюсь я никогда не был на собеседовании, устраиваясь на вакансию Go разработчика, но подозреваю, что там не задают вопросов про SOLID, Dependency Injection и различные прелести ООП. Там другой мир, другая парадигма (в целом разумеется не экстраординарная), связанная с параллельным программированием, строгой типизацией и отсутствием полноценного ООП в строгом его смысле — к тому ООП к которому мы привыкли по PHP, С++ или Java.

Поэтому в начале, разумеется, был определенный дискомфорт и ломка шаблонов. Я не понимал как использовать тот же context.Context, зачем он? Мои шаблоны готовы уже были треснуть, но матерого PHP программиста без хрена не съешь. Пора что-то с этим делать и писать свой велосипед! А именно то решение, которое мне, как PHP программисту, казалось достаточно очевидным для решения задача связанных с параллельным программирование, краеугольным камнем Go. Усевшись за рабочий ноутбук я почти месяц корпел над работой. Я хотел не просто сделать реализацию сферического коня в вакууме, а показать на конкретном примере возможность использования данного подхода. Так сказать, proof of concept. Ну и заодно набить руку на Go, чего греха таить.

После того как велосипед был готов, я выкатил его, осмотрел и, выдохнув, сказал сам себе: «ну, блин, вроде неплохо получилось. Нужно срочно рассказать об этом сообществу, пускай оценят«. Сказано — сделано. На Reddit была опубликована небольшая заметка про новый шаблон проектирования Go и, судя по реакции я понял… что люди ничего не поняли. «Зачем? Как это использовать? Так это же over-engineering» — в целом так можно охарактеризовать реакцию. Я не сдавался: «сейчас я вам нафотошоплю свой контраргумент. Ага, добавить это в README.md — пусть знают эти суслики«.

Как видят решение программисты

А если без шуток, то это, наверное, тема для отдельной статьи.

В целом о чем я? Много воды — ноль конкретики. Чтобы было реализовано:

  1. Шаблон проектирования Job — это поведенческий шаблон проектирования, который инкапсулирует всю необходимую информацию для параллельного выполнения задач (task).
  2. В качестве примера использования данного шаблона был реализован простой прокси-сервер, выполняющий роль балансировщика уровня L4; клиент, который сканируют указанную директорию на наличие изображений и отправляет все найденные изображения на backend сервер для изменения их размера; backend сервер, который обрабатывает запросы по изменению размера изображений. В основе всех трех приложений лежит компонент Job. Код так же доступен в репозитории на Github.

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

Parallel Processing Where the commands are written as tasks to a shared resource and executed by many threads in parallel (possibly on remote machines; this variant is often referred to as the Master/Worker pattern)

Выполнение задач зависит друг от друга, если одна задача прерывает свое выполнение из-за ошибки — все остальные задачи останавливаются тоже. Все это, безусловно, можно реализовать с помощью context.Context, но реализация на более высоком уровне позволяет избавиться от рутинных действий, связанных с организацией параллельного выполнения задач и сконцентрироваться на реализации самой бизнес логики. Ну а сами ошибки очень легко отлавливать вызовами специальных методов вроде task.Assert заменяя ими более емкие конструкции if err != nil < panic(err) >.

Задачи разделяют данные и оркестрируют свое выполнение с помощью так называемой ping/pong синхронизации. Я приведу здесь лишь небольшой кускок кода, чтобы дать общее представление — полностью библиотека доступна в репозитории на Github по ссылке.

// Saves resized image to the output dir func (s *ImageResizer) SaveResizedImageTask(j job.Job) (job.Init, job.Run, job.Finalize) < // Do some initialization here init := func(t job.Task) < if _, err := os.Stat(s.inputDir); os.IsNotExist(err) < t.Assert(err) >if _, err := os.Stat(s.outputDir); os.IsNotExist(err) < err := os.Mkdir(s.outputDir, 755) t.Assert(err) >> run := func(task job.Task) < stream := j.GetValue().(netmanager.Stream) select < case finishedTask := task.Tick() case frame := err := frame.Decode(res) task.Assert(err) baseName := fmt.Sprintf("%s-%dx%d%s", res.OriginalName, res.ResizedWidth, res.ResizedHeight, res.Typ.ToFileExt()) filename := s.outputDir + string(os.PathSeparator) + baseName if ! s.dryRun < ioutil.WriteFile(filename, res.ImgData, 0775) >j.Log(1) > > return init, run, nil >

Это одна из задач клиента, которая обрабатывает приходящий ответ от сервера и сохраняет полученное изображение. Задача оркестирует свое выполнение — используя вышеупомянутую технику ping/pong синхронизации — с задачей, которая занимается файловым сканированием. Также она определяет, когда пришел последний ответ от сервера и когда нужно завершить выполнение всей работы (Job).

Насколько это решение over-engineered и насколько его использование вместо context.Context оправдано — пусть это решает читатель, я своё мнение выразил в виде сарказма на изображении выше.

Всем хороших выходных и да прибудет с нами сила пэхэпе в мире сусликов.

Учимся создавать и настраивать Jenkins Jobs

Jenkins CI позволяет разработчикам автоматизировать создание, тестирование и развёртывание кода. Jenkins Jobs фокусируется на непрерывном создании и тестировании кода, чтобы любые внесённые изменения легко интегрировались в сборку. В этой статье мы посмотрим на Jenkins в действии — разберём, как создавать и настраивать Jenkins Jobs.

Что такое Jenkins Jobs

Jenkins Jobs — это набор задач, которые выполняются последовательно, как определено пользователем. Любая автоматизация, реализованная в Jenkins, — это Jenkins Job. Эти джобы являются важной частью процесса сборки. Мы можем создавать их для тестирования нашего приложения или проекта.

При работе с Jenkins термины «Jenkins Job» и «Jenkins Project» являются синонимами. С помощью Jenkins Job мы можем клонировать исходный код из системы управления версиями, компилировать код и запускать модульные тесты в соответствии с требованиями. Кроме того, Jenkins позволяет объединять код с помощью инструментов управления — Superversion, CVS, CVN и др.

Существуют разные типы Jenkins Jobs под разные цели. Исходя из сложности и характера проекта, мы можем выбрать те, что лучше всего соответствуют нашим потребностям. Кратко рассмотрим типы джоб в Jenkins:

Название

Описание

Freestyle Project

Центральная и наиболее широко используемая функция в Jenkins. С её помощью можно легко создавать и запускать пайплайны или скрипты.

Maven Project

Подойдёт, если работа связана с управлением и созданием проектов, содержащих POM-файлы. При выборе этой опции Jenkins, по умолчанию, выберет POM-файлы, создаст конфигурации и запустит сборки.

Pipeline

Подходит для работы с длительными действиями, содержащими несколько агентов сборки.

Multi-configuration Project

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

GitHub Organization

Параметр сканирует учётную запись пользователя на GitHub на наличие всех репозиториев, соответствующих определённым маркерам.

Подробнее о Jenkins Freestyle Project

Jenkins поддерживает разные способы создания джоб. Наиболее часто используемыми считаются Freestyle и Maven 2/3. Ключевое преимущество Jenkins Freestyle Project заключается в том, что он позволяет настраивать практически любую джобу. Maven 2/3 понимает структуру проекта Maven и позволяет быстро настраивать задания с дополнительными функциями.

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

Другие плагины Jenkins также позволяют использовать дополнительные типы шагов сборки. К ним относятся Grails, Gant, Rake, Gradle, Ruby, MSBuild и др. Но Jenkins Freestyle Project отличает то, что он позволяет создавать джобы общего назначения с максимальной гибкостью. Суть в том, что JenkinsFreestyle Project позволяет настроить практически любое задание сборки.

Существуют ограничения на типы действий, которые мы можем выполнять на этапе сборки или после сборки. В рамках Jenkins Freestyle Project доступно несколько стандартных подключаемых модулей, которые помогаютт преодолеть проблему. Эти подключаемые модули позволяют настраивать триггеры сборки и обеспечивают безопасность проекта Jenkins.

Когда использовать Jenkins Freestyle Project

В freestyle project средах удобно создать скрипт, который предписывает Jenkins freestyle job передать файл по FTP с одного сервера на другой, скомпилировать каталог Java-кода или даже запустить тест SonarQube. Jenkins freestyle job может быть таким же мощным и сложным, как и любое задание сборки, созданное с помощью пайплайна Jenkins или Groovy DSL. Единственный недостаток freestyle project заключается в том, что пользователь должен знать, как заскриптовать все эти действия, а разработчикам нужно научиться управлять этими скриптами.

Плагины вроде Git, Maven и SonarQube являются предпочтительными для доступа к ресурсам. И технически каждый разработчик может написать скрипт для доступа к этим ресурсам в рамках Jenkins Freestyle Project. Тем не менее, рекомендуется, чтобы каждый разработчик в команде следовал рекомендациям по обеспечению безопасности и воздерживался от адаптации подхода, основанного на скриптах.

Как создать Freestyle Build Job

Шаг 1. Войдите в учётную запись Jenkins. После этого нажмите на кнопку «New Item» в панели управления.

После этого вы будете перенаправлены на новую страницу, где нужно ввести название джобы и выбрать тип.

Шаг 2: Введите название элемента. Для примера возьмём «Привет, мир». И выберите «Freestyle project». Нажмите кнопку ОК.

Когда вы нажмёте «Ок», Jenkins автоматически переведёт вас в конфигурации, где нужно настроить сведения о проекте. Кроме того, вы можете предоставить сложные детали через параметры вкладки.

Первая вкладка — общие сведения о проекте.

Шаг 3. Введите сведения о проекте на вкладке «General».

Помимо описания (Description), в разделе «General» есть некоторые опции.

Название

Описание

Discard old builds

Если вы хотите отказаться от старых сборок при запуске новой сборки, вы выбираете эту опцию.

GitHub Project

Указывает, что вы запускаете сборку с GitHub.

This project is parameterized

Если вы хотите запустить сборку с другими параметрами, которые будут передаваться во время выполнения, вы используете эту опцию.

Throttle builds

Обеспечивает минимальное время между сборками на основе желаемой максимальной скорости.

Disable this project

Если вы отметите этот параметр, новая сборка проекта выполняться не будет

Execute concurrent builds if necessary

Если вы отметите этот параметр, сможете выполнять несколько сборок проекта параллельно.

Далее разберёмся, что делает вкладка «Source Code Management». Она проверяет код с узлов управления версиями — если ваш код размещён на GitHub или в любых других репозиториях, вы должны добавить сведения о репозитории. Jenkins клонирует репозиторий.

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

Шаг 4. На вкладке «Source Code Management» (SCM) выберите Git в качестве источника репозитория и введите URL вашего репозитория Git. В случае, если репозиторий создан локально, допускается использование локального репозитория.

А теперь предположим, репозиторий GitHub, который вы используете, является закрытым. В этом случае Jenkins проверит учётные данные для входа в систему с помощью GitHub, и после успешной проверки извлечёт исходный код из вашего репозитория GitHub.

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

Шаг 5. Перейдите в раздел «Build» и нажмите на «Add build step».

И здесь есть разные варианты:

Название

Описание

Execute Windows batch command

Запускает пакетный сценарий Windows для сборки проекта. Сценарий запускается с рабочей областью в качестве текущего каталога.

Execute shell

Запускает сценарий оболочки для сборки проекта. Сценарий запускается с рабочей областью в качестве текущего каталога.

Invoke Ant

Указывает список вызываемых целей Ant

Invoke Gradle Script

Предназначен для проектов, которые используют Gradle в качестве системы сборки. Здесь Jenkins вызывает Gradle с заданными переключателями и задачами.

Invoke top-level Maven targets

Предназначен для проектов, которые используют Maven в качестве системы сборки. Это приводит к тому, что Jenkins вызывает Maven с заданными целями и параметрами. Jenkinsпередаёт Maven различные переменные среды, к которым вы можете получить доступ из Maven как $.

Run with timeout

Если сборка не завершается за указанное время, она автоматически завершается и помечается как прерванная. Время по умолчанию будет не менее 3 минут.

Нажмите «Execute Windows batch command» и добавьте команды, которые вы хотите выполнить в процессе сборки.

Например, пакетные команды компиляции Java:

Шаг 6. Когда введёте все данные, нажмите кнопку «Apply» и сохраните проект.

Шаг 7. На левой боковой панели нажмите кнопку «Build Now», чтобы создать исходный код.

Шаг 8. Вы можете проверить историю выполненной сборки в разделе «Build History», щёлкнув по номеру сборки. Нажав на Build Number –> Console Output, вы должны получить сообщение об успешном выполнении или сбое в зависимости от того, как было выполнено задание.

Итог

Итак, что мы сделали? Мы запустили программу «HelloWorld» на GitHub. Jenkins загрузил исходный код из удалённого репозитория и непрерывно создавал его с заданной вами частотой.

Что такое подписка

Подписка — это концентрированное обучение с курсами, которые выбираете именно вы. Если хочется одновременно обучиться на Jenkins и DevOps Tools — подписка станет вашим лучшим другом.

Подписка действует 3 месяца и позволяет пройти неограниченное количество курсов из этого списка.

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

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