BG Development


  Reply to this topicStart new topicStart Poll

> Увеличаване на ulimits, open file descriptors
relax4o
Публикувано на: 22-05-2024, 11:21
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2823
Регистриран на: 04.04.07



Здравейте,

Вчера на работа, един от тасковете, който върви на заден план умря и причината беше, че системата е стигнала лимита си за "open file handles".

Текущия лимит, който ulimit ми връща е 1024 (soft) и 524288 (hard).

Понеже няма как да рефакторнем скрипта толкова бързо, обмислям да увелича софт лимита на нещо от рода на 5000-10000.

Интересува ме, някой има ли идея дали това би оказало негативен ефект върху системата, ако не предвидя нещо предварително?


--------------------
Бисери :D

QUOTE (oveRLuckEd)
Ползваш някоя нова версия на PHP, която е вече ооп ориентирана и заради това ти я изкарва тази грешка.


QUOTE (nbacool2)
Щом няма input полета, значи няма откъде да се направи SQL инжекция Very Happy
PM
Top
ici
Публикувано на: 22-05-2024, 11:36
Quote Post


Group Icon
Име: Ивайло Илчев
Група: VIP
Ранг: Почетен член

Мнения: 18607
Регистриран на: 06.06.04



Това е памет и донякъде пърформанс за fopen, close и пр.


--------------------
Ние не сме в една лодка, ние сме в една буря. Лодките са различни.

Следващият път когато се почувстваш ненужен, грозен и недооценен, помни че освен това си и тъп.
PMEmail PosterUsers Website
Top
SuN
Публикувано на: 22-05-2024, 16:28
Quote Post


Group Icon
Име:
Група: Администратор
Ранг: Почетен член

Мнения: 12805
Регистриран на: 27.01.05



И аз очаквам да е както го пише ici, но ако желязото ви е голямо не знам дали ще го усетите. Все пак ограничението от 1024 броя отворени файлове е за всеки жив процес, а те обикновено са стотици.

Направих тест да отворя колкото се може файлове и не усетих някакъв проблем с компютъра. Ако евентуално си затваряте файловете, едва ли ще е проблем.

Описание на средата: с обикновен потребител вдигнах ограничението до 1'000'000 отворени файла и без проблем стигнах до 999'997 отворени файла преди да достигна нови ограниченията за отворени файлове. Създаването и триенето отнема десетки секунди на моята малка машинка с 4 ядра и 12гб рам и малък nvme диск.

Тестова програма:

CODE
// Изпълнение:
// g++ -Wall leaked-fd.cpp && ./a.out

// За да се почистят временните файлове, може да се изпълни тази команда:
// $ find /tmp/ -name 'leaked-file-*' -print|xargs -n 100 rm

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>

int main (int argc, char* argv[]) {
   if (argc != 2) {
       printf ("Usage: %s $positive-integer\n", argv[0]);
       return 0;
   }
   const int N = atoi (argv[1]);
   constexpr int min = 1;
   constexpr int max = 999'997; // Като обикновен потребител стигнах
                                // до това ограничение при настройка:
                                // $ ulimit -n
                                // 1000000

   if (N < min || N > max) {
       printf ("Expected a number between [%d; %d]\n", min, max);
       return 0;
   }
   
   char filepath[64];
   
   for (int i = 0; i < N; ++i) {
     snprintf (filepath, sizeof(filepath), "/tmp/leaked-file-%d", i);
     int fd = open (filepath, O_CREAT| O_RDWR, S_IRUSR | S_IWUSR);

     if (fd == -1) {
      printf ("stopping earlier than expected...\n");
      perror ("An error during file creation");
      return 0;
     }

     // утечка
     // close (fd);
   }

   return 0;
}


П.П.
След няколко оправени проблема май нагодих програмата да работи правилно, но не гарантирам, че няма още проблеми. icon_smile.gif

Това мнение е било редактирано от SuN на 22-05-2024, 16:58


--------------------
Само аз не троля.
Всички коментари са плод на художествена измислица и нямат общо с действителни и недействителни лица, събития и факти.
PMEmail Poster
Top
relax4o
Публикувано на: 22-05-2024, 17:22
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2823
Регистриран на: 04.04.07



Цял ден се опитвам да репликирам проблема на тестов сървър и не мога. С проба грешка стигнах до извода, че лимита не е само за потребител, а също и на процес.

Единственото, което не съм тествал (и за сега не искам) е изпращането на имейл. Системата като цяло е доста старо PHP и използваме доста стара библиотека на Mandrill и имам съмнения, че библиотеката не затваря мрежови потоци на време и когато има много неща за изпълнение в рамките на същия процес, то има много висящи хендлъри.

Имаме друг таск, който проверява всички имейли, които са били наредени на опашка в Мандрил и извикваме АПИ-то, за да видим новия статус.
Този таск реално преди малко забелязах, че достига хендлъри от рода на 1135 (което е повече от 1024) и изчезва и след това отново тръгва и така няколко пъти докато приключи таска. Това число ми се струва прекалено много предвид, че имейлите, които трябва да се проверят не са дори близо до това число.

Броя го проверявам чрез тази команда, но не знам колко резултата е коректен. Може и да брои неща, които вероятно не трябва да брои и от 1024 го прави на 1135.
CODE

lsof | grep -E "httpd|php" | awk '{ print $1 " " $2; }' | sort -rn | uniq -c | sort -rn | head -25


В началото мислих, че file_get_contents() не затваря навреме, но с моите тестове изглежда, че освобождава ресурса веднага след получаване на съдържанието на файла.

Сега докато пишех съобщението забелязах, че доста потоци към на Мандрил АПИ-то стоят отворени на ESTABLISHED и след това доста време стоят на CLOSE_WAIT. Не съм сигурен дали мога да направя нещо относно това и да гарантирам по-бързо приключване на потока.


--------------------
Бисери :D

QUOTE (oveRLuckEd)
Ползваш някоя нова версия на PHP, която е вече ооп ориентирана и заради това ти я изкарва тази грешка.


QUOTE (nbacool2)
Щом няма input полета, значи няма откъде да се направи SQL инжекция Very Happy
PM
Top
SuN
Публикувано на: 22-05-2024, 17:37
Quote Post


Group Icon
Име:
Група: Администратор
Ранг: Почетен член

Мнения: 12805
Регистриран на: 27.01.05



Щом ти работи дълго процеса, може да видиш броя на отворените файлове в /proc/$PID/fd. Това би трябвало да работи:
CODE
ls /proc/$PID/fd|wc -l


--------------------
Само аз не троля.
Всички коментари са плод на художествена измислица и нямат общо с действителни и недействителни лица, събития и факти.
PMEmail Poster
Top
relax4o
Публикувано на: 22-05-2024, 17:52
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2823
Регистриран на: 04.04.07



QUOTE (SuN @ 22-05-2024, 17:37)
Щом ти работи дълго процеса, може да видиш броя на отворените файлове в /proc/$PID/fd. Това би трябвало да работи:
CODE
ls /proc/$PID/fd|wc -l

Да, така умря на 1023 и стартира на ново. Разликата с моята команда е около 100 бройки. Интересното е, че процеса се рестартира (същото PID) без да ми логва грешки, докато в другия случай не умираше и логваше грешки.

Така или иначе от вчера не е ставало и ще е трудно да установя къде се е сбъркала работата, но пък открих каква идиотщина е направена в кода.


--------------------
Бисери :D

QUOTE (oveRLuckEd)
Ползваш някоя нова версия на PHP, която е вече ооп ориентирана и заради това ти я изкарва тази грешка.


QUOTE (nbacool2)
Щом няма input полета, значи няма откъде да се направи SQL инжекция Very Happy
PM
Top
SuN
Публикувано на: 22-05-2024, 18:22
Quote Post


Group Icon
Име:
Група: Администратор
Ранг: Почетен член

Мнения: 12805
Регистриран на: 27.01.05



Просто твоята команда ползва grep и е възможно да хваща повече работи - включително имена на пътища, които съдържат "/php/" или "/httpd/".

Това мнение е било редактирано от SuN на 22-05-2024, 18:27


--------------------
Само аз не троля.
Всички коментари са плод на художествена измислица и нямат общо с действителни и недействителни лица, събития и факти.
PMEmail Poster
Top
relax4o
Публикувано на: 22-05-2024, 18:48
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2823
Регистриран на: 04.04.07



QUOTE (SuN @ 22-05-2024, 18:22)
Просто твоята команда ползва grep и е възможно да хваща повече работи - включително имена на пътища, които съдържат "/php/" или "/httpd/".

Всъщност да. Трябваше да сложа grep след awk.

Благодаря и на двамата за мненията. Утре ще вдигна ulimit на Апаче (все още не знам дали това ще делегира броя към php процеса - ако не ще трябва да ровя как да го вдигна за конкретен процес). Въпреки, че системата не е с фрапантни ресурси (2 ядра, 4гб рам и nvme), вдигане до 4000-5000 не би трябвало да окаже проблем.

Реално установих, че само 1-2 таска могат да достигнат този лимит на този етап и докато оправим бъговете (единия е лесен, другия не толкова) би трябвало да е наред.

Иначе, проблема идва от там, че не преизползваме инстанция на Мандрил (curl), а за всеки един имейл отваряме нов хендъл.


--------------------
Бисери :D

QUOTE (oveRLuckEd)
Ползваш някоя нова версия на PHP, която е вече ооп ориентирана и заради това ти я изкарва тази грешка.


QUOTE (nbacool2)
Щом няма input полета, значи няма откъде да се направи SQL инжекция Very Happy
PM
Top
1 потребители преглеждат тази тема в момента (1 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2019 | BG Development | All Rights Reserved
RSS 2.0