Контакты

Достижения

Все достижения (5)

Наибольший вклад в теги

Все теги (79)

Лучшие ответы пользователя

Все ответы (93)
  • MySQL запрос из двух таблиц

    seriyPS
    @seriyPS
    Надеюсь эту картинку вы знаете?



    Допустим, таблица A это SELECT * FROM games, а таблица B это SELECT * FROM uploaded_games WHERE user_id = ?.

    Т.е. вам нужно из таблицы A вычесть таблицу B (в терминах теории множеств). На картинке это левый столбец, второй сверху.

    SELECT *
    FROM games as A
    LEFT JOIN uploaded_games as B ON (A.game_id = B.game_id)
    WHERE B.game_id is NULL AND B.user_id = ?
    


    Можно записать более наглядно, но, скорее всего, MySQL его не соптимизирует эффективно

    SELECT *
    FROM games
    WHERE game_id NOT IN (
      SELECT game_id FROM uploaded_games WHERE user_id = ?
    )
    
    Ответ написан
  • Какой шаблонизатор взять для нового проекта на php?

    seriyPS
    @seriyPS
    XSLT советую. Для него можно XML-ку собрать каким нить SimpleXML — очень удобно. Каждый модуль проекта может в один и тот же объект SimpleXML вставлять свои данные а потом XSLT уже выбирает то, что ему нужно.

    Из плюсов — хорошо переносится между языками (если вдруг понадобится), можно с помощью тех — же XSLT попробовать реализовать REST API. Да просто довольно правильный стиль навязывает при создании шаблонов. Опять же, для NGINX есть модули для XSL трансформации внутри него (хотя смысла делать шаблонизацию внутри легкого асинхронного веб-сервера я лично не вижу)

    Если умудриться распарсенные шаблоны каким-то образом сохранять в памяти между запросами (на PHP трудно реализуемо пожалуй) то вообще летать будет.
    Ответ написан
  • Как обрабатывает множество одновременных запросов серверная часть сайта на php?

    seriyPS
    @seriyPS
    Объяснение не будет привязано конкретно к PHP и Nginx, но будет более-менее одинаково применимо к любому сетевому сервису работающему по prefork-модели.

    Пререквизиты:
    1. Имеется серверное ПО, которое делает системный вызов `accept()` на сокете на определённом TCP порту (например, Nginx на порту 443)
    2. Имеется ограниченное количество (N) процессов-обработчиков (бэкенд), каждый из которых может обрабатывать только один запрос одновременно. Но сами по себе процессы-обработчики могут работать параллельно и независимо друг от друга. Т.е. в момент времени может обрабатываться не больше N запросов (например, php-fpm)
    3. Для простоты будем считать что запросы - HTTP и не будем касаться KEEP-ALIVE; так же будем считать, что `accept()` делается только из одного потока

    Дело в том, что в реальном мире не существует "1000 запросов пришло одновременно". Они всегда приходят в определённом порядке, т.к. просто сетевые пакеты приходят по проводу в каком-то порядке. Системный вызов `accept()` всегда возвращает только один подключившийся сокет, чтобы получить следующий нужно вызвать `accept()` ещё раз. Таким образом, какой из клиентов первым установил TCP соединение тот и будет считаться первым (правда в случае с nginx и http скорее всего nginx не будет передавать запрос бэкенду до того как клиент не отправит весь запрос полностью, т.е. первым будет передан на обработку бэкенду тот запрос, который будет первым полностью отправлен клиентом - т.е. как только после очередного `read()` из сокета http парсер nginx поймет что клиент отправил запрос полностью, тогда и передаст запрос бэкендам).

    Бэкенды как правило бывают организованы в пул.
    Наиболее популярная реализация пула выглядит так:

    * Имеется очередь для запросов. Очередь может быть бесконечного размера, может иметь ограничение на максимальное количество запросов в очереди (backlog), может иметь ограничение на то как долго запрос может лежать в очереди (timeout) и прочее.
    * Воркеры бэкенда, не занятые обработкой запроса, тем или иным способом (mutex/spin-wait etc) проверяют есть ли сейчас задания в конце очереди. Если нет, блокируются в ожидании их появления. Если есть, забирает задание из очереди, обрабатывает его, возаращая ответ, и снова идет проверять очередь. Если все воркеры заняты обработкой запросов, то длина очереди не будет уменьшаться пока один из них не освободится.
    * Ну а сервер который принимает запросы (nginx) просто добавляет запросы в начало очереди. Если очередь имеет ограничения по длине и переполнена, попытка добавить новый запрос приводит к ошибке (например, "502 Bad Gateway"). Если у очереди есть максимальное время нахождения в ней запроса и это время исткело, запрос будет удалён из очереди и будет возвращена ошибка (напр "504 Gateway Time-out").

    Теперь представим ситуацию, что у нас есть nginx и N = 50 процессов-обработчиков (например 50 форков php-fpm). На сервер пришло "одновременно" 1000 запросов (как выяснили выше, одновременно всё-же подразумевает явный порядок). Т.е. все 1000 запросов будут добавлены в очередь пула "одновременно" в цикле один за другим. Пусть на обработку одного запроса процессу бэкенда нужна одна секунда, лимит длины очереди (backlog) выставлен в 800 запросов и timeout в 10 секунд. При таком раскладе первые 50 запросов сразу будут подхвачены воркерами и будут обрабатыватсья 1 секунду. Из оставшихся 950ти следующие 800 будут помещены в очередь а последние 150 сразу же отвалятся с ошибкой "502 Bad Gateway".
    Т.к. наш пул воркеров способен обработать 50 запросов в секунду (`50 воркеров / 1 секунда на запрос`) то из 800 добавленных в очередь запросов за время до таймаута 10 секунд они успеют обработать ещё 50 * 10 = 500 запросов (или 50 * 9 = 450 если время собственно обработки тоже считается). Остальные 800 - 500 = 300 отвалятся с "504 Gateway Time-out". А ответы на запросы будут возвращены так: через 1 секунду с момента отправки запросов ответы на первые 50 запросов, через 2 секунды на следующие 50, через 3 на следующие 50 и т.д. до 10 секунд. Т.е. наиболее удачливые будут ждать 1 секунду, менее удачливые 2 секунды, максимальое ожидание составит 10 секунд.

    Немного упрощённо и грубовато, но общее представление должно дать.
    Ответ написан
  • А что вы делаете после установки ubuntu?

    seriyPS
    @seriyPS
    При установке с нуля ставлю кодеки, архиваторы, Chrome, флеш, скайп.

    Но стараюсь по-возможности сохранить список софта с уже настроенного компа dpkg --get-selections > software_list и применить его к новой установке dpkg --set-selections < software_list ; apt-get dselect-upgrade.
    Ответ написан