Содержание

PHP: Сокеты — Manual

Change language: EnglishBrazilian PortugueseChinese (Simplified)FrenchGermanJapaneseRomanianRussianSpanishTurkishOther

  • Введение
  • Установка и настройка
  • Предопределённые константы
  • Примеры
  • Ошибки сокетов
  • Функции сокета
    • socket_accept — Принимает соединение на сокете
    • socket_addrinfo_bind — Создать и привязать к сокету из указанного addrinfo
    • socket_addrinfo_connect — Создать и подключиться к сокету из указанного addrinfo
    • socket_addrinfo_explain — Получить информацию о addrinfo
    • socket_addrinfo_lookup — Получить массив с содержимым getaddrinfo про указанное имя хоста
    • socket_bind — Привязывает имя к сокету
    • socket_clear_error — Очищает ошибку на сокете или последний код ошибки
    • socket_close — Закрывает экземпляр Socket
    • socket_cmsg_space — Вычислить размер буфера сообщения
    • socket_connect — Начинает соединение с сокетом
    • socket_create_listen — Открывает сокет на указанном порту для принятия соединений
    • socket_create_pair — Создаёт пару неразличимых сокетов и сохраняет их в массиве
    • socket_create — Создаёт сокет (конечную точку для обмена информацией)
    • socket_export_stream — Экспортировать сокет в поток, инкапсулирующий сокет
    • socket_get_option — Получает опции потока для сокета
    • socket_getopt — Псевдоним socket_get_option
    • socket_getpeername — Запрашивает удалённую сторону указанного сокета, в результате может быть возвращён хост/порт или путь в файловой системе Unix, в зависимости от типа сокета
    • socket_getsockname — Запрашивает локальную сторону указанного сокета, в результате можно получить хост/порт или путь в файловой системе Unix, в зависимости от типа сокета
    • socket_import_stream — Импортировать поток
    • socket_last_error — Возвращает последнюю ошибку на сокете
    • socket_listen — Прослушивает входящие соединения на сокете
    • socket_read — Читает строку максимальную длину байт из сокета
    • socket_recv — Получает данные из подсоединённого сокета
    • socket_recvfrom — Получает данные из сокета, независимо от того, подсоединён он или нет
    • socket_recvmsg — Прочитать сообщение
    • socket_select — Запускает системный вызов select() для заданных массивов сокетов с указанным тайм-аутом
    • socket_send — Отправляет данные в подсоединённый сокет
    • socket_sendmsg — Отправить сообщение
    • socket_sendto — Отправляет сообщение в сокет, независимо от того, подсоединён он или нет
    • socket_set_block — Устанавливает блокирующий режим на сокете
    • socket_set_nonblock — Устанавливает неблокирующий режим для файлового дескриптора fd
    • socket_set_option — Устанавливает опции для сокета
    • socket_setopt — Псевдоним socket_set_option
    • socket_shutdown — Завершает работу сокета на получение и/или отправку данных
    • socket_strerror — Возвращает строку, описывающую ошибку сокета
    • socket_write — Запись в сокет
    • socket_wsaprotocol_info_export — Экспорт структуры WSAPROTOCOL_INFO
    • socket_wsaprotocol_info_import — Импортирует сокет из другого процесса
    • socket_wsaprotocol_info_release — Высвобождает экспортированную структуру WSAPROTOCOL_INFO
  • Socket — Класс Socket
  • AddressInfo — Класс AddressInfo

There are no user contributed notes for this page.

PHP: Сокеты — Manual

Change language: EnglishBrazilian PortugueseChinese (Simplified)FrenchGermanJapaneseRomanianRussianSpanishTurkishOther

  • Введение
  • Установка и настройка
  • Предопределенные константы
  • Примеры
  • Ошибки сокетов
  • Сокетные Функции
    • socket_accept — Принимает соединение на сокете
    • socket_bind — Привязывает имя к сокету
    • socket_clear_error — Очищает ошибку на сокете или последний код ошибки
    • socket_close — Закрывает ресурс сокета
    • socket_cmsg_space — Calculate message buffer size
    • socket_connect — Начинает соединение с сокетом
    • socket_create_listen — Открывает сокет на указанном порту для принятия соединений
    • socket_create_pair — Создаёт пару неразличимых сокетов и сохраняет их в массиве
    • socket_create — Создаёт сокет (конечную точку для обмена информацией)
    • socket_get_option — Gets socket options for the socket
    • socket_getopt — Псевдоним socket_get_option
    • socket_getpeername — Запрашивает удалённую сторону указанного сокета, в результате может быть возвращен хост/порт или путь в файловой системе Unix, в зависимости от типа сокета
    • socket_getsockname — Опрашивает локальную сторону указанного сокета, в результате можно получить хост/порт или путь в файловой системе Unix, в зависимости от типа сокета
    • socket_import_stream — Import a stream
    • socket_last_error — Возвращает последнюю ошибку на сокете
    • socket_listen — Прослушивает входящие соединения на сокете
    • socket_read — Читает строку байт максимальной длины length из сокета
    • socket_recv — Получает данные из подсоединённого сокета
    • socket_recvfrom — Получает данные из сокета, независимо от того, подсоединён он или нет
    • socket_recvmsg — Read a message
    • socket_select — Runs the select() system call on the given arrays of sockets with a specified timeout
    • socket_send — Отправляет данные в подсоединённый сокет
    • socket_sendmsg — Send a message
    • socket_sendto — Отправляет сообщение в сокет, независимо от того, подсоединён он или нет
    • socket_set_block — Устанавливает блокирующий режим на ресурсе сокета
    • socket_set_nonblock — Устанавливает неблокирующий режим для файлового дескриптора fd
    • socket_set_option — Устанавливает опции для сокета
    • socket_setopt — Псевдоним socket_set_option
    • socket_shutdown — Завершает работу сокета на получение и/или отправку данных
    • socket_strerror — Возвращает строку, описывающую ошибку сокета
    • socket_write — Запись в сокет

There are no user contributed notes for this page.

Что такое сокет в PHP

Вы здесь: Главная — PHP — PHP Основы — Что такое сокет в PHP

Не так давно меня попросили рассказать про сокеты на PHP. Вообще я планирую написать ещё несколько статей в ближайшее время по этой теме, а в этой статье я расскажу о том, что такое сокеты в PHP

. Чтобы Вы уже могли понять, нужны они Вам или нет.

Сокет — это интерфейс взаимодействия клиента и сервера. Интерфейс — это, в свою очередь, правило, по которым происходит общение между клиентом и сервером. Чтобы стало понятнее, приведу пример из обычной жизни. Например, люди общаются с помощью слов на конкретном языке. Это наш с Вами интерфейс. В зависимости от входящих слов мы формируем образ у себя в голове, и отдаём ответ, в виде опять же слов. Другой пример, дельфины общаются в ультразвуком спектре, и это их интерфейс.

Надеюсь, про интерфейс теперь понятно, это правило взаимодействия. Теперь про клиента. Клиентом может выступать как человек, формирующий определённые запросы к серверу, так и программа, написанная на любом языке программирования, способном обмениваться данными с удалённым сервером. Сервер — это машина, ждущая подключения клиентов, принимающая от них запросы, и в зависимости от запросов, возвращающая ответ.

Кратко резюмирую, что же такое сокет: есть клиент, есть сервер, есть правила взаимодействия (интерфейс), клиент, согласно этим правилам, посылает запрос, а сервер данный запрос принимает и, согласно тем же правилам, даёт ответ.

Как видите, всё совсем не сложно. Очень здорово то, что клиент и сервер могут быть написаны на совсем разных языках программирования и могут находиться друг от друга за тысячи километров. Мы же с Вами будет писать и клиент, и сервер в будущих статьях на языке PHP.

  • Создано 13.01.2012 14:01:12
  • Михаил Русаков
Предыдущая статья Следующая статья

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:
    <a href=»https://myrusakov.ru» target=»_blank»><img src=»https://myrusakov.ru/images/button.gif» alt=»Как создать свой сайт» /></a>

    Она выглядит вот так:

  2. Текстовая ссылка:
    <a href=»https://myrusakov.ru» target=»_blank»>Как создать свой сайт</a>

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):
    [URL=»https://myrusakov.ru»]Как создать свой сайт[/URL]

Nginx unix socket, ускорение Nginx в связки с PHP-FPM

В Nginx unix socket — способ подключения к бэкенду в виде PHP-FPM, позволяющий избежать сетевых запросов и дающий значительный прирос в скорости работы.

 

Nginx является самым быстрым веб-сервером, но он не может обрабатывать скрипты. Для этого нужен бэкенд в виде Apache или PHP-FPM. Для Ruby/Python применяются другие бэкенды.

 

 

Использование Unix сокета вместо TCP сокета позволяет работать быстрее за счет отсутствия сетевых запросов (

обращений к 127.0.0.1).

 

Рассмотрим установку на Debian 9. Для дистрибутива FPM сразу запускается на unix socket-е. Все, что нужно для более ранних версий Debian, Centos или Ubuntu — привести состояние конфигурационных файлов к такому.

 

Устанавливаем пакеты на новый облачный сервер

apt-get install php-fpm

apt-get install nginx

 

Настройка Nginx

Создаем файл виртуального хоста

cd /etc/nginx/sites-available && mcedit fpm

server {
listen 80;
server_name fpm.com;

root /var/www/fpm.com;
index index.php index.html;

location / {
try_files $uri $uri/ =404;
}

location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
# fastcgi_pass 127.0.0.1:9000;
}

}

 

В последней секции задано, что при обработке всех файлов с расширением .php запросу нужно направлять на unix сокет unix:/var/run/php/php7.0-fpm.sock. В случае с TCP эта строк комментируется, с fastcgi_pass 127.0.0.1:9000; знак комментария снимается.

 

 

fpm.com нужно добавить в файл hosts на компьютере.

 

Далее тестовый скрипт

mcedit /var/www/fpm.com/index.php

<?php
echo «Works»;
?>

 

Активируем виртуальный хост

ln -s /etc/nginx/sites-available/fpm /etc/nginx/sites-enabled/

 

Перечитываем конфигурацию

nginx -s reload

 

 

 

Настройка FPM

PHP-FPM запущен, но в netstat -nltp его не увидеть, потому, что TCP-сокет не используется

ss -l | grep fpm

u_str LISTEN 0 128 /run/php/php7.0-fpm.sock 17149 * 0

 

В файле /etc/php/7.0/fpm/pool.d/www.conf директивой listen для FPM задается как запускать службу. Unix сокет или комбинация порта и IP адреса.

 

Значение всегда можно поменять, что и требуется сделать когда нужен переход с TCP на Unix-сокет. Дополнительно к внесению изменений в Nginx.

 

mcedit /etc/php/7.0/fpm/pool.d/www.conf

listen = /run/php/php7.0-fpm.sock
listen.owner = www-data
listen.group = www-data

 


Обратившись в браузере к URL, который выбран для тестирования, можно увидеть, что PHP скрипт выполняется.

 

Это говорит об успешном перенаправлении запросов на /run/php/php7.0-fpm.sock и о том, что конфигурация с Nginx unix socket работает.

 

Если обращений к серверу много, улучшить производительность позволит тонкая настройка Nginx.

Разница betweens php socket Функции ввода/вывода

Inconsistency and redundancy seem to be hallmarks of PHP unfortunately: you do have a lot from which to choose. And streams are just plain confusing frankly.

I think what’s important to keep in mind in this case is that some functions that operate on sockets are generic and others are more specific. The PHP streams API attempts to provide a way to generalize file/network operations and therefore provides generic functions for common operations such as fwrite and fread. That’s why you can fopen a Web page, local file or compressed archive all with the same function. However the stream_socket_*() family of functions are more specific and provide extra functionality that pertain only to sockets. For example, the stream_socket_recvfrom() and stream_socket_sendto() calls allow for out-of-band data channels (essentially a way to multiplex another data stream using a single connection).

I’ll try to compare/contrast some of the generic versus specific PHP functions as they apply to sockets.

  • fopen() vs stream_socket_client(): You can fopen a TCP connection for example but suppose you wanted to get more information about the connection status or handle timeouts. The stream_socket_client() function allows you to set connection timeout status and get more advanced error feedback when a connection is unsuccessful. It also allows you to connect asynchronously (i.e. in non-blocking mode).

  • fread()/fwrite() vs stream_socket_sendto()/stream_socket_recvfrom(): As already stated you can receive/send out-of-band data using the later set of functions; you can also encapsulate the connection and read/write operations into a single call.

  • fclose() vs stream_socket_shutdown(): These aren’t exactly analogous but the names imply something similar. You still want to call fclose to free the socket and any associated memory. The function of stream_socket_shutdown is to shutdown a channel (either send or receive) in the underlying TCP connection. For example, you can stop sending on a full-duplex socket but still keep reading.

Note: this next comparison isn’t really a comparison between a generic, stream function and a socket-specific function. It is a comparison of two generic stream functions that happen to do different things. I included it since you mentioned it in the question.

  • fread() vs stream_get_contents(): fread reads up to a pre-determined amount of bytes; stream_get_contents reads the remaining data on the stream. You can see this is pretty much a convenience function that can improve performance. However there are times when you need to stream the data in using fread such as when you expect a lot of data that can’t fit into main memory.

Hopefully you get the idea. A lot of this parallels the structure of the lower-level programming interfaces. In Linux, for example, the interfaces for working with I/O devices are polymorphic. You can read() on a file, domain socket, stream socket, datagram socket, pipe, fifo, ETC. However there are functions for specifically operating on a certain type of I/O device (e.g. send() is called only on sockets).

I would recommend choosing what best fits your needs and not predispose yourself to any general rules regarding what to use. For example, if you need to GET a Web page over HTTP, just use file_get_contents. If you know the response is going to be huge you might want to fopen it and stream the result to disk. If you need to implement a client for a custom protocol then I would use the more specific stream socket family of functions that give you more fine tuned control.

AMD рассказала о перспективах Socket AM4

Вчера вместе с новыми 4-ядерными процессорами Ryzen 3 3100 и Ryzen 3 3300X был представлен и чипсет B550. Причем не все новости были радостными, что связано с совместимостью между разными чипсетами и поколениями Ryzen. AMD впервые рассказала о совместимости грядущих процессоров Ryzen на архитектуре Zen 3. Сомнений не осталось: они будут работать только на материнских платах на чипсетах X570 и B550.

Интересно, что даже для линейки Ryzen 4000 (если настольные процессоры будут так называться) останется сокет AM4, который можно назвать вполне надежной платформой. AMD начала разрабатывать сокет AM4 девять лет назад, впервые он был использован 5 сентября 2016 вместе с APU Bristol Ridge.

В своем блоге AMD рассказала о прошлом и будущем Socket AM4. И Socket AM4 пережил несколько событий:

  • Число ядер и потоков увеличилось в четыре раза после объявления процессоров (4C4T → 16C32T)
  • На Socket AM4 использовались четыре архитектуры (Excavator → Zen → Zen+ → Zen 2)
  • Процессоры на Socket AM4 изготавливались по разным техпроцессам (28 nm → 14 nm → 12 nm → 7 nm)
  • Число линий PCI Express и их скорость увеличились с 12x PCIe 3.0 до 24x PCIe 4.0
  • Память DDR4 увеличилась с DDR4-2400 до DDR4-3200+

Многие упомянутые факторы весьма интересны, поскольку они показывают, насколько предусмотрительными оказались инженеры AMD. Удвоение линий PCI Express, например, потребовало изначально зарезервировать значительную часть из 1.331 контактов, которые первое время не использовались. То же самое касается и мощности питания, поскольку если TDP менялся и не так значительно, подача питания на четыре или 16 ядер отличается. Схожая ситуация и с использованием разных техпроцессов.

С другой стороны, меняющиеся архитектуры и растущая скорость памяти вряд ли накладывают существенные ограничения на сокет, поэтому они не так сильно сказались на сроке жизни AM4.

Но перейдем к вопросам, касающимся перспектив сокета AM4:

Будет ли архитектура Zen 3 совместима с Socket AM4?

«Yes! AMD officially plans to support next-gen AMD Ryzen desktop processors, with the “Zen 3” architecture, on AMD X570 and B550 motherboards. This will require a BIOS update. Specific details about this update will come at a later time, but we’re committed to keeping you up-to-date.»

Так что AMD ответила на вопрос утвердительно, но только для материнских плат на чипсете X570 и B550. Конечно, потребуется обновление BIOS.

Что насчет старых чипсетов и Zen 3?

«AMD has no plans to introduce “Zen 3” architecture support for older chipsets.»

На данный вопрос AMD ответила отрицательно. И если раньше можно было использовать для свежих поколений Ryzen, по крайней мере, одно-два предыдущих поколения чипсетов, то в случае Zen 3 этого уже не будет.

Будет ли Socket AM4 актуален после Zen 3?

«This will depend on the schedule of industry I/O technologies. Such technology changes typically require adjustments to the pin count or layout of a processor package, which would necessitate a new socket. We have no specific details to share concerning this roadmap or timing right now, but we know it’s important to keep you updated—and we will.»

AMD пока не стала делиться какими-либо подробностями и давать обещания. Компания указывает на будущие технологии ввода/вывода, также и добавление памяти DDR5 с 2021 года может сыграть свою роль.

Проблема совместимости

Если верить AMD, процессоры Ryzen на архитектуре Zen 3 будут работать только на материнских платах с чипсетами X570 и B550. Появятся ли к тому времени еще чипсеты X670 и B650 — неизвестно.

Досада пользователей была велика, поскольку все владельцы материнских плат на X470 уже не могут рассчитывать на процессоры Ryzen с архитектурой Zen 3, что несколько подрывает доверие к обещаниям AMD насчет долгого срока службы платформы.

Цвет полосок на диаграмме уже намекают на ограничения в прошлом. Из-за разнообразия процессоров AM4 и микрокода файлы BIOS значительно увеличились в размерах, и стандартные чипы BIOS на 8 или 16 Мбайт просто не могут их вместить. Некоторые производители материнских плат даже выпустили два разных BIOS для разных процессоров. Подобная проблема наблюдается и у некоторых материнских плат под EPYC.

Повлияла ли данная причина на ограничения по процессорам Ryzen на архитектуре Zen 3, неизвестно. AMD говорит об ограничениях из-за BIOS, но, как мы упомянули выше, производители материнских плат нашли выход, предложив разные версии, в зависимости от используемого процессора. Конечно, такой шаг тоже приводит к техническим сложностям, поскольку прошить BIOS можно только при наличии процессора в сокете. Только у high-end материнских плат имеется возможность прошивки BIOS без процессора.

В конечном итоге AMD лишь дает рекомендации, но производитель материнской платы уже сам решает, какие процессоры он будет поддерживать в BIOS. Например, есть материнские платы X570, которые работают с процессорами Ryzen первого поколения, пусть даже AMD данную возможность не предусматривает. Хотя есть и исключения. В любом случае, лучше руководствоваться приведенной иллюстрацией, определяя совместимость процессоров с платформами.

AMD уже обеспечивает достаточную гибкость

Почему же пользователи жалуются на то, что не смогут устанавливать процессоры Ryzen на архитектуре Zen 3 на материнские платы X470 и B450?

На этот вопрос сложно ответить, поскольку AMD многие годы обеспечивала довольно гибкую и долговечную платформу Socket AM4, но компании приходится преодолевать различные трудности. Не только технические, но и экономические.

DПроизводители материнских плат хотят продавать свои продукты, да и ASUS, ASRock, Gigabyte, MSI и другие компании постоянно представляют какие-либо инновации. Конечно, здесь можно посетовать на жадность производителей материнских плат, но есть и другие нюансы.

Ниже приведены разные чипсеты под Socket AM4.

Сравнение чипсетов
B350X370B450X470B550X570
Подключение CPU4x PCIe 2.04x PCIe 3.04x PCIe 3.04x PCIe 3.04x PCIe 3.04x PCIe 4.0
USB 3.2 Gen 2222228
USB 3.2 Gen 126262
USB 2.0666664
SATA46684 (+2) 4 (+4)
Дополнительные линии6x PCIe 2.08x PCIe 2.06x PCIe 2.08x PCIe 2.06x PCIe 3.08x PCIe 4.0
Техпроцесс 55 nm55 nm55 nm55 nm14 nm14 nm
TDP6,8 W6,8 W4,8 W4,8 W5 W11 W

Современный чипсет X570 был разработан AMD. Он представляет собой кристалл IOD процессора Ryzen, преобразованный в чипсет. Производство выполняется по 14-нм технологии, из-за поддержки линий PCIe 4.0 со стороны чипсета тепловой пакет увеличен до 11 Вт, поэтому без активного охлаждения под нагрузкой уже не обойтись. Чипсет X570 пока единственный, подключающийся к процессору по четырем линиям PCIe 4.0.

Чипсет B550 разработан ASMedia, как и предыдущие чипсеты, но он изготавливается по 14-нм техпроцессу на мощностях Globalfoundries. Тепловой пакет составляет всего 5 Вт, поэтому пассивного охлаждения здесь уже достаточно. По сравнению с предыдущими чипсетами семейств 300 и 400, B550 предлагает стандарт PCI Express 3.0 вместо старого стандарта 2.0. И для производства больше не используется старый 55-нм техпроцесс.

Подписывайтесь на группы Hardwareluxx ВКонтакте и Facebook, а также на наш канал в Telegram (@hardwareluxxrussia).

Ресурсы расширения Socket (Socket и AddressInfo) являются объектами класса

В PHP 8.0 и более поздних версиях все функции из расширения Sockets возвращают / принимают объекты типа \ Socket и \ AddressInfo вместо ресурса типа Socket и AddressInfo .

Это похоже на расширение Curl, использующее объекты \ CurlHandle в отличие от ресурса в PHP 8.0, и расширение GD, использующее объекты \ GdImage вместо ресурсов gd .

Обратите внимание, что это применимо только к функциям socket _ * () из ext / sockets . stream_socket_ * функции (которые возвращают потоков ресурсов) не затронуты.

  final class Socket {
}  

\ Объекты класса Socket заменяют возвращаемые значения функций, которые ранее возвращали ресурс типа Socket :

  • socket_accept ()
  • socket_addrinfo_bind ()
  • socket_addrinfo_connect ()
  • socket_create ()
  • socket_create_listen ()
  • socket_import_stream ()
  • socket_wsaprotocol_info_import ()

Ресурсы Socket можно закрыть с помощью функции socket_close () , которая по-прежнему необходима в PHP 8.0, а также для быстрого закрытия открытого сокета.

  final class AddressInfo {
}  

Массив объектов класса \ AddressInfo будет возвращен функцией socket_addrinfo_lookup () , которая ранее возвращала массив из ресурсов AddressInfo .

\ Socket и \ AddressInfo семантика класса
  • Оба класса объявлены в глобальном пространстве имен.
  • Объявлен окончательный .
  • Не имеет методов.
  • Невозможно создать экземпляр с new \ Socket () и new AddressInfo () .
  • Невозможно сериализовать.
  • Невозможно клонировать.

Попытка создать экземпляр объекта \ Socket приведет к фатальной ошибке:

  Ошибка PHP: невозможно напрямую создать Socket, вместо этого используйте socket_create () в ... on line ...  

socket _ * () параметры и возвращаемые значения

Все функции из расширения Sockets будут возвращать / принимать новые объекты классов \ Socket и \ AddressInfo .

Все функции, которые создают объекты ресурсов / классов из расширения Sockets, возвращают false , если операция была неудачной.
Хотя это и не обязательно, использование is_resource () для возвращаемого значения таких функций довольно распространено.

Если вы вызываете is_resource , теперь вам нужно будет также учитывать возвращаемый тип объекта \ Socket .

  - если (is_resource ($ socket)) {
+ if (is_resource ($ socket) || $ socket instanceof \ Socket) { 

Также вполне допустимо проверять возвращаемое значение функций, возвращающих ресурсы, чтобы проверить возвращаемое значение на false .

  - если (is_resource ($ socket)) {
+ if ($ socket! == false) { 

Воздействие обратной совместимости

Расширения сокетов Преобразование ресурса в объект выполняется без проблем. Если у вас нет вызова is_resource () , который проверяет переданное / возвращаемое значение, никаких изменений в PHP 8.0 не потребуется.


Реализация

WebSocket в PHP — когда и как его использовать, примеры

WebSocket, протокол, обеспечивающий двустороннюю асинхронную связь между клиентом и хостом, существует уже несколько лет.И все же, несмотря на множество преимуществ, которые она дает, поддержка этой технологии в PHP по меньшей мере шаткая. Но означает ли это, что мы вообще не можем использовать его с PHP? Если мы можем, как лучше всего это реализовать? Я постараюсь ответить вам на эти вопросы сегодня.

Почему именно WebSockets?

Веб-узлы были хорошо известны уже давно, но мы все еще не так часто видим их в реальных приложениях PHP. Поток данных в реальном времени важен, улучшает взаимодействие с пользователем и позволяет повысить производительность как на стороне внешнего, так и на внутреннем интерфейсе.Веб-сокеты сокращают задержку и помогают избежать обходов HTTP-запросов, потому что после открытия сокет остается открытым.

Кроме того, это 2019 год и , мы должны использовать WebSockets . Я покажу вам, как подойти к этой проблеме в PHP.

Приложение WebSocket с PHP и Symfony — возможное решение

Я нашел три популярных способа добавить поддержку WebSockets в приложение Symfony.

  • Geniuses пакета Symfony WebSocket, то есть Ratchet, завернутый в инфраструктуру пакета, совместимую с Symfony,
  • Ratchet в исходной форме с настраиваемой оболочкой,
  • Swoole extension в исходной форме, также с настраиваемой оболочкой.

Подход GOS Bundle

Пакет Geniuses Of Symfony WebSocket использует внутреннюю структуру Ratchet WebSocket, но многое строит поверх нее. Пакет хорошо интегрирован с фреймворком Symfony.

Архитектура пакета довольно сложная — используется маршрутизация контроллера и стандартные файлы конфигурации YAML. Архитектура пытается навязать свой собственный способ написания приложений с поддержкой реального времени, который может показаться привлекательным, но вместо этого может вызвать проблемы, которых вы никогда не ожидаете.Авторизация основана на пакете безопасности Symfony, и, честно говоря, мне не удалось заставить авторизацию работать в разумные сроки.

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

GOS WebSocket Bundle — профи :
  • Тесно интегрирован с Symfony и следует его архитектуре — хорошо, если вы хотите использовать только Symfony и иметь согласованную кодовую базу,
  • Если вы можете заставить его делать то, что вы хотите, он будет сэкономить много кода,
  • Представляет ресурсы с файлами JS для внешнего интерфейса; некоторые могут счесть это полезным.

GOS WebSocket Bundle — минусы :
  • Низкокачественная документация,
  • почти нет демонстрационных приложений, чтобы проверить, как делать то, что вы хотите,
  • , если вы хотите, чтобы он делал что-то, для чего он точно не был разработан, вы можете попасть в ситуацию, когда вам нужно будет написать больше кода в качестве обходного пути, чем вы бы написали с помощью собственной пользовательской оболочки Ratchet, реализация
  • следует нескольким странным вариантам и соглашениям об именах,
  • тесно интегрирована с Symfony и ее механизмами — плохо если вы хотите изменить либо фреймворк, либо реализацию WebSocket,
  • , похоже, тратит ресурсы ЦП во время простоя по неизвестной причине,
  • странные проблемы с Docker, поскольку он не принимает имена хостов для привязки адресов — только IP-адреса (в результате php не является допустимым хостом, а 172.22.0.3 есть. Это может вызвать проблемы с переносимостью, которые, вероятно, можно было бы решить на лету, если бы конфигурация не была в YAML).

Заинтересованы в разработке микросервисов? 🤔 Обязательно ознакомьтесь с нашим отчетом «Состояние микросервисов в 2020 году», основанным на мнениях более 650 экспертов по микросервисам!

Ratchet подход к реализации WebSocket

Ratchet представляет собой структуру WebSocket и, в отличие от GOS, предлагает только исходную реализацию, которая оказывается очень гибкой.Написание собственной оболочки может показаться не очень хорошей идеей. В конце концов, зачем повторять работу, уже проделанную командой GOS со своей связкой? Имеет смысл, но бывают ситуации, когда это действительно хорошая идея. Иногда написать собственную оболочку проще, быстрее, безопаснее и удобнее в обслуживании, чем использовать готовую к использованию оболочку , особенно когда последняя не так хороша, как вы надеялись.

На первый взгляд может показаться трудным интегрировать контейнер Symfony и внедрение зависимостей с системой, которая не использует ни один из них, но на самом деле это не так.Просто запустите сервер Ratchet с помощью команды Symfony. Таким образом, ядро ​​фреймворка уже загружено после запуска Ratchet. Тебе хорошо идти.

Авторизация может выполняться с сохранением состояния или без отслеживания состояния.

Stateful означает, что сразу после подключения клиенту необходимо отправить данные авторизации, будь то имя пользователя / пароль или токен, полученный от стандартной конечной точки. Оболочка в любом случае должна хранить подключенных клиентов для широковещательных целей. Как только клиент отправляет правильные учетные данные, оболочка может хранить информацию об авторизации клиента вместе с соответствующими идентификационными данными.

Без сохранения состояния означает, что клиенту необходимо отправлять учетные данные с каждым запросом. Хотя это может показаться простым, широковещательная передача может значительно усложнить задачу, поскольку оболочка не знает, какой клиент авторизован. Об этих проблемах я расскажу позже в статье.

Простой класс, обертывающий сервер, может выглядеть так:

Метод start должен запускаться из консольной команды Symfony, чтобы Framework загрузилась.

Трещотка — профи:
  • Кажется, что это наименее сложное решение,
  • обеспечивает большую гибкость.

Трещотка — минусы:
  • Требуется специальная обертка,
  • Внутренняя структура трещотки может быть трудной для понимания.

Swoole подход для реализации WebSocket

Swoole — это расширение для PHP, написанное на C. Среди других полезных функций он предлагает сервер WebSocket. Я написал больше о Swoole здесь. Подход с Swoole очень похож на то, что мы сделали с Ratchet. Дело в том, что , если мы абстрагируем сервер, одна и та же настраиваемая оболочка может использоваться как с Swoole в Ratchet .

Однако есть два отличия Swoole: он многопроцессорный и невероятно быстрый. На скорость жаловаться, конечно, нельзя. С другой стороны, многопроцессорность является проблемой, потому что приложения с отслеживанием состояния не могут использовать память процесса, поскольку она не используется совместно. Вместо этого мы можем использовать что-то вроде redis, memcached или базу данных для хранения состояния приложения в виде списка подключенных веб-сокетов.

Код оболочки для Swoole будет очень похож на код Ratchet.Вы можете найти его в связанной статье Swoole, о которой я упоминал выше.

Swoole — профи:
  • Это действительно быстро,
  • обеспечивает большую гибкость.

Swoole — минусы:
  • для некоторых предприятий расширение, сделанное в Китае, может не подходить,
  • многопроцессорность усложняет приложения с отслеживанием состояния (это можно решить, установив счетчик процессов на 1, за счет представление).

Общие проблемы с WebSockets в Symfony

Есть пара общих проблем, которые влияют на все подходы.Один из них — это выбор между реализацией с сохранением состояния или без сохранения состояния и устойчивость обработки в обоих вариантах. Вариант с отслеживанием состояния основан на хранении аутентификации клиентов и других данных сеанса в памяти сервера PHP WebSocket. Это дает скорость, но имеет некоторые недостатки. Например, если процесс умирает, все данные теряются, и масштабирование становится затруднительным. Вообще говоря, я не могу рекомендовать это решение. Вариант без сохранения состояния может быть реализован с помощью уровня сохраняемости. Использование таких решений, как memcached и redis, или повторное использование базы данных повлияет на скорость, но принесет большую безопасность — серверы могут умереть, WebSockets может повторно подключаться и продолжать операции, а масштабирование становится меньшей проблемой.

Но есть еще одна важная проблема — это использование памяти. PHP не был разработан для поддержки длительно выполняющихся процессов. Вместо этого он ожидает загрузки и умирания с каждым запросом. Это решение влияет на управление памятью в ядре PHP. И оказывается, утечка памяти в случае WebSockets и Symfony — это очень плохо .

Чтобы проанализировать эту проблему, я создал очень простое приложение, которое использует Doctrine для сохранения и имеет только одну конечную точку на стороне WebSocket.Эта конечная точка создает одну сущность, сохраняет ее, затем использует репозиторий для поиска некоторых сущностей и отправляет их всем подключенным WebSockets. Неважно, какой фреймворк WebSocket мы используем, потому что утечка связана с Symfony и (возможно) Doctrine. Вот график, который показывает использование памяти, коррелированное с номером запроса:

Да, я пытался запустить GC вручную, очистить диспетчер сущностей, очистить диспетчер сущностей и установить для регистратора SQL значение null — безрезультатно.

Реализации WebSockets на PHP — сравнение и заключение

Прежде всего, если говорить о пропускной способности, то производительность всех представленных мной решений не так уж и важна. Это потому, что большая часть вычислительной мощности будет использоваться самой Symfony и вашим приложением, а не кодом, который обрабатывает WebSockets. Хотя Swoole технически является самым быстрым, поскольку это единственное решение, которое обрабатывает WebSockets с помощью собственного кода, чем сложнее приложение, тем меньше оно имеет значения.

Тем не менее, как ни заманчиво, PHP явно еще не готов для поддержки долго работающего сервера WebSocket . Утечки памяти — огромная проблема; заставляя вас перезапустить сервер. Хотя это можно сделать, это может привести к возникновению трудно поддающихся отладке ошибок и несогласованности в состоянии приложения, если не сделать это осторожно.

Что делать вместо этого?

Несмотря на то, что я только что сказал, есть еще несколько практических примеров использования WebSockets . У каждого из них есть несколько недостатков, но это цена, которую вы должны заплатить сейчас:

  • Сервер WebSocket можно перезагрузить, чтобы контролировать использование памяти.Требуется много внимания, чтобы правильно выполнить перезагрузку, чтобы в процессе не сбрасывались сообщения. Планировщик перезагрузки тоже должен быть написан (возможно, не на PHP).
  • Веб-узлы можно обрабатывать на другом языке (например, JavaScript с Node.js), а затем сообщения могут ретранслироваться в очередь, которую PHP периодически выбирает каждые пару секунд. Результаты из PHP также помещаются в очередь — в этом случае их отправляет Node.js. Это было бы очень надежно, но добавляемая задержка сводит на нет один из основных аргументов в пользу WebSockets.
  • Мы также можем попробовать использовать SSE с PHP, но учебные ресурсы трудно найти, а основная библиотека еще не появилась.
  • Конечно, вы можете просто полностью пропустить WebSockets и вместо этого перейти к периодическим вызовам старой школы Ajax сайт

    Нужна дополнительная помощь?

    Ваш PHP-проект требует немедленного внимания? В The Software House у нас есть команда очень талантливых разработчиков PHP, которые с радостью возьмутся за нее.Чтобы получить бесплатную консультацию, вам достаточно заполнить контактную форму. Кричите нам!

    Микросервисы PHP: тесты производительности REST и Socket | Девин Диксон | Helium MVC

    Когда дело доходит до микросервисов, наиболее распространенным и популярным методом взаимодействия со службой является RESTful API. И REST — отличный выбор, потому что он:

    • Поддерживает CRUD
    • Использовать HTTP, что упрощает подключение с любого устройства
    • Легко присваивать имена и организовывать ресурсы, особенно сложные API

    Но даже с этими преимуществами он ВОССТАНОВЛЕНИЕ лучший вариант? Если ваша главная цель — производительность, HTTP REST API может быть одним из наименее оптимальных решений.В этом руководстве мы собираемся запустить тесты двух форм REST API по сравнению с программированием сокетов, чтобы увидеть, какое решение даст вам лучшую производительность.

    Перед тем, как перейти к этому руководству, необходимо посетить следующие соответствующие руководства:

    Эти короткие руководства помогут вам понять программирование сокетов и реализацию RESTFUL API, обсуждаемую ниже.

    Код этого руководства и других примеров доступен по адресу: https://github.com/ProdigyView-Toolkit/Microservices-Examples-PHP

    Используйте папку с именем socket_vs_http и следуйте инструкциям README.

    В нашем первом тестовом примере мы будем вызывать API, как если бы он находился за маршрутизатором. Чтобы прояснить маршрутизацию — обсуждаемая здесь маршрутизация происходит на уровне приложения и направляет ресурсы на основе URL-адреса. Например, api / video / upload перейдет к функциям службы для загрузки видео, а / posts / 1023 может перейти к другой службе для поиска сообщения по идентификатору.

    Все самые популярные на сегодняшний день фреймворки имеют возможности маршрутизации в своем наборе инструментов.Сюда входят Lumen, Slim, Laravel, DJango, Flask и т. Д. Последние два — это Python, потому что концепция маршрутизации не зависит от языка.

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

    В нашем тесте наш класс, который будет определять маршрут, будет http_server / index.php и будет возвращать только такой ответ:

    В нашем следующем тесте кода мы собираемся выключить маршрутизация целиком.Вместо этого у нас будет прямой HTTP-ответ в http_server / get.php . Довольно простой и понятный тест.

    В нашем последнем тесте у нас будет Socket Server. Теперь я хочу, чтобы вы оценили, что тест сокета делает дополнительный шаг, которого нет в двух HTTP-тестах, — это расшифровка и шифрование данных!

    Шифрование не только требует времени для запуска, но и увеличивает длину отправляемых данных. Другой простой тест, который просто отправляет информацию обратно после того, как она была получена:

    Клиент для отправки теста состоит из двух отправленных запросов CURL и 1 теста Socket.Данные, отправляемые на все конечные точки, одинаковы, за исключением того, что сокет должен сначала зашифровать свои данные. Один запрос CURL — это GET , а другой — POST . Код ниже:

    И давайте запустим тест!

    Тест 1: 100 запросов

    Время маршрутизации HTTP: 0,39216995239258

    Время HTTP GET (без маршрутизации): 0,33528399467468

    Время тестирования сокета: 0,0825278759

    103 запросов HTTP Тест 2: 9 500342 Время:

    1.8593518733978

    Время HTTP GET (без маршрутизации): 1,5577518939972

    Время тестирования сокета: 0,37446594238281

    Тест 3: 1000 запросов

    Время маршрутизации HTTP: 4,1550130844116

    время GET000 (нет) 3,1718351840973

    Время тестирования сокета: 0,72313618659973

    Важное примечание: Тот же тест был запущен с запросом GET для реализации маршрутизатора, чтобы сделать его более сопоставимым с другим тестом GET.Результаты были такими же.

    При 100 запросах HTTP без маршрутизации на 15% быстрее, чем с маршрутизацией. А при использовании розетки скорость была на 130% выше. Когда нагрузка увеличилась до 1000 запросов, разница в производительности между HTTP с маршрутизацией и без маршрутизации составила 26%, а по сравнению с сокетом разница составила 140%. Вот такой контраст!

    Этот момент следует повторить еще раз: Сокеты шифруют и дешифруют данные, но по-прежнему превосходят HTTP!

    Теперь для защиты HTTP заголовки HTTP огромны! Подумайте обо всей информации, которая попадает в заголовок:

    • Тип содержимого
    • Кодировка
    • Allow-Access-Control- *
    • Код ответа
    • X-Forwarded-For
    • Удаленный адрес
    • Метод запроса
    • и т. Д. и т. д. и т. д.

    И список может продолжаться со многими элементами, которые включают заголовки HTTP.Эта информация представляет собой большой объем данных, которые нужно обрабатывать не только для отправки, но и для обработки принимающим сервером. Программирование сокетов более прямое, когда вы подключаетесь к конечной точке и просто отправляете данные.

    Чтобы запустить приведенный выше пример на вашем локальном компьютере, вы можете посетить репозиторий здесь.

    Когда вы создаете свои микросервисы, REST - отличный подход к созданию микросервисов, к которым легко получить доступ, организовать и понять, особенно для сложных API. Но с точки зрения производительности REST очень медленный по сравнению с сокетами.Преимущество REST заключается в том, что для некоторых клиентов, таких как Javascript, асинхронная связь может помочь с проблемами производительности.

    При создании микросервисов учитывайте компромисс между скоростью и удобством обслуживания. Сколько запросов обрабатываются вашими микросервисами и какую пользу принесет это изменение бизнесу? Есть ли решение, которое может получать HTTP-запросы быстрее, чем PHP, но затем быстро отправлять их в службу PHP через сокет? Действительно ли микросервису нужен REST API?

    Если требуется HTTP и вы хотите повысить скорость, подумайте:

    • Удаление раздутого маршрутизатора из вашей реализации до минимальных решений.
    • Учитывая небольшой микросервис, напишите собственный маршрутизатор без реальной функциональности, но с условными операторами (например, if ($ request == 'GET') {// Do Action} else {// Do Other Action}.
    • Уменьшите размер отправляемой информации, т. Е. Отбросив ненужные поля заголовка.

    Если вам интересно узнать больше о микросервисах с PHP, прочтите некоторые из наших других руководств:

    Как подключить NGINX к PHP- FPM с использованием UNIX или TCP / IP Socket

    Веб-сервер NGINX (в качестве обратного прокси) обслуживает приложения PHP по протоколу FastCGI (в качестве внутреннего сервера приложений). NGINX использует PHP-FPM (FastCGI Process Manager), альтернативную реализацию PHP FastCGI , которая работает в фоновом режиме как демон, прослушивая запросы CGI . Он поставляется с дополнительными функциями, предназначенными для работы с сильно загруженными веб-сайтами или веб-приложениями, но его можно использовать для сайтов любого размера.

    Не только PHP-FPM поддерживает конфигурацию пулов ресурсов FastCGI , но также улучшает многие из внутренних компонентов FastCGI и увеличивает отчеты об ошибках, завершение скриптов и многое другое.Он включает демонизацию PHP, управление процессами, динамическое количество процессов, из которых могут поступать запросы, заголовок ошибки, поддержку ускоренной загрузки и многое другое.

    Для приема запросов FastCGI от NGINX , PHP-FPM может либо прослушивать сокет TCP / IP , либо сокет домена UNIX. Какой бы адрес вы ни выбрали, NGINX использует для подключения (запросы прокси) к PHP-FPM с использованием директивы fastcgi_pass .

    В этом руководстве объясняется, как настроить NGINX для серверных приложений PHP с использованием PHP-FPM . В нем описывается, когда использовать сокет TCP / IP или сокет домена UNIX для подключения NGINX к PHP-FPM и почему.

    В этом руководстве предполагается, что в вашей системе Linux установлены NGINX и PHP-FPM , в противном случае см .:

    Что мне использовать: сокет домена UNIX или сокет TCP / IP?

    Доменные сокеты UNIX (или IPC ) - это средства межпроцессного взаимодействия (IPC), которые обеспечивают эффективный обмен данными между процессами, работающими в одной операционной системе, в то время как сокеты TCP / IP (или Internet Domain ) разрешить процессам обмениваться данными по сети.

    В отличие от сокета TCP / IP , который идентифицирует сервер по IP-адресу и порту (например, 127.0.0.1:9000 ), вы можете привязать сервер к сокету домена UNIX, используя путь к файлу (например, / run / php-fpm / www.sock ), который виден в файловой системе.

    Доменный сокет UNIX - это особый тип файла - к нему применяются права доступа к файлам и каталогам (как и в случае с любым другим типом файлов UNIX), и его можно использовать для ограничения того, какие процессы на хосте могут читать и записывать в файл. , (и, таким образом, общаться с внутренним сервером).

    Таким образом, сокет домена UNIX является безопасным, поскольку его могут использовать только процессы на локальном хосте. Сокет TCP / IP может быть открыт для доступа в Интернет, создавая угрозу безопасности, если не будут реализованы дополнительные меры безопасности, такие как брандмауэр.

    Важно отметить, что использование сокета домена UNIX - это не то же самое, что использование сокета TCP / IP в отношении производительности, несколько тестов и тестов показали, что сокеты домена UNIX работают быстрее. Главный недостаток сокетов домена UNIX заключается в том, что они менее масштабируемы, они поддерживают только межпроцессное взаимодействие в одной операционной системе (ОС).

    Где я могу настроить адрес прослушивания PHP-FPM?

    Вы можете настроить адрес , который PHP-FPM прослушивает, в файле конфигурации пула ресурсов. Обратите внимание, что с PHP-FPM вы можете запускать несколько пулов процессов с разными настройками. Пул по умолчанию называется www .

    Расположение файла конфигурации пула ресурсов зависит от способа установки PHP и PHP-FPM в системе Linux (будь то версия по умолчанию / одна версия или несколько версий одновременно).

    Например, в CentOS 8 с одной версией все файлы конфигурации PHP расположены в каталоге / etc , а файл конфигурации по умолчанию PHP-FPM pool (www) - / etc / php -fpm.d / www.conf :

    Чтобы вывести список всех файлов конфигурации PHP, используйте следующую команду ls.

     # ls / etc / php *
     
    Список всех файлов конфигурации PHP

    В Ubuntu 20.04 файлы конфигурации PHP расположены в каталоге / etc / php / / и в файле конфигурации пула PHP-FPM по умолчанию (www) по умолчанию это / etc / php / / fpm / pool.d / www.conf :

     $ ls /etc/php/7.4/
     
    Список всех файлов конфигурации PHP в Ubuntu

    Настройка PHP-FPM для прослушивания в доменном сокете UNIX

    Чтобы настроить PHP-FPM для прослушивания сокета домена UNIX, откройте файл конфигурации пула PHP-FPM по умолчанию, используя свой любимый текстовый редактор.

     # vim /etc/php-fpm.d/www.conf # Ubuntu / Debian
    ИЛИ ЖЕ
    $ sudo vim /etc/php/7.4/fpm/pool.d/www.conf # CentOS / RHEL / Fedora
     

    Затем найдите директиву listen и задайте ей путь к файлу сокета домена UNIX следующим образом.Обратите внимание, что в большинстве установок по умолчанию используется сокет домена UNIX.

     слушайте = /run/php/php7.4-fpm.sock # Ubuntu / Debian
    ИЛИ ЖЕ
    слушайте = /run/php-fpm/www.sock # CentOS / RHEL / Fedora
     

    Если вы используете сокет домена UNIX, вам также необходимо установить соответствующие разрешения на чтение / запись для файла, чтобы разрешить соединения с веб-сервером NGINX. По умолчанию NGINX запускается как пользователь и группа nginx на CentOS / RHEL / Fedora и www-data на Ubuntu и Debian .

    Итак, найдите параметры listen.owner и listen.group и установите их соответственно. Также установите режим 0660 с помощью параметра listen.mode .

      ------------- В Debian и Ubuntu ------------- 
    listen.owner = www-data
    listen.group = www-data
    listen.mode = 0660
    
      ------------- В CentOS / RHEL и Fedora ------------- 
    listen.owner = nginx
    listen.group = nginx
    Слушать.mode = 0660
     

    Обратите внимание, что если разрешения для файла сокета домена UNIX установлены неправильно, NGINX может вернуть ошибку неверного шлюза.

    Конфигурация PHP-FPM

    Настройка PHP-FPM для прослушивания сокета TCP / IP

    Хотя сокет домена UNIX быстрее, чем сокет TCP / IP, первый менее масштабируемый, поскольку он может поддерживать межпроцессное взаимодействие только в одной и той же ОС. Если NGINX и сервер внутренних приложений ( PHP-FPM ) работают в разных системах, вам необходимо настроить PHP-FPM для прослушивания сокета TCP / IP для соединений.

    В файле конфигурации пула PHP-FPM установите адрес listen следующим образом. Убедитесь, что выбранный вами порт не используется другим процессом или службой в той же системе.

     слушать = 127.0.0.1:3000
     
    Конфигурация PHP-FPM для TCP Socket

    Настройка NGINX для работы с сервером приложений PHP-FPM

    После того, как вы настроили адрес , который прослушивает PHP-FPM , вам необходимо настроить NGINX на прокси-запрос к нему через этот адрес, используя параметр конфигурации fastcgi_pass в файле конфигурации блока виртуального сервера.

    Например, если файл конфигурации для вашего веб-сайта - /etc/nginx/conf.d/example.com.conf , откройте его для редактирования.

     # vim /etc/nginx/conf.d/example.com.conf
     

    Найдите блок location для обработки файлов .php и установите параметр fastcgi_pass следующим образом, если вы настроили PHP-FPM для прослушивания сокета домена UNIX.

     fastcgi_pass unix: /run/php/php7.4-fpm.sock # Ubuntu / Debian
    ИЛИ ЖЕ
    fastcgi_pass unix: / run / php-fpm / www.носок # CentOS / RHEL / Fedora
     
    Подключите Nginx к PHP-FPM с помощью Unix Socket

    Или используйте адрес TCP / IP , если вы настроили PHP-FPM для прослушивания сокета TCP / IP . Если сервер внутренних приложений ( PHP-FPM ) работает на отдельном сервере (замените 10.42.0.10 IP-адресом машины, на которой работает сервер PHP-FPM FastCGI).

     fastcgi_pass 10.42.0.10:3000;
     
    Подключите Nginx к PHP-FPM с помощью TCP Socket

    Важное замечание : в CentOS 8 , PHP-FPM определен как вышестоящий сервер в файле / etc / nginx / conf.d / php-fpm.conf в блоке восходящего потока с именем php-fpm .

    Вы можете внести здесь соответствующие изменения в зависимости от адреса PHP-FPM , настроенного для прослушивания, в файле конфигурации пула. Конфигурация по умолчанию указывает на сокет домена UNIX.

     восходящего потока php-fpm {
            сервер unix: /run/php-fpm/www.sock;
    }
     
    Настройте восходящий сервер PHP в Nginx

    и в файле блока сервера вашего сайта, просто установите параметр fastcgi_pass , как показано.

     fastcgi_pass php-fpm;
     
    Настройте Nginx для работы с вышестоящим сервером PHP-FPM

    После внесения изменений в конфигурации PHP-FPM и NGINX проверьте их синтаксис конфигурации на правильность, как показано ниже.

      ------------- В Debian и Ubuntu ------------- 
    $ sudo php-fpm -t
    $ sudo nginx -t
    
      ------------- В CentOS / RHEL и Fedora ------------- 
    # php-fpm -t
    # nginx -t
     

    Хотя выходные данные команды показывают только основной файл конфигурации, все остальные файлы конфигурации также включены и проверены.

    Проверьте конфигурацию Nginx и PHP-FPM

    Затем вам нужно перезапустить две службы, чтобы изменения вступили в силу, с помощью команды systemctl.

      ------------- В Debian и Ubuntu ------------- 
    $ sudo systemctl перезапустить nginx
    $ sudo systemctl перезапустить php7.4-fpm
    
      ------------- В CentOS / RHEL и Fedora ------------- 
    # systemctl перезапуск nginx
    # systemctl перезапуск php-fpm
     

    Если вы получите какие-либо ошибки, вы можете проверить файлы журнала NGINX и PHP-FPM с помощью команды cat.

      ------------- В Debian и Ubuntu ------------- 
    $ cat /var/log/nginx/error.log
    $ cat /var/log/php7.4-fpm.log
    
      ------------- В CentOS / RHEL и Fedora ------------- 
    $ cat /var/log/nginx/error.log
    $ cat /var/log/php-fpm/www-error.log
     

    Это все, что у нас было для вас. Раздел комментариев ниже можно использовать, чтобы задавать вопросы. Для получения дополнительной информации см. Документацию NGINX и документацию PHP-FPM.

    PHP-FPM - HTTPD - Apache Software Foundation

    С выпуском apache httpd 2.4 благодаря ничего не подозревающему населению мы получили некоторые очень полезные функции, касающиеся apache и php: возможность запускать PHP в качестве сервера процессов fastCGI и обращаться к этому серверу fastCGI непосредственно из apache через специальный модуль прокси (mod_proxy_fcgi.)

    • Начиная с версии 5.3.3 в начале 2010 года, PHP объединил менеджер процессов php-fpm fastCGI со своей кодовой базой, и теперь (по состоянию на 5.4.1) он довольно стабилен.
    • php-fpm ранее находился по адресу http: // php-fpm.org

    Это означает, что теперь мы можем запускать безопасный, быстрый и надежный PHP-код , используя только стандартные версии apache httpd и php.net ; больше не нужно возиться с suphp или suexec - или, действительно, mod_php .

    php-fpm

    Предварительные требования:

    • установка пакетов программного обеспечения
    • редактирование файлов конфигурации
    • управление сервисными демонами.

    Начиная с версии 5.3.3, PHP теперь включает диспетчер процессов fastCGI (php-fpm) в исходный код акции.

    Ваш дистрибутив или ОС либо включат его в стандартный пакет PHP, либо сделают его доступным как дополнительный пакет; вы можете собрать его из исходного кода, добавив --enable-fpm в свои параметры ./configure.

    Это дает нам новый двоичный файл с именем php-fpm , а файл конфигурации по умолчанию с именем php-fpm.conf установлен в / etc .

    Значения по умолчанию в этом файле должны подойти для начала работы, но имейте в виду, что ваш дистрибутив мог его изменить или изменить его местоположение.

    Внутри этого файла конфигурации вы можете создать произвольное количество «пулов» fastcgi, которые определяются IP и портом, который они прослушивают, как и apache virtualhosts.

    Самым важным параметром в каждом пуле является сокет TCP (IP и порт) или сокет домена unix (UDS), который php-fpm будет прослушивать для получения запросов fastCGI; это настраивается с помощью опции listen .

    Пул по умолчанию, [www] , настроен как прослушивание 127.0.0.1: 9000 : он будет отвечать только на запросы на локальном петлевом сетевом интерфейсе (localhost), на TCP-порту 9000.

    Также представляют интерес параметры для каждого пула пользователь и группа параметры, которые позволить вам запустить этот конкретный пул fpm под заданными uid и gid; до свидания, suphp!

    Обратите особое внимание на настройки slowlog (директивы request_slowlog_timeout и slowlog), то есть с помощью этого журнала и разумного времени ожидания вы можете легко увидеть, какие вызовы php из вашего приложения занимают больше времени, чем ожидалось, и сразу же начать их отладку.

    Давайте просто воспользуемся заводскими настройками по умолчанию и запустим демон php-fpm; если ваш дистрибутив использует предоставленный сценарий инициализации, запустите
    /etc/init.d/php-fpm start
    Или, если нет, запустите его вручную с помощью
    php-fpm -y /path/to/php-fpm.conf -c /path/to/custom/php.ini
    Если вы не предоставите php-fpm собственный файл php.ini , будет использоваться глобальный файл php.ini. Помните об этом, если вы хотите включить больше или меньше расширений, чем используют двоичные файлы CLI или CGI, или если вам нужно изменить некоторые другие значения там.

    Вы можете включить значений php.ini для каждого пула точно так же, как вы определяли их в apache ранее для mod_php, используя php_ [admin _] (flag | value) .

    См. Официальную документацию PHP для fpm для всех возможных вариантов конфигурации.

    Я также изменил параметр php-fpm.conf logging , чтобы я мог легко видеть, что именно регистрируется php-fpm:
    error_log /var/log/php-fpm.log
    Если вы этого не сделаете установите файл журнала php-fpm, ошибки будут регистрироваться, как определено в php.ini .

    Примечание: вы можете заставить запущенный php-fpm перезагрузить свою конфигурацию, отправив ему сигнал SIGUSR2 .; SIGUSR1 будет циклически перебирать файлы журнала (идеально для сценария logrotate!). Небольшое экспериментирование имеет большое значение.

    Вот и все, о чем мы позаботились о php-fpm; если при запуске не было ошибок, он должен быть готов к подключению.

    apache httpd 2.4

    предварительные требования:

    • редактирование httpd.conf
    • понимание контекста vhost
    • понимание сопоставления пространства имен URL-файловой системы
    • управление демоном apache httpd

    В этом выпуске apache httpd представлены два примечательные особенности: новый прокси-модуль специально для fastCGI (mod_proxy_fcgi) и переход к событию MPM в качестве диспетчера процессов apache по умолчанию.

    Как и рабочий MPM предыдущей версии, многопоточная модель этого MPM вызывает проблемы, когда mod_php используется с небезопасными для потоков сторонними расширениями PHP.

    Это было проклятием для пользователей mod_php с момента выпуска apache 2.2, фактически вынуждая их собирать решения fastcgi или использовать гораздо более медленный и требовательный к памяти prefork MPM.

    Чтобы творить чудеса с менеджером процессов PHP fastCGI, мы будем использовать новый модуль mod_proxy_fcgi , который предназначен специально для связи с (возможно внешними) серверами fastCGI.

    Убедитесь, что вы включили модуль proxy_fcgi в свой httpd.conf, чтобы мы могли использовать его возможности; поскольку для этого требуется базовый прокси-модуль, убедитесь, что оба загружены (без комментариев):

    LoadModule proxy_module modules / mod_proxy.so

    LoadModule proxy_fcgi_module modules / mod_proxy_fcgi.so

    Теперь есть разные способы пересылки запросов. для файлов .php с по этот модуль, от всего (с использованием [ProxyPass]) до очень специфических или перезаписанных файлов или шаблонов (с использованием mod_rewrite с флагом [P]).Знаки (каретка) и $ (доллар) используются для привязки как абсолютного начала, так и конца URL-адреса, чтобы гарантировать, что никакие символы из запроса не ускользнут от нашего соответствия шаблону.

    Вложенные круглые скобки позволяют нам ссылаться на весь URI запроса (за вычетом ведущей косой черты) как $ 1 , сохраняя при этом завершающую pathinfo необязательной.

    fcgi: //127.0.0.1: 9000

    пересылать через mod_proxy_fcgi, используя протокол fastCGI, на порт, который прослушивает наш демон php-fpm.

    Определяет, какой пул fastcgi будет обслуживать запросы, проксируемые этим правилом.
    / path / to / your / documentroot /

    ВАЖНО! Это должно точно совпадать с реальным расположением файловой системы ваших файлов php, потому что именно там демон php-fpm будет их искать.

    php-fpm просто интерпретирует переданные ему файлы php; это не веб-сервер, и он не понимает пространство имен ваших веб-серверов, макет виртуального хоста или псевдонимы.

    ВАЖНО! Прочтите это еще раз.
    $ 1

    расширяется на весь URI запроса из исходного запроса, за вычетом ведущей косой черты (потому что мы уже добавили это выше.)

    DirectoryIndex /index.php index.php

    запрос для / должен быть сопоставлен с ресурсом на бэкэнде fcgi. Неспособность решить эту проблему может вызвать пустой ответ, обычно известный как WSOD (Белый экран смерти), особенно если проксируется только URI запроса, содержащий расширение php, как в этом примере. Цепочка обработки сначала отобразит запрос для / на /index.php или любой другой файл index.php относительно текущего uri запроса, а затем будет правильно проксировать серверную часть PHP-FPM./(.*\.php(/.*)?)$ unix: /path/to/socket.sock | fcgi: // localhost / path / to / your / documentroot /

    unix: / path / to /socket.sock

    путь к вашему сокету fpm

    Обратите внимание, что при таком подходе URI захваченного запроса ($ 1) не передается после пути

    Прокси через обработчик

    При таком подходе вы можете проверить наличие наличие ресурса до проксирования на бэкэнд php-fpm.

    # Определение воркера улучшит производительность

    # И в этом случае повторно используйте воркера (в зависимости от поддержки со стороны приложения fcgi)

    # Если у вас достаточно простаивающих воркеров, это только улучшит производительность незначительно

    {{}}

    {{# Выберите один из следующих подходов}}

    {{# Использовать стандартный сокет TCP}}

    { {#SetHandler «proxy: fcgi: // localhost /: 9000»}}

    {{# Если ваша версия httpd — 2.4.9 или новее (или имеет функцию обратного переноса), вы можете использовать сокет домена unix }}

    {{#SetHandler «proxy: unix: /path/to/app.sock | fcgi: // localhost /»}}

    {{}}

    Объединение FilesMatch и If может быть достигнуто как таковое:

    Для нетерпеливых

    Очень простой пример

    Если вас интересует проверка концепции и вы хотите оставить настройку на потом, вы можете использовать по следующему рецепту.Он вызовет стандартную информационную страницу php, на которой перечислены все скомпилированные и загруженные расширения, а также все параметры конфигурации времени выполнения и информация о скрипте. / (.* \. php) $ fcgi: //127.0.0.1: 9000 / var / www / $ 1

    Опять же, предполагая, что / var / www — это DocumentRoot рассматриваемого виртуального хоста.

    Перезагрузите apache с apachectl graceful , и теперь вы можете вызвать страницу phpinfo, используя http://example.com/yourscript.php

    Performance and Pitfalls

    mod_proxy_fcgi теперь поддерживает сокеты домена unix, начиная с версии 2.4.9 ( Поддержка сокетов домена Unix для mod_proxy_fcgi)

    Легко перегрузить доступные сокеты вашей системы, пройти через ulimit и т. Д.Несколько советов, как этого избежать:

    Использование слишком большого количества сокетов приведет к тому, что apache выдаст ошибку (99) Невозможно назначить запрошенный адрес: . Это означает, что ваша операционная система не позволяет создавать новые сокеты.

    В Linux вы можете использовать / proc / sys / net / ipv4 / tcp_tw_reuse, чтобы не создавать столько сокетов, но есть предупреждения, связанные с использованием этого за NAT.

    Не забудьте изменить ulimit и разрешить достаточно открытых файлов и процессов как для пользователя apache, так и для пользователя php-fpm.
    ulimit -n и ulimit -u (nofile и nproc)

    Если php-fpm не имеет достаточно большого nproc, он выйдет ( код 255 , без дополнительной информации с php 5.3) в цикле без дополнительных сообщений.

    Если php-fpm не имеет достаточно большого файла nofile, вы, вероятно, не сможете вести журнал для каждого ребенка, как показано выше. Это будет отражено в общем журнале ошибок.

    Если apache и php-fpm запускаются от имени одного и того же пользователя (не обязательно или рекомендуется) и nproc слишком мал, apache не запустится со следующим сообщением (11) Ресурс временно недоступен: AH02162: setuid: невозможно изменить на uid : 600

    Предупреждение: когда вы ProxyPass отправляете запрос другому серверу (в данном случае демону php-fpm), ограничения аутентификации и другие конфигурации помещаются в блок каталога или.htaccess, можно обойти.

    Предостережения

    Может возникнуть соблазн указать, что жадная директива ProxyPassMatch может разрешить обслуживание некоторого вредоносного содержимого, загруженного HTTP-клиентом.

    Это ни в коем случае не всеобъемлющий документ по безопасности, но вместо этого он укажет на возможный вектор внедрения, который может быть сгенерирован из директив в этом документе.

    Возьмем, например:

    /uploads/malicious.jpg/lalalaalala.php

    Приведет php-fpm к обработке этого файла (/ uploads / dangerous.jpg), и без определенной проверки работоспособности может привести к взлому сервера.

    Это, конечно, не рекомендуется. Содержимое, загруженное с использованием php, должно быть безопасно сохранено за пределами DocumentRoot , а pathinfo должен быть тщательно изучен.

    Кроме того, php-fpm должен проверять, разрешен ли вызываемый скрипт.

    Если такие ограничения не могут быть легко реализованы, то проверки могут быть выполнены до проксирования с помощью RewriteCond или FallbackResource , чтобы гарантировать, что URI не изменяется клиентом HTTP.

    Эксперименты с тайм-аутом

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

      
       Время ожидания ProxySet = 300
    
    
    
       SetHandler "прокси: fcgi: // localhost"
      

    Laravel Websockets — Запуск сервера WebSocket

    После того, как вы настроили свои приложения WebSocket и параметры Pusher, вы можете запустить сервер Laravel WebSocket, введя команду artisan:

      php artisan websockets: служить
      

    Использование другого порта

    #

    Порт по умолчанию для сервера Laravel WebSocket — 6001 .Вы можете передать команде другой порт, используя параметр --port .

      php artisan websockets: serve --port = 3030
      

    Начнется прослушивание порта 3030 .

    Ограничение прослушивающего хоста

    #

    По умолчанию сервер Laravel WebSocket будет прослушивать 0.0.0.0 и разрешать входящие соединения из всех сетей. Если вы хотите ограничить это, вы можете запустить сервер с параметром --host , за которым следует IP.

    Например, используя 127.0.0.1 , вы разрешите соединения WebSocket только с localhost.

      php artisan websockets: serve --host = 127.0.0.1
      

    Поддержание работы сервера сокетов с супервизором

    #

    Демон websockets: serve должен всегда работать, чтобы принимать соединения. Это основной вариант использования supervisor , средства выполнения задач в Linux.

    Сначала убедитесь, что установлен супервизор .

     
    apt install supervisor
    
    
    yum install supervisor
    systemctl включить супервизор
      

    После установки добавьте новый процесс, который должен продолжать работу супервизора . Вы помещаете свои конфигурации в каталог /etc/supervisor/conf.d (Debian / Ubuntu) или /etc/supervisord.d (Red Hat / CentOS).

    В этом каталоге создайте новый файл с именем websockets.conf .

      [программа: веб-сокеты]
    команда = / usr / bin / php / home / laravel-echo / laravel-websockets / artisan websockets: служить
    numprocs = 1
    autostart = true
    autorestart = true
    пользователь = laravel-echo
      

    После создания проинструктируйте supervisor перезагрузить файлы конфигурации (не влияя на уже запущенные задания супервизора ).

      supervisorctl обновить
    supervisorctl запускает веб-сокеты
      

    Теперь ваш эхо-сервер должен быть запущен (вы можете проверить это с помощью supervisorctl status ). Если произойдет сбой, диспетчер автоматически перезапустит его.

    Обратите внимание, что по умолчанию супервизор принудительно устанавливает максимальное количество открытых файлов для всех процессов, которыми он управляет. Это настраивается параметром minfds в супервизоре .conf .

    Если вы хотите увеличить максимальное количество открытых файлов, вы можете сделать это в /etc/supervisor/supervisord.conf (Debian / Ubuntu) или /etc/supervisord.conf (Red Hat / CentOS):

      [руководитель]
    minfds = 10240
      

    После изменения этого параметра вам необходимо перезапустить процесс супервизора (который, в свою очередь, перезапустит все ваши процессы, которыми он управляет).

    Командная строка

    — PHP-FPM не создает сокет при перезапуске службы

    Проблема и вопрос

    Сервер Ubuntu 18.04 LTS.

    Использование systemctl restart на PHP-FPM не создает требуемый сокет в / var / run / php / , но перезагрузка создает.

    Как я могу настроить мои настройки, чтобы разрешить перезапуск службы без перезагрузки?

    Обзор

    Я компилирую несколько экземпляров PHP-FPM из исходного кода на одном сервере (без контейнеров) для использования с веб-приложениями разного возраста. Я успешно установил PHP 7.1, PHP 7.2 и PHP 7.3 рядом друг с другом. Все они запускаются правильно при загрузке, все они имеют сокет в / var / run / php / , все они отвечают, как и ожидалось от браузера.

    Содержимое

    / var / run / php после загрузки
      / var / run / php $ ls -l
    всего 0
    srw-rw ---- 1 www-data www-data 0 2 апреля 12:57 php7.1-fpm.sock
    srw-rw ---- 1 www-data www-data 0 2 апреля 12:57 php7.2-fpm.sock
    srw-rw ---- 1 www-data www-data 0 2 апреля 12:57 php7.3-fpm.sock
      

    Кажется, что каждая служба работает без проблем. Вот вывод systemctl status для каждого:

    PHP 7.1 после загрузки

      ~ $ sudo systemctl status php7.1 кадр / мин
    ● php7.1-fpm.service - менеджер процессов PHP FastCGI.
       Загружено: загружено (/etc/systemd/system/php7.1-fpm.service; включено; предустановка поставщика: включено)
       Активен: активен (работает) с Вт 2019-04-02 12:57:51 UTC; 21мин назад
     Основной PID: 875 (php-fpm)
        Задач: 3 (лимит: 1152)
       CGroup: /system.slice/php7.1-fpm.service
               ├─875 php-fpm: главный процесс (/etc/php/7.1/etc/php-fpm.conf)
               ├─970 php-fpm: бассейн www
               └─971 php-fpm: бассейн www
    
    02 апреля, 12:57:51 darwin systemd [1]: запущен менеджер процессов PHP FastCGI. 

    PHP 7.2 после загрузки

      ~ $ sudo systemctl status php7.2-fpm
    ● php7.2-fpm.service - Менеджер процессов PHP FastCGI (7.2)
       Загружено: загружено (/etc/systemd/system/php7.2-fpm.service; включено; предустановка поставщика: включено)
       Активен: активен (работает) с Вт 2019-04-02 12:57:51 UTC; 22мин назад
     Основной PID: 837 (php-fpm)
        Задач: 3 (лимит: 1152)
       CGroup: /system.slice/php7.2-fpm.service
               ├─837 php-fpm: главный процесс (/etc/php/7.2/etc/php-fpm.conf)
               ├─963 php-fpm: бассейн www
               └─964 php-fpm: бассейн www
    
    02 апреля, 12:57:51 darwin systemd [1]: запущен диспетчер процессов PHP FastCGI (7.2).
      

    PHP 7.3 после загрузки

      ~ $ sudo systemctl status php7.3-fpm
    ● php7.3-fpm.service - Менеджер процессов PHP FastCGI (7.3)
       Загружено: загружено (/etc/systemd/system/php7.3-fpm.service; включено; предустановка поставщика: включено)
       Активен: активен (работает) с Вт 2019-04-02 12:57:51 UTC; 23мин назад
     Основной PID: 836 (php-fpm)
        Задач: 3 (лимит: 1152)
       CGroup: /system.slice/php7.3-fpm.service
               ├─836 php-fpm: главный процесс (/etc/php/7.3/etc/php-fpm.conf)
               ├─965 php-fpm: бассейн www
               └─966 php-fpm: бассейн www
    
    02 апреля, 12:57:51 darwin systemd [1]: запущен диспетчер процессов PHP FastCGI (7.3).
      

    Если я внесу изменения в соответствующий файл php.ini , это потребует перезапуска службы для обработки изменений. В моем случае, когда я перезапускаю службу с помощью systemctl restart (например, sudo systemctl restart php7.1-fpm ), кажется, что служба корректно перезапускается, но все сокеты PHP удаляются — независимо от версии, которую я перезапускаю.

    Нет вывода на консоль после systemctl restart , и когда я проверяю systemctl status на перезапущенной службе (например.g PHP 7.1 в предыдущем абзаце), служба работает: :

    PHP 7.1 после перезапуска

    systemctl
      ~ $ sudo systemctl status php7.1-fpm
    ● php7.1-fpm.service - менеджер процессов PHP FastCGI.
       Загружено: загружено (/etc/systemd/system/php7.1-fpm.service; включено; предустановка поставщика: включено)
       Активен: активен (работает) с Вт 2019-04-02 13:28:06 UTC; 28с назад
     Основной PID: 1704 (php-fpm)
        Задач: 3 (лимит: 1152)
       CGroup: /system.slice/php7.1-fpm.service
               ├─1704 php-fpm: главный процесс (/ etc / php / 7.1 / etc / php-fpm.conf)
               ├─1718 php-fpm: бассейн www
               └─1722 php-fpm: бассейн www
    
    02 апреля, 13:28:06 darwin systemd [1]: остановлен диспетчер процессов PHP FastCGI.
    02 апр, 13:28:06 darwin systemd [1]: запущен менеджер процессов PHP FastCGI.
      

    Обратите внимание на разницу в отметках времени на Active . Если я запрашиваю другие службы таким же образом (обратите внимание: они не были перезапущены мной), временные метки будут с момента первоначального запуска при загрузке:

    PHP 7.2 после

    перезапуска systemctl на PHP 7.1
      ~ $ sudo systemctl status php7.2-fpm
    ● php7.2-fpm.service - Менеджер процессов PHP FastCGI (7.2)
       Загружено: загружено (/etc/systemd/system/php7.2-fpm.service; включено; предустановка поставщика: включено)
       Активен: активен (работает) с Вт 2019-04-02 12:57:51 UTC; 33мин назад
     Основной PID: 837 (php-fpm)
        Задач: 3 (лимит: 1152)
       CGroup: /system.slice/php7.2-fpm.service
               ├─837 php-fpm: главный процесс (/etc/php/7.2/etc/php-fpm.conf)
               ├─963 php-fpm: бассейн www
               └─964 php-fpm: бассейн www
    
    02 апреля, 12:57:51 darwin systemd [1]: запущен диспетчер процессов PHP FastCGI (7.2).
      

    PHP 7.3 после

    перезапуск systemctl на PHP 7.1
      ~ $ sudo systemctl status php7.3-fpm
    ● php7.3-fpm.service - Менеджер процессов PHP FastCGI (7.3)
       Загружено: загружено (/etc/systemd/system/php7.3-fpm.service; включено; предустановка поставщика: включено)
       Активен: активен (работает) с Вт 2019-04-02 12:57:51 UTC; 34мин назад
     Основной PID: 836 (php-fpm)
        Задач: 3 (лимит: 1152)
       CGroup: /system.slice/php7.3-fpm.service
               ├─836 php-fpm: главный процесс (/ etc / php / 7.3 / etc / php-fpm.conf)
               ├─965 php-fpm: бассейн www
               └─966 php-fpm: бассейн www
    
    02 апреля, 12:57:51 darwin systemd [1]: запущен менеджер процессов PHP FastCGI (7.3).
      

    … и все же розетки отсутствуют:

    Содержимое

    / var / run / php после systemctl restart на PHP 7.1
      $ ls -l
    всего 0
      

    Мне кажется, что я что-то испортил в файле .service , не осознавая этого. Во время устранения неполадок я заметил, что использую разные каталоги для PID и сокета.PID — , а не , созданный во время загрузки, поскольку / run / php-fpm / не существует. Я смутно помню, как мне советовали не хранить сокеты и PID в одном каталоге, но я не могу вспомнить точных деталей.

    PHP 7.1

    .service файл
      [Единица]
    Описание = Менеджер процессов PHP FastCGI
    После = network.target
    
    [Услуга]
    Тип = простой
    RuntimeDirectory = php
    RuntimePermissions = 755
    PIDFile = / запустить / php-fpm / php7.1-fpm.pid
    ExecStart = / etc / php / 7.1 / sbin / php-fpm --nodaemonize --fpm-config / etc / php / 7.1 / и т.д. / php-fpm.conf
    ExecReload = / bin / kill -USR2 $ MAINPID
    
    [Установить]
    WantedBy = multi-user.