Upgrade to Pro — share decks privately, control downloads, hide ads and more …

最近メールフォームかいてないメールフォーマーによる、ちょっとだけ変わった一応PHPのメールフォーム(?)のお話 〜副題 最近swooleがたのしいです〜

uzulla
June 15, 2018

最近メールフォームかいてないメールフォーマーによる、ちょっとだけ変わった一応PHPのメールフォーム(?)のお話 〜副題 最近swooleがたのしいです〜

at 全然野菜(PHPCon Fukuoka 2018 非公式 前々夜祭)
20min talk
https://pepabo.connpass.com/event/85144/

uzulla

June 15, 2018
Tweet

More Decks by uzulla

Other Decks in Programming

Transcript

  1. php (ڞ௨ɺ΄΅aptͰ͍Εͨ··) • PHP 7.2.6 • opcache • xdebugͳͲ͸ແ͠ •

    swoole֦ு͸swooleςετ࣌ͷΈ • (cliʹͷΈ֦ுΛϩʔυʣ
  2. nginx (ڞ௨ɺ΄΅aptͰ͍Εͨ··) • worker_processes auto; • worker_connections 768; • gzip

    on; • tcp_nopush on; • tcp_nodelay on; • keepalive_timeout 65;
  3. php-fpmʢൺֱ༻ʣ • FW͸ slim 3 • fpmઃఆ • pm =

    static • pm.max_children = 8 • fastcgi unix socket઀ଓ
  4. ϕϯν̍ • / (ϑΥʔϜ)Λճ͢ɺrpsΛܭଌ • wrk -c {N} -t 8

    -d 10s -R 100000 http:/ /{host}/ • ಉ࣌઀ଓ਺ΛมԽ͍ͤͯ͘͞(c͕1ͷ࣌ͷΈɺt΋1) • ̎ճճͯ͠ߴ͍ํΛ࠾༻ • Τϥʔ͕ͰͨΒ0ѻ͍
  5. root@ubu:~/wrk2# ./wrk -c 1 -t 1 -d 10s -R 100000

    http://127.0.0.1/ Running 10s test @ http://127.0.0.1/ 1 threads and 1 connections Thread Stats Avg Stdev Max +/- Stdev Latency 5.13s 2.83s 9.95s 58.97% Req/Sec -nan -nan 0.00 0.00% 4022 requests in 10.00s, 2.14MB read Requests/sec: 402.19 Transfer/sec: 218.75KB
  6. N php-fpm swoole 1 402 2530 50 946 5782 100

    931 5429 150 Τϥʔ 5335 200 - 5994 500 - 6612 1000 - Τϥʔ
  7. ϕϯν̎ • /post (อଘ)Λճ͢ɺrpsΛܭଌ • ab -c {N} -n 1000

    -p postdata -m POST -T "application/x-www- form-urlencoded" http:/ /{host}/post • ಉ࣌઀ଓ਺ΛมԽ͍ͤͯ͘͞ • ̎ճճͯ͠ߴ͍ํΛ࠾༻ • Τϥʔ͕ͰͨΒ0ѻ͍ • (͕ࠩϠό͗͢ΔͷͰDNS໰͍߹ΘͤΛൈ͍ͯ͋Γ·͢)
  8. N php-fpm swoole 1 110 303 10 412 477 100

    408 514 150 Τϥʔ 537 200 520 400 540
  9. ࢀߟه࿥ helloworldϕϯν • wrk -c {N} -t 8 -d 10s

    -R 100000 http:/ /{host}/hello • ୯ʹʮhelloʯ͚ͩΛฦ͢ɺయܕతͳʮϕϯν൪௕ʯίʔυ • ͸͖ͬΓݴͬͯҙຯ͸ͳ͍͆
  10. N php-fpm swoole 1 948 3187 50 1984 5935 100

    1909 7303 150 Τϥʔ 6649 200 7649 500 8915
  11. ᐽՍಛੑ EasySwoole ੋҰ׺جဋSwoole Server 䇖ؿ֥ӈሁଽթ྘֥ٳ҃ൔ PHPᐽՍɼህູAPIࣕੜɼϥຂԮ๤PHPᄎྛଆൔᄝࣉӱߒఏބ໓ࡱ ࡆᄛഈջট֥ྟି෥ാbEasySwoole ߴ౓෧૷ྃ Swoole Server

    ࣕ ґچົӻ Swoole Server ݪ༗ಛੑɼࢧ࣋ಉൈࠁކࡓ๐HTTPɺࣗఆ ၬTCPɺUDPླྀၰđಞषؿᆀၛቋ֥֮࿐༝ӮЧބࣚ৯щཿԛ؟ࣉ ӱđॖၳ҄đۚॖႨ֥ႋႨڛༀb
  12. ॏཁͳϑΝΠϧ project App Root dir !"App App Class # !"HttpController

    # # $"Index.php ίϯτϩʔϥ !"Config.php ઃఆ !"EasySwooleEvent.php Πϕϯτ !"easyswoole easyswoole ίϚϯυ • ͜ΕΒ͸composer create-projectͰੜ੒Ͱ͖Δ • ॻ͔ͳ͖Ό͍͚ͳ͍ͷ͸࠷௿ݶIndex.phpͷΈʢޙड़ʣ
  13. • ʮΊͬͪΌΧϥϑϧͳதࠃޠ…͚ͩͲ·͋ɺͳΜͱͳ͘Θ͔ Δɺ͍͚Δ͍͚Δʂʯ • ͨͱ͑͹… • --d -> ͚ͭΔͱσʔϞϯԽ •

    --workerNum-1 -> ϫʔΧʔ਺ • (--workerNum 1 Ͱ͸ͳ͍…) • --user-nobody -> nobodyϢʔβʔͰ࣮ߦ • (--user nobodyͰ͸ͳ͍…ʣ
  14. server { root /path/to/htdocs/; location / { proxy_http_version 1.1; proxy_set_header

    Connection "keep-alive"; proxy_set_header X-Real-IP $remote_addr; if (!-e $request_filename) { proxy_pass http://127.0.0.1:9501; } } }
  15. ඪ४ͷίϯτϩʔϥʔ • /{Ϋϥε໊}/{ϝιου໊} Έ͍ͨͳελΠϧͰϚοϓɺઃఆϑΝ Πϧ͸ແ͍ • /Auth/Login -> \App\HttpController\Auth::login() •

    / -> \App\HttpController\Index::index() • /HelloWorld -> \App\HttpController \HelloWorld::index() or \App\HttpController \Index::HelloWorld()
  16. • REST͸ͮ͠Β͍ • HTTP Method੾Γ෼͚͸ແ͍ɺURL಺ύϥϝλ΋ύʔε͠ͳ͍ • ʮผʹRESTͳͯ͘΋ࢮͳͳ͍͠…ʯʮࢮ͵ਓ΋͍Δʯ • ͦ͏͍͏ਓ͸΋͏ҰͭͷΧελϜϧʔλΛ͔͓ͭ͏ •

    γϯϓϧͩ͠ɺઃఆ͍Βͳ͍͠ɺURL͕៉ྷͰͳͯ͘΋͍͍͠… ͱ͍͏͜ͱͰݸਓతʹ͸ͪ͜Β͕… • ʢGET ?id=1͘Β͍ͳΒڐͤΔ͠ɺෳࡶͳύϥϝλ͸JSONΛ POST͢Ε͹͍͍ͱࢥ͍ͬͯΔݹ͍ਓؒͷൃ૝Ͱ͢ʣ
  17. ΋͏Ұͭͷख๏ɺΧελϜϧʔλʔ • nikic/FastRoute ͦͷ΋ͷɻͳͷͰলུ • https:/ /www.easyswoole.com/Manual/2.x/En/_book/Http/ router.html • ΞΫγϣϯͷ࡞Γ͸ඪ४ͷίϯτϩʔϥʔͱ͸͜ͱͳΓɺҾ਺

    ʹreq/resΛ͍ΕΔPSR-7ରԠFWʹΑ͋͘ΔܗʹͳΓ·͢ $routeCollector->get( '/user/{id:\d+}',function (Request $request ,Response $response,$id){ $response->write("this is router user ,your id is {$id}"); $response->end(); });
  18. public static function mainServerCreate(/* ... */): void { // timerͰ1ඵຖʹΠϯλʔόϧ࣮ߦ

    $register->add($register::onWorkerStart, function ($server, $workerId) { if ($workerId == 0) { Timer::loop(1000, function () { echo 'TICK!'; }); } }); }
  19. function lookupCo() {// ίϧʔνϯ൛ for($i=0; $i<100; $i++) { $ip =

    \Swoole\Coroutine::gethostbyname("dns.google.com"); } } function lookupNormal() {//ී௨൛ for($i=0; $i<100; $i++) { $ip = gethostbyname("dns.google.com"); } } function hello() { $this->response()->write('hello'); }
  20. • lookupCoʹෛՙΛ͔͚ͭͭɺhelloʹෛՙΛ͔͚Δࢼݧ • lookupCo: 1.64 rps / / ͜͜͸େ͖͘มΘΒͳ͍ •

    hello: 147.36 rps / / 100ഒʹ • lookup͕໰͍߹ΘͤதʹଞͷॲཧΛਐΊΔͷͰϒϩοΫͮ͠ Β͘ɺhello͕଎͘ͳͬͨ
  21. protected function isProbablyExistsMailServer($host) { $goog_dns = "dns.google.com"; $dns_ip = static::getHostByNameWithCache($goog_dns);

    $cli = new \Swoole\Coroutine\Http\Client($dns_ip, 443, true); $cli->setHeaders([ 'Host' => $goog_dns, "User-Agent" => 'php', 'Accept' => 'application/json', 'Accept-Encoding' => 'gzip', ]); $encoded_host = urlencode($host);
  22. $cli->get("/resolve?name={$encoded_host}&type=MX"); $mx_records = json_decode($cli->body, true); $cli->get("/resolve?name={$encoded_host}&type=A"); $a_records = json_decode($cli->body, true);

    $cli->close(); return isset($mx_records['Answer']) || isset($a_records['Answer']); } function some() { $res = $this->isProbablyExistsMailServer('example.jp') ? "found":"notfound"; }
  23. λεΫͷొ࿥ class Index extends Controller { function index() // ͱ͋Δίϯτϩʔϥʔ

    { // ... $this->response()->write('Ϩεϙϯε'); $some = 'data'; TaskManager::async(function () use ($some) { $log = new Log; $log->set($some); // ॏ͍ॲཧͳͲ }); // ผʹλεΫొ࿥͸࠷ޙͰͳͯ͘΋Α͍ } }
  24. public static function frameInitialize(): void { // ॳظԽ Cache::init(new Files([

    'expire' => 0, // ߏթݖ௹ൈࡗ 'cache_subdir' => true, // 䇖ఓሰଢ੣թ٢ 'prefix' => '', // ߏթ໓ࡱުሗ଀ 'path' => __DIR__.'/cache', // อଘDIR 'hash_type' => 'md5', // จ໊݅తᄒرํࣜ 'data_compress' => false, // ఓႨߏթଽಸ࿢෪ 'thread_safe' => false, // ϑΝΠϧϩοΫ͢Δ͔ 'lock_timeout' => 3000, // จ݅࠷Ӊ෭קൈࡗ(ms) ]));
  25. Cache::get('name', 'औಘͰ͖ͳ͔ͬͨΒ'); Cache::set('name', 1, $ttl); Cache::has('name'); Cache::delete('name'); Cache::clear(); Cache::set('name', 1);

    Cache::inc('name');// +1 Cache::dec('name', 10);// -10 Cache::pull('name', 'औಘͰ͖ͳ͔ͬͨΒ');// pop Cache::remember('name', 'value'); // ͳ͚Ε͹set
  26. protected function getHostByNameWithCache($host){ $val = Cache::get($host, null); if(!is_null($val)){ return $val;

    } $ip = \Swoole\Coroutine::gethostbyname("dns.google.com"); Cache::set($host, $ip, 3600); return $ip }
  27. easy-swoole঺հ·ͱΊ • ϝʔϧϑΥʔϜΛߴ଎Խ͢Δʹ͋ͨͬͯ • ϑΥʔϜΛදࣔ -> ूܭσʔλΛද͓ࣔͯ͘͠ • ֬ೝը໘ ->

    ϝΞυଘࡏ֬ೝͷDNS໰͍߹Θͤ͸ඇಉظͰ • อଘ -> λεΫԽͯ͠ͱʹ͔͘ฦ͢ • ͱ͍ͬͨࣄ͕easy swooleͰϥΫϥΫͰ͖Δ
  28. $ cat bot_log |grep swoole| wc -l 25 $ cat

    bot_log |grep laravel| wc -l 333 $ cat bot_log |grep slim| wc -l 15 $ cat bot_log |grep cakephp| wc -l 22 $ cat bot_log |grep zend| wc -l 8
  29. Πϯετʔϧํ๏͸ʁ • swoole͸ී௨ͷ֦ுͱಉ͡ $ git clone https://github.com/swoole/swoole-src.git $ cd swoole-src/

    $ phpize $ ./configure --enable-openssl $ make all $ make install $ echo "extension=swoole" >> /etc/php/7.2/cli/conf.d/30-swoole.ini
  30. ։ൃαϙʔτ • 䎔ဋIDEॿख(ิ׬༻ϔϧύ) • composer require easyswoole/swoole-ide-helper • https:/ /www.easyswoole.com/Manual/2.x/Cn/_book/Introduction/

    install.html • (Swoole͸C֦ுͳͷͰɺϔϧύΛ͍Εͳ͍ͱิ׬Ͱ͖ͳ͍Օ ॴ΋ʣ • ʢrequire-devͰeasy-swooleΛ͍ΕͨΒೖΔʣ
  31. [Unit] Description=swoole service After=network.target [Service] Type=simple LimitNOFILE=65535 WorkingDirectory=/path/to/easyswoole-sample/ ExecStart=/usr/bin/php /path/to/easyswoole-sample/easyswoole

    start --pid-/path/to/easyswoole-sample/Log/pid.pid ExecReload=/bin/sh -c "/bin/kill -USR1 `cat /path/to/easyswoole-sample/Log/pid.pid`" ExecStop=/usr/bin/php /path/to/easyswoole-sample/easyswoole stop --pid-/path/to/easyswoole-sample/Log/pid.pid Restart=always User=www-data [Install] WantedBy=multi-user.target
  32. server { listen 80; root /path/to/htdocs; server_name _; location /

    { proxy_http_version 1.1; proxy_set_header Connection "keep-alive"; proxy_set_header X-Real-IP $remote_addr; # proxy_pass http://127.0.0.1:9501; proxy_pass http://unix:/tmp/swoole.sock:; } }
  33. EOL