Goã§ã®ãããã¯ãŒã¯ãµãŒãã¹ã®èšè¿°ã¯éåžžã«ç°¡åã§ããæšæºã©ã€ãã©ãªã«ã¯å€ãã®ããŒã«ããããäžè¶³ããŠãããã®ãããã°ãGithubã«ã¯ã»ãšãã©ã®ããŒãºãæºããããã®ãã¬ã³ãã£ãªã©ã€ãã©ãªããããããããŸãã
ããããåãã€ã³ãã©ã¹ãã©ã¯ãã£ã§åäœããããŸããŸãªãµãŒãã¹ã«ã€ããŠæžãå¿
èŠãããå Žåã¯ã©ãã§ããããïŒ
ãã¹ãŠã®æªéããã¹ãŠã®æ°é®®ã§å€æ§ãªã¹ã ãŒãžãŒã䜿çšããå Žåãæ°ããæ©èœãè¿œå ããããšã¯èšããŸã§ããªãããã¯ãããžãŒã¯ç¶æããã®ãé£ãããé«äŸ¡ãªãåç©åãããããããŸãã
Badooã«ã¯ãããŸããŸãªèšèªã§æžããã30ãè¶
ããã»ã«ãã¹ã¿ã€ã«ã®ããŒã¢ã³ãããããã®ãã¡ã®10åãGoã«ãããŸãã ãããã®ããŒã¢ã³ã¯ãã¹ãŠãçŽ300å°ã®ãµãŒããŒã§åäœããŸãã æåŸã«ãåç©åããååŸããã«ãã©ããã£ãŠã¹ã ãŒãžãŒãéçºè
ãQAãããã³ãªãªãŒã¹ã«èª°ãå¶éããã«å¹³åçã«ç ãæ¹æ³ã管çè
ãã©ã®ããã«ç®¡çããŠããã®ãããŸã å£è«ãããŠããªã
Badoo Goãæåã«ç»å Žããã®ã¯2014幎é ã§ããŠãŒã¶ãŒã®åº§æšéã®äº€å·®ç¹ãæ¢ãããŒã¢ã³ããã°ããäœæããã¿ã¹ã¯ã«çŽé¢ãããšãã§ãã ãã®åŸãGoã®ææ°ããŒãžã§ã³ã¯1.3ã§ãã£ããããé·ãéGCã®äžæåæ¢ã«èŠåŽããŸãããããã«ã€ããŠã¯ããªãã£ã¹ã§ã®GoããŒãã£ã³ã°ã§èª¬æããŸããã
ãã以æ¥ãGoã§æžãããããŒã¢ã³ãå¢ããŠããŸãã åºæ¬çã«ãããã¯ä»¥åã¯Cã§èšè¿°ãããŠãããã®ã§ãããPHPã§ã¯ããŸãæ©èœããªãå ŽåããããŸãïŒããšãã°ã éåæãããã·ããã¯ã©ãŠããã®ãªãœãŒã¹ã¹ã±ãžã¥ãŒã©ãŒ ïŒã
ã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ããã®ãã¹ãŠã®ãªã¯ãšã¹ãã¯PHPã«ãã£ãŠåŠçãããPHPã¯ããŸããŸãªèªå·±èšè¿°åããã³éèªå·±èšè¿°åã®ãµãŒãã¹ã«éãããŸãã ç°¡ç¥åãããšã次ã®ããã«ãªããŸãã
ãã®ã«ãŒã«ã«ã¯ããã€ãã®äŸå€ããããŸãããäžè¬çã«ãGoã®ãã¹ãŠã®æªéã«ã€ããŠã¯ã次ã®ããšãåœãŠã¯ãŸããŸãã
- 圌ãã¯ã€ã³ã¿ãŒãããã«åºãªã
- ããŒã¢ã³ã®äž»ãªããŠãŒã¶ãŒãã¯PHPã³ãŒãã§ãã
ç§ãã¡ã®ãã¹ãŠã®æªéã¯ãå·çã®èšèªã«é¢ä¿ãªãããããã³ã«ããã°ãçµ±èšãå±éãªã©ã®ç¹ã§ãå€éšãããåãããã«èŠããŸãã ããã«ããã管çè
ããªãªãŒã¹ãšã³ãžãã¢ãQAãPHPéçºè
ã®äœæ¥ã楜ã«ãªããŸãã
ãããã£ãŠãäžæ¹ã§ã¯ãGoããŒã¢ã³ã«äœ¿çšããå€ãã®ã¢ãããŒãã¯ãC / C ++ã§ããŒã¢ã³ãäœæããæ¢åã®ã¢ãããŒãã«ãã£ãŠæ±ºå®ãããä»æ¹ã§ã¯ããã®èšäºã®å€ãã¯Goã ãã§ãªãããã¹ãŠã®ããŒã¢ã³ã«ãåœãŠã¯ãŸããŸãã
以äžã§ã¯ãåºæ¬çãªã€ã³ãã©ã¹ãã©ã¯ãã£ããŒããã©ã®ããã«é
眮ãããGoã³ãŒãã«ã©ã®ããã«åæ ããããã説æããŸãã
ãããã³ã«
ã¯ã©ã€ã¢ã³ããšãµãŒããŒã®çžäºäœçšã«é¢ããŠã¯ããããã³ã«ã«é¢ããŠçåãçããŸãã Google Protobufãåºç€ãšããŠæ¡çšããŸããã ç§ãã¡ã®ãããã³ã«ã¯gRPCã®ç°¡æããŒãžã§ã³ã«äŒŒãŠããããããè»èŒªãåçºæããå¿
èŠãããã®ã¯ãªãã§ããããšããã«ããŽãªããç¹°ãè¿ã質åãããŸããã ã»ãšãã©ã®å Žåãä»æ¥ã¯gRPCãå®éã«äœ¿çšããŸãããåœæïŒ2008幎ïŒã¯ãŸã ååšããŠããªãã£ããããçžäºã«äº€æããæå³ããããŸããã
Protobufã¯ãã¡ãã»ãŒãžæ¬æããã€ããªè¡šçŸã§ã©ããããã ãã§ããã®ã¿ã€ãã¯ä¿æããŸããã ãããã£ãŠãã¯ã©ã€ã¢ã³ãããªã¯ãšã¹ãã䜿çšããŠãµãŒããŒã«ã¢ã¯ã»ã¹ãããã³ã«ããµãŒããŒã¯ãã©ã®protobufã¡ãã»ãŒãžã§ããããã©ã®ã¡ãœãããå®è¡ããå¿
èŠãããããç解ããå¿
èŠããããŸãã ãããè¡ãã«ã¯ãprotobufã¡ãã»ãŒãžã®åã«ã¡ãã»ãŒãžã¿ã€ãèå¥åãšã¡ãã»ãŒãžé·ãè¿œå ããŸãã èå¥åã«ãããã©ã®GPBã¡ãã»ãŒãžãå°çããããæ確ã«ãªããé·ãã«ãããå¿
èŠãªãµã€ãºã®ãããã¡ãããã«å²ãåœãŠãããšãã§ããŸãã
ãã®çµæããããã³ã«ã«é¢ãã1ã€ã®åŒã³åºãã¯æ¬¡ã®ããã«ãªããŸãã
ã¯ã©ã€ã¢ã³ããšãµãŒããŒã®äž¡æ¹ãã¡ãã»ãŒãžèå¥åã«ã€ããŠåãæ
å ±ãæã€ããã«ãç¹å¥ãªåårequest_msgid
ãšresponse_msgid
æã€enumã®åœ¢åŒã§ãããããããã¿ã€ããã¡ã€ã«ã«ä¿åããŸãã äŸïŒ
enum request_msgid { REQUEST_RUN = 1; REQUEST_STATS = 2; } // request response, enum response_msgid { RESPONSE_GENERIC = 1; // , response , RESPONSE_RUN = 2; RESPONSE_STATS = 3; } message request_run { // ... } message response_run { // ... } message request_stats { // ... } // ...
gpbrpcãšåŒã°ããã©ã€ãã©ãªã¯ããã®ãã¹ãŠã®ãããã³ã«éšåãæ
åœããŸãã 倧ãŸãã«2ã€ã®éšåã«åããããšãã§ããŸãã
- 1ã€ã¯ã
request_msgid
ãšresponse_msgid
åºã¥ããŠresponse_msgid
äžèŽãããid =>ã¡ãã»ãŒãžããã³ãã©ãŒã¡ãœããã®ãã³ãã¬ãŒããåãã£ã¹ãã«ããåŒã³åºãã®ããããããã³å¿
èŠãªä»ã®ã³ãŒããçæããã³ãŒããžã§ãã¬ãŒã¿ãŒã§ãã - 2çªç®ã®éšåã§ã¯ ããããã¯ãŒã¯çµç±ã§éä¿¡ããããã®ããŒã¿ããã¹ãŠè§£æã ã察å¿ãããã³ãã©ãŒã¡ãœãããåŒã³åºããŸãã
æåã®éšåã®ã³ãŒããžã§ãã¬ãŒã¿ãŒã¯ãGoogle Protobufã®ãã©ã°ã€ã³ãšããŠå®è£
ãããŸãã
äžèšã®protoãã¡ã€ã«çšã«èªåçæããããã³ãã©ãŒã¯æ¬¡ã®ããã«ãªããŸãã
// , , proto- type GpbrpcInterface interface { RequestRun(rctx gpbrpc.RequestT, request *RequestRun) gpbrpc.ResultT RequestStats(rctx gpbrpc.RequestT, request *RequestStats) gpbrpc.ResultT } func (GpbrpcType) Dispatch(rctx gpbrpc.RequestT, s interface{}) gpbrpc.ResultT { service := s.(GpbrpcInterface) switch RequestMsgid(rctx.MessageId) { case RequestMsgid_REQUEST_RUN: r := rctx.Message.(*RequestRun) return service.RequestRun(rctx, r) case RequestMsgid_REQUEST_STATS: r := rctx.Message.(*RequestStats) return service.RequestStats(rctx, r) } } // - /* func ($receiver$) RequestRun(rctx gpbrpc.RequestT, request *$proto$.RequestRun) gpbrpc.ResultT { // ... } func ($receiver$) RequestStats(rctx gpbrpc.RequestT, request *$proto$.RequestStats) gpbrpc.ResultT { // ... } */
gogo / protobuf
Protobufã®ããã¥ã¡ã³ãã§ã¯ãGoã§ãã®ã©ã€ãã©ãªã䜿çšããããšããå§ãããŸãã ããããæ®å¿µãªããšã«ãäžæ£ãªGCã³ãŒããçæãããŸãã ããã¥ã¡ã³ãã®äŸïŒ
message Test { required string label = 1; optional int32 type = 2 [default=77]; }
ã«ãªããŸã
type Test struct { Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` }
æ§é ã®åãã£ãŒã«ãã¯ãã€ã³ã¿ãŒã«ãªã£ãŠããŸãã ããã¯optional
ãã£ãŒã«ãã«å¿
èŠoptional
ãã£ãŒã«ãã§ã¯ããã£ãŒã«ããååšããªãå Žåãšããã£ãŒã«ãã«ãŒãå€ãå«ãŸããŠããå Žåãåºå¥ããå¿
èŠããããŸãã
äžèŠãªå Žåã§ããçæãããã³ãŒãå
ã®ãã€ã³ã¿ãŒã®ååšãã©ã€ãã©ãªã§å¶åŸ¡ããããšã¯ã§ããŸããã ãããããã¹ãŠãããã»ã©æªãããã§ã¯ãããŸããã圌女ã¯ããããµããŒããããŠããgogoprotobufã®ãã©ãŒã¯ãæã£ãŠããŸãã ãããè¡ãã«ã¯ãããããã¡ã€ã«ã§é©åãªãªãã·ã§ã³ãæå®ããå¿
èŠããããŸãã
message Test { required string label = 1 [(gogoproto.nullable) = false]; optional int32 type = 2 [(gogoproto.nullable) = false]; }
ãã€ã³ã¿ãŒãåãé€ãããšã¯ãGCã®äžæåæ¢ãã¯ããã«é·ãã£ãããŒãžã§ã³1.5ãŸã§Goã§ç¹ã«åœãŠã¯ãŸããŸããã ãã ããçŸåšã§ããããŒãããããµãŒãã¹ã®ããã©ãŒãã³ã¹ã倧å¹
ã« ïŒå Žåã«ãã£ãŠã¯ïŒ åäžãããããšãã§ããŸãã
nullable
ã«å ããŠãã©ã€ãã©ãªã§ã¯ãããã©ãŒãã³ã¹ãšçµæã®ã³ãŒãã®å©äŸ¿æ§ã®äž¡æ¹ã«åœ±é¿ããä»ã®å€æ°ã®çæãªãã·ã§ã³ãè¿œå ã§ããŸãã ããšãã°ã gostring
ã¯ãGoæ§æã®å€ã§çŸåšã®æ§é ãä¿åããŸããããã¯ããããã°ããã¹ãã®äœæã«äŸ¿å©ã§ãã
ãªãã·ã§ã³ã®é©åãªã»ããã¯ãç¹å®ã®ç¶æ³ã«ãã£ãŠç°ãªããŸãã ã»ãšãã©ã®å Žåãå°ãªããšãnullable
ã sizer_all, unsafe_marshaler_all
ã unsafe_unmarshaler_all
ãŸãã ãšããã§ãæ¥å°ŸèŸ_all
ãä»ãããªãã·ã§ã³ãæã€ãªãã·ã§ã³ã¯ããã£ãŒã«ãããšã«è€è£œããããšãªãããã¡ã€ã«å
šäœã«ããã«é©çšã§ããŸãã
option (gogoproto.sizer_all) = true; message Test { required string label = 1; optional int32 type = 2; }
ãžã§ã³ãœã³
Google Protobufã§ã¯ãã»ãšãã©ãã¹ãŠãåé¡ãããŸãããããã€ããªãããã³ã«ã§ããããããããã°ããã®ã¯å°é£ã§ãã
å®æããã¯ã©ã€ã¢ã³ããšãµãŒããŒéã®çžäºäœçšã®ã¬ãã«ã§åé¡ãèŠã€ããå¿
èŠãããå Žåãããšãã°Wiresharkã® gpbs-dissectorã䜿çšã§ããŸãã ãã ããããã¯ãã¯ã©ã€ã¢ã³ããŸãã¯ãµãŒããŒããŸã ãªãæ°ããæ©èœãéçºããå Žåã«ã¯é©ããŠããŸããã
å®éãããçš®ã®ãã¹ãèŠæ±ããµãŒãã¹ã«æžã蟌ãã«ã¯ãããããã€ããªã¡ãã»ãŒãžã«ã©ããã§ããã¯ã©ã€ã¢ã³ããå¿
èŠã§ãã ããŒã¢ã³ããšã«ãã®ãããªãã¹ãã¯ã©ã€ã¢ã³ããäœæããããšã¯ãããã»ã©é£ããã¯ãããŸããããäžäŸ¿ã§æ¥åžžçãªäœæ¥ã§ãã ãããã£ãŠãgpbrpcã¯ãgpbã€ã³ã¿ãŒãã§ãŒã¹ãšã¯ç°ãªãããŒãã§ãããã³ã«ã®JSONã®ãããªè¡šçŸãåŠçã§ããŸãã ããã«å¯Ÿãããã€ã³ãã£ã³ã°å
šäœãèªåçã«çæãããŸãïŒprotobufã«ã€ããŠäžèšã§èª¬æããæ¹æ³ãšåæ§ã®æ¹æ³ã§ïŒã
ãã®çµæãã³ã³ãœãŒã«ã§ããã¹ã圢åŒã§ãªã¯ãšã¹ããäœæããããã«åçãåŸãããšãã§ããŸãã ãããã°ã«äŸ¿å©ã§ãã
pmurzakov@shell1.mlan:~> echo 'run {"url":"https://graph.facebook.com/?id=http%3A%2F%2Fhabrahabr.ru","task_hash":"a"}' | netcat xtc1.mlan 9531 run { "task_hash": "a", "task_status": 2, "response": { "http_status": 200, "body": "{\"og_object\":{\"id\":\"627594553918401\",\"description\":\" â , . , , â IT- .\",\"title\":\" / \",\"share\":{\"comment_count\":0,\"share_count\":2456},\"id\":\"http:\\/\\/habrahabr.ru\"}", "response_time_ms": 179 } }
çããèšå€§ã§ãããããäžéšãéžæããå¿
èŠãããå ŽåããŸãã¯äœããã®åœ¢ã§å€æããå¿
èŠãããå Žåã¯ã jqã³ã³ãœãŒã«ãŠãŒãã£ãªãã£ã䜿çšã§ããŸãã
æ§æ
äžè¬ã«ãæ§æã«ã¯éåžž2ã€ã®åºæ¬èŠä»¶ããããŸãã
- èªã¿ããã;
- æ§é ã説æããæ©äŒã
ãã®ããã«ãŸã æ°ãããšã³ãã£ãã£ãå°å
¥ããªãããã«ããã§ã«ãããã®ãå©çšããŸããïŒprotobuf-æ§é ãå¯èªæ§-ãã®JSONè¡šçŸã
ãããã°çšã®JSONè¡šçŸçšã®protobufããã³ããŒãµãŒãžã§ãã¬ãŒã¿ãŒã®ãã¹ãŠã®ãã€ã³ãã£ã³ã°ãæ¢ã«ãããŸãïŒåã®ã»ã¯ã·ã§ã³ãåç
§ïŒã ããšã¯ãæ§æçšã®ãããã¿ã€ããã¡ã€ã«ãè¿œå ããŠããã®ããŒãµãŒã«ããã£ãŒããããã ãã§ãã
å®éããã¹ãŠãå°ãè€éã§ããç°ãªãããŒã¢ã³ãå¯èœãªéãæšæºåããããšãéèŠã§ãããããæ§æã«ã¯ãã¹ãŠã®ããŒã¢ã³ã«åãéšåããããŸãã ããã¯ãäžè¬çãªprotobufã¡ãã»ãŒãžã«ãã£ãŠèšè¿°ãããŸãã æçµçãªæ§æã¯ãæšæºåãããéšåãšç¹å®ã®ããŒã¢ã³ã«åºæã®ãã®ã®çµã¿åããã§ãã
ãã®ã¢ãããŒãã¯åã蟌ã¿ã«é©ããŠããŸãïŒ
type FullConfig struct { badoo.ServiceConfig yourdaemon.Config }
ããããããããããã®äŸã å
±ééšåïŒ
message service_config { message daemon_config_t { message listen_t { required string proto = 1; required string address = 2; optional bool pinba_enabled = 4; } repeated listen_t listen = 1; required string service_name = 2; required string service_instance_name = 3; optional bool daemonize = 4; optional string pid_file = 5; optional string log_file = 6; optional string http_pprof_addr = 7;
ç¹å®ã®ããŒã¢ã³ã®äžéšïŒ
message config { optional uint32 workers_count = 1 [default = 4000]; optional uint32 max_queue_length = 2 [default = 50000]; optional uint32 max_idle_conns_per_host = 4 [default = 1000]; optional uint32 connect_timeout_ms = 5 [default = 2000]; optional uint32 request_timeout_ms = 7 [default = 10000]; optional uint32 keep_alive_ms = 8 [default = 30000]; }
ãã®çµæãJSONèšå®ã¯æ¬¡ã®ããã«ãªããŸãã
{ "daemon_config": { "listen": [ { "proto": "xtc-gpb", "address": "0.0.0.0:9530" }, { "proto": "xtc-gpb/json", "address": "0.0.0.0:9531" }, { "proto": "service-stats-gpb", "address": "0.0.0.0:9532" }, { "proto": "service-stats-gpb/json", "address": "0.0.0.0:9533" }, ], "service_name": "xtc", "service_instance_name": "1.mlan", "daemonize": false, "pinba_address": "pinbaxtc1.mlan:30002", "http_pprof_addr": "0.0.0.0:9534", "pid_file": "/local/xtc/run/xtc.pid", "log_file": "/local/xtc/logs/xtc.log", }, // "workers_count": 4000, "max_queue_length": 50000, "max_idle_conns_per_host": 1000, "connect_timeout_ms": 2000, "handshake_timeout_ms": 2000, "request_timeout_ms": 10000, "keep_alive_ms": 30000, }
listen
ã¯ãããŒã¢ã³ããªãã¹ã³ãããã¹ãŠã®ããŒãããªã¹ãããŸãã ã¿ã€ãxtc-gpb
ããã³xtc-gpb/json
ã®æåã®2ã€ã®èŠçŽ ã¯ããã®gpbrpc
ã®ããŒããšãã®JSONè¡šçŸçšã§ãã ãŸãã service-stats-gpb
ããã³service-stats-gpb/json
ãŠãçµ±èšæ
å ±ãåéããŸããããã«ã€ããŠã¯åŸã§èª¬æããŸãã
çµ±èš
çµ±èšãåéããå ŽåïŒæ§æã®æšæºåãããéšåã®å ŽåïŒãåããŒã¢ã³ãå°ãªããšãåºæ¬çãªã¡ããªãã¯ãæäŸããããšãéèŠã§ãïŒåŠçãããèŠæ±ã®æ°ãCPUãšã¡ã¢ãªã®æ¶è²»ããããã¯ãŒã¯ãã©ãã£ãã¯ãªã©ããã®ã¿ã€ãã®çµ±èšã¯service-stats-gpb
ããŒãããåéãããŸãservice-stats-gpb
ãããã¯ãã¹ãŠã®æªéã«åãã§ãã
å®éãçµ±èšã®èŠæ±ã¯ãããŒã¢ã³ãžã®éåžžã®èŠæ±ãšå€ãããªããããåãã¢ãããŒãã䜿çšããŸããçµ±èšã¯ãéåžžã®èŠæ±ãšåæ§ã«gpbrpcã®èŠ³ç¹ãã説æãããŸãã ãã®ãæšæºåããããçµ±èšã®ãã³ãã©ãŒã¯ãã§ã«ãã¬ãŒã ã¯ãŒã¯ã«ããããã次ã®ããŒã¢ã³ã®ããã«æ¯åèšè¿°ããå¿
èŠã¯ãããŸããã
æ§æãšã®é¡æšã«ããããã¹ãŠã®ããŒã¢ã³ã®åãçµ±èšã«å ããŠãåããŒã¢ã³ãç¹å®ã®ããŒã¢ã³ãæäŸã§ããŸãã
1åããšã«ãPHPã¯ã©ã€ã¢ã³ãçµ±èšã³ã¬ã¯ã¿ãŒã¯ããŒã¢ã³ã«æ¥ç¶ããå€ãèŠæ±ããŠæç³»åã¹ãã¢ã«ä¿åããŸãã ãããã®ããŒã¿ã«åºã¥ããŠããã®ãããªã°ã©ããäœæããŸãã
æåã®5ã€ã®ã°ã©ãã®å€ã¯ãã¹ãŠã®ããŒã¢ã³ããèªåçã«åéãããæ®ãã¯ç¹å®ã®ããŒã¢ã³ã«åºæã®å€ã§ãã
äžè¬çã«ãçµ±èšæ
å ±ãå€ãããããšã¯ãªããšèããŠãããããŒã¿ã®æ倧éãååŸããããšããŠããŸãããã®ãããåŸã§åé¡ãå€æŽã«å¯ŸåŠããã®ã容æã«ãªããŸãã ãããã£ãŠãconfigã§pinba_address
ãã©ã¡ãŒã¿ãŒã確èªã§ããŸããããã¯ãããŒã¢ã³ãçµ±èšæ
å ±ãéä¿¡ããPinbaãµãŒããŒã®ã¢ãã¬ã¹ã§ãã
ãã³ããããå¿çæéååžã°ã©ããäœæããŸãã
ãããã°ãšãããã¡ã€ãªã³ã°
èšå®ã§ãããã©ã¡ãŒã¿http_pprof_addr
æ°ä»ãããšãã§ããŸãã ããã¯net / http / pprof portã§ãGoã®çµã¿èŸŒã¿ããŒã«ã§ãããã³ãŒãã®ãããã¡ã€ã«ãç°¡åã«äœæã§ããŸãã 圌ã«ã€ããŠã¯å€ãã®èšäºãæžãããŠããã®ã§ïŒããšãã°ã thisãthis ïŒã圌ã®äœåã®è©³çŽ°ã«ã€ããŠã¯è§ŠããŸããã
æ¬çªããŒã¢ã³ã®ãã«ãã§ãpprofãæ®ããŸãã 䜿çšãããŸã§ãªãŒããŒãããã¯ã»ãšãã©ãããŸããããæè»æ§ãè¿œå ãããŸãããã€ã§ãæ¥ç¶ããŠãäœãçºçããŠã©ã®ãªãœãŒã¹ãæ¶è²»ãããŠããããææ¡ã§ããŸãã
ããã«ã expvarã䜿çšããŠãHTTPçµç±ã§ä»»æã®ããŒã¢ã³å€æ°ã®ã¢ã¯ã»ã¹å¯èœãªå€ã1è¡ã®ã³ãŒãã®JSON圢åŒã§äœæã§ããããã«ããŸãã
expvar.Publish("varname", expvar.Func(func() interface{} { return somevariable }))
ããã©ã«ãã§ã¯ã expvar
HTTPãã³ãã©ãŒexpvar
DefaultServeMux
è¿œå ããã httpïŒ// yourhost / debug / varsã§å©çšå¯èœã§ãã æ¥ç¶ãããšãããã±ãŒãžã«å¯äœçšããããŸãã runtime.ReadMemStats()
çµæã ãã§ãªãããââã€ããªãèµ·åãããã³ãã³ãã©ã€ã³ããã¹ãŠã®ãã©ã¡ãŒã¿ãŒã§èªåçã«å
¬éããŸãã
ã泚æ ReadMemStatsïŒïŒã¯ã倧éã®ã¡ã¢ãªãå²ãåœãŠãããå Žåãé·ãéäžçãåæ¢ããå¯èœæ§ããããŸãã ååã®Marko Kevacããã®ãããã¯ã«é¢ãããã±ãããäœæããŸããããããŒãžã§ã³1.9ã§ã¯ãããä¿®æ£ããå¿
èŠããããŸãã
æšæºå€ã«å ããŠããã¹ãŠã®ããŒã¢ã³ã¯å€ãã®ãããã°æ
å ±ãå
¬éããŠããŸããæãéèŠãªã®ã¯æ¬¡ã®ãšããã§ãã
- ããŒã¢ã³ã®èµ·åã«äœ¿çšããæ§æã
- äžèšã§æžãããã¹ãŠã®çµ±èšã«ãŠã³ã¿ãŒã®å€ã
- ãã€ããªã®åéæ¹æ³ã«é¢ããããŒã¿ã
æåã®2ã€ã®ãã€ã³ãã§ã¯ããã¹ãŠãæ確ã ãšæããŸãã åŸè
ã¯ãããŒã¢ã³ããã«ããããGoã®ããŒãžã§ã³ãgitã³ãããã®ããã·ã¥ããã«ãæéãããã³ãã«ãã«é¢ãããã®ä»ã®æçšãªããŒã¿ã«é¢ããæ
å ±ãæäŸããŸãã
äŸïŒ
ãããè¡ãã«ã¯ãversion.goãã¡ã€ã«ãäœæãããšãã«çæããŸãããã®ãã¡ã€ã«ã«ã¯ãã¹ãŠã®æ
å ±ãæžã蟌ãŸããŸãã ãã ãã ldflags -Xã䜿çšããŠãåæ§ã®å¹æãåŸãããŸãã
ãã°
ãã¬ãŒãšããŠãã«ã¹ã¿ã ãã©ãŒããã¿ã§logrusã䜿çšããŸãã Rsyslogããã³Logstashã䜿çšãããã°ãã¡ã€ã«ã¯Elasticsearchã§åéããããã®åŸKibana ããã·ã¥ããŒã ïŒELKïŒã«è¡šç€ºãããŸãã
ãããã®ãœãªã¥ãŒã·ã§ã³ãéžæããçç±ãããã³ãã°ã¢ã»ã³ããªã®ãã®ä»ã®è©³çŽ°ã«ã€ããŠã¯ã ãã®èšäºã§æ¢ã«èª¬æããã®ã§ãç¹°ãè¿ããŸããã
ã¯ãŒã¯ãããŒããã¹ããªã©
ãã¹ãŠã®äœæ¥ã¯JIRAã§è¡ãããŸãã åãã±ããã¯åå¥ã®ãã©ã³ãã§ãã TeamCityã¯ããã±ãããã©ã³ãããšã«ãã€ããªãåéããŸãã ã¢ã»ã³ããªã«ã¯ãGNU Makeã䜿çšããŸããããã¯ãçŽæ¥ã³ã³ãã€ã«ããããšã«å ããŠãproto-filesããversion.goãšgpbrpcã®ã³ãŒããçæããå¿
èŠããããããã€ãã®ã¿ã¹ã¯ãå®è¡ããããã§ãã
Go 1.5 Vendor Experimentã䜿çšããŠããã³ããŒãã£ã¬ã¯ããªã«äŸåã³ãŒããé
眮ã§ããŸãã ãããæ®å¿µãªãããä»ã®ãšããããã¹ãŠã®äŸåãã¡ã€ã«ããªããžããªã«è¿œå ããã ãã§ãããè¡ã£ãŠããŸãã 販売ã«ã¯äœããã®ãŠãŒãã£ãªãã£ã䜿çšããèšç»ããããŸãã Depã¯ææã«èŠããŸãããå®å®åãåŸ
ã€ã ãã§ãã
ãã±ãããã¬ãã¥ãŒã«åæ ŒãããšãQAããŒã ã®ã¡ã³ããŒããã±ãããåãåããŸãã ããŒã¢ã³ã®æ°æ©èœã®æ©èœãã¹ããäœæãããªã°ã¬ãã·ã§ã³ããã§ãã¯ããŸãã ãã¹ãã¯PHPã§èšè¿°ãããŠããŸããã»ãšãã©ã®å Žåãå®çšŒåç°å¢ã®ããŒã¢ã³ã®ã¯ã©ã€ã¢ã³ãã¯åœŒã§ããããã§ãã ãããã£ãŠããã¹ãã§äœããæ©èœããå Žåãå®çšŒåã§ãæ©èœããããšãä¿èšŒããŸãã
Goã®ãã¹ãã«é¢ããŠã¯ããªãã·ã§ã³ã§ãããå¿
èŠã«å¿ããŠèšè¿°ãããŠããŸãã ããããç§ãã¡ã¯ããã«åãçµãã§ãããGoã§ããã«ãã¹ããæžãäºå®ã§ãïŒè¿œèšãåç
§ïŒã
QAã«ãã£ãŠæ€èšŒããããªãªãŒã¹ã®æºåãã§ããŠãããã±ãããããTeamCityã¯ãã«ããã©ã³ããåéããŸãã èšç®ã®æºåãã§ããããéçºè
ã¯ç¹å¥ãªã€ã³ã¿ãŒãã§ã€ã¹ã«å
¥ããçµäºããŸãã åæã«ããã«ããã©ã³ãããã¹ã¿ãŒã«ããŒãžããã管çè
ã®JIRAãããžã§ã¯ãã«èšç®çšã®ãã±ãããäœæãããŸãã
鬌æ
ç§ãã¡ã®æ¡ä»¶ã§æ°ããããŒã¢ã³ãæžãã®ã¯ç°¡åã§ãããããã§ãããã€ãã®ãã³ãã¬ãŒãã¢ã¯ã·ã§ã³ãå¿
èŠã§ãïŒãã£ã¬ã¯ããªæ§é ãäœæããã¯ã©ã€ã¢ã³ããµãŒããŒãããã³ã«ã®ããããã¡ã€ã«ãäœæãããã®ããã®èšå®ãã¡ã€ã«ãšããããã¡ã€ã«ãäœæããgpbrpcã«åºã¥ããŠãµãŒããŒéå§ã³ãŒããæžãå¿
èŠããããŸãã ã æ¯åããã«ç
©ããããªãããã«ãå°ããªbashã¹ã¯ãªããããããã³ãã¬ãŒãããŒã¢ã³ã䜿çšããŠãªããžããªãäœæããŸãããããã«ããããã®ãã³ãã¬ãŒãçšã®æ°ããæ¬æ ŒçãªããŒã¢ã³ãäœæãããŸãã
ãããã«
ãã®çµæãæ°ããããŒã¢ã³ã§ã³ãŒãã1è¡ãèšè¿°ãããŠããªãå Žåã§ããã€ã³ãã©ã¹ãã©ã¯ãã£ã®æºåããã§ã«æŽã£ãŠããããšãããããŸããã
- åãæ¹æ³ã§æ§æå¯èœã
- çµ±èšãšãã°ãæžã蟌ã¿ãŸãã
- ä»ã®ããŒã¢ã³ïŒä»ã®èšèªã§æžããããã®ãå«ãïŒãšåãçç£çïŒprotobufïŒããã³èªã¿ãããïŒJSONïŒãããã³ã«ã䜿çšããŠéä¿¡ããŸãã
- çããç¶æããã³ç£èŠãããŸãã
ããã«ãããéçºè
ã®ãªãœãŒã¹ãç¡é§ã«ããããšãªããäºæž¬å¯èœã§ç°¡åã«ãµããŒãããããµãŒãã¹ãååŸã§ããŸãã
ããã ãã§ã Goã§ã©ã®ããã«æªéãæžããŸããïŒ ã³ã¡ã³ããžããããïŒ
PSãã®æ©äŒã«ç§ãã¡ã¯æèœãæ¢ããŠãããšèšããŸãã
Goã«ã¯ãã§ã«å€ãã®ããšãæžãããŠããŸããããã®åéãçºå±ããããã®ã§ããŸã æžãããŠããªããšããããããŸãã ãããŠãç§ãã¡ã¯ãããæäŒã£ãŠãããç¥çãªäººãæ¢ããŠããŸãã
Go-developerã§ãããC / C ++ãå°ãç¥ã£ãŠããå Žåã¯ãPMãŸãã¯ã¡ãŒã«ã§mkevacãæžããŠãã ãã ïŒm.kevac@corp.badoo.comïŒåœŒã®ããŒã ã®ååãèŠãŠãã ããïŒã