ããã«ã¡ã¯ ç§ã®ååã¯ã¢ã³ãã¬ã€ã§ããã¢ã¹ã¯ã¯ã®å·¥ç§å€§åŠã®å€§åŠé¢çã§ãããéåžžå€ã§ãã ãšãŠãæ§ãã㪠åå¿è
ã®èµ·æ¥å®¶ããã³éçºè
ã ãã®èšäºã§ã¯ãPHPïŒä»¥åã¯åçŽã ã£ãã®ã§æ°ã«å
¥ã£ãŠããŸãããããããŠç§ã«å«ãããŸãã-ãªãã«ãããããŠããã®ãïŒãNodeJSã«åãæ¿ããçµéšãå
±æããããšã«ããŸããã ããã§ã¯éåžžã«åçŽã§äžèŠåºæ¬çãªã¿ã¹ã¯ãæäŸã§ããŸãããããã§ãNodeJSãšJavaScriptã§ã®ãµãŒããŒåŽéçºã®æ©èœã«ç²ŸéããŠããéã«è§£æ±ºããããšæã£ãŠããŸããã PHPãããããæ¥æ²¡ã«ãªããNodeJSã«åã£ãŠä»£ãã£ãããšãæ確ã«èª¬æããå®èšŒããããšããŸãã Nodeã§HTMLããŒãžãã¬ã³ããªã³ã°ããããã€ãã®æ©èœãåŠã¶ããšã¯ã誰ãã䟿å©ã ãšæããããããŸããã
ã¯ããã«
ãšã³ãžã³ãæžããŠããéãç§ã¯æãåçŽãªãã¯ããã¯ã䜿çšããŸããã ããã±ãŒãžãããŒãžã£ãŒãã«ãŒãã£ã³ã°ããããŸããã ããã»ã¹ããŒã«ããµããŒãããããã«PHP-FPMã«ãã£ãŠæ§æããããèŠæ±ãããã«ãŒããšååãäžèŽããããŒãã³ã¢ãã©ã«ããŒãšãããããã®index.phpã®ã¿ã åŸã«ComposerãšLaravelã䜿çšããå¿ èŠãçããŸãããããã¯ç§ã«ãšã£ãŠæåŸã®ã¹ãããŒã§ããã PHPããNodeJSãŸã§ãã¹ãŠãæžãçŽãããšã«ããçç±ã®è©±ã«ç§»ãåã«ãèæ¯ã«ã€ããŠå°ã説æããŸãã
ããã±ãŒãžãããŒãžã£ãŒ
2018幎ã®çµããã«ãç§ã¯Laravelã§æžããã1ã€ã®ãããžã§ã¯ãã§äœæ¥ããæ©äŒããããŸããã ããã€ãã®ãã°ãä¿®æ£ããæ¢åã®æ©èœãå€æŽããã€ã³ã¿ãŒãã§ãŒã¹ã«ããã€ãã®æ°ãããã¿ã³ãè¿œå ããå¿ èŠããããŸããã ããã»ã¹ã¯ãããã±ãŒãžãšäŸåé¢ä¿ãããŒãžã£ãŒãã€ã³ã¹ããŒã«ããããšããå§ãŸããŸããã PHPã§ã¯ãComposerãããã«äœ¿çšãããŸãã ãã®åŸã顧客ã¯1ã³ã¢ãš512ã¡ã¬ãã€ãã®RAMãåãããµãŒããŒãæäŸããŸããããããã¯Composerã§ã®æåã®çµéšã§ããã ã¡ã¢ãªã512ã¡ã¬ãã€ãã®ä»®æ³ãã©ã€ããŒããµãŒããŒã«äŸåé¢ä¿ãã€ã³ã¹ããŒã«ãããšãã¡ã¢ãªäžè¶³ã®ããããã»ã¹ãã¯ã©ãã·ã¥ããŸããã
Linuxã«ç²ŸéããDebianãšUbuntuã§ã®äœæ¥çµéšãããç§ã«ãšã£ãŠããã®åé¡ã®è§£æ±ºçã¯æããã§ãã-SWAPãã¡ã€ã«ã®ã€ã³ã¹ããŒã«ïŒã¹ã¯ãããã¡ã€ã«-Linux管çã«äžæ
£ããªäººåãïŒã ããšãã°ãåã®Laravelãã£ã¹ããªãã¥ãŒã·ã§ã³ãDigital Oceanã«ã€ã³ã¹ããŒã«ããçµéšã®æµ
ãéçºè
ã¯ãã³ã³ãããŒã«ããã«ã«ç§»åããŠãäŸåé¢ä¿ã®ã€ã³ã¹ããŒã«ãã¡ã¢ãªã»ã°ã¡ã³ããŒã·ã§ã³ãšã©ãŒã§åæ¢ãããŸã§é¢çšãåŒãäžããŸãã NodeJSã¯ã©ãã§ããïŒ
ãŸããNodeJSã«ã¯ç¬èªã®ããã±ãŒãžãããŒãžã£ãŒnpmããããŸãã 䜿çšãã¯ããã«ç°¡åã§ãããã³ã³ãã¯ãã§ãæå°éã®RAMã®ç°å¢ã§ãæ©èœããŸãã äžè¬ã«ãComposerãNPMã®ããã¯ã°ã©ãŠã³ãã«å¯ŸããŠéé£ããããšã¯ãããŸããããããã±ãŒãžãã€ã³ã¹ããŒã«ãããšãã«ãšã©ãŒãçºçãããšãComposerã¯éåžžã®PHPã¢ããªã±ãŒã·ã§ã³ã®ããã«ã¯ã©ãã·ã¥ããããã±ãŒãžã®ã©ã®éšåãã€ã³ã¹ããŒã«ãããæåŸã«ã€ã³ã¹ããŒã«ããããã©ãããããããŸããçµäºããŸãã äžè¬ã«ãLinux管çè
ã®å Žåãã€ã³ã¹ããŒã«ã®ã¯ã©ãã·ã¥= Rescueã¢ãŒãããã³dpkg --configure -a
ãã©ãã·ã¥ããã¯ã ãã®ãããªãé©ãããç§ãè¿œãè¶ããŸã§ã«ãç§ã¯PHPã奜ãã§ã¯ãããŸããã§ãããããããã¯PHPã«å¯Ÿãããã€ãŠã®å€§ããªæã®coã®æåŸã®éã§ããã
é·æçãªãµããŒããšããŒãžã§ã³ç®¡çã®åé¡
éçºè ãæåã«PHP7ãçºè¡šãããšããã©ã®ãããªè奮ãšé©ããPHP7ãåŒãèµ·ããããèŠããŠããŸããïŒ çç£æ§ã2å以äžãäžéšã®ã³ã³ããŒãã³ãã§ã¯5åãŸã§åäžããŸãïŒ PHP第7ãçãŸãããšããèŠããŠããŸããïŒ ãããŠãWordPressãã©ãã»ã©æ©ãç²åŸãããïŒ 2015幎12æã§ããã PHP 7.0ã¯çŸåšãå€ãããŒãžã§ã³ã®PHPãšèŠãªãããŠãããããæŽæ°ããããšã匷ããå§ãããŸã...ããããããŒãžã§ã³7.1ã§ã¯ãªããããŒãžã§ã³7.2ã«æŽæ°ããŠãã ããã éçºè ã«ãããšãããŒãžã§ã³7.1ã¯ãã§ã«ã¢ã¯ãã£ããªãµããŒãã奪ãããŠãããã»ãã¥ãªãã£ã¢ããããŒãã®ã¿ãåãåããŸãã ãããŠã8ãæåŸã«ããã¯åæ¢ããŸãã ã¢ã¯ãã£ããªãµããŒããšããŒãžã§ã³7.2ãšãšãã«å»æ¢ãããŸãã ä»å¹Žã®çµãããŸã§ã«ãPHPã«ã¯çŸåšã®ããŒãžã§ã³ã7.3ãããããŸããã
å®éãããã¯ããŸãæå³ã®ãªãããšã§ã¯ãªããPHP 7.0ã§äœæãããããžã§ã¯ãã®å ŽåãPHPããã®è±åŽã®çç±ã«èµ·å ãããã®ã§ã¯ãããŸããã*éããæç¹ã§æ¢ã«éæšå¥šã®èŠåã¯çºçããŠããŸããã äŸåé¢ä¿ã®ã€ã³ã¹ããŒã«ãã¯ã©ãã·ã¥ãããããžã§ã¯ãã«æ»ããŸãããã ããã¯ã2015幎ã«Laravel 4ãšPHP 5.6ã§æžããããããžã§ã¯ãã§ãã ããã4幎ãéããããã«èŠããŸããããããã§ã¯ãããŸãã-å€ãã®å»æ¢èŠåãå€ãã¢ãžã¥ãŒã«ãéåžžã¯ã«ãŒããšã³ãžã³ã®æŽæ°ãåå ã§Laravel 5ã«ã¢ããã°ã¬ãŒãã§ããŸããã
ãããŠãããã¯Laravelã ãã«åœãŠã¯ãŸããŸããã PHP 7.0ã®æåã®ããŒãžã§ã³ãã¢ã¯ãã£ãã«ãµããŒããããŠããéã«æžãããPHPã¢ããªã±ãŒã·ã§ã³ã䜿çšããŠãå€ãPHPã¢ãžã¥ãŒã«ã§çºçããåé¡ã®è§£æ±ºçãæ¢ããŠå€ãéããæºåãããŠãã ããã æåŸã«ãèå³æ·±ãäºå®ïŒPHP 7.0ã®ãµããŒãã¯ãPHP 5.6ã®ãµããŒããããæ©ãå»æ¢ãããŸããã ã¡ãã£ãšã
NodeJSã¯ã©ãã§ããïŒ ããã§ãã¹ãŠãããè¯ããªããšã¯èšããŸããããNodeJSã®ãµããŒãæéã¯PHPãšæ ¹æ¬çã«ç°ãªããŸãã ããããããã§ã¯ã»ãŒåãã§ããåLTSããŒãžã§ã³ã¯3幎éãµããŒããããŠããŸãã ãã ããNodeJSã«ã¯ããããã®ææ°ããŒãžã§ã³ãããå°ããããŸãã
2016幎ã«äœæãããã¢ããªã±ãŒã·ã§ã³ããããã€ããå¿ èŠãããå Žåã¯ãããã§ãŸã£ããåé¡ããªãããšã確èªããŠãã ããã ã¡ãªã¿ã«ãããŒãžã§ã³6ã*ã¯ä»å¹Ž4æã®ã¿ãµããŒããããªããªããŸãã ãããŠãåã«8ã10ã11ããããŠæ¬¡ã®12ããããŸãã
NodeJSã«åãæ¿ããéã®é£ãããšé©ã
ãããããNodeJSã§HTMLããŒãžãã¬ã³ããªã³ã°ããæ¹æ³ã«ã€ããŠãç§ã«ãšã£ãŠæããšããµã€ãã£ã³ã°ãªè³ªåããå§ããŸãããã ããããæåã«ãããPHPã§ã©ã®ããã«è¡ãããããæãåºããŸãããã
- HTMLãPHPã³ãŒãã«çŽæ¥åã蟌ã¿ãŸãã MVCã«ãŸã å°éããŠããªããã¹ãŠã®åå¿è ãåæ§ã§ãã ãã®ãããWordPressã§è¡ãããŸãããããã¯éåžžã«æãããããšã§ãã
- MVCã䜿çšããŸããããã«ãããéçºè ã®ããåããç°¡çŽ åããããããžã§ã¯ããããã€ãã®éšåã«åå²ããããšãã§ããŸãããå®éã«ã¯ãã®ã¢ãããŒãã§ã¯ãã¹ãŠãè€éã«ãªãã ãã§ãã
- ãã³ãã¬ãŒããšã³ãžã³ã䜿çšããŸãã æã䟿å©ãªãªãã·ã§ã³ã§ãããPHPã§ã¯äœ¿çšã§ããŸããã TwigãŸãã¯Bladeã§ææ¡ãããŠããæ§æãäžæ¬åŒ§ãšããŒã»ã³ããŒãžã§èŠãŠãã ããã
ç§ã¯ãããã€ãã®æè¡ãçµã¿åãããããçµ±åãããããããšã«ç±å¿ã«å察ããŠããŸãã HTMLã¯åå¥ã«ååšããã¹ã¿ã€ã«ã¯åå¥ã«ååšããJavaScriptã¯åå¥ã«ååšããå¿ èŠããããŸãïŒReactã§ã¯ãéåžžãããã¯æªããã«èŠããŸã-HTMLãšJavaScriptã¯æ··åšããŠããŸãïŒã ããããç§ã®ãããªå¥œã¿ãæã€éçºè ã«ãšã£ãŠçæ³çãªãªãã·ã§ã³ããã³ãã¬ãŒããšã³ãžã³ã§ããçç±ã§ãã NodeJSã®Webã¢ããªã±ãŒã·ã§ã³ã§é·ãéæ€çŽ¢ããå¿ èŠããªãã£ããããJadeïŒPugJSïŒãéžæããŸããã æ§æãã·ã³ãã«ã§ããããšãæè¬ããŸãã
div.row.links div.col-lg-3.col-md-3.col-sm-4 h4.footer-heading . div.copyright div.copy-text 2017 - #{current_year} . div.contact-link span : a(href='mailto:hello@flaut.ru') hello@flaut.ru
ããã§ã¯ãã¹ãŠãéåžžã«ç°¡åã§ãããã³ãã¬ãŒããäœæãããããã¢ããªã±ãŒã·ã§ã³ã«ããŠã³ããŒãããäžåºŠã³ã³ãã€ã«ããŠããããã€ã§ãéœåã®è¯ãå Žæã§äœ¿çšããŸãã ç§ã®æèŠã§ã¯ãPugJSã®ããã©ãŒãã³ã¹ã¯ãPHPã³ãŒãã«HTMLãåã蟌ãããšã§ã¬ã³ããªã³ã°ãããããçŽ2ååªããŠããŸãã PHPã®åæ段éã§çŽ200ã250ããªç§ã§ãµãŒããŒã«ãã£ãŠéçããŒãžãçæãããå Žåããã®æéã¯çŽ90ã120ããªç§ã«ãªããŸãïŒPugJSã§ã®ã¬ã³ããªã³ã°ã§ã¯ãªããããŒãžãªã¯ãšã¹ããããµãŒããŒãžã®HTMLã䜿çšããã¯ã©ã€ã¢ã³ããžã®å¿çãŸã§ã®æéã«ã€ããŠã§ãïŒ ïŒ ããã¯ãã¢ããªã±ãŒã·ã§ã³ã®èµ·å段éã§ãã³ãã¬ãŒããšãã®ã³ã³ããŒãã³ããããŒãããã³ã³ã³ãã€ã«ããæ¹æ³ã§ãã
const pugs = {} fs.readdirSync(__dirname + '/templates/').forEach(file => { if(file.endsWith('.pug')) { try { var filepath = __dirname + '/templates/' + file pugs[file.split('.pug')[0]] = pug.compile(fs.readFileSync(filepath, 'utf-8'), { filename: filepath }) } catch(e) { console.error(e) } } }) // return pugs.tickets({ ...config })
éåžžã«ã·ã³ãã«ã«èŠããŸãããJadeã§ã¯ãã³ã³ãã€ã«æžã¿ã®HTMLãæäœãã段éã§å°ãè€éã§ããã å®éãããŒãžã«ã¹ã¯ãªãããå®è£
ããã«ã¯ããã£ã¬ã¯ããªãããã¹ãŠã®.js
ãã¡ã€ã«ã.js
ãããããã«æçµå€æŽã®æ¥ä»ãè¿œå ããéåæé¢æ°ã䜿çšãããŸãã ãã®é¢æ°ã®åœ¢åŒã¯æ¬¡ã®ãšããã§ãã
for(let i = 0; i < files.length; i++) { let period = files[i].lastIndexOf('.') // get last dot in filename let filename = files[i].substring(0, period) let extension = files[i].substring(period + 1) if(extension === 'js') { let fullFilename = filename + '.' + extension if(env === 'production') { scripts.push({ path: paths.production.web + fullFilename, mtime: await getMtime(paths.production.code + fullFilename)}) } else { if(files[i].startsWith('common') || files[i].startsWith('search')) { scripts.push({ path: paths.developer.scripts.web + fullFilename, mtime: await getMtime(paths.developer.scripts.code + fullFilename)}) } else { scripts.push({ path: paths.developer.vendor.web + fullFilename, mtime: await getMtime(paths.developer.vendor.code + fullFilename)}) } } } }
åºåã§ã¯ããã¡ã€ã«ãžã®ãã¹ãšã¿ã€ã ã¹ã¿ã³ãã§æåŸã«ç·šéãããæéïŒã¯ã©ã€ã¢ã³ããã£ãã·ã¥ãæŽæ°ããããïŒãšãã2ã€ã®ããããã£ãæã€ãªããžã§ã¯ãã®é åãååŸããŸãã åé¡ã¯ããã£ã¬ã¯ããªããã¹ã¯ãªãããã¡ã€ã«ãåéãã段éã§ããããããããã¹ãŠå³å¯ã«ã¢ã«ãã¡ãããé ã«ã¡ã¢ãªã«ããŒããããããšã§ãïŒãã£ã¬ã¯ããªèªäœã«é 眮ããããã¡ã€ã«ã¯äžããäž-æåããæåŸãŸã§åéãããããïŒã ããã«ããã app.jsãã¡ã€ã«ãæåã«èªã¿èŸŒãŸãã ãã®åŸã«polyfillsãå«ãcore.min.jsãã¡ã€ã«ãèªã¿èŸŒãŸãã æåŸã«vendor.min.jsãèªã¿èŸŒãŸããŸããã ãã®åé¡ã¯éåžžã«ç°¡åã«è§£æ±ºãããŸãã-éåžžã«ãããµãããœãŒãïŒ
scripts.sort((a, b) => { if(a.path.includes('core.min.js')) { return -1 } else if(a.path.includes('vendor.min.js')) { return 0 } return 1 })
PHPã§ã¯ãæååã§äºåã«èšè¿°ãããJSãã¡ã€ã«ãžã®ãã¹ãšãã圢ã§ããã¹ãŠã巚倧ãªå€èŠ³ãããŠããŸããã ã·ã³ãã«ã ãéçŸå®çã
NodeJSã¯ã¢ããªã±ãŒã·ã§ã³ãRAMã«ä¿æããŸã
ããã¯å€§ããªãã©ã¹ã§ãã ãµãŒããŒäžã«ãäºãã«ç¬ç«ããŠäžŠè¡ããŠãéçºè
çšããŒãžã§ã³ãšæ¬çªããŒãžã§ã³ã®2ã€ã®ãµã€ããååšããããã«ããã¹ãŠãæºåãããŠããŸãã éçºãµã€ãã®PHPãã¡ã€ã«ã«ããã€ãã®å€æŽãå ãããããã®å€æŽãå®çšŒåç°å¢ã«ããŒã«ã¢ãŠãããå¿
èŠããããšæ³åããŠãã ããã ãããè¡ãã«ã¯ããµãŒããŒãåæ¢ãããããç³ãèš³ãããŸããããtechãWorkãã¹ã¿ããé
眮ãããã®æç¹ã§éçºè
ãã©ã«ããŒããæ¬çªãã©ã«ããŒã«ãã¡ã€ã«ãåå¥ã«ã³ããŒããå¿
èŠããããŸãã ããã«ãããäœããã®ããŠã³ã¿ã€ã ãçºçããå€æã倱ãããå¯èœæ§ããããŸãã NodeJSã®ã€ã³ã¡ã¢ãªã¢ããªã±ãŒã·ã§ã³ã®å©ç¹ã¯ããšã³ãžã³ãã¡ã€ã«ãžã®ãã¹ãŠã®å€æŽãåèµ·ååŸã«ã®ã¿è¡ãããããšã§ãã ããã¯éåžžã«äŸ¿å©ã§ãããªããªããå¿
èŠãªãã¹ãŠã®ãã¡ã€ã«ãå€æŽãšãšãã«ã³ããŒããŠããããµãŒããŒãåèµ·åããã ãã ããã§ãã ãã®ããã»ã¹ã«ã¯1ã2ç§ãããããããããŠã³ã¿ã€ã ã¯çºçããŸããã
ããšãã°ãnginxã§ãåãã¢ãããŒãã䜿çšãããŸãã æåã«æ§æãç·šéãã nginx -t
ã§ç¢ºèªããŠããã service nginx reload
å€æŽãå ããŸãã
NodeJSã¢ããªã±ãŒã·ã§ã³ã®ã¯ã©ã¹ã¿ãªã³ã°
NodeJSã«ã¯éåžžã«äŸ¿å©ãªããŒã«pm2ããã»ã¹ãããŒãžã£ãŒããããŸãã éåžžãNodeã§ã¢ããªã±ãŒã·ã§ã³ãå®è¡ããã«ã¯ã©ãããã°ããã§ããïŒ ã³ã³ãœãŒã«ã«å
¥ãã node index.js
ãèšè¿°ãnode index.js
ã ã³ã³ãœãŒã«ãéãããšããã«ãã¢ããªã±ãŒã·ã§ã³ãéããŸãã å°ãªããšãããã¯ãUbuntuãæèŒãããµãŒããŒã§çºçããããšã§ãã ãããåé¿ããã¢ããªã±ãŒã·ã§ã³ãåžžã«å®è¡ãç¶ããã«ã¯ãåçŽãªpm2 start index.js --name production
ã³ãã³ãã§pm2ã«è¿œå ããã ãã§ãã ããããããã ãã§ã¯ãããŸããã ãã®ããŒã«ã䜿çšãããšãã¢ãã¿ãªã³ã°ïŒ pm2 monit
ïŒããã³ã¢ããªã±ãŒã·ã§ã³ã¯ã©ã¹ã¿ãªã³ã°ãå¯èœã«ãªããŸãã
PHPã§ã®ããã»ã¹ã®ç·šææ¹æ³ãæãåºããŸãããã httpãªã¯ãšã¹ããåŠçããnginxãããããªã¯ãšã¹ããPHPã«æž¡ãå¿ èŠããããšããŸãã ãããçŽæ¥è¡ãããšãã§ããŸããããªã¯ãšã¹ãããšã«æ°ããPHPããã»ã¹ãçæãããå®äºãããšåŒ·å¶çµäºãããŸãã ãŸãã¯ãfastcgiãµãŒããŒã䜿çšã§ããŸãã 誰ãããããäœã§ããããç¥ã£ãŠããã詳现ã«ç«ã¡å ¥ãå¿ èŠã¯ãªããšæããŸããã念ã®ãããPHP-FPMã¯fastcgiãšããŠæããã䜿çšããããã®ã¿ã¹ã¯ã¯ãã€ã§ãæ°ãããªã¯ãšã¹ããåãå ¥ããŠåŠçããæºåãã§ããŠããå€ãã®PHPããã»ã¹ãçæããããšã§ãã ãã®ã¢ãããŒãã®æ¬ ç¹ã¯äœã§ããïŒ
1ã€ç®ã¯ãã¢ããªã±ãŒã·ã§ã³ãæ¶è²»ããã¡ã¢ãªéãããããªãããšã§ãã 次ã«ãããã»ã¹ã®æ倧æ°ãåžžã«å¶éãããããããã©ãã£ãã¯ãæ¥æ¿ã«å¢å ãããšãPHPã¢ããªã±ãŒã·ã§ã³ã¯äœ¿çšå¯èœãªãã¹ãŠã®ã¡ã¢ãªã䜿çšããŠã¯ã©ãã·ã¥ããããããã»ã¹ã®èš±å®¹å¶éã«åãããŠäŒã¿ãå€ãããã»ã¹ã匷å¶çµäºããŸãã ãããé²ãã«ã¯ãPHP-FPMæ§æãã¡ã€ã«ã®ã©ã®ãã©ã¡ãŒã¿ãŒãåçã«èšæ¶ããªãããèšå®ããŸãããã®æç¹ã§å¿ èŠãªæ°ã®ããã»ã¹ãçæãããŸãã ãã ããåºæ¬çãªDDoSæ»æã¯ãã¹ãŠã®RAMã䜿ãæããããµãŒããŒã䜿çšããŸãã ãŸãã¯ãããšãã°ããã°ã¹ã¯ãªããããã¹ãŠã®RAMãæ¶è²»ãããµãŒããŒããã°ããããªãŒãºããŸãïŒéçºããã»ã¹ã«ã¯åäŸããããŸããïŒã
NodeJSã®åºæ¬çãªéãã¯ãã¢ããªã±ãŒã·ã§ã³ã1.5ã®ã¬ãã€ããè¶ ããRAMãæ¶è²»ã§ããªãããšã§ãã ããã»ã¹ã®å¶éã¯ãªããã¡ã¢ãªã®å¶éã®ã¿ããããŸãã ããã«ãããå¯èœãªéã軜éãªããã°ã©ã ãäœæããããšãæšå¥šãããŸãã ããã«ã䜿çšå¯èœãªCPUãªãœãŒã¹ã«å¿ããŠãäœè£ã®ããã¯ã©ã¹ã¿ãŒã®æ°ãèšç®ããã®ã¯éåžžã«ç°¡åã§ãã åã³ã¢ã§1ã€ä»¥äžã®ã¯ã©ã¹ã¿ãŒããã³ã°ã¢ããããããšããå§ãããŸãïŒnginxãšãŸã£ããåãããã«-CPUã³ã¢ããšã«1ã€ä»¥äžã®ã¯ãŒã«ãŒïŒã
ãã®ã¢ãããŒãã®å©ç¹ã¯ãPM2ããã¹ãŠã®ã¯ã©ã¹ã¿ãŒãé çªã«ãªããŒãããããšã§ãã åã®æ®µèœã«æ»ããšãåèµ·åäžã®ããŠã³ã¿ã€ã ã¯1ã2ç§ã§ããã Cluster-Modeã§ã¯ããµãŒããŒãåèµ·åãããšãã¢ããªã±ãŒã·ã§ã³ã§ããªç§ã®ããŠã³ã¿ã€ã ãçºçããŸããã
NodeJSã¯åªããã¹ã€ã¹ãã€ãã§ã
çŸåšãPHPã¯ãµã€ããäœæããããã®èšèªãšããŠæ©èœããPythonã¯ãããã®åããµã€ããã¯ããŒã«ããããã®ããŒã«ãšããŠæ©èœããŸãã NodeJSã¯2 in 1ã§ãçåŽã«ãã©ãŒã¯ãããçåŽã«ã¹ããŒã³ããããŸãã åãã¢ããªã±ãŒã·ã§ã³å ã®åããµãŒããŒäžã§ãé«éã§åŒ·åãªã¢ããªã±ãŒã·ã§ã³ãšWebã¯ããŒã©ãŒãäœæã§ããŸãã é åçã§ããã ãããããããã©ã®ããã«å®çŸã§ããã®ã§ããããïŒ Googleèªäœãå ¬åŒã®Chromium API-Puppeteerãå ¬éããŸããã Headless ChromeïŒãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ã®ãªããã©ãŠã¶-ããããã¬ã¹ãChromeïŒãå®è¡ãããã©ãŠã¶APIã«å¯èœãªéãåºç¯å²ã«ã¢ã¯ã»ã¹ããŠããŒãžãã¯ããŒã«ã§ããŸãã Puppeteerã䜿çšããæãç°¡åã§ã¢ã¯ã»ã¹ããããæ¹æ³ ã
ããšãã°ãVKontakteã°ã«ãŒãã§ã¯ãCISã®éœåžããããŸããŸãªç®çå°ãžã®å²åŒãç¹å¥ãªãã¡ãŒã®å®æçãªæçš¿ããããŸãã èªåã¢ãŒãã§æçš¿çšã®ç»åãçæããŸããããããçŸããããã«ã¯ãçŸããåçãå¿ èŠã§ãã ããŸããŸãªAPIã«çµã³ä»ããŠäœåãã®ãµã€ãã«ã¢ã«ãŠã³ããäœæããããªãã®ã§ãã¹ããã¯ã€ã¡ãŒãžã§ãµã€ãå ãæ©ãåããããŒã¯ãŒãã§èŠã€ãã£ãã€ã¡ãŒãžãã©ã³ãã ã«éžæããGoogle Chromeãã©ãŠã¶ãŒã§äžè¬ãŠãŒã¶ãŒãæš¡å£ããã·ã³ãã«ãªã¢ããªã±ãŒã·ã§ã³ãäœæããŸããã ããã«ã¯PythonãšBeautifulSoupã䜿çšããŠããŸããããä»ã§ã¯ããã¯å¿ èŠãããŸããã ãŸããPuppeteerã®äž»ãªæ©èœãšå©ç¹ã¯ããµã€ãäžã®JavaScriptã³ãŒããç解ããŠå®è¡ããæ¬æ Œçãªãã©ãŠã¶ãèªç±ã«äœ¿çšã§ãããããSPAãµã€ãã§ãç°¡åã«äžæ£è¡çºãã§ããããšã§ãã ãšãŠãç°¡åã§ãïŒ
const browser = await puppeteer.launch({headless: true, args:['--no-sandbox']}) const page = (await browser.pages())[0] await page.goto(`https://pixabay.com/photos/search/${imageKeyword}/?cat=buildings&orientation=horizontal`, { waitUntil: 'networkidle0' })
ãã®ããã3è¡ã®ã³ãŒãã§ãã©ãŠã¶ãŒãèµ·åããã¹ããã¯ã€ã¡ãŒãžãå«ããµã€ãããŒãžãéããŸããã ããã§ãããŒãžäžã®ç»åãå«ãã©ã³ãã ãããã¯ãéžæããããã«ã¯ã©ã¹ãè¿œå ããããšãã§ããŸããããã«å¿ããŠãä»åŸåãæ¹æ³ã§ããŒãžãéããç»åèªäœãçŽæ¥èªã¿èŸŒãã§ããã«èªã¿èŸŒãããšãã§ããŸãã
var imagesLength = await page.evaluate(() => { var photos = document.querySelectorAll('.search_results > .item') if(photos.length > 0) { photos[Math.floor(Math.random() * photos.length)].className += ' --anomaly_selected' } return photos.length })
PhantomJSã§ãããæžãã®ã«ã©ãã ãã®ã³ãŒããå¿ èŠããæãåºããŠãã ããïŒå¶ç¶ãéããŠãPuppeteeréçºããŒã ãšã®ç·å¯ãªã³ã©ãã¬ãŒã·ã§ã³ãéå§ããŸããïŒã ãã®ãããªãã°ãããããŒã«ã¯ãã ãã§ãNodeJSã«åãæ¿ããããšã劚ããããšãã§ããŸããïŒ
NodeJSã«ã¯åºæ¬çãªéåææ§ããããŸã
ããã¯ãç¹ã«ES2017ã§async / awaitãç»å Žããããšã«ãããNodeJSãšJavaScriptã®å€§ããªå©ç¹ãšèããããšãã§ããŸãã PHPãšã¯ç°ãªããåŒã³åºãã¯åæçã«è¡ãããŸãã ç°¡åãªäŸãæããŸãã 以åã¯ãæ€çŽ¢ãšã³ãžã³ã§ããŒãžããµãŒããŒäžã§çæãããŸããããJavaScriptã䜿çšããŠã¯ã©ã€ã¢ã³ãã®ããŒãžã«äœãã衚瀺ããå¿ èŠãããããã®æç¹ã§Yandexã¯ãŸã Webãµã€ãã§JavaScriptã䜿çšã§ããããã®ããã®ã¹ãããã·ã§ããã¡ã«ããºã ïŒã¹ãããã·ã§ããïŒãå®è£ ããå¿ èŠããããŸããPrerenderã䜿çšããŸãã ã¹ãããã·ã§ããã¯ãµãŒããŒã«ä¿åããããªã¯ãšã¹ãã«å¿ããŠããããã«çºè¡ãããŸããã ãžã¬ã³ãã¯ããããã®ç»åã3ã5ç§ä»¥å ã«çæãããããšã§ãããããã¯å®å šã«åãå ¥ãããããæ€çŽ¢çµæã§ã®ãµã€ãã®ã©ã³ãã³ã°ã«åœ±é¿ãäžããå¯èœæ§ããããŸããã ãã®åé¡ã解決ããããã«ãåçŽãªã¢ã«ãŽãªãºã ãèæ¡ãããŸããïŒãããããæ¢ã«æã£ãŠããã¹ãããã·ã§ããã®ããŒãžãèŠæ±ããå Žåãæ¢åã®ã¹ãããã·ã§ãããåã«äžãããã®åŸãããã¯ã°ã©ãŠã³ãã§æ°ããã¹ãããã·ã§ãããäœæããŠçœ®ãæããæäœãå®è¡ããŸããã§ã«å©çšå¯èœã§ãã PHPã§è¡ãããæ¹æ³ïŒ
exec('/usr/bin/php ' . __DIR__ . '/snapshot.php -a ' . $affiliation_type . ' -l ' . urlencode($full_uri) . ' > /dev/null 2>/dev/null &');
絶察ã«ããªãã§ãã ããã
NodeJSã§ã¯ãéåæé¢æ°ãåŒã³åºãããšã§ãããå®çŸã§ããŸãã
async function saveSnapshot() { getSnapshot().then((res) => { db.saveSnapshot().then((status) => { if(status.err) console.error(err) }) }) } /** * await * .. resolve() */ saveSnapshot()
èŠããã«ãåæããã€ãã¹ããããšããã®ã§ã¯ãªããåæã³ãŒãå®è¡ã䜿çšããã¿ã€ãã³ã°ãšéåæã䜿çšããã¿ã€ãã³ã°ã決å®ããŸãã ãšãŠã䟿å©ã§ã ç¹ã«Promise.allïŒïŒã®å¯èœæ§ã«ã€ããŠåŠã¶ãšã
ãã©ã€ãæ€çŽ¢ãšã³ãžã³ãšã³ãžã³èªäœã¯ãããŒã¿ãåéããã³éçŽãã2çªç®ã®ãµãŒããŒã«èŠæ±ãéä¿¡ããããã«çºè¡ã§ããããŒã¿ãèŠæ±ããããã«èšèšãããŠããŸãã æ¹åããŒãžã¯ããªãŒã¬ããã¯ãã©ãã£ãã¯ãåŒãä»ããããã«äœ¿çšãããŸãã
ããšãã°ãã¯ãšãªãFlights Moscow St. Petersburgãã®å Žåãã¢ãã¬ã¹/ãã±ãã/ã¢ã¹ã¯ã¯/ãµã³ã¯ãããã«ãã«ã°/ã®ããŒãžãçºè¡ãããããŒã¿ãå¿ èŠã§ãã
- ä»æã®ãã®æ¹åã®èªç©ºäŒç€Ÿã®äŸ¡æ Œ
- ä»åŸ1幎éã®ãã®æ¹åã®èªç©ºäŒç€Ÿã®äŸ¡æ ŒïŒä»åŸ12ãæéã®åæã®å¹³åäŸ¡æ ŒïŒ
- ãã®æ¹åã®ãã©ã€ãã®ã¹ã±ãžã¥ãŒã«
- 掟é£éœåžããã®äººæ°ã®ããç®çå°ã¯ã¢ã¹ã¯ã¯ããã§ãïŒãªã³ã¯çšïŒ
- å°çéœåžããã®äººæ°ã®ç®çå°ã¯ãµã³ã¯ãããã«ãã«ã¯ããã§ãïŒãªã³ã¯çšïŒ
PHPã§ã¯ãããããã¹ãŠã®ãªã¯ãšã¹ãã¯åæçã«å®è¡ãããŸãã-é çªã«ã ãªã¯ãšã¹ããããã®å¹³åAPIå¿çæéã¯150ã200ããªç§ã§ãã 200ã5åããŠãå¹³åããŠãããŒã¿ã«å¯ŸãããµãŒããŒãžã®èŠæ±ãæºããããã ãã«1ç§ãååŸããŸãã NodeJSã«ã¯ããã¹ãŠã®èŠæ±ã䞊è¡ããŠå®è¡ããçŽ æŽãããçµæã Promise.allããããŸãããçµæã¯é çªã«æžã蟌ãŸããŸãã ããšãã°ãäžèšã®5ã€ã®ãªã¯ãšã¹ããã¹ãŠã®å®è¡ã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
var [montlyPrices, yearlyPrices, flightsSchedule, originPopulars, destPopulars] = await Promise.all([ getMontlyPrices(), getYearlyPrices(), getFlightSchedule(), getOriginPopulars(), getDestPopulars() ])
ãŸãããã¹ãŠã®ããŒã¿ã200ã300ããªç§ã§ååŸããããŒãžã®ããŒã¿çææéã1ã1.5ç§ããçŽ500ããªç§ã«ççž®ããŸãã
ãããã«
PHPããNodeJSã«åãæ¿ããããšã§ãéåæJavaScriptã«ç²Ÿéããpromiseãšasync / awaitãæäœããæ¹æ³ãåŠã¶ããšãã§ããŸããã ãšã³ãžã³ãæžãçŽãããåŸãããŒãžã®ããŒãé床ãæé©åããããšã³ãžã³ãPHPã§ç€ºããçµæãšã¯åçã«ç°ãªããŸããã ãã®èšäºã§ã¯ãNodeJSã§ãã£ãã·ã¥ïŒReââdisïŒããã³pg-promiseïŒPostgreSQLïŒãæäœããMemcachedããã³php-pgsqlãšæ¯èŒããããã«åçŽãªã¢ãžã¥ãŒã«ãã©ã®ããã«äœ¿çšããããã«ã€ããŠè©±ãããšãã§ããŸãããããã®èšäºã¯éåžžã«èšå€§ã§ããããšãå€æããŸããã ãããŠãç§ã®æžããæèœããç¥ã£ãŠãã圌女ã¯ãŸããæ§é ãäžååã§ããããšãå€æããŸããã ãã®èšäºã®ç®çã¯ããŸã PHPã§äœæ¥ããŠããéçºè ã®æ³šç®ãéããããšã§ããã€ãŠPHPã§èšè¿°ãããŠããå®ç°å¢ãããžã§ã¯ãã®äŸã䜿çšããŠãNodeJSã®åã³ãšNodeJSã§ã®WebããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ã®éçºãèªèããŠããŸãããã®ææè ã¯å¥ã®ãã©ãããã©ãŒã ã«è¡ããŸããã
ç§ã¯èªåã®èããäŒãããã®è³æã§ããããè¡šçŸããããã«å€ããå°ãªããæ§é åã§ããããšãé¡ã£ãŠããŸãã å°ãªããšãç§ãè©Šãã:)
ã³ã¡ã³ããæžã-å奜çãŸãã¯æã£ãŠããŸãã 建èšçãªè³ªåã«ã¯çããŸãã