ã¿ãªãããããã«ã¡ã¯ãéçºè ã®ã¢ã³ãã¬ã€ã»ã¯ãªãšãã§ãã æè¿ãç§ã¯ãã®ãããªä»äºã«çŽé¢ããŸãã-ãŠãŒã¶ãŒãèªåã®è¡åã«å¯ŸããŠè¿ éãªããŒãã¹ãåãåãããšãã§ããã€ã³ã¿ã©ã¯ãã£ããªãµãŒãã¹ãäœæããããšã åé¡ã¯ããããžã§ã¯ãã®è² è·èŠä»¶ãããªãé«ããæ¡ä»¶ãéåžžã«çããšããäºå®ã«ãã£ãŠè€éã«ãªããŸããã
ãã®èšäºã§ã¯ããããžã§ã¯ãã®å°é£ãªèŠä»¶ãéçºããã»ã¹äžã«çºçããåé¡ã«å¯ŸããŠWebSocketãµãŒããŒãå®è£ ããããã®ãœãªã¥ãŒã·ã§ã³ãã©ã®ããã«éžæãããã説æããŸãããŸããLinuxã«ãŒãã«æ§æãäžèšã®ç®æšã®éæã«ã©ã®ããã«åœ¹ç«ã€ãã«ã€ããŠãå°ã説æããŸãã
ãã®èšäºã¯ãéçºããã¹ããããã³ç£èŠããŒã«ãžã®äŸ¿å©ãªãªã³ã¯ã§ç· ããããããŠããŸãã
ã¿ã¹ã¯ãšèŠä»¶
ãããžã§ã¯ãæ©èœã®èŠä»¶ïŒ
- ãªãœãŒã¹äžã§ã®ãŠãŒã¶ãŒã®ååšã远跡ããèŠèŽæéã远跡ã§ããããã«ããŸãã
- ãŠãŒã¶ãŒãããŒãã¹ãåãåãæéã¯å³å¯ã«å¶éãããŠãããããã¯ã©ã€ã¢ã³ããšãµãŒããŒéã§è¿ éãªã¡ãã»ãŒãžã³ã°ãæäŸããŸãã
- ãŠãŒã¶ãŒãè€æ°ã®ã¿ããŸãã¯ããã€ã¹ãåæã«äœ¿çšããŠãµãŒãã¹ãæäœããå Žåããã¹ãŠã®ã¢ã¯ã·ã§ã³ãåæããåçãªã€ã³ã¿ã©ã¯ãã£ãã€ã³ã¿ãŒãã§ã€ã¹ãäœæããŸãã
è² è·èŠä»¶ïŒ
- ã¢ããªã±ãŒã·ã§ã³ã¯ããªã³ã©ã€ã³ã§å°ãªããšã15äžäººã®ãŠãŒã¶ãŒã«èããå¿ èŠããããŸãã
å®è£ æéã¯1ãæã§ãã
æè¡ã®éžæ
ãããžã§ã¯ãã®ã¿ã¹ã¯ãšèŠä»¶ãæ¯èŒãããšãWebSocketãã¯ãããžãŒãéçºã«äœ¿çšããã®ãæãé©åã§ãããšããçµè«ã«éããŸããã ãµãŒããŒãžã®æ°žç¶çãªæ¥ç¶ãæäŸããajaxããã³ãã³ã°ããŒãªã³ã°ãã¯ãããžãŒã䜿çšããå®è£ ã«ååšãããã¹ãŠã®ã¡ãã»ãŒãžã®æ°ããæ¥ç¶ã®ãªãŒããŒããããæé€ããŸãã ããã«ãããé©åãªãªãœãŒã¹æ¶è²»ãšçµã¿åãããŠå¿ èŠãªé«éã¡ãã»ãŒãžã³ã°ãååŸã§ããŸããããã¯ãé«è² è·ã®å Žåã«éåžžã«éèŠã§ãã
ãŸããã€ã³ã¹ããŒã«ãšåæã2ã€ã®æ確ãªã€ãã³ãã§ãããšããäºå®ã«ããããŠãŒã¶ãŒããµã€ãã«ããæéãæ£ç¢ºã«è¿œè·¡ããããšãå¯èœã«ãªããŸãã
ãããžã§ã¯ãã®ã¹ã±ãžã¥ãŒã«ãããªãéãããŠãããããWebSocketãã¬ãŒã ã¯ãŒã¯ã䜿çšããŠéçºãè¡ãããšã«ããŸããã PHP ReactPHPãPHP RatchetãNode.JS websockets / wsãPHP SwooleãPHP WorkermanãGo GorillaãElixir Phoenixã®ããã«æããŸããã Intel Core i5ããã»ããµãš4 GBã®RAMãæèŒããã©ãããããã®è² è·ã«é¢ããŠããããã®æ©èœããã¹ãããŸããïŒãã®ãããªãªãœãŒã¹ã¯ç 究ã«ã¯ååã§ããïŒã
PHP Workermanã¯ãéåæã®ã€ãã³ãæåãã¬ãŒã ã¯ãŒã¯ã§ãã ãã®æ©èœã¯ãwebsocketãµãŒããŒã®æãåçŽãªå®è£ ãšãéåæã€ãã³ãéç¥ã®åŠçã«å¿ èŠãªlibeventã©ã€ãã©ãªãæäœããæ©èœã«ãã£ãŠäœ¿ãæããããŸãã ã³ãŒãã¯PHP 5.3ã§ãããæšæºã«æºæ ããŠããŸããã ç§ã«ãšã£ãŠã®äž»ãªæ¬ ç¹ã¯ããã¬ãŒã ã¯ãŒã¯ãé«è² è·ã®ãããžã§ã¯ãã®å®è£ ãèš±å¯ããªãããšã§ããã ãã¹ããã³ãã§ã¯ãéçºãããHello Worldã¬ãã«ã®ã¢ããªã±ãŒã·ã§ã³ã¯äœåãã®æ¥ç¶ãä¿æã§ããŸããã§ããã
ReactPHPãšRatchetã®æ©èœã¯äžè¬ã«Workermanã«å¹æµããŸãã Ratchetã¯å éšçã«ReactPHPã«äŸåããŠãããlibeventãä»ããŠåäœããé«è² è·ã®ãœãªã¥ãŒã·ã§ã³ãäœæã§ããŸããã
Swooleã¯Cã§æžãããèå³æ·±ããã¬ãŒã ã¯ãŒã¯ã§ãããPHPã®æ¡åŒµæ©èœãšããŠãã©ã°ã€ã³ãã䞊åããã°ã©ãã³ã°çšã®ããŒã«ãåããŠããŸãã æ®å¿µãªããããã¬ãŒã ã¯ãŒã¯ã¯ååã«å®å®ããŠããªãããšãããããŸããããã¹ããã³ãã§ã¯ã1ç§ããã«æ¥ç¶ãåæãããŸããã
次ã«ã Node.JS WSã確èªããŸããã ãã®ãã¬ãŒã ã¯ãŒã¯ã¯è¯å¥œãªçµæã瀺ããŸãã-è¿œå ã®èšå®ãªãã§ãã¹ããã³ãã§çŽ5,000ã®æ¥ç¶ã ããããç§ã®ãããžã§ã¯ãã¯è² è·ãèããé«ãããšãæ瀺ããŠãããããGo Gorilla + Echo FrameworkãšElixir Phoenix frameworksãéžæããŸããã ãããã®ãªãã·ã§ã³ã¯ãã§ã«è©³çŽ°ã«ãã¹ããããŠããŸãã
è² è·è©Šéš
ãã¹ãã«ã¯ãå€§ç ²ãã¬ããªã³ã°ãflood.ioãµãŒãã¹ãªã©ã®ããŒã«ã䜿çšãããŸããã
ãã¹ãã®ç®çã¯ãããã»ããµãªãœãŒã¹ãšã¡ã¢ãªã®æ¶è²»éã調æ»ããããšã§ããã ãã·ã³ã®ç¹æ§ã¯åãã§ãã-Intel iCore 5ããã»ããµãŒãš4 GBã®RAMã GoãšPhoenixã§ã®æãåçŽãªãã£ããã®äŸã§ãã¹ããè¡ââãããŸããã
ããã¯ã25ã3äžäººã®ãŠãŒã¶ãŒã®è² è·ã®äžã§ãæå®ããã容éã®ãã·ã³ã§æ£åžžã«æ©èœããç°¡åãªãã£ããã¢ããªã±ãŒã·ã§ã³ã§ãã
config: target: "ws://127.0.0.1:8080/ws" phases - duration:6 arrivalCount: 10000 ws: rejectUnauthorized: false scenarios: - engine: âwsâ flow - send âhelloâ - think 2 - send âworldâ
Class LoadSimulation extends Simulation { val users = Integer.getInteger (âthreadsâ, 30000) val rampup = java.lang.Long.getLong (ârampupâ, 30L) val duration = java.lang.Long.getLong (âdurationâ, 1200L) val httpConf = http .wsBaseURL(âws://8.8.8.8/socketâ) val scn = scenario(âWebSocketâ) .exes(ws(âConnect WSâ).open(â/websocket?vsn=2.0.0â)) .exes( ws(âAuthâ) sendText(âââ[â1â, â1â, âmy:channelâ, âphp_joinâ, {}]âââ) ) .forever() { exes( ws(âHeartbeatâ).sendText(âââ[null, â2â, âphoenixâ, âheartbeatâ, {}]âââ) ) .pause(30) } .exes(ws(âClose WSâ).close) setUp(scn.inject(rampUsers(users) over (rampup seconds))) .maxDuration(duration) .protocols(httpConf)
ãã¹ããéå§ãããšããã瀺ããã容éã®ãã·ã³ã§ã25ã3äžãŠãŒã¶ãŒã®è² è·ã§ãã¹ãŠãéãã«åäœããããšã瀺ãããŸããã
CPUæ¶è²»ïŒ
ãã§ããã¯ã¹

ãŽãªã©

äž¡æ¹ã®ãã¬ãŒã ã¯ãŒã¯ã®å Žåã20000æ¥ç¶ã®è² è·ã§ã®RAMæ¶è²»éã¯2 GBã«éããŸããã
ãã§ããã¯ã¹

ãŽãªã©

åæã«ãGoã¯ããã©ãŒãã³ã¹ã«ãããŠãElixirãããåªããŠããŸãããPhoenix Frameworkã¯ããã«å€ãã®æ©èœãæäŸããŸãã ãããã¯ãŒã¯ãªãœãŒã¹ã®æ¶è²»ã瀺ãäžã®ã°ã©ãã§ã¯ããã§ããã¯ã¹ãã¹ãã§1.5åã®ã¡ãã»ãŒãžãéä¿¡ãããŠããããšãããããŸãã ããã¯ããã®ãã¬ãŒã ã¯ãŒã¯ã«ã¯ãå ã®ãç®±å ¥ããããŒãžã§ã³ã®ããŒãããŒãã¡ã«ããºã ïŒå®æçãªåæä¿¡å·ïŒãæ¢ã«ãããGorillaã§èªåã§å®è£ ããå¿ èŠãããããã§ãã éãããæéæ ã§ãè¿œå ã®ä»äºã¯ãã§ããã¯ã¹ãæ¯æãã匷åãªè°è«ã§ããã
ãã§ããã¯ã¹

ãŽãªã©

Phoenix Frameworkã«ã€ããŠ
Phoenixã¯ãRailsã«éåžžã«ãã䌌ãã¯ã©ã·ãã¯MVCãã¬ãŒã ã¯ãŒã¯ã§ãããã®éçºè ããã³Elixirèšèªã®äœæè ã®1人ã¯ãRuby on Railsã®äž»èŠãªäœæè ã®1人ã§ããJose Valimã§ãã æ§æã«ãããã€ãã®é¡äŒŒç¹ãèŠãããŸãã
ãã§ããã¯ã¹ ïŒ
defmodule Benchmarker.Router do use Phoenix.Router alias Benchmarker.Controllers get "/:title", Controllers.Pages, :index, as: :page end
ã¬ãŒã«ïŒ
Benchmarker::Application.routes.draw do root to: "pages#index" get "/:title", to: "pages#index", as: :page end
Mix-Elixirãããžã§ã¯ãã®èªååãŠãŒãã£ãªãã£
PhoenixãšElixirã䜿çšããå Žåãããã»ã¹ã®å€§éšåã¯MixãŠãŒãã£ãªãã£ãä»ããŠè¡ãããŸãã ããã¯ãã¢ããªã±ãŒã·ã§ã³ã®äœæãã³ã³ãã€ã«ããã¹ããäŸåé¢ä¿ããã³ãã®ä»ã®ããã»ã¹ã®ç®¡çã«ãããããŸããŸãªã¿ã¹ã¯ã解決ãããã«ãããŒã«ã§ãã
ããã¯ã¹ã¯ãElixirãããžã§ã¯ãã®éèŠãªéšåã§ãã ãã®ãŠãŒãã£ãªãã£ã¯ãä»ã®èšèªã®ã¢ããã°ããã決ããŠå£ããã決ããŠåªããŠããããã§ã¯ãããŸããããå®ç§ã«æ©èœããŸãã ãŸããElixir-codeãErlangä»®æ³ãã·ã³ã§å®è¡ããããšããäºå®ã«ãããErlangã®äžçããã©ã€ãã©ãªãè¿œå ããããšãå¯èœã«ãªããŸãã ããã«ãErlang VMã䜿çšãããšã䟿å©ã§å®å šãªäžŠè¡æ§ãšé«ãèé害æ§ãåŸãããŸãã
åé¡ãšè§£æ±ºç
ãã¹ãŠã®å©ç¹ãåããPhoenixã«ã¯æ¬ ç¹ããããŸãã ãã®1ã€ã¯ãé«è² è·ç¶æ ã§ãµã€ãäžã®ã¢ã¯ãã£ããŠãŒã¶ãŒã远跡ãããªã©ã®åé¡ã解決ããã®ãé£ããããšã§ãã
å®éããŠãŒã¶ãŒã¯ããŸããŸãªã¢ããªã±ãŒã·ã§ã³ããŒãã«æ¥ç¶ã§ããåããŒãã¯èªèº«ã®ã¯ã©ã€ã¢ã³ãã«ã€ããŠã®ã¿ç¥ãããšãã§ããŸãã ã¢ã¯ãã£ããªãŠãŒã¶ãŒã®ãªã¹ãã衚瀺ããã«ã¯ããã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³ããŒããããŒãªã³ã°ããå¿ èŠããããŸãã
ãã§ããã¯ã¹ã§ãããã®åé¡ã解決ããããã«ãéçºè ãæåéã3è¡ã®ã³ãŒãã§ã¢ã¯ãã£ããŠãŒã¶ãŒã远跡ã§ãããã¬ãŒã³ã¹ã¢ãžã¥ãŒã«ããããŸãã ã¯ã©ã¹ã¿å ã§ããŒãããŒãã¡ã«ããºã ãšç«¶åã®ãªãã¬ããªã±ãŒã·ã§ã³ã䜿çšããPubSubãµãŒããŒã䜿çšããŠããŒãéã§ã¡ãã»ãŒãžã亀æããŸãã

è¯ãããã«èãããŸãããå®éã«ã¯æ¬¡ã®ããã«ãªããŸãã æ°åäžã®æ¥ç¶ãŠãŒã¶ãŒãšåæãŠãŒã¶ãŒãããŒãéã®åæã®ããã«æ°çŸäžã®ã¡ãã»ãŒãžãçæããŸãããã®ãããããã»ããµãªãœãŒã¹ã®æ¶è²»ã蚱容ç¯å²ãè¶ ããŠãããRedis PubSubãæ¥ç¶ããŠãç¶æ³ã¯ä¿åãããŸããã ãŠãŒã¶ãŒã®ãªã¹ãã¯åããŒãã§è€è£œãããæ°ããæ¥ç¶ããšã®å·®åã®èšç®ã¯ãŸããŸãé«äŸ¡ã«ãªããŸã-ããã¯èšç®ãæ¢åã®åããŒãã§å®è¡ãããããšãèæ ®ããŠããŸãã

ãã®ãããªç¶æ³ã§ã¯ã10äžäººã®é¡§å®¢ã®ããŒã¯ã§ããéæã§ããªããªããŸãã ãã®ã¿ã¹ã¯ã®ä»ã®æ¢æã®ãœãªã¥ãŒã·ã§ã³ãèŠã€ããããšãã§ããªãã£ãããã次ã®ããšãè¡ãããšã«ããŸããããŠãŒã¶ãŒã®ãªã³ã©ã€ã³ãã¬ãŒã³ã¹ãç£èŠãã責任ãããŒã¿ããŒã¹ã«å²ãåœãŠãŸãã
äžèŠãããšãããã¯è€éãªããšã¯äœããããŸãããããŒã¿ããŒã¹ã«æåŸã®ã¢ã¯ãã£ããã£ãã£ãŒã«ããä¿åããå®æçã«æŽæ°ããã ãã§ãã æ®å¿µãªãããé«è² è·ã®ãããžã§ã¯ãã®å Žåãããã¯ãªãã·ã§ã³ã§ã¯ãããŸããããŠãŒã¶ãŒæ°ãæ°åäžäººã«éãããšãã·ã¹ãã ã¯ãŠãŒã¶ãŒããã®æ°çŸäžã®ããŒãããŒãã«å¯Ÿå¿ã§ããªããªããŸãã
åãã«è¶³ããªããããçç£çãªãœãªã¥ãŒã·ã§ã³ãéžã³ãŸããã ãŠãŒã¶ãŒãæ¥ç¶ãããšãäžæã®è¡ãããŒãã«ã«äœæãããŸãããã®è¡ã«ã¯ããŠãŒã¶ãŒã®èå¥åããšã³ããªã®æ£ç¢ºãªæå»ãæ¥ç¶å ã®ããŒãã®ãªã¹ããæ ŒçŽãããŸãã ããŒãã®ãªã¹ãã¯JSONBãã£ãŒã«ãã«æ ŒçŽãããè¡ã競åããå Žåã¯æŽæ°ããã ãã§ååã§ãã
create table watching_times ( id serial not null constraint watching_times_pkey primary key, user_id integer, join_at timestamp, terminate_at timestamp, nodes jsonb ); create unique index watching_times_not_null_uni_idx on watching_times (user_id, terminate_at) where (terminate_at IS NOT NULL); create unique index watching_times_null_uni_idx on watching_times (user_id) where (terminate_at IS NULL);
ãã®ãªã¯ãšã¹ãã¯ããŠãŒã¶ãŒã®ãã°ã€ã³ãæ åœããŸãã
INSERT INTO watching_times ( user_id, join_at, terminate_at, nodes ) VALUES (1, NOW(), NULL, '{nl@192.168.1.101â: 1}') ON CONFLICT (user_id) WHERE terminate_at IS NULL DO UPDATE SET nodes = watching_times.nodes || CONCAT( '{nl@192.168.1.101:', COALESCE(watching_times.nodes->>'nl@192.168.1.101', '0')::int + 1, '}' )::JSONB RETURNING id;
ããŒãã®ãªã¹ãã¯æ¬¡ã®ããã«ãªããŸãã

ãŠãŒã¶ãŒã2çªç®ã®ãŠã£ã³ããŠãŸãã¯å¥ã®ããã€ã¹ã§ãµãŒãã¹ãéããšãå¥ã®ããŒãã«ã¢ã¯ã»ã¹ã§ãããªã¹ãã«ãè¿œå ãããŸãã æåã®ãŠã£ã³ããŠãšåãããŒãã«ããå Žåããªã¹ãå ã®ãã®ããŒãã®ååã®å察ã®æ°ãå¢å ããŸãã ãã®æ°ã¯ãç¹å®ã®ããŒããžã®ã¢ã¯ãã£ããªãŠãŒã¶ãŒæ¥ç¶ã®æ°ãåæ ããŠããŸãã
以äžã¯ãã»ãã·ã§ã³ãéãããããšãã«ããŒã¿ããŒã¹ã«éä¿¡ãããã¯ãšãªã§ãã
UPDATE watching_times SET nodes CASE WHEN ( CONCAT( '{ânl@192.168.1.101â: ', COALESCE(watching_times.nodes ->> 'nl@192.168.1.101', '0') :: INT - 1, '}' )::JSONB ->>'nl@192.168.1.101' )::INT <= 0 THEN (watching_times.nodes - 'nl@192.168.1.101') ELSE CONCAT( '{ânl@192.168.1.101â: ', COALESCE(watching_times.nodes ->> 'nl@192.168.1.101', '0') :: INT - 1, '}' )::JSONB END ), terminate_at = (CASE WHEN ... = '{}' :: JSONB THEN NOW() ELSE NULL END) WHERE id = 1;
ããŒãã®ãªã¹ãïŒ

ç¹å®ã®ããŒãã§ã»ãã·ã§ã³ãéãããããšãããŒã¿ããŒã¹å ã®æ¥ç¶ã«ãŠã³ã¿ãŒã1ã€æžãããŒãã«éãããšãããŒãã¯ãªã¹ãããåé€ãããŸãã ããŒãã®ãªã¹ããå®å šã«ç©ºã«ãªããšããã®ç¬éã¯æçµçãªãŠãŒã¶ãŒçµäºæéãšããŠä¿®æ£ãããŸãã
ãã®ã¢ãããŒãã«ããããŠãŒã¶ãŒã®ãªã³ã©ã€ã³ãã¬ãŒã³ã¹ãšèŠèŽæéã远跡ã§ããã ãã§ãªããããŸããŸãªåºæºã«åŸã£ãŠãããã®ã»ãã·ã§ã³ããã£ã«ã¿ãªã³ã°ããããšãå¯èœã«ãªããŸããã
ãã®ãã¹ãŠã«ãããŠãå¯äžã®æ¬ ç¹ããããŸã-ããŒããèœã¡ãå Žåããã®ãã¹ãŠã®ãŠãŒã¶ãŒããªã³ã©ã€ã³ã§ããã³ã°ãããŸãã ãã®åé¡ã解決ããããã«ããã®ãããªã¬ã³ãŒãããããŒã¿ããŒã¹ãå®æçã«ã¯ãªãŒãã³ã°ããããŒã¢ã³ããããŸããããããŸã§ã®ãšããããã¯å¿ èŠãããŸããã§ããã ãããžã§ã¯ãã®éçšéå§åŸã«å®è¡ãããè² è·ã®åæãšã¯ã©ã¹ã¿ã®ç£èŠã¯ãããŒãã®ããããããªãããã®ã¡ã«ããºã ã䜿çšãããŠããªãããšã瀺ããŸããã
ä»ã«ãå°é£ããããŸããããããå ·äœçã§ãããããã¢ããªã±ãŒã·ã§ã³ã®åŸ©å åã®åé¡ã«ç§»ã䟡å€ããããŸãã
ããã©ãŒãã³ã¹ãåäžãããããã®Linuxã«ãŒãã«ã®æ§æ
åªããã¢ããªã±ãŒã·ã§ã³ãçç£çãªèšèªã§æžãããšã¯ãæŠãã®ååã«ãããŸãããèªã¿æžãã®ã§ããDevOpsããªããã°ãå°ãªããšãé«ãææãäžããããšã¯äžå¯èœã§ãã
ã¿ãŒã²ããè² è·ã«å¯Ÿããæåã®éå£ã¯ãLinuxãããã¯ãŒã¯ã«ãŒãã«ã§ããã ãªãœãŒã¹ã®ããåççãªäœ¿çšãå®çŸããã«ã¯ãããã€ãã®èª¿æŽãå¿ èŠã§ããã
Linuxã§ã¯ãéããŠããåãœã±ããã¯ãã¡ã€ã«èšè¿°åã§ããããã®æ°ã¯å¶éãããŠããŸãã å¶éã®çç±ã¯ãã«ãŒãã«å ã®éããŠãããã¡ã€ã«ããšã«ãåå©çšã§ããªãã«ãŒãã«ã¡ã¢ãªãå æããCæ§é ãäœæãããããã§ãã
æ倧ã¡ã¢ãªã䜿çšããã«ã¯ãéä¿¡ãããã¡ãšåä¿¡ãããã¡ã®ãµã€ãºãéåžžã«å€§ããèšå®ããTCPãœã±ãããããã¡ã®ãµã€ãºã倧ããããŸããã ããã§ã®å€ã¯ãã€ãåäœã§ã¯ãªãã¡ã¢ãªããŒãžåäœã§èšå®ãããŸããéåžžã1ããŒãžã¯4 kBã§ãããè² è·ã®é«ããµãŒããŒã®æ¥ç¶ãåŸ æ©ããŠããéããŠãããœã±ããã®æ倧æ°ã15,000ã«èšå®ããŸãã
ãã¡ã€ã«èšè¿°åã®å¶éïŒ
#!/usr/bin/env bash sysctl -w 'fs.nr_open=10000000' # sysctl -w 'net.core.rmem_max=12582912' # sysctl -w 'net.core.wmem_max=12582912' # sysctl -w 'net.ipv4.tcp_mem=10240 87380 12582912' # TCP sysctl -w 'net.ipv4.tcp_rmem=10240 87380 12582912' # sysctl -w 'net.ipv4.tcp_wmem=10240 87380 12582912'# <code>sysctl -w 'net.core.somaxconn=15000' # ,
ã«ãŠããŒã€ãµãŒããŒã®åã§nginxã䜿çšããŠããå Žåã¯ãå¶éãå¢ããããšãæ€èšããå¿ èŠããããŸãã ãã£ã¬ã¯ãã£ãworker_connectionsããã³worker_rlimit_nofileããããæ åœããŸãã
2çªç®ã®éå£ã¯ããã»ã©æçœã§ã¯ãããŸããã ãã®ãããªã¢ããªã±ãŒã·ã§ã³ãåæ£ã¢ãŒãã§å®è¡ãããšãCPUæ¶è²»ãæ¥æ¿ã«å¢å ããäžæ¹ã§ãæ¥ç¶æ°ãå¢å ããããšã«æ°ä»ãã§ãããã åé¡ã¯ãããã©ã«ãã§ã¯ErlangãPollã·ã¹ãã ã³ãŒã«ã§åäœããããšã§ãã Linuxã«ãŒãã«ã®ããŒãžã§ã³2.6ã«ã¯ãå€æ°ã®åæãªãŒãã³æ¥ç¶ãåŠçããã¢ããªã±ãŒã·ã§ã³ã«ããå¹ççãªã¡ã«ããºã ãæäŸã§ããEpollããããŸããOïŒnïŒã®è€éãã§ã¯ãªãOïŒ1ïŒã®è€éãã§ãã
幞ããªããšã«ãEpollã¢ãŒãã¯1ã€ã®ãã©ã°ã§ãªã³ã«ãªããŸãã
æ祚察 ãšããŒã«
#!/usr/bin/env bash Elixir --name ${MIX_NODE_NAME}@${MIX_HOST} --erl â-config sys.config -setcookie ${ERL_MAGIC_COOKIE} +K true +Q 500000 +P 4194304â -S mix phx.server
3çªç®ã®åé¡ã¯ããå人çãªãã®ã§ããã誰ããããã«çŽé¢ã§ããããã§ã¯ãããŸããã ChefãšKubernetesã䜿çšããèªåå±éãšåçã¹ã±ãŒãªã³ã°ã®ããã»ã¹ã¯ããã®ãããžã§ã¯ãã§ç·šæãããŸããã Kubernetesã䜿çšãããšãå€æ°ã®ãã¹ãã«Dockerã³ã³ãããŒããã°ããå±éã§ããŸãããããã¯éåžžã«äŸ¿å©ã§ãããæ°ãããã¹ãã®IPã¢ãã¬ã¹ãäºåã«èŠã€ããããšã¯ã§ããŸããããŸããErlangæ§æã«ç»é²ããªããšãæ°ããããŒããåæ£ã¢ããªã±ãŒã·ã§ã³ã«æ¥ç¶ã§ããŸããã
幞ããªããšã«ããããã®åé¡ã解決ããããã«libclusterã©ã€ãã©ãªãååšããŸãã APIãä»ããŠKubernetesãšéä¿¡ãã圌女ã¯ãªã¢ã«ã¿ã€ã ã§æ°ããããŒãã®äœæã«ã€ããŠåŠã³ãããããerlangã¯ã©ã¹ã¿ãŒã«ç»é²ããŸãã
config :libcluster, topologies: [ k8s: [ strategy: Cluster.Strategy.Kubernetes, config: [ kubernetes_selector: âapp=my -backendâ, kubernetes_node_basename: âmy -backendâ]]]
çµæãšå±æ
éžæããããã¬ãŒã ã¯ãŒã¯ãšæ£ãããµãŒããŒèšå®ã«ããããããžã§ã¯ãã®ãã¹ãŠã®ç®æšãéæããããšãã§ããŸããïŒèšå®ãããæéæ ïŒ1ãæïŒä»¥å ã«ããªã¢ã«ã¿ã€ã ã§ãŠãŒã¶ãŒãšéä¿¡ããåæã«15äžä»¥äžã®æ¥ç¶ããã®è² è·ã«èããããšãã§ããã€ã³ã¿ã©ã¯ãã£ããªWebãµãŒãã¹ãéçºããŸãã
æ¬çªç°å¢ã§ã®ãããžã§ã¯ãã®éå§åŸãç£èŠãå®è¡ããã次ã®çµæã瀺ãããŸãããæ倧æ¥ç¶æ°ã80äžãŸã§ã®å Žåãããã»ããµãªãœãŒã¹ã®æ¶è²»ã¯45ïŒ ã«éããŸãã 60äžã®æ¥ç¶ã§ã®å¹³åè² è·ã¯29ïŒ ã§ãã

ãã®ã°ã©ãã§ã¯ãããããã8 GBã®RAMãæèŒãã10å°ã®ãã·ã³ã®ã¯ã©ã¹ã¿ãŒã§äœæ¥ããŠãããšãã®ã¡ã¢ãªæ¶è²»éã


ãã®ãããžã§ã¯ãã®äž»ãªäœæ¥ããŒã«ã§ããElixirãšPhoenix Frameworkã«ã€ããŠã¯ãä»åŸæ°å¹Žã®ãã¡ã«RubyãRailsãšåãããã人æ°ã«ãªããšä¿¡ããçç±ããããŸãã®ã§ãä»ããéçºãéå§ããã®ã¯çã«ããªã£ãŠããŸãã
ãæž èŽããããšãããããŸããïŒ
åç §è³æ
éçºïŒ
elixir-lang.org
phoenixframework.org
è² è·ãã¹ãïŒ
gatling.io
flood.io
ç£èŠïŒ
prometheus.io
grafana.com