Нашим разработчикам нужен бамбук из-за интеграции с другим программным обеспечением 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
так что изменения сохраняются после обновления пакета. На нашем сервере это не имело значения, поскольку приложение недоступно во время работы диспетчера пакетов, поэтому служба была создана вручную.