All streams
Search
Write a publication
Pull to refresh
0
0
Денис @DrDet

User

Send message

У KPHP действительно есть отличия от оригинальной пыхи. KPHP не поддерживает все то, что не дружит со статической типизацией и не может быть скомпилено. Например, не поддерживается рефлексия, вызовы функций по динамическому имени, всякие eval'ы и прочее.

Еще KPHP не разрешает вещи, которую ломают систему типов - например нельзя смешивать классы с примитвами, т.е. mixed не может быть классом.
Более подробно можно почитать об отличиях в доке.
В целом, все эти ограничения заставляют писать более понятный (как для людей так и для IDE), статически типизизруемый код, который чаще всего еще и более эффективен.

Алгебраические типы сейчас действительно не совсем честные, так как string|int выводится как mixed, и получается может содержать array. Возможно в будущем мы с этим что-то сделаем, есть кое-какие идеи на этот счет.
Но зато в случае со строго типизированным кодом, компилятор все четко проверяет, и если попытаться например передать в mixed объект класса, или в interface несовместимый класс, то получим ошибку на этапе компиляции, а не TypeError в рантайме как в пхп.

  1. Под множественными имелось в виду просто несколько серверных сокетов, у каждого из которых свой backlog. Путем многочисленных экспериментов выяснили, что в случае с двумя сокетами, причем на разных портах, можем держать больший RPS без деградации, чем с одним. Пробовали разные варианты: и SO_REUSEPORT на 2 сокета + fork n раз, и отдельный listen сокет в каждом воркере с SO_REUSEPORT, и еще много всяких. Резльутат один: 2 слушающих сокета на разных портах выигрывают. Скорее всего причина тому -- contention в ядре на слушающий сокет на accept'е.

  2. Напомню, что в KPHP prefork сервер, то есть много воркер процессов которые обрабатывают запросы. Под CPU affinity имелось в виду прибивание этих воркер процессов к ядрам. Более точно - к наборам ядер, соответвующих конкретной NUMA ноде. Еще из подобных оптимизаций решили сделать прибитие проксей к NUMA нодам, чтобы каждый воркер взаимодействовал с проксей со "своей" ноды. В совокупности это все позволило выиграть несколько процентов CPU.

Да, именно об этом. Все благодаря SCM_RIGHTS.
По UNIX сокету просто передается массив чисел - открытых файловых дескрипторов. Дальше вся магия происходит в kernel space: происходит что-то типа dup файловых дескрипторов из таблицы открытых файлов одного процесса в таблицу открытых файлов другого. В итоге на принимающей стороне в user space просто отдаются полученные файловые дескрипторы.
Сами числа файловых дескрипторов могут отличаться, но они будут указывать на те же записи в системной таблице файлов.

Есть хорошая статья от cloudflare на эту тему.

Еще можно почитать man unix, man open - там довольно хорошо описано.

У kphp сервера есть специальный файлик в разделяемой памяти (см. shm_open).
Когда новый сервер стартует, он через этот специальный файлик связывается со старым сервером, и начинается graceful restart.
Сначала старый сервер через UNIX сокет с помощью SCM_RIGHTS посылает новому открые файловые дескрипторы нужных серверных коннектов.
Затем старый сервер начинает плавно тушить своих воркеров (в kphp prefork сервер), в то время как новый поднимает своих.
В итоге, когда воркеров больше не остается, старый сервер завершается, и получается бесшовный рестарт.

Information

Rating
Does not participate
Registered
Activity

Specialization

Backend Developer, Database Developer