По умолчанию nofile
ограничение для учетных записей пользователей OS X в наши дни составляет около 256 файловых дескрипторов. Я пытаюсь протестировать какое-то программное обеспечение, которому требуется гораздо больше подключений, чем открыто одновременно.
В типичном компьютере Debian с модулем ограничений pam я бы отредактировал /etc/security/limits.conf
чтобы установить более высокие ограничения для пользователя, который будет запускать программное обеспечение, но я не понимаю, где установить эти ограничения в OS X.
Для этого есть графический интерфейс? Для этого есть где-нибудь файл конфигурации? Какой самый простой способ изменить ограничения по умолчанию в OS X?
В Leopard начальный процесс launchd
. Улимиты по умолчанию для каждого процесса наследуются от launchd
. Для справки, ограничения по умолчанию (скомпилированы в):
$ sudo launchctl limit
cpu unlimited unlimited
filesize unlimited unlimited
data 6291456 unlimited
stack 8388608 67104768
core 0 unlimited
rss unlimited unlimited
memlock unlimited unlimited
maxproc 266 532
maxfiles 256 unlimited
Чтобы изменить любое из этих ограничений, добавьте строку (вам может потребоваться сначала создать файл) в /etc/launchd.conf
, аргументы такие же, как и переданные в launchctl
команда. Например
echo "limit maxfiles 1024 unlimited" | sudo tee -a /etc/launchd.conf
тем не мение launchd
уже запустил вашу оболочку входа в систему, поэтому самый простой способ заставить эти изменения вступить в силу - перезапустить нашу машину. (Используйте >> для добавления в /etc/launchd.conf.)
Ресурсы, доступные оболочке и процессам, могут быть изменены с помощью ulimit
команда, которую можно добавить в сценарии запуска, такие как ~/.bashrc
или ~/.bash_profile
для индивидуальных пользователей или /etc/bashrc
для всех пользователей. Пример строки для добавления:
ulimit -Sn 4096 && ulimit -Sl unlimited
Видеть: help ulimit
и man bash
Чтобы получить больше информации.
Как правило, системные ограничения контролируются Launchd рамки и могут быть изменены launchctl
команда, например
launchctl limit maxfiles 10240 unlimited
Чтобы изменения были постоянными, вам необходимо создать файл списка свойств в определенном Запускать совместимые папки который действует как агент запуска.
Вот пример команды, создающей такой файл запуска:
sudo /usr/libexec/PlistBuddy /Library/LaunchAgents/com.launchd.maxfiles.plist -c "add Label string com.launchd.maxfiles" -c "add ProgramArguments array" -c "add ProgramArguments: string launchctl" -c "add ProgramArguments: string limit" -c "add ProgramArguments: string maxfiles" -c "add ProgramArguments: string 10240" -c "add ProgramArguments: string unlimited" -c "add RunAtLoad bool true"
Файл будет загружен при запуске системы, однако для загрузки вручную:
sudo launchctl load /Library/LaunchAgents/com.launchd.maxfiles.plist
Чтобы проверить текущие ограничения, запустите: launchctl limit
.
Видеть: Создание демонов запуска и агентов.
sysctl
команда.sysctl -a | grep ^kern.max
.sudo sysctl -w kern.maxfiles=20480
.Связанный:
В более ранней версии macOS эти ограничения можно было установить в /etc/sysctl.conf
общесистемный, как обычно в Unix, однако, похоже, он не поддерживается.
С помощью ~/.launchd.conf
или /etc/launchd.conf
Похоже, что он также не поддерживается ни в одной из существующих версий macOS.вики
То же самое с /etc/rc.local
файл запуска, он не поддерживается в macOS.
sudo echo "limit maxfiles 1024 unlimited" >> /etc/launchd.conf
не работает, потому что sudo находится не в том месте, попробуйте следующее:
echo 'limit maxfiles 10000 unlimited' | sudo tee -a /etc/launchd.conf
% ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) 6144
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 2560
pipe size (512 bytes, -p) 1
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 266
virtual memory (kbytes, -v) unlimited
%
Теперь мне нужно выяснить, почему существует 2 способа проверки / установки пределов ....
Хорошо - похоже ulimit
и sysctl
создают ложноположительное ощущение, что они действительно что-то делают, но вместо этого они кажутся бесполезный. Может кто-нибудь это проверить?
Хорошо, я начинаю понимать. Начиная с версии 10.4, нет init
процесс больше, он был заменен на launchd
, который также работает с PID 1.
% ps -fu root
UID PID PPID C STIME TTY TIME CMD
0 1 0 0 0:30.72 ?? 0:46.72 /sbin/launchd
И, конечно, стоит упомянуть, что ulimit
это встроенная оболочка, launchctl
это программа, не зависящая от оболочки.
В OS X, если вы пытаетесь изменить мягкие ограничения для демона, процесса или задачи, правильный способ изменить эти мягкие ограничения не путем изменения конфигурации launchd по умолчанию для все процессов, но установив его для процесса, который вы пытаетесь запустить.
Это выполняется в вашем файле launchd .plist для вашего процесса.
Если у вас запущен демон или процесс, для которого нужно иметь больше открытых файлов, создайте для него файл plist и добавьте к нему следующие параметры:
<key>SoftResourceLimits</key>
<dict>
<key>NumberOfFiles</key>
<integer>1024</integer>
</dict>
Пример с использованием mongodb. Я создаю файл .plist с именем org.mongo.mongodb.plist и сохраняю его в /Library/LaunchDaemons/org.mongo.mongodb.plist. Файл выглядит так:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<false/>
<key>Label</key>
<string>org.mongo.mongod</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/lib/mongodb/bin/mongod</string>
<string>--dbpath</string>
<string>/Users/Shared/mongodata/</string>
<string>--logpath</string>
<string>/var/log/mongodb.log</string>
</array>
<key>QueueDirectories</key>
<array/>
<key>RunAtLoad</key>
<true/>
<key>UserName</key>
<string>daemon</string>
<key>SoftResourceLimits</key>
<dict>
<key>NumberOfFiles</key>
<integer>1024</integer>
<key>NumberOfProcesses</key>
<integer>512</integer>
</dict>
</dict>
</plist>
Теперь у вашего процесса есть необходимые ему ресурсы, и вы не нарушаете глобальную конфигурацию системы. Это будет автоматически установлено при перезапуске. Или, если вы не хотите перезапускать, вы можете запустить
sudo launchctl load /Library/LaunchDaemons/org.mongod.plist
Если ваш процесс или задача - это скорее агент, чем демон, вместо этого вы можете поместить .plist в / Library / LaunchAgents. В любом случае применяются разные правила для того, как launchd будет управлять вашим процессом. LaunchDaemons кажется зарезервированным для процессов, которые launchd всегда будет стараться не отставать.
Следующие действия должны разрешить большинство решений (и перечислены в порядке их иерархии):
echo 'kern.maxfiles=20480' | sudo tee -a /etc/sysctl.conf
echo -e 'limit maxfiles 8192 20480\nlimit maxproc 1000 2000' | sudo tee -a /etc/launchd.conf
echo 'ulimit -n 4096' | sudo tee -a /etc/profile
Ноты:
Мой опыт показывает, что моя задача с большим количеством процессов была успешной только с:
kern.maxproc=2500 # This is as big as I could set it.
kern.maxprocperuid=2048
ulimit -u 2048
Первые два могут войти в /etc/sysctl.conf
и значение ulimit в launchd.conf для надежной настройки.
Поскольку tcp / ip был частью того, что я делал, мне также нужно было увеличить
kern.ipc.somaxconn=8192
по умолчанию 128.
До того, как я увеличил пределы процесса, я получал сбои "вилки", нехватку ресурсов. До того, как я увеличил kern.ipc.somaxconn, я получал ошибку «сломанная труба».
Это было при запуске изрядного количества (500-4000) отдельных процессов на моем чудовищном Mac, OS 10.5.7, затем 10.5.8, теперь 10.6.1. Под Linux на компьютере моего начальства это просто работало.
Я думал, что количество процессов будет ближе к 1000, но похоже, что каждый процесс, который я запускал, включал свою собственную копию оболочки в дополнение к фактическому элементу, выполняющему фактическую работу. Очень празднично.
Я написал игрушку с дисплеем, которая выглядела примерно так:
#!/bin/sh
while[ 1 ]
do
n=netstat -an | wc -l
nw=netstat -an | grep WAIT | wc -l
p=ps -ef | wc -l
psh=ps -ef | fgrep sh | wc -l
echo "netstat: $n wait: $nw ps: $p sh: $psh"
sleep 0.5
done
и смотрел максимальное количество процессов в ps -ef и зависал в netstat в ожидании TIME_WAIT
до истечения срока ... С поднятыми лимитами увидел 3500+ TIME_WAIT
предметы в пике.
Прежде чем я поднял пределы, я мог «подкрасться» к порогу отказа, который вначале был ниже 1 КБ, но поднялся до высокого значения 1190 ... каждый раз, когда он был доведен до отказа, в следующий раз могло потребоваться немного больше, вероятно, из-за чего-то кэшируется, что увеличивается до предела каждый раз, когда он терпит неудачу.
Несмотря на то, что в моем тестовом примере в качестве окончательного утверждения было «ожидание», после его выхода все еще оставалось МНОЖЕСТВО отдельных процессов.
Большую часть информации я получил из сообщений в Интернете, но не вся она была точной. Ваш пробег может отличаться.