Как мы делаем модули PHP в Badoo – Антон Довгаль
-
Upload
badoo-development -
Category
Internet
-
view
285 -
download
15
Transcript of Как мы делаем модули PHP в Badoo – Антон Довгаль
![Page 1: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/1.jpg)
Антон Довгаль
20 июля 2017
Модули PHPв Badoo
![Page 2: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/2.jpg)
● Свой первый модуль написал в 16 лет 2004 году - PECL/memcache
● Когда-то давно написал PECL/rar, PECL/sphinx, PECL/memtrack и ещё
какой-то трэш, по пути исправив сотни багов в PHP
● Успел 3 года поработать в Zend (в основном над Zend Server), в
процессе переписал заново PECL/oci8
● 10 лет в Badoo: поддержка/доработка PHP, разработка сервисов на C,
недорого
Про меня
![Page 3: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/3.jpg)
● Крупнейший сервис знакомств в мире - 350 млн пользователей
● ~3 млн строк кода на PHP + ~1.5 млн строк тестов
● ~1000 серверов с PHP-FPM (разработан в Badoo, добавлен в PHP в 2010
году)
● ~600 серверов MySQL
● >200 инженеров
● 2 + 0.5 + 0.5 (=3?) датацентра
● 2 офиса разработки - Москва и Лондон
Про Badoo
![Page 4: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/4.jpg)
Модули PHPони же - экстеншены
![Page 5: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/5.jpg)
● Как работает PHP с модулями?
● Что представляют из себя модули PHP?
● Как и на чём их пишут?
● Зачем их (иногда) нужно писать?
● Как они работают?
● Как начать писать свой модуль PHP
● Пара примеров из жизни
У меня был план
![Page 6: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/6.jpg)
Архитектура PHP в двух словах
![Page 7: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/7.jpg)
● Пишутся на C/C++
● Статические модули - встроены в PHP, нельзя выгрузить
● Динамические - обычный .so/.dll, можно загрузить dl()
● Могут использовать сторонние библиотеки на C/C++
Модули PHP
![Page 8: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/8.jpg)
● встроенные (standard, date, pcre, SPL, Reflection)
● собираемые по умолчанию (ctype, dom, hash, json etc.)
● поставляемые в дистрибуции
● модули из PECL - pecl.php.net
● сторонние модули - Github & Co.
Виды модулей PHP
![Page 9: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/9.jpg)
bcmath
bz2
calendar
com_dotnet
ctype
curl
date
dba
dom
enchant
exif
fileinfo
filter
Модули в дистрибуцииftp
gd
gettext
gmp
hash
iconv
imap
interbase
intl
json
ldap
libxml
mbstring
mysqli
mysqlnd
oci8
odbc
opcache
openssl
pcntl
pcre
pdo
pdo_dblib
pdo_firebird
pdo_mysql
pdo_oci
pdo_odbc
pdo_pgsql
pdo_sqlite
pgsql
phar
posix
pspell
readline
recode
reflection
session
shmop
simplexml
skeleton
snmp
soap
sockets
spl
sqlite3
standard
sysvmsg
sysvsem
sysvshm
tidy
tokenizer
wddx
xml
xmlreader
xmlrpc
xmlwriter
xsl
zend_test
zip
zlib
![Page 10: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/10.jpg)
● обычные модули
○ имплементируют функции, классы, методы
● Zend extension
○ имплементируют функции, классы, методы
○ вмешиваются в работу ядра (opcache, XDebug)
Типы модулей PHP
![Page 11: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/11.jpg)
● blitz - движок шаблонов на C
● geoi - используется для гео-поиска
● gpbs - общий интерфейс к нашим сервисам на C/C++/Go
● handlersocketi - интерфейс к HS
● imatch - сравнение изображений, поиск дубликатов
● leptonica - работа с изображениями: ресайз, поворот, искажения для
капчи
● memtrack - следит за использованием памяти в PHP, ищет прожорливые
функции
● pinba - клиент для нашего сервиса статистики на базе MySQL
Нестандартные модули PHP в Badoo
![Page 12: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/12.jpg)
● Нужен интерфейс к библиотеке на C/C++ (mysql, oci8)
● Есть задача, которая не решается на PHP (gpbs)
● Есть узкое место в коде, которое можно оптимизировать на C (blitz)
● Нужно добавить функционал в сам PHP (xdebug)
● Хочется посмотреть “что у ней внутре”
Причины написания своего модуля
![Page 13: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/13.jpg)
Пишем модуль PHPcrash course
![Page 14: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/14.jpg)
> git clone https://github.com/php/php-src
> cd php-src/ext
> ./ext_skel
./ext_skel --extname=module [--proto=file] [--stubs=file] [--xml[=file]] [--skel=dir]
[--full-xml] [--no-help]
--extname=module module is the name of your extension
--proto=file file contains prototypes of functions to create
--stubs=file generate only function stubs in file
--xml generate xml documentation to be added to phpdoc-svn
--skel=dir path to the skeleton directory
--full-xml generate xml documentation for a self-contained extension (not yet
implemented)
--no-help don't try to be nice and create comments in the code and helper functions
to test if the module compiled
Пишем модуль PHP
![Page 15: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/15.jpg)
> ./ext_skel --extname=example
Creating directory example
Creating basic files: config.m4 config.w32 .gitignore example.c
php_example.h CREDITS EXPERIMENTAL tests/001.phpt example.php [done].
Пишем модуль PHP
![Page 16: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/16.jpg)
config.m4 - опции configure и проверки библиотек, хидеров и пр.
config.w32 - используется для сборки под Windows
CREDITS - информация об авторах
EXPERIMENTAL - файл-метка, показывающий статус модуля
.gitignore - игнорируем мусор от сборки
php_example.h - заголовок модуля
example.c - исходник модуля
example.php - небольшой скрипт для демонстрации работы
tests/ - ??? какие тесты ???
Пишем модуль PHP
![Page 17: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/17.jpg)
config.m4:
PHP_ARG_ENABLE(example, whether to enable example support,[ --enable-example Enable example support])
if test "$PHP_EXAMPLE" != "no"; then PHP_NEW_EXTENSION(example, example.c, $ext_shared)fi
Пишем модуль PHP
![Page 18: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/18.jpg)
● Функции-обработчики:
○ MINIT - при загрузке/старт PHP
○ MSHUTDOWN - при выгрузке/окончание работы PHP
○ MINFO - вывод в phpinfo()
○ RINIT - начало запроса, на каждый запрос
○ RSHUTDOWN - конец запроса, на каждый запрос
● Функции, методы классов
● Список функций модуля - zend_function_entry[]
● Структура модуля - zend_module_entry
Структура модуля PHP
![Page 19: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/19.jpg)
php_example.h:
#ifndef PHP_EXAMPLE_H#define PHP_EXAMPLE_H
extern zend_module_entry example_module_entry;#define phpext_example_ptr &example_module_entry
#define PHP_EXAMPLE_VERSION "0.1.0"
#endif /* PHP_EXAMPLE_H */
Пишем модуль PHP
![Page 20: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/20.jpg)
example.c:
#ifdef HAVE_CONFIG_H#include "config.h"#endif
#include "php.h"#include "php_ini.h"#include "ext/standard/info.h"#include "php_example.h"
…
Пишем модуль PHP
![Page 21: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/21.jpg)
example.c:…/* {{{ proto string confirm_example_compiled(string arg) Return a string to confirm that the module is compiled in */PHP_FUNCTION(confirm_example_compiled){ char *arg = NULL; size_t arg_len, len; zend_string *strg;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) { return; }
strg = strpprintf(0, "Congratulations! You have successfully modified ext/%s/config.m4. Module %s is now compiled into PHP.", "example", arg);
RETURN_STR(strg);}/* }}} */…
Пишем модуль PHP
![Page 22: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/22.jpg)
БЕЗ ПАНИКИ!всё это можно потом найти тут:
github.com/tony2001/example
![Page 23: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/23.jpg)
example.c:…/* {{{ proto string confirm_example_compiled(string arg) Return a string to confirm that the module is compiled in */
/* }}} */…
Пишем модуль PHP
![Page 24: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/24.jpg)
example.c:…
PHP_FUNCTION(confirm_example_compiled){
RETURN_STR(strg);}…
Пишем модуль PHP
![Page 25: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/25.jpg)
#define PHP_FUNCTION(name) ZEND_FUNCTION(name)
#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
#define ZEND_FN(name) zif_##name
#define ZEND_NAMED_FUNCTION(name) name(INTERNAL_FUNCTION_PARAMETERS)
#define INTERNAL_FUNCTION_PARAMETERS zend_execute_data *execute_data, zval *return_value
PHP_FUNCTION(name) => zif_name(zend_execute_data *execute_data, zval *return_value)
PHP + макросы = ❤�
![Page 26: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/26.jpg)
#define RETURN_STR(s) { RETVAL_STR(s); return; }
#define RETVAL_STR(s) ZVAL_STR(return_value, s)
#define ZVAL_STR(z, s) do { \ zval *__z = (z); \ zend_string *__s = (s); \ Z_STR_P(__z) = __s; \ /* interned strings support */ \ Z_TYPE_INFO_P(__z) = ZSTR_IS_INTERNED(__s) ? \ IS_INTERNED_STRING_EX : \ IS_STRING_EX; \ } while (0)
PHP + макросы = ❤�
![Page 27: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/27.jpg)
typedef union _zend_value { zend_long lval; /* long value */ double dval; /* double value */ zend_refcounted *counted; zend_string *str; zend_array *arr; zend_object *obj; zend_resource *res; zend_reference *ref; zend_ast_ref *ast; zval *zv; <---------- :) void *ptr; zend_class_entry *ce; zend_function *func; struct { uint32_t w1; uint32_t w2; } ww;} zend_value;
Переменные в PHP. ZVAL
![Page 28: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/28.jpg)
ZVAL в PHP7
![Page 29: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/29.jpg)
example.c:…
char *arg = NULL; size_t arg_len, len; zend_string *strg;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) { return; }
…
Пишем модуль PHP
![Page 30: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/30.jpg)
example.c:…
strg = strpprintf(0, "Congratulations! You have successfully modified ext/%s/config.m4. Module %s is now compiled into PHP.", "example", arg);
RETURN_STR(strg);}/* }}} */…
Пишем модуль PHP
![Page 31: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/31.jpg)
example.c:…
PHP_MINFO_FUNCTION(example){ php_info_print_table_start(); php_info_print_table_header(2, "example support", "enabled"); php_info_print_table_end();}
…
Пишем модуль PHP
![Page 32: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/32.jpg)
example.c:…const zend_function_entry example_functions[] = { PHP_FE(confirm_example_compiled, NULL) PHP_FE_END};
zend_module_entry example_module_entry = { STANDARD_MODULE_HEADER, "example", example_functions, NULL, //MINIT NULL, //MSHUTDOWN NULL, //RINIT NULL, //RSHUTDOWN PHP_MINFO(example), PHP_EXAMPLE_VERSION, STANDARD_MODULE_PROPERTIES};
Пишем модуль PHP
![Page 33: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/33.jpg)
Нам понадобится phpize и заголовки PHP.
Обычно они есть в пакетах:
● php7-devel
● или php-devel
● или php-dev
Пишем Собираем модуль PHP
![Page 34: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/34.jpg)
> phpizeConfiguring for:PHP Api Version: 20160303Zend Module Api No: 20160303Zend Extension Api No: 320160303
> ./configure --with-php-config=/path/to/php/php-configconfigure: loading site script /usr/share/site/x86_64-unknown-linux-gnuchecking for grep that handles long lines and -e... /usr/bin/grep……
> make installInstalling shared extensions: /path/to/php/lib64/extensions/debug-non-zts-20160303/
Пишем Собираем модуль PHP
![Page 35: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/35.jpg)
<?php
dl('example.so');
echo confirm_example_compiled(“example”);
?>
Используем модуль PHP
Congratulations! You have successfully modified ext/example/config.m4. Module “example” is now compiled into PHP.
![Page 36: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/36.jpg)
Cсылка на исходники
github.com/tony2001/example
![Page 37: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/37.jpg)
Пример из жизни #1совсем простой
![Page 38: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/38.jpg)
Код для “шифрования” ID пользователя:
function map_canonical($n, $d = true) { $seed = 3358638055; $map1 = array(31, 27, 23, 19, 15, 11, 7, 3, 28, 24, 20, 16, 12, 8, 4, 0, 29, 25, 21, 17, 13, 9, 5, 1, 30, 26, 22, 18, 14, 10, 6, 2); $map2 = array(15, 23, 31, 7, 14, 22, 30, 6, 13, 21, 29, 5, 12, 20, 28, 4, 11, 19, 27, 3, 10, 18, 26, 2, 9, 17, 25, 1, 8, 16, 24, 0);
$m = 0; $n = $d ? $n : ($n ^ $seed);
foreach ($d ? $map1 : $map2 as $i => $l) { $k = $n & (1 << $i); if ($k) $m |= 1 << $l; } return $d ? $m ^ $seed : $m; }
Пример #1. Оригинал на PHP
![Page 39: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/39.jpg)
Вызовем 100 млн раз:
# time php5.3 /tmp/original.php
real 9m9.008suser 9m8.904ssys 0m0.028s
~180 тысяч вызовов в секунду
Пример #1. Оригинал на PHP
![Page 40: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/40.jpg)
static PHP_FUNCTION(bi_map_encode) /* {{{ */{ long n; unsigned int result = 0; unsigned int number;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &n) == FAILURE) { return; }
number = (unsigned int)n;#define K(i) (number & (1 << i))#define ITER(i, n) result += (n > i) ? (K(i) << (n - i)) : (K(i) >> (i - n));
ITER(0, 31); ITER(1, 27); ITER(2, 23); ITER(3, 19);…
Пример #1. Жалкая пародия на C
![Page 41: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/41.jpg)
Вызовем 100 млн раз:
# time php5.3 /tmp/copy.php
real 0m9.427suser 0m9.417ssys 0m0.008s
~11 млн вызовов в секундут.е. в 60 раз быстрее
Пример #1. Жалкая пародия на C
![Page 42: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/42.jpg)
5.3
PHP - ~550 секундМодуль - ~9 секунд
Мини-бенчмарк PHP 5.3 vs PHP 7.1
7.1
PHP - ~100 секундыМодуль - ~4 секунды
![Page 43: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/43.jpg)
Обновляйте PHP!Мораль:
![Page 44: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/44.jpg)
Пример из жизни #2чуть посложнее
![Page 45: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/45.jpg)
![Page 46: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/46.jpg)
<?php
$connect = memcache_connect(“service.host”, 3113);
$result = memcache_laccess_update($connect, $anketa_id, $user_id,
$mode, $command, $partner_id);
C:
модуль - snprintf(buf, sizeof(buf), "laccess_update v17 %u %u %c %c %u
%s %u", aid, user_id, mode, command, partner_id, ip, country_id);
сервис - sscanf(buf, "%u %ld %ld %c %f %f %c %*s %*s %ld %*s %*s %ld
%*s %*s %*s %*s %ld"....); >_<
Пример #2. Текстовый протокол
![Page 47: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/47.jpg)
Минусы:
○ приходится постоянно менять модуль PHP вместе с API сервисов
○ неэкономно расходуется сеть
○ сложный разбор аргументов методов
Плюсы:
○ человеко-читабельность протокола
Пример #2. Текстовый протокол
![Page 48: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/48.jpg)
![Page 49: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/49.jpg)
● Google Protobuf: формат сериализации, бинарная
альтернатива XML, JSON и пр.
● Google Protocol Buffers Service - RPC на базе GPB
● Формат данных задаётся proto-файлом
● Из proto можно генерировать код на C, C++, PHP, Go,
Java, Python и прочих языках
● gRPC - официальный RPC от Google 2015 года, но у нас
всё работает c 2011 года
Пример #2. GPBS
![Page 50: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/50.jpg)
Пример #2. GPBS
package badoo.cityd2;
message city { required uint32 id = 1; required string name = 2; required uint32 lang_id = 3; required uint32 user_cnt = 4; optional float lat = 5; optional float lon = 6;}
message request_find_city { required string name = 1; optional uint32 limit = 2; repeated uint32 lang_ids = 3;}
message response_cities { repeated city cities = 1;}
![Page 51: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/51.jpg)
- с помощью protobuf-c генерируем из proto-файла код на C и
дескриптор (описывает все структуры в proto a-la reflection)
- собираем код в .so, добавляя дескриптор
- подгружаем .so в PHP (dlopen, dlsym)
- используем для кодирования/декодирования пакетов Protobuf в модуле
Пример #2. GPBS
![Page 52: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/52.jpg)
<?php
$module = gpbs_import(“cityd.so”);
$connect = gpbs_connect(“cityd.host”, 1331, $module);
$call_result = gpbs_call(“find_city”, array(“name” => ”mos”));
//добавляем новый аргумент
$call_result = gpbs_call(“find_city”, array(“name” => ”mos”,
“country_id” => 1));
Пример #2. GPBS
![Page 53: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/53.jpg)
Разница между GPB и JSON:
<?php
//грузим .so, создаём объект модуля со всеми методами из дескриптора
$so = gpbs_import(“cityd.so");
//сериализуем запрос в Protobuf
$j = gpbs_serialize($so->request_find_city, array("name" => "mos",
"limit"=>10, "lang_ids"=>array(1,2,3)));
var_dump($j); // string(13). Тот же самый запрос в JSON - 44 байта!
Пример #2. GPBS
![Page 54: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/54.jpg)
Плюсы:
● все сервисы унифицированы, используют общую базу кода
● бинарный протокол - меньше потребление сети
● при изменениях в API сервиса нужно пересобрать .so из proto-файла,
в остальном меняется только PHP-код клиентской части
Пример #2. RPC на Google Protobufs
Минусы:
● бинарный протокол приходится разбирать Wireshark
![Page 55: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/55.jpg)
Плюсы:
● все сервисы унифицированы, используют общую базу кода
● бинарный протокол - меньше потребление сети
● при изменениях в API сервиса нужно пересобрать .so из proto-файла,
в остальном меняется только PHP-код клиентской части
Пример #2. RPC на Google Protobufs
Ещё плюсы:
● можно генерить JSON!
![Page 56: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/56.jpg)
![Page 57: Как мы делаем модули PHP в Badoo – Антон Довгаль](https://reader033.fdocuments.net/reader033/viewer/2022051007/5a6554b17f8b9a8c388b4ae5/html5/thumbnails/57.jpg)
PHP:
● PHP at the Core: A Hacker's Guide php.net/manual/en/internals2.php
● Extending and Embedding PHP, Sara Golemon 2006 (местами устарела).
● Читайте исходники PHP и других модулей!
Google Protobuf:
● github.com/google/protobuf
● github.com/grpc/grpc
Badoo:
● techblog.badoo.com
● habrahabr.ru/company/badoo
Полезные ссылки