• Как ускорить отдачу динамически генерируемых thumbnail'ов на PHP + GD?

    @OnlyMyQuestion
    Алексей Медведев, в дополнению к ответу, указанному выше, проверьте количесто воркеров php, возможно, вам просто не хватает количества, и изображения генерируются по очереди. И в добавок, настройте путь для thumbs, не thumb.php?xxx, а /thumbs/size/oroginal.jpg, или что-то похожее. Если файла нет - должен отрабатывать скрипт, генерироваться нужный размер и ложиться в путь запроса, после этого, можете отдать 30* редирект на данный путь и файл отдастся уже самим web сервером (и будет так делать впредь), ибо отдача файлов через php - зло, быстро заблокируете все воркеры при нагрузке.
  • Как всё-таки правильно сделать аутентификацию на php?

    @OnlyMyQuestion
    Нет, REMOTE_ADDR не может подделаться клиентом в явном виде. Для подделывания использывается "IP-спуфинг", но ответ не придет атакующему в прямом виде, а отправиться на поддельный IP, есть варианты обхода и данного ограничения, но все это сложно и описать парой строк невозможно. Если используется proxy, то в данном поле будет находиться ip proxy сервера, а реальный ip клиента будет в HTTP_X_FORWARDED_FOR, или подобном ключе. Если рассмотреть в данном контексте обработку безопасности REMOTE_ADDR достаточно безопасен, в отличии от HTTP_* ключей, которые на деле являются заголовками запроса и легко могут быть подделаны клиентом.
    В REMOTE_ADDR, может находится и адрес клиента, при работе через proxy, но данная настройка происходит на сервере, пример:
    Пускаем трафик через cloudflare, в nginx для масок cloudflare, ставит настройку для замены REMOTE_ADDR на X_FORWARDED_FOR.
    Технически - REMOTE_ADDR подделан, но он верный, так как cloudflare не пропустит поддельный заголовок X_FORWARDED_FOR, а назначит его сам.
  • Как убрать предупреждение file_get_contents?

    @OnlyMyQuestion
    BoShurik, согласен, так намного красивее, но это не сработает с большинством кода - любая другая библиотека может переопределять error_handler и нет уверенности, что error_get_last что-то вернет.
    Пример, в том же symfony и laravel - свой обработчик ошибок, и при использовании данного метода получится такая ситуация:

    <?php
    /*
     * Обычно, хандлер работает по такой логике:
     * debug = true - warning пишется в лог, ошибки не происходит
     * debug = false - пишем в лог, выкидывем исключение
     */
    define('DEBUG', false);
    
    // где-то вдали
    function framework_handler($code, $message){
    
        // ...
        // Пишем в лог
    
        if(DEBUG){
            throw new \Exception($message);
        }
    
        return true;
    }
    
    set_error_handler('framework_handler');
    
    function read($filename)
    {
        if (($content = @file_get_contents($filename)) === false) {
            var_dump('Last error: '.error_get_last());
        }
    
        return $content;
    }
    
    read(__DIR__.'/.none');


    Поиграйте с DEBUG - в любом случае код не будет работать так, как ожидалось.
    P.S Первый раз приятно общаться на данном портале, ибо ведется адекватный и интересный диалог.
  • Как убрать предупреждение file_get_contents?

    @OnlyMyQuestion
    BoShurik, это сравнимо с первым вариантом, считаю приемлемым. Второй вариант не подходит из-за описанных выше проблем, тем более, если мы имеем дело с производительностью.
    Поиграйтесь, и увидете ошибку.

    <?php declare(ticks=3);
    
    $start = microtime(true);
    
    $test = __DIR__.'/.test';
    
    register_tick_function(function () use ($test) {
        unlink($test);
    });
    
    if(!is_file($test)){
        file_put_contents($test, 'test');
    }
    
    
    for ($i = 0; $i < 100000; $i++) {
        file_put_contents($test, 'test', FILE_APPEND);
    
        if (file_exists($test)) {
            $content = file_get_contents($test);
        }
    }


    После чего вариант номер два превращается в:
    <?php
    
    $start = microtime(true);
    
    fclose(STDERR);
    
    ob_start();
    for ($i = 0; $i < 100000; $i++) {
    
        $filename = $i . '.txt';
    
        if (true) {
            $content = file_get_contents($filename);
        }
    }
    
    ob_end_clean();
    
    var_dump(microtime(true) - $start);


    Где не имеет такой абстрактной производительности. Да, если файлы не меняются соседями - нет проблем,
    в параллельных запросах, где файл быстро меняется - все может легко встать боком, и вылетим мы не внутри нашего кода обработки, а в том-же exception_handler фреймворка. На самом деле, мое мнение - лучше код из совокупности 2 и третьего метода, т.к он сгладит скорость и решит проблему атомарности:

    <?php
    
    $start = microtime(true);
    
    function read($filename)
    {
        set_error_handler(function () {
            throw new \Exception();
        });
    
        try {
            if(is_file($filename)){
                return file_get_contents($filename);
            }
    
            throw new \Exception();
        } finally {
            restore_error_handler();
        }
    }
    
    for ($i = 0; $i < 100000; $i++) {
        $filename = $i . '.txt';
    
       try{
           $content = read($filename);
       }catch (\Throwable $e){
    
       }
    }
    
    // float(5.6699061393738) - текущий, при втором варианте - float(5.537750005722)
    var_dump(microtime(true) - $start);


    Примерно, равен скорости 2 варианта, и не имеет его недостатков, но это уже если мы говорим о критичной производительности. При 10 чтении файлов на запрос - другие методы будут узким горлышком.
  • Как убрать предупреждение file_get_contents?

    @OnlyMyQuestion
    BoShurik, вся суть в оверхеде на создание нового класса. У вас есть и другие классы в приложении, да и если вы обрабатываете 10к файлов, то вы это делаете не для отдачи в браузер, а в задачах воркерами, где это не критично, зато более понятно.
  • Как убрать предупреждение file_get_contents?

    @OnlyMyQuestion
    BoShurik, оверхед который ничего не дает. В моем случае с exception - производительность та же, но мы можем конкретно узнать о том, что файла нет или о том, что он пустой, чего не получиться в вашем случае.
    Также, ваш бенчмарк лишь показывает нагрузку при создании нового класса ошибки. В итоге 3 вариант равен второму по производительности уже при получении ошибки, второй быстрее, но имеет дыру в виде удаления между двумя проверками, а учитывая остальную работу приложения и то, что за раз 10к файлов ни кто не будет читать быстро - ситуация абсурдная.
  • Как убрать предупреждение file_get_contents?

    @OnlyMyQuestion
    BoShurik, Ну, когда руки не из того места растут - тут ничего не поделать...

    <?php
    
    $start = microtime(true);
    for ($i = 0; $i < 100000; $i++) {
        $filename = $i . '.txt';
        $content = @file_get_contents($filename);
    }
    
    // float(8.7935888767242)
    var_dump(microtime(true) - $start);


    <?php
    
    $start = microtime(true);
    for ($i = 0; $i < 100000; $i++) {
        $filename = $i . '.txt';
        if (file_exists($filename)) {
            $content = file_get_contents($filename);
        }
    }
    
    // float(5.4787609577179)
    var_dump(microtime(true) - $start);


    <?php
    
    $start = microtime(true);
    
    
    function read($filename)
    {
        set_error_handler(function(){
            throw new \LogicException();
        });
    
        try {
            return file_get_contents($filename);
        } catch (\LogicException $e) {
            throw $e;
        }finally{
            restore_error_handler();
        }
    }
    
    for ($i = 0; $i < 100000; $i++) {
        $filename = $i . '.txt';
    
        try{
            $content = read($filename);
        }catch (\LogicException $e){
    
        }
    }
    
    //float(9.6839311122894)
    var_dump(microtime(true) - $start);
  • Как убрать предупреждение file_get_contents?

    @OnlyMyQuestion
    edward_freedom, вам не хочется отвечать из-за того, что нечего ответить, а не из-за, якобы, стиля, где вы сами пренебрегаете панибратством.
  • Как убрать предупреждение file_get_contents?

    @OnlyMyQuestion
    edward_freedom,
    Можно было в таком случае просто отключить вывод ошибок

    Вот это действительно - худшее решение. После такого - вам лучше просто исчезнуть из обсуждения.
    Но, вы можете обосновать - чем решение try-catch - худшее? У вашего решения - проблема даже не решается, про атомарность вы явно не слышали...
  • Как убрать предупреждение file_get_contents?

    @OnlyMyQuestion
    Us59, выше описал проблему данного решения.
  • Как убрать предупреждение file_get_contents?

    @OnlyMyQuestion
    edward_freedom, ниже посмотрите - увидите мое решение. Какая у вас проблема:
    // true - файл еще существует
    $exsits = file_exists($path);
    // Кто-то другой удалил файл
    // Словим warning
    $data = file_get_contents($path);
  • Как убрать предупреждение file_get_contents?

    @OnlyMyQuestion
    Не панацея. Между двумя вызовами - будет промежуток.
  • Какие характеристики виртуального сервера необходимы для данной нагрузки?

    @OnlyMyQuestion Автор вопроса
    То, что показывает топ, можно попробовать найти в /proc, но на самом деле, кроме user/system там также считается wa, hi, si, st. Поэтому просто процент еще не означает именно нагрузку на процессор. Это как раз может быть нагрузка на дисковую систему или другие устройства.

    Да, может быть, но это не отменяет того, что top показывает процент использованного процессорного времени, выделенного планировщиком.
    Я рад, что мы пришли к консенсусу в этой напряженной дискуссии.

    Собственно, с вами - мы ни к чему не пришли. Ответ Vitaly Karasik лишь позволил мне убедиться в моих расчетах. Да они грубые, но данный способ имеет место быть для примерного вычисления. Как и оказалось - при буферизации nginx request|response - 16 fpm воркеров, которые отрабатывают за 0.015-.0.025 вполне достаточно, для 280rps, которые удалось выдать с нескольких машин, использовалось всего 10. Если установить минимальное количество воркеров больше 5 - удастся избежать резкого скачка нагрузки, и того, что fpm не успеет создать новых воркеров, что случалось при тестах из-за резких скачков 0-280 rps, и то - таких, ошибочных запросов было штук 5, а в реалиях - это не критично, посещаемость на сервере есть всегда, и количество воркеров держится на 8. В реальности - php не течет, уже больше 3х дней. Каждый воркер занимает 12-20мб, что в максимуме дает 350mb. В большую часть времени это значение в пределах 150mb. Чуть больше 100mb занимает mysql. Еще сотня уходит на nginx + остальные системные процессы.
    400mb постоянно свободно, 1.2gb занимает разные кэши, буферы, которые немного подвинутся при нужде.
    nginx работает на 1 воркере. В итоге имеем 0.05-0.4 la. Если сравнить расчеты из вопроса - можно наложить одно на другое. Собственно - все это можно уместить и на 1 ядре с 1gb ram при желании.
    Если зайти в любое облако, вы увидите кучу других подобных услуг - базы, различные сервера приложений, веб сервера, услуги для расчета, для очереди сообщений и так далее. Потому что это удобно, и это ГОРАЗДО ДЕШЕВЛЕ, чем целый виртуальный сервер как для клиента так и для хостера. Поэтому, если у вас изначально вопрос заключался в экономии финансов, то стоит рассмотреть услугу хостинга, если она подходит по ресурсам.
    Современные тренды уходят потихоньку от аренды виртуальных серверов, и переходят в сторону аренды конкретных услуг, или контейнеров. А виртуальные сервера - либо для уникальных ситуаций, либо когда нужно универсальное решение

    Облачную инфраструктуру сравнивать с хостингом - бред... В 1 случае - вы сможете накатать нужную инфраструктуру на n-ное количество инстансов, если конечно это не узкоспециализированная услуга, вроде бд, во втором - вы ограничены инструментами, которые вам предлагают. И если на вашем хостинге нет nodejs, а вы захотите ssr, то ничего, кроме костыля в виде отдельного сервиса - вы не придумаете.
  • Какие характеристики виртуального сервера необходимы для данной нагрузки?

    @OnlyMyQuestion Автор вопроса
    shurshur, но увидели ответ на вопрос, да? Учитывая то, что второй куратор сам признался в конце, что ответом на вопрос является ответ Vitaly Karasik.
  • Какие характеристики виртуального сервера необходимы для данной нагрузки?

    @OnlyMyQuestion Автор вопроса
    shurshur, то есть, адекватное и вежливое общение с собеседником для вас является "сюсюкаением"?
  • Какие характеристики виртуального сервера необходимы для данной нагрузки?

    @OnlyMyQuestion Автор вопроса
    Ну насколько я вижу вы не понимаете этой очевидной вещи, поэтому и повторяю.

    Насколько я вижу - вы мастер пропускать аргументы мимо ушей, но пытаться цепляться за каждую ниточку, чтобы оказаться правым в разговоре, который не имеет отношения к первоначальной теме.
  • Какие характеристики виртуального сервера необходимы для данной нагрузки?

    @OnlyMyQuestion Автор вопроса
    Sanes, да, так и поступил. Просто надеялся о каких-то формулах и.т.д., но по сути - ничего такого нет, как получается. А для формул - смысла в качестве сервера не было, там можно было бы высчитать эталон, померить сервер, и накинуть одно на другое.
  • Какие характеристики виртуального сервера необходимы для данной нагрузки?

    @OnlyMyQuestion Автор вопроса
    АртемЪ,
    При чем тут шлакосерверы?

    При том, что у одних селлеров виртуалок качество явно лучше, чем у других. Старые диски, как минимум.

    У всех разные сервера. Поэтому разные VDS 30gb ssd, 2 ядра, 2 гига оперативки могут отличаться по производительности на порядок.

    Вы капитан Очевидность? Повторяете то, что написал человек выше. По сути - простой спам.