Как предотвратить одновременное выполнение определенных заданий Jenkins?
У меня есть несколько заданий, которые используют общий ресурс (базу данных), что иногда может привести к сбою сборок в (редком) случае, когда задания запускаются одновременно.
Например, если заданы задания от A до E, есть ли способ указать, что A и C никогда не должны выполняться одновременно?
Помимо вышеупомянутого ресурса, сборки не зависят друг от друга (например, не в отношении восходящего / нисходящего потоков).
Способ "грубой силы" будет ограничивать число исполнителей до одного, но это, очевидно, далеко не идеально, если большинство заданий вполне может быть выполнено одновременно и нет недостатка вычислительных ресурсов на сервере сборки.
6 ответов
В настоящее время есть 2 способа сделать это:
- Используйте плагин Throttle Concurrent Builds.
- Настройте эти задания для работы на подчиненном, имеющем только 1 исполнителя.
Плагин Locks and Latches здесь должен помочь.
Этот вопрос, вероятно, является обманом Как я могу гарантировать, что только одна из определенной категории заданий выполняется одновременно в Гудзоне?
Это старый вопрос, но тема все еще может быть актуальной, особенно при запуске тестов приложений на Jenkins.
Плагин Lockable Resources позволяет вам определять блокируемые ресурсы, которые могут использоваться сборками. Если вашей сборке требуется ресурс, она берет блокировку. Если вторая сборка требует того же ресурса (который затем уже заблокирован), он будет поставлен в очередь для освобождения ресурса.
Хотя в документах используются компьютеры или принтеры в качестве примеров для блокируемых ресурсов, приведенный выше пример базы данных также должен работать.
В противоположность плагину Locks and Latches, упомянутому в ответах от 2012 года, этот пакет, похоже, поддерживается (в настоящее время ~2016).
Взгляните на внешний плагин Jenkins Dispatcher Resourcecher, который был впервые опубликован в ноябре 2012 года. Этот (относительно) новый плагин, по-видимому, точно охватывает этот вариант использования.
Обратите внимание, что вам не нужно физическое или виртуальное оборудование для ведомого / узла, вы можете настроить "ведомые", которые работают на главном сервере.
Управление Jenkins> Управление узлами> Новый узел
и сделать "немых рабов", каждый со своим корневым каталогом.
Создайте несколько подчиненных, выполняйте их при загрузке сервера, а затем вы по существу создали пулы исполнителей.
Вы могли бы, скажем...
дб - только один исполнитель в вашем случае. compile - ограничение в зависимости от оборудования или количества процессоров. у сценариев - есть много исполнителей для всех тех маленьких заданий, которые Дженкинс хорошо выполняет.
Старый вопрос, и будет ли это работать для вашего приложения, я не могу быть уверен, так как вы не упомянули детали вашего приложения. Однако я хотел добавить способ, которым я справился с этим, в нашем тестовом наборе приложений Rails.
Конфигурация базы данных нашего приложения (database.yml
) нет в исходном хранилище. Вместо этого он живет в /var/lib/configs/uniquing_database.yml
на виртуальной машине, которая запускает наш экземпляр Jenkins.
Один из шагов нашего процесса сборки включает копирование этого файла конфигурации в рабочую область проекта:
cp /var/lib/jenkins/configs/myapp_unique_database.yml config/database.yml
и эта конфигурация учитывает информацию о рабочем пространстве и числе номеров, предоставляемую Jenkins для среды, чтобы создать базу данных с уникальным именем для этого задания и его конкретного выполнения:
test:
adapter: postgresql
encoding: unicode
host: 127.0.0.1
port: 5432
database: myapp_test<%= ENV['JOB_NAME'].split('/').last %><%= ENV['BUILD_NUMBER'] %>
Остальная часть нашей сборки происходит без каких-либо знаний или забот, что она выполняется в отдельной базе данных. Наконец, в конце нашей сборки мы обязательно удалим эту базу данных, чтобы у нас не было набора тестовых баз данных, загрязняющих файловую систему:
RAILS_ENV=test bundle exec rake db:drop