
æåã«ãç§ãã¡ãäžè¬çã«éçºãããã®ããã¹ãŠã®æè¡ãšã¢ãŒããã¯ãã£ãåºã¥ããŠãããã®ãé«è² è·ã®åå ã«ã€ããŠå°ã説æããŸãã ããã«-ãã®è² è·ã«å¯ŸåŠããããã«é©çšãã5ã€ã®åºæ¬çãªæ±ºå®ã
ã³ã¡ã³ãã·ã¹ãã
Cackle Commentsã¯ã2011幎ã«çºè¡šãããæåã®è£œåã§ãã
å¿åããœãŒã·ã£ã«ããµã€ããšã®çµ±åãªã©ã䟿å©ãªæ¿èªã«ããã³ã¡ã³ãã®ããã»ã¹ãç°¡çŽ åããŸãã æ€çŽ¢ãšã³ãžã³ã§ã®ã€ã³ããã¯ã¹äœæããœãŒã·ã£ã«ãããã¯ãŒã¯ïŒVKããã€ã¯ãŒã«ããFacebookãTwitterïŒã®å£ãžã®ã³ã¡ã³ãã®ãããŒããã£ã¹ããæ°ããã³ã¡ã³ããšåçã®è³Œèªã«ãããããå€ãã®ãã©ãã£ãã¯ãéããããšãã§ããŸãã ãµã€ãããã®ç¬ç«æ§ã«ããè² è·ã軜æžããŸãã

ãªã³ã©ã€ã³ã¹ãã¢ã®ãã£ãŒãããã¯ã·ã¹ãã
Cackle Reviewsã¯2013幎ã«ãªãªãŒã¹ãããã¬ãã¥ãŒã·ã¹ãã ã§ãã äž»ã«ãªã³ã©ã€ã³ã¹ãã¢ã§äœ¿çšãããŠããŸãããã©ã®ãµã€ãã§ãåé¡ãªãåäœããŸãã
äž»ãªæ©èœïŒ
- Yandex.Marketããã¬ãã¥ãŒãããŠã³ããŒãããŸãã
- ãããã«äœ¿ããããã€ã¯ãããŒãã³ã°ïŒ æ€çŽ¢çµæã§ã®ã©ã³ãã³ã° ïŒã«ããGoogleã®ã€ã³ããã¯ã¹äœæã
- è³Œå ¥åŸã«ãã£ãŒãããã¯ãæ®ãããã«æåŸ ç¶ãéä¿¡ãããã©ããŒã¢ããã
- 䟿å©ãªå¿åããœãŒã·ã£ã«ãåäžã®æ¿èª;
- ãœãŒã·ã£ã«ãããã¯ãŒã¯ã§ã®ã¬ãã¥ãŒã®ãããŒããã£ã¹ãïŒVKãMy WorldãFacebookãTwitterã
- ã¬ãã¥ãŒã®ãªã¢ã«ã¿ã€ã ã¢ãã¬ãŒã·ã§ã³ã
- ã¬ãã¥ãŒã«é¢ããã³ã¡ã³ãã
- ã¹ãã ä¿è·ã
- CMSãã©ã°ã€ã³ïŒ 1C-Bitrix ã JoomlaïŒK2ãVirtuemartãZooïŒ ã OpenCart ã PrestaShop

ãªã³ã©ã€ã³ã³ã³ãµã«ã¿ã³ã
Cackle Live Chat - 2013幎ã«ãªãªãŒã¹ããããµã€ã蚪åè åãã®ãªã³ã©ã€ã³ãã£ãã ã
æ©èœã®ãã¡ãã¯ã€ãã¯ã€ã³ã¹ããŒã«ãæäœããã«ã¯ãã©ãŠã¶ã«å®è£ ãããŠããããããã¹ã¯ãããã¯ã©ã€ã¢ã³ãã®ã€ã³ã¹ããŒã«ã«æéã浪費ããå¿ èŠã¯ãããŸããã ãªãã¬ãŒã¿ãŒãã¯ã©ã€ã¢ã³ãã«é¢ããæ å ±ïŒååãåçãé»åã¡ãŒã«ããããã¡ã€ã«ãžã®ãªã³ã¯ïŒãåä¿¡ããŠââããéã®ãŠãŒã¶ãŒã®ç€ŸäŒçæ¿èªã

調æ»ãŠã£ãžã§ãã
Cackle Polls-åãã 2013幎ã«ãªãªãŒã¹ãããããœãŒã·ã£ã«ãããã¯ãŒã¯ãIPãŸãã¯Cookieãä»ããŠæ祚ããæ©èœãæã€æ祚ã
調æ»ã¯Googleã«ãã£ãŠèªåçã«ã€ã³ããã¯ã¹åãããè¿œå ã®ãã©ãã£ãã¯ãéããŸãã ç»åãã¢ããããŒãã§ããŸããYouTubeããã³Vimeoã®ãããªèªèããããŸãã

ãã¯ãããžãŒ
Cackleã®ç解ã«ãããããã³ããšã³ãã¯JavaScriptã§ãã ããã¯ãšã³ãã¯ããŒã¿ããã³ããžãã¯ãµãŒããŒã§ãã
ããã³ããšã³ã
ããã³ããšã³ãã¯ãŠã£ãžã§ããã§æ§æãããŠããŸãã ãŠã£ãžã§ããã¯ãä»ã®å ±æJavaScriptã©ã€ãã©ãªã«åºã¥ãå®è¡å¯èœãªJavaScriptã©ã€ãã©ãªã§ãã å ±æã©ã€ãã©ãªã®äŸïŒ
- DOMãæäœããããã®ã©ã€ãã©ãªïŒjQueryã¯éåžžã«é ããããã€ãã®ã¢ãã€ã«ãã©ãããã©ãŒã ã§ã¯åäœããªãã£ãããã圌ãã¯Vanilla JSã§ãœãªã¥ãŒã·ã§ã³ãäœæããŸããã ãã®çµæãäžéšã®æäœã§ã¯ãé床ã600åã«å¢å ããŸããããã®ãœãªã¥ãŒã·ã§ã³ã¯ãAndroidããã³iOSã®ãã¹ãŠã®ããŒãžã§ã³ã§æ©èœããŸãã
- çµ±åèªèšŒã©ã€ãã©ãªïŒå¿åããœãŒã·ã£ã«ãSSOïŒ;
- 察話ãããã³ã«ïŒWebSocketãEventSourceãLong-PollingïŒãã¹ããŒãã«éžæã§ãããªã¢ã«ã¿ã€ã ã¢ãŒããµããŒãã©ã€ãã©ãªã
- ã¯ãã¹ãã¡ã€ã³GET / POSTãªã¯ãšã¹ãã©ã€ãã©ãªã
- ãã®ä»ïŒæ¥ä»ããã©ãŠã¶ããŒã¿ããŒã¹ïŒcookieãlocalstorageïŒãjsonãç»åã®èªã¿èŸŒã¿ããããªèªèïŒYouTubeãVimeoïŒãéç¥ãã¬ã€ãããŒãžããŒã·ã§ã³ãªã©ãæäœããŸãã
ãã¹ãŠã®ãŠã£ãžã§ããã¯iframeãªãã§æ©èœããŸããããã«ãããCSSãWebãµã€ãã®ã¹ã¿ã€ã«ã«åãããŠå€æŽã§ããŸãã
RequireJSã«äŒŒããããåçŽãªæ±çšãŠã£ãžã§ããããŒããŒïŒwidget.jsïŒããããŸãã ããŒãããŒããŒã«ã¯ãdevelãšprodã®2ã€ã®æäœã¢ãŒãããããŸãã æåã¯éçºäžã«äœ¿çšãããã©ã€ãã©ãªãã«ãŒãã§ããŒãããŸãã 2çªç®ã®å®åã§ã¯ãã¢ã»ã³ãã«ããããã³ãã«ïŒãã³ãã«ïŒãããŒãããŸãã prodã¢ãŒãã§ã¯ããŠã£ãžã§ããã¯ã©ã³ãã ã«éžæãããããŸããŸãªãµãŒããŒããããŠã³ããŒãããããã®çµæããã©ã³ã¹ãåããŸãïŒããã«ã€ããŠã¯åŸã§èª¬æããŸãïŒã
ã¯ãã¹ãã©ãŠã¶ãŒããŒãããŒããŒã³ãŒãïŒwidget.jsããŒã1ïŒ
Cackle.Bootstrap = Cackle.Bootstrap || { appendToRoot: function(child) { (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(child); }, // js loadJs: function(src, callback) { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = src; script.async = true; if (callback) { if (typeof script.onload != 'undefined') { script.onload = callback; } else if (typeof script.onreadystatechange != 'undefined') { script.onreadystatechange = function () { if (this.readyState == 'complete' || this.readyState == 'loaded') { callback(); } }; } else { script.onreadystatechange = script.onload = function() { var state = script.readyState; if (!state || /loaded|complete/.test(state)) { callback(); } }; } } this.appendToRoot(script); }, // css loadCss: function(href) { var style = document.createElement('link'); style.rel = 'stylesheet'; style.type = 'text/css'; style.href = href; this.appendToRoot(style); }, // css loadCsss: function(url, css) { for (var i = 0; i < css.length; i++) { Cackle.Bootstrap.loadCss(url + css[i] + Cackle.ver); } }, // js loadJss: function(url, js, i) { var handler = this; if (js.length > i) { Cackle.Bootstrap.loadJs(url + js[i] + Cackle.ver, function() { handler.loadJss(url, js, i + 1); }); } }, // load: function(host, js, css) { var url = host + '/widget/'; this.loadJss(url + 'js/', js, 0); if (css) this.loadCsss(url + 'css/', css); }, /** * , , */ Comment: { isLoaded: false, load: function(host) { this.isLoaded = true; if (Cackle.env == 'prod') { // Cackle.Bootstrap.load(host, ['comment.js'], ['comment.css']); } else { // / Cackle.Bootstrap.load(host, ['fastjs.js', 'json2.js', 'rt.js', 'xpost.js', 'storage.js', 'login.js', 'comment.js'], ['comment.css']); } } }, ... }; // (widget == 'Comment') //host - ( ) if (!Cackle.Bootstrap[widget].isLoaded) { Cackle.Bootstrap[widget].load(host); }
ããã¯ãšã³ã
ããã¯ãNginxãµãŒããŒã®å€åŽã«ã©ãããããApache Tomcatã³ã³ãããŒã®ã¯ã©ã¹ã¿ãŒã§ãã ãã®å Žåã®Nginxã¯ãããã·ãšããŠã ãã§ãªããè² è·ã®ãã·ã³ã¯ããšããŠãæ©èœããŸãã è€æ°ã®ã¹ã¬ãŒããžã®ã¹ããªãŒãã³ã°ã¬ããªã±ãŒã·ã§ã³ãåããPostgreSQLããŒã¿ããŒã¹ã
ãã¹ãŠã®ããã¯ãšã³ãã¯ããã·ã¢ãšãšãŒãããã®è€æ°ã®ããŒã¿ã»ã³ã¿ãŒïŒDPCïŒã«åæ£ãããŠããŸãã ç§ãã¡ã®çµéšã§ã¯ããã¹ãŠã®ãµãŒããŒã1ã€ã®ããŒã¿ã»ã³ã¿ãŒã§ãã¹ãããã®ã¯å±éºãããããã3ã€ã®ç°ãªãããŒã¿ã»ã³ã¿ãŒã«æ¥ç¶ããŠããŸãã
ãªã¢ã«ã¿ã€ã
ãã©ãŠã¶åŽã§ã®ãªã¢ã«ã¿ã€ã æŽæ°ïŒã³ã¡ã³ããããããç·šéãã¢ãã¬ãŒã·ã§ã³ããã©ã€ããŒãã¡ãã»ãŒãžããã£ããïŒã®ãµããŒãã¯ããµããŒããããŠãããã¯ãããžãŒã®ãããããéããŠè¡ãããŸãïŒWebSocketãEventSourceãLong-Pollingã ã€ãŸããæåã«WebSocketããããã©ããã確èªãã次ã«EventSourceãLong-Pollingã確èªããŸãã åæïŒãšã©ãŒïŒã®å Žââåãéä¿¡ã¯setTimeoutã§æ¥ç¶ã¹ããŒã¿ã¹ãç£èŠããæ©èœã«ãã£ãŠèªåçã«åŸ©å ãããŸãã
ãµãŒããŒã§ã¯ãNginxã¯ã©ã¹ã¿ãŒ+ ããã·ã¥ã¹ããªãŒã ã¢ãžã¥ãŒã«ã䜿çšããŸãã ãµãŒããŒã¯3å°ã®ã¿ã§ãã2å°ã¯å ±æã1å°ã¯ãªã³ã©ã€ã³ã³ã³ãµã«ã¿ã³ãçšã§ãã ããã¯ãšã³ãïŒTomcat-sïŒããã®ãªã¢ã«ã¿ã€ã ã¡ãã»ãŒãžã¯ããã¹ãŠã®ãµãŒããŒã«éä¿¡ãããŸãã ãŸãããã©ãŠã¶ã§ãŠã£ãžã§ããããæ¥ç¶ãããšãä»»æã®ãµãŒããŒãïŒã©ã³ãã ã«ïŒéžæãããŸãã ãã®çµæããã©ã³ã¹ã®ãããªãã®ãåŸãããŸãïŒæ®å¿µãªãããããã·ã¥ã¹ããªãŒã ã¯ãã®ãŸãŸäœ¿çšã§ãããã©ã³ã¹ããµããŒãããŠããŸããïŒã
ããã«ã次ã®ãã®ããããŸãã
- ãµãŒããŒã®ç»åã®èªã¿èŸŒã¿ãåŠçãä¿åã
- SMTPãµãŒããŒã
建ç¯

PG-PostgreSQLã
RT-ãªã¢ã«ã¿ã€ã ã
DPCïŒ1,2ã...ãNïŒ-ããŸããŸãªããŒã¿ã»ã³ã¿ãŒã
RMI-ãªã¢ãŒãã¡ãœããåŒã³åºãçšã®Javaãã¯ãããžïŒ ãŠã£ãããã£ã¢ ïŒã
ç解ãæ·±ããããããŠã£ãžã§ããã®ããŒãã·ãŒã±ã³ã¹å³ã¯æ¬¡ã®ãšããã§ãã

è² è·
以äžã¯ããŠã£ãžã§ããããã³APIåŒã³åºãã«é¢ããçµ±èšã®èŠçŽã§ãã
1æ¥ãããã®ãŠããŒã¯ãããæ°ïŒ6,000ã7000äž
ããŒã¯ãªã¯ãšã¹ã/ç§ïŒ2700
åæãªã¢ã«ã¿ã€ã ã»ãã·ã§ã³ã®ããŒã¯ïŒ300,000
ããŒã¯åž¯åå¹ ïŒ780 Mbps
1æ¥ãããã®ãã©ãã£ãã¯ïŒ1.6 TB
Nginxæ¥æ¬¡èŠçŽãã°ïŒ102 GB
ããŒã¿ããŒã¹ãžã®ãªã¯ãšã¹ãã®èªã¿åãïŒ1æ¥ãããïŒïŒ80ã120çŸäž
èšé²ã®ããã®ããŒã¿ããŒã¹ãžã®ãªã¯ãšã¹ãïŒ1æ¥ãããïŒïŒ300,000
ç»é²ãµã€ãã®æ°ïŒ32,558
ç»é²ãŠãŒã¶ãŒæ°ïŒ8 220 681
æçš¿ãããã³ã¡ã³ãïŒ23,840,847
1æ¥ã®å¹³åã³ã¡ã³ãå¢å çïŒ50,000
æ¯æ¥ã®å¹³åãŠãŒã¶ãŒæé·ïŒ15,000
åé¡
é«è² è·ã¯2ã€ã®åé¡ãåŒãèµ·ãããŸãã
ãŸããã»ãšãã©ãã¹ãŠã®ãã¹ãã£ã³ã°äºæ¥è ã¯ãããã©ã«ãã§100 Mbpsã®ãµãŒããŒåž¯åå¹ ãæã£ãŠããŸãã äžèšã®ãã¹ãŠãåæžãããããããããè¿œå ã®åž¯åãè³Œå ¥ããããã«æ±ããããŸãïŒäŸ¡æ Œã¯ãµãŒããŒèªäœã®ã³ã¹ããããæ°åé«ããªããŸãïŒã
2çªç®ã®åé¡ã¯è² è·ãã®ãã®ã§ãã ç©çåŠã欺ãããšã¯ã§ããŸããããµãŒããŒãã©ãã»ã©ã¯ãŒã«ã§ãã£ãŠãããµãŒããŒã«ã¯ç¬èªã®å¶éããããŸãã
»ãœãªã¥ãŒã·ã§ã³1ïŒJavaScriptã§ã®ãã©ã³ã¹èª¿æŽ
è² è·åæ£ã®æšæºçãªæ¹æ³ã¯ããµãŒããŒäžã®å ¥åèŠæ±ã®åæ£ã«ã€ããŠèª¬æããŸãã ããã«ãã2çªç®ã®åé¡ã¯è§£æ±ºãããŸãããæåã®ïŒåž¯åå¹ ïŒã¯è§£æ±ºãããŸãããçºä¿¡ãã©ãã£ãã¯ã¯åããµãŒããŒãééããããã§ãã
2ã€ã®åé¡ãåæã«è§£æ±ºããããã«ãããŒããŒèªäœïŒwidget.jsïŒã§JavaScriptã®ãã©ã³ã¹ããšããããã¯ãšã³ããã©ã³ãã ã«éžæããŸãã ãã®çµæããµãŒããŒãŠã£ãžã§ããã®ã¯ã©ã¹ã¿ãŒãããµãŒããŒã«ãã©ãã£ãã¯ããªãã€ã¬ã¯ããããããã®éã§åž¯åå¹ ãåå²ããè² è·ãåæ£ããŸãã
ãã®æ¹æ³ã®ãã1ã€ã®å€§ããªå©ç¹ã¯ãJavaScriptãã£ãã·ã¥ã§ãã ããŒãžãæŽæ°ããããšããã¹ãŠã®ã©ã€ãã©ãªïŒwidget.jsããŒããŒãå«ãïŒããã©ãŠã¶ãŒãã£ãã·ã¥ããåä¿¡ããããµãŒããŒã¯æ°ãããªã¯ãšã¹ããéãã«åŠçãç¶ããŸãã
ããŒããŒã³ãŒãã®ç¶ç¶ïŒwidget.jsããŒã2ïŒïŒ
var Cackle = Cackle || {}; Cackle.protocol = ('https:' == window.location.protocol) ? 'https:' : 'http:'; Cackle.host = Cackle.host || 'cackle.me'; Cackle.origin = Cackle.protocol + '//' + Cackle.host; // (a.cackle.me, b.cackle.me, c.cackle.me): Cackle.cluster = ['a.' + Cackle.host, 'b.' + Cackle.host, 'c.' + Cackle.host]; // , . widget.js 1 Cackle.getRandInt = function(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } Cackle.getRandHost = function() { return Cackle.cluster[Cackle.getRandInt(0, Cackle.cluster.length - 1)]; }; Cackle.initHosts = function() { //getRandHost var host = Cackle.getRandHost(); for (var i = 0; i < cackle_widget.length; i++) { cackle_widget[i].host = Cackle.protocol + '//' + host; } }; //cackle_widget - , // ( ). //: cackle_widget.push({widget: 'Comment', id: 1}); Cackle.main = function() { Cackle.initHosts(); for (var i = 0; i < cackle_widget.length; i++) { var widget = cackle_widget[i].widget; if (!Cackle.Bootstrap[widget].isLoaded) { Cackle.Bootstrap[widget].load(cackle_widget[i].host); } } }; Cackle.main();
ããã®CDNã¯ã©ãã§ããïŒ
ããã¯ãããïŒ å¯äžã®åé¡ã¯ãCDNã䜿çšããã«ã¯ãçŸåšã®å£²äžé«ãç¶æããªãããäŸ¡æ Œãå°ãªããšã3åäžããå¿ èŠãããããšã§ãã
»ãœãªã¥ãŒã·ã§ã³2ïŒNginx Microcache
ãã€ã¯ããã£ãã·ã¥ã¯ãéåžžã«çã寿åœïŒããšãã°3ç§ïŒã®ãã£ãã·ã¥ã§ãã æ¯ç§äœåãã®åäžã®GETèŠæ±ãéä¿¡ãããããŒã¯è² è·æã«éåžžã«äŸ¿å©ã§ãã ç§ãã¡ã«ãšã£ãŠãããã¯JSON圢åŒã®ãŠã£ãžã§ããããŒã¿ã§ãã ã¡ã€ã³ããã¯ãšã³ãïŒTomcatïŒãä¿è·ããããã«Nginxãªã©ã®ãããã·ãµãŒããŒã§ãã€ã¯ããã£ãã·ã³ã°ãè¡ãããšã¯çã«ããªã£ãŠããŸãã
ãã€ã¯ããã£ãã·ã¥ã䜿çšããNginxæ§æã®äžéšïŒ
... location /bootstrap { try_files $uri @proxy; } ... location @proxy { # (Tomcat) proxy_pass http://localhost:8888; proxy_redirect off; # Nginx , # - , proxy_ignore_headers X-Accel-Expires Expires Cache-Control; set $no_cache ""; # GET|HEAD if ($request_method !~ ^(GET|HEAD)$) { set $no_cache "1"; } if ($no_cache = "1") { add_header Set-Cookie "_mcnc=1; Max-Age=2; Path=/"; add_header X-Microcachable "0"; } if ($http_cookie ~* "_mcnc") { set $no_cache "1"; } proxy_cache microcache; proxy_no_cache $no_cache; proxy_cache_bypass $no_cache; proxy_cache_key $scheme$host$request_method$request_uri; # 3 proxy_cache_valid 200 301 302 3s; proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504 http_403 http_404 updating; default_type application/json; } ...
ãã®èšå®ã®ç解ã«åé¡ãããå Žåã¯ã ngx_http_proxy_moduleãèªãå¿ èŠããããŸãã
»ãœãªã¥ãŒã·ã§ã³3ïŒTomcatãJavaãã£ãã·ã¥ã®èª¿æŽ
Tomcat
ç¹ã«Tomcat Tomcatã§ã¯åäœããŸããã å®åçµéšããïŒ
- ã³ãã¯ã¿ïŒHttp11ProtocolãNioã4æïŒã®éžæã«ã ãŸãããªãã§ãã ããã è² è·ãé«ãå Žåãããã¯åœ¹å²ãæãããŸããã
- connectionTimeoutãã§ããã ãå°ãããã§ããã°5ç§ä»¥å ã«ããŠãã ããã
- maxThreadsã倧ããããããªãã§ãã ãããå©ãã«ã¯ãªãããç¶æ³ã«ãã£ãŠã¯å€§ããªå®³ãåãŒãã ãã§ãã ããŒãããããããžã§ã¯ãã®æšæºã¯300ã350ã§ãã ããã§ååã§ãªãå Žåã¯ãæ°ããTomcatãµãŒããŒãè¿œå ããŸãã
- ãã ããacceptCountã¯æ°åïŒ2000ã4000ïŒã«ããããšãã§ããŸãã å€ãäœããšãæ¥ç¶ãåæããïŒæ¥ç¶ãæåŠãããŸãïŒããã¥ãŒã«è¿œå ãããŸãã åæã«ãOSã§åããŸãã¯ãã以äžã®ããã¯ãã°ãèšå®ããããšãå¿ããªãã§ãã ããã
Javaãã£ãã·ã¥
äžè¬ã«ãè² è·ã®é«ããããžã§ã¯ãã®ããŒã¿ããŒã¹ã¯åŒ±ç¹ã§ãããšåãå ¥ããããŠããŸãã æ¬åœã«ããã§ãã ããšãã°ããµãŒããŒã¯èŠæ±ãåãå ¥ãããµãŒãã¹ã¬ãã«ã«éä¿¡ããŸãããµãŒãã¹ã¬ãã«ã§ã¯ããµãŒãã¹ãããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ããŠçµæãè¿ããŸãã ãã®å Žåã®ãªã³ã¯ããµãŒãã¹-ããŒã¿ããŒã¹ïŒãªã¬ãŒã·ã§ãã«ïŒãã¯ãã¹ãŠã®äžã§æãé ãããããµãŒãã¹ããã£ãã·ã¥ã§ã©ããããã®ãäžè¬çã§ãã ãããã£ãŠãããŒã¿ããŒã¹ããã®çµæã¯ãµãŒãã¹ãã£ãã·ã¥ã«å ¥ãããã次ã«ãã£ãã·ã¥ããååŸãããŸãã
ãã£ãã·ã³ã°ãµãŒãã¹ã«ã€ããŠã¯ãç¬èªã®ãã£ãã·ã¥ãéçºããŸãããããã¯ãæšæºã®ãã£ãã·ã¥ïŒEhcacheãªã©ïŒã®åäœãé ããç¹å®ã®ã¿ã¹ã¯ãå¿ ãããããŸã解決ã§ããªãããã§ãã ç¹å®ã®ã¿ã¹ã¯ã®ãã¡ãåäžã®å€ã«å¯ŸããŠè€æ°ã®ããŒããµããŒããããã£ãã·ã³ã°ã§ãã org.apache.commons.collections.map.MultiKeyMapã䜿çšããŸãã
ããã¯ã©ã®ã¿ã¹ã¯ã«å¿ èŠã§ãã ããšãã°ããŠãŒã¶ãŒã¯ã³ã¡ã³ãä»ãã®ããŒãžã«ã¢ã¯ã»ã¹ããŸãã ããããã®ã³ã¡ã³ããèšã£ãŠã¿ãŸãããã300åã ãããã¯ãããã3ããŒãžïŒããŒãžããŒã·ã§ã³ïŒã«åå²ããããããã100ããŒãžã§ãã æåã®åŒã³åºãã§ãæåã®ããŒãžããã£ãã·ã¥ããïŒ100ã³ã¡ã³ãïŒããŠãŒã¶ãŒãäžã«ã¹ã¯ããŒã«ãããšã2ããŒãžãš3ããŒãžãé çªã«ãã£ãã·ã¥ãããŸãã ãŠãŒã¶ãŒããã®ããŒãžã«ã³ã¡ã³ããå ¬éãããã3ã€ã®ãã£ãã·ã¥ããã¹ãŠãªã»ããããå¿ èŠããããŸãã MultiKeyMapã䜿çšãããšã次ã®ããã«ãªããŸãã
MultiKeyMap cache = MultiKeyMap.decorate(new LRUMap(capacity)); cache.put(chanId, "page1", commentSerivce.list(chanId, 1)); //chanId - id cache.put(chanId, "page2", commentSerivce.list(chanId, 2)); //commentSerivce.list - (chanId) (2) cache.put(chanId, "page3", commentSerivce.list(chanId, 3)); cache.removeAll(chanId); // 3
以äžã¯ãé«è² è·ã§æ£åžžã«åäœãããã£ãã·ã¥ã³ã¢ã³ãŒãã§ãã
ãã£ãã·ã¥ã³ã¢ïŒã¹ã¬ããã»ãŒããé
延ããã£ãã·ã¥çµæã®å¯äžã®å®è¡ãOOMãåé¿ããããã®ãœãããªã³ã¯
public class CackleCache { private final MultiKeyMap CACHE = MultiKeyMap.decorate(new LRUMap(capacity)); public static class SoftValue<K, V> extends SoftReference<V> { final K key; final long expired; public SoftValue(V ref, ReferenceQueue<V> q, K key, long timelife) { super(ref, q); this.key = key; this.expired = System.currentTimeMillis() + timelife; } } public synchronized Future<Object> get(final MultiKey key, final long timelife, final MethodInvocation invocation) { Future<Object> ret; @SuppressWarnings("unchecked") SoftValue<MultiKey, Future<Object>> sr = (SoftValue<MultiKey, Future<Object>>) CACHE.get(key); if (sr != null) { ret = sr.get(); if (ret != null) { if (sr.expired > System.currentTimeMillis()) { return ret; } else { sr.clear(); } } } ret = executor.submit(new Callable<Object>() { @Override public Object call() throws Exception { try { return invocation.proceed(); } catch (Throwable t) { throw new Exception(t); } } }); SoftValue<MultiKey, Future<Object>> value = new SoftValue<MultiKey, Future<Object>>(ret, referenceQueue, key, timelife); CACHE.put(key, value); return ret; } public synchronized void evict(Object key) { try { CACHE.removeAll(key); } catch (Throwable t) {} } }
»ãœãªã¥ãŒã·ã§ã³4ïŒããŸããŸãªããŒã¿ã»ã³ã¿ãŒãžã®ã¬ããªã±ãŒã·ã§ã³ãã¹ããªãŒãã³ã°ããPostgreSQL
ç§ãã¡ã®æèŠã§ã¯ãPostgreSQLã¯è² è·ã®é«ããããžã§ã¯ãã«æé©ãªãœãªã¥ãŒã·ã§ã³ã§ãã ä»ã§ã¯NoSQLã䜿çšããã®ãæµè¡ããŠããŸãããã»ãšãã©ã®å Žåãé©åãªã¢ãããŒããšé©åãªã¢ãŒããã¯ãã£ãåããŠãããããPostgreSQLã®æ¹ãåªããŠããŸãã
PostgreSQLã§ã¯ãã¹ããªãŒãã³ã°ã¬ããªã±ãŒã·ã§ã³ã¯éåžžã«ããŸãæ©èœããåããµããããäžã§ããç°ãªããããã¯ãŒã¯äžã§ããç°ãªãããŒã¿ã»ã³ã¿ãŒã§ãåé¡ã«ãªããŸããã ããšãã°ãããã€ãã®åœã«ããŒã¿ããŒã¹ãµãŒããŒããããæ·±å»ãªåé¡ã¯ãããŸããã§ããã å¯äžã®æ³šæç¹ã¯ããªãªãŒã¹ã®å€§èŠæš¡ãªããŒã¹å€æŽïŒALTER TABLEïŒã§ãã äžåºŠã«ãã¹ãŠã®UPDATEãå®è¡ããªãããã«ãæççã«äœæããå¿ èŠããããŸãã
è€è£œãèšå®ããããã®å€ãã®ãªãœãŒã¹ããããŸãããããã¯ããã¯ããããããã¯ãªã®ã§ãè¿œå ããç¹å¥ãªãã®ã¯ãããŸããïŒ
- ãã§ã€ã«ãªãŒããŒïŒãã¹ã¿ãŒã®ã¯ã©ãã·ã¥ïŒã®å Žåã¯å¿ ãèšç»ïŒæ§æïŒãäœæããå®éã«ãã¹ãããŠãã ããã
- WALã®åçãç解ããŠãã ãããã¹ã¬ãŒããšãã¹ã¿ãŒãåæããŠããªãå Žåãã¢ãŒã«ã€ããå¿ èŠãªçç±ãšã¢ãŒã«ã€ãã®å Žæãç¥ãå¿ èŠããããŸãã
- ãŠã£ã¶ãŒãã®HDDäžã®å Žæã远跡ããŸããçªç¶æ¶ãããšãPostgreSQLãã¯ã©ãã·ã¥ããå¯èœæ§ããããã¬ããªã±ãŒã·ã§ã³ã§ã¯å€§ããªãã©ãã«ãçºçããŸãã
»ãœãªã¥ãŒã·ã§ã³5ïŒOSã®ãã¥ãŒãã³ã°
OSã®ã«ãŒãã«ãã©ã¡ãŒã¿ãŒã調æŽããããšãå¿ããªãã§ãã ãããããããªããšãNginxãŸãã¯Tomcatã®äžéšã®èšå®ãåã«æ©èœããŸããã
ããšãã°ãã©ãã«ã§ãDebianããããŸãã OSã®ã«ãŒãã«èšå®ïŒ/etc/sysctl.confïŒã§ã¯ãç¹ã«æ¬¡ã®ããšã«æ³šæããå¿ èŠããããŸãã
kernel.shmmax = 8000234752 // PostgreSQL, shared_buffers (6 - 8GB) fs.file-max = 99999999 // Nginx, "Too many open files" net.ipv4.tcp_max_syn_backlog=524288 // net.ipv4.tcp_max_orphans=262144 // TCP net.core.somaxconn=65535 // net.ipv4.tcp_mem=1572864 1835008 2097152 // TCP net.ipv4.tcp_rmem=4096 16384 16777216 // TCP net.ipv4.tcp_wmem=4096 32768 16777216 // , TCP
ãŸã 解決ãããŠããªãåé¡
ãããã1ã€ã®åé¡ã¯ããŒã¿ããŒã¹ã®ãµã€ãºã§ãã ãã¡ãããã·ã£ãŒãã£ã³ã°ã¯ãããŸãããããã©ãŒãã³ã¹ãäœäžãããªãPostgreSQLã®æšæºçãªãœãªã¥ãŒã·ã§ã³ã¯ãŸã èŠã€ãããŸããã 誰ããå®éã®çµéšãå ±æã§ããå Žå-ããããïŒ
ãæž èŽããããšãããããŸããã ç§ãã¡ã®ã·ã¹ãã ã«é¢ãã質åãææ¡ã¯å€§æè¿ã§ãïŒ