[Я разместил это на форумах Nginx, но неделю спустя не получил ответа, поэтому попробую здесь]
Я новичок в Linux и Nginx, но узнал достаточно, чтобы установить его, запустить и работать как простой обратный прокси для двух внутренних веб-серверов. Это работало нормально в течение нескольких месяцев, но недавно я начал получать 500 ошибок.
Вот недавний вывод /var/log/nginx/error.log
(Я заменил название нашей компании на "companyname.com" и заменил наш общедоступный IP-адрес в глобальной сети на
2020/02/10 15:17:49 [alert] 1069#1069: *1011 socket() failed (24: Too many open files) while connecting to upstream, client: 10.10.10.1, server: web1.companyname.com, request: "GET / HTTP/1.0", upstream: "https://<WANIP>:443/", host: "web1.companyname.com"
2020/02/10 15:21:41 [alert] 1069#1069: *2022 socket() failed (24: Too many open files) while connecting to upstream, client: 10.10.10.1, server: web2.companyname.com, request: "GET / HTTP/1.0", upstream: "https://<WANIP>:443/", host: "web2.companyname.com"
2020/02/10 15:33:28 [alert] 1084#1084: *19987 socket() failed (24: Too many open files) while connecting to upstream, client: 10.10.10.1, server: web2.companyname.com, request: "GET / HTTP/1.0", upstream: "https://<WANIP>:443/", host: "web2.companyname.com"
2020/02/10 15:34:16 [alert] 1084#1084: *39974 socket() failed (24: Too many open files) while connecting to upstream, client: 10.10.10.1, server: web1.companyname.com, request: "GET / HTTP/1.0", upstream: "https://<WANIP>:443/", host: "web1.companyname.com"
2020/02/10 15:50:30 [error] 1086#1086: *1 client intended to send too large body: 4294967295 bytes, client: 176.58.124.134, server: london.companyname.com, request: "GET /msdn.cpp HTTP/1.1", host: "<WANIP>"
2020/02/10 16:32:56 [alert] 1086#1086: *19989 socket() failed (24: Too many open files) while connecting to upstream, client: 10.10.10.1, server: web1.companyname.com, request: "GET / HTTP/1.0", upstream: "https://<WANIP>:443/", host: "web1.companyname.com"
Я добавил следующее в конец /etc/security/limits.conf
nginx soft nofile 10000
nginx hard nofile 30000
Я добавил следующее в /etc/sysctl.conf
fs.file-max=70000
... И перезагрузился. Однако сразу после перезагрузки у меня возникает та же проблема.
Интересно то, что IP-адрес, который отображается в журнале "176.58.124.134
"Я не узнаю, и быстрый поиск в Google показывает, что это оскорбительный IP-адрес. Я могу заблокировать его с помощью брандмауэра, но не уверен, что это проблема.
Любые советы, предложения приветствуются. Спасибо.
Ваш nginx сервер не успевает за количеством поступающих запросов. Точнее, в нем отсутствуют доступные файловые дескрипторы для открытия соединений с восходящим потоком.
Они регулируются тремя параметрами:
800000
на моем маленьком сервере).Жесткое ограничение на процесс (RLIMIT_NOFILE), который может быть установлен только корень (или процесс, имеющий CAP_SYS_RESOURCES
). Обычно это довольно много (ulimit -Hn
, вокруг 1000000
), поэтому увеличивать его не нужно. Если вы хотите увеличить его, pam_limit.so конфигурация /etc/security/limits.conf
воля не помочь вам, как nginx начато systemd (Я должен предположить, поскольку вы не упоминаете свой дистрибутив), который не использует PAM. Вам нужно будет отредактировать nginx.service
файл вместо этого:
systemctl edit --full nginx.service
и добавьте следующую строку в [Service]
раздел:
LimitNOFILE=your_limit
Мягкое ограничение для каждого процесса. nginx может увеличить его сам с помощью директивы, упомянутой Ромео:
worker_rlimit_nofile = your_limit;
Каждый лимит не может быть выше, чем в предыдущих пунктах.
Однако, если ваш веб-сайт не стал чрезвычайно популярным в одночасье, гораздо более вероятно, что он подвергается DDOS-атаке. Вы можете смягчить его, ограничив количество подключений на одного клиента, используя http_limit_conn модуль. Пример конфигурации в документации должен непосредственно относиться к вашему случаю:
http {
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn addr 10;
...
что ограничит количество подключений на IP-адрес до 10. В большинстве дистрибутивов вы можете поместить два limit_*
директивы в отдельном файле (например, /etc/nginx/conf.d/limit.conf
) без изменения основного nginx.conf
.