Назад | Перейти на главную страницу

Ограничения ОС игнорируются bamboo

Нашим разработчикам нужен бамбук из-за интеграции с другим программным обеспечением Atlassian, и у нас регулярно возникают проблемы с этим сервером сборки. Часто сборочные работы терпят неудачу с такими исключениями OutOfMemory:

 java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:717)
        at org.apache.tools.ant.taskdefs.ProcessDestroyer.removeShutdownHook(ProcessDestroyer.java:149)
        at org.apache.tools.ant.taskdefs.ProcessDestroyer.remove(ProcessDestroyer.java:202)
        at org.apache.tools.ant.taskdefs.Execute.execute(Execute.java:481)
        at org.apache.tools.ant.taskdefs.ExecTask.runExecute(ExecTask.java:629)
        at org.apache.tools.ant.taskdefs.ExecTask.runExec(ExecTask.java:670)
        at org.apache.tools.ant.taskdefs.ExecTask.execute(ExecTask.java:496)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:293)
        at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:68)
        at net.sf.antcontrib.logic.IfTask.execute(IfTask.java:197)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.TaskAdapter.execute(TaskAdapter.java:155)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:293)
        at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.Target.execute(Target.java:435)
        at org.apache.tools.ant.Target.performTasks(Target.java:456)
        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1405)
        at org.apache.tools.ant.helper.SingleCheckExecutor.executeTargets(SingleCheckExecutor.java:38)
        at org.apache.tools.ant.Project.executeTargets(Project.java:1260)
        at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:441)
        at org.apache.tools.ant.taskdefs.CallTarget.execute(CallTarget.java:105)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:293)
        at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.Target.execute(Target.java:435)
        at org.apache.tools.ant.Target.performTasks(Target.java:456)
        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1405)
        at org.apache.tools.ant.helper.SingleCheckExecutor.executeTargets(SingleCheckExecutor.java:38)
        at org.apache.tools.ant.Project.executeTargets(Project.java:1260)
        at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:441)
        at org.apache.tools.ant.taskdefs.CallTarget.execute(CallTarget.java:105)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:293)
        at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:68)
        at net.sf.antcontrib.logic.IfTask.execute(IfTask.java:197)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.TaskAdapter.execute(TaskAdapter.java:155)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:293)
        at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.Target.execute(Target.java:435)
        at org.apache.tools.ant.Target.performTasks(Target.java:456)
        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1405)
        at org.apache.tools.ant.Project.executeTarget(Project.java:1376)
        at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
        at org.apache.tools.ant.Project.executeTargets(Project.java:1260)
        at org.apache.tools.ant.Main.runBuild(Main.java:857)
        at org.apache.tools.ant.Main.startAnt(Main.java:236)
        at org.apache.tools.ant.launch.Launcher.run(Launcher.java:287)
        at org.apache.tools.ant.launch.Launcher.main(Launcher.java:113)

Памяти точно хватит. Я увеличил объем оперативной памяти Bamboo JVM с 512/1024 до 4096 МБ (как минимум, так и максимум). В интерфейсе администратора всегда есть минимум 50% бесплатного. Сам сервер имеет 24 ГБ памяти.

Похоже, ошибка нехватки памяти не указывает на нехватку памяти но вместо этого отсутствуют ограничения ОС. В /etc/security/limits.conf Я установил следующие ограничения (сначала для пользователя bamboo который используется для работы, позже * для всех пользователей):

*      soft   nofile  16384
*      hard   nofile  16384
*      soft   nproc   65535
*      hard   nproc   65535

а также установите это в /etc/sysctl.conf:

fs.file-max = 16384

Чтобы проверить, работают ли ограничения:

su - bamboo
ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 94782
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 16384
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 65535
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Поскольку бамбук по-прежнему падает, я добавил план оболочки, который выполняет

whoami
ulimit -a

со следующим выводом:

build   07-Feb-2020 11:29:11    bamboo
build   07-Feb-2020 11:29:11    core file size          (blocks, -c) unlimited
build   07-Feb-2020 11:29:11    data seg size           (kbytes, -d) unlimited
build   07-Feb-2020 11:29:11    scheduling priority             (-e) 0
build   07-Feb-2020 11:29:11    file size               (blocks, -f) unlimited
build   07-Feb-2020 11:29:11    pending signals                 (-i) 94782
build   07-Feb-2020 11:29:11    max locked memory       (kbytes, -l) 64
build   07-Feb-2020 11:29:11    max memory size         (kbytes, -m) unlimited
build   07-Feb-2020 11:29:11    open files                      (-n) 4096
build   07-Feb-2020 11:29:11    pipe size            (512 bytes, -p) 8
build   07-Feb-2020 11:29:11    POSIX message queues     (bytes, -q) 819200
build   07-Feb-2020 11:29:11    real-time priority              (-r) 0
build   07-Feb-2020 11:29:11    stack size              (kbytes, -s) 8192
build   07-Feb-2020 11:29:11    cpu time               (seconds, -t) unlimited
build   07-Feb-2020 11:29:11    max user processes              (-u) 94782
build   07-Feb-2020 11:29:11    virtual memory          (kbytes, -v) unlimited
build   07-Feb-2020 11:29:11    file locks                      (-x) unlimited

Мы видим, например, что для открытых файлов просто установлено значение 4096 вместо 16384, как было настроено.

Что делает бамбук, если он игнорирует эти общесистемные ограничения?

На этот раз проблема возникла не из-за Bamboo, вместо этого кажется, что systemd игнорирует общесистемные ограничения. Пришлось отредактировать сервис:

vim /etc/systemd/system/bamboo.service

и вручную добавьте лимит в [Service] такой раздел:

LimitNOFILE=65536

Имейте в виду, что в случае автоматически сгенерированных сервисов (например, менеджером пакетов) вы должны переопределить его в /etc/systemd/system/<service-name>.service.d/override.conf так что изменения сохраняются после обновления пакета. На нашем сервере это не имело значения, поскольку приложение недоступно во время работы диспетчера пакетов, поэтому служба была создана вручную.