转载

[Erlang_Question33]使用recon从网页查看Erlang运行状态

It's not who you are underneath, it's what you do that defines you

[Erlang_Question33]使用recon从网页查看Erlang运行状态

学贵有恒

不要输给这个世界的常识; 不能把这个世界,让给你所鄙视的人.

  • 博客园
  • 闪存
  • 首页
  • 新随笔
  • 联系
  • 管理
  • 订阅 [Erlang_Question33]使用recon从网页查看Erlang运行状态

随笔- 45  文章- 1  评论- 60 

[Erlang_Question33]使用recon从网页查看Erlang运行状态

0.需求分析

Erlang最好的卖点之一就是提供了一个非常强大的shell来查看Node运行时的各种状态,可以进行各种各样的内部查看,在运行时调试和分析,热更新代码。

但是总有一些在生产环境下要慎用的状态查看函数。比如:

1.在进程数达到10w级以上的Node调用erlang:processes()来得到所有的进程Pid.然后算长度blabla...; 2. 当某个进程的信箱被堵塞了上万个消息队列时调用erlang:process_info(Pid,messages)来查看所有的消息。

为了避免在shell中进行这些危险的操作,就有了recon这个项目。它保证在生产环境下可以调用安全。

项目地址github: recon ,     文档可见: fred

与 Erlang in anger 食用更佳。

然而在体会到一段时间的recon的强大之后,突然感觉为了查看状态每次检查时都要 在shell中输入相同的命令集是一件非常枯燥的事情 ,于是就想要一个可以直接用网页直接查看状态的工具。并且加上图表显示。让分析问题变得更加快速,易懂。

recon_web是一个可以通过web 查看Eralng节点各种状态的工具。

它与observer的区别:

recon_web observer
web页面查看,不需求wx GUI 需要Erlang安装wx GUI application
保证可以在生产环境中被安全调用 如果对于ets非常多或进程达到一定数量时会崩溃掉,不适合大多数在Node已出状况时使用

1. 项目介绍

项目地址github: recon_web .

Demo地址: Demo

使用的框架:

cowboy 1.0.1 websocket 用于server通信
recon 用于查看Node状态
jsx 用于json转换
lager 日志记录
socket.io.client web端的websocket维护
highcharts web端绘制图表

上手也非常简单,make&&make shell然后打开127.0.0.1:8080就可以看到效果啦,还不快来试试~。其它命令详见Readme。

2.recon_web 实现

[Erlang_Question33]使用recon从网页查看Erlang运行状态

说明:

2.1.为什么要分成system_info 和recon_info?

system_info是指Node中基本不会变化的那些指标:

[Erlang_Question33]使用recon从网页查看Erlang运行状态

因为他们基本不会变化,所以只会在连接建立时传一次就行了。

recon_info是用recon得到的Memory, Scheduler, Port的情况,它们会一直变化,所以在每个Heartbeat都会更新一次给Client.

2.2. 如果大量的(比如1000个)连接上来查看。每个连接的心跳都会去用recon得到新的Node信息,会不会造成CPU在这上面消耗过多?

这就是recon_server的职责,它是一个独立的gen_server,存着上次使用recon计算出的Node信息和计算时间:

{ReconInfo, LastUpdateTime}.每个连接上来的点都会向recon_server请求ReconInfo,如果Now - LastUpdateTime >

规则的时间就会重新计算一份ReconInfo存起来。所以大量的连接在同时请求ReconInfo,recon_server也只会计算一次。

2.3.为什么不直接使用handler 同步call recon_server得到recon_info,然后回传给Client?

现在实现是:

2.3.1 handler 同步call session_gen_server ;

2.3.2 session_gen_server再异步info recon_server;

2.3.3 recon_server再异步info recon_info 给session_gen_server,

2.3.4 session_gen_server得到recon_info后异步info handler有新的消息在我这,你快来取;

2.3.5 handller得知3.4后,再同步call session_gen_server拿到recon_info,然后encode 通过websocket发给Client.

这种方式就是多了session_gen_server这个中间缓冲层。

好处是:可以把要传给client的多条消息都缓冲在这里,然后一次性发给Client。

当然对于现在只有recon_info这一种消息来说,没有什么优势。可是考虑到扩展性(那些不需要及时发给Client的消息),加个缓冲层明显是好得多。 

3. recon_web中各种图表说明 

1> recon_web_status:get_recon_info(node_stats_list). [{process_summary,[{process_count,86},  {run_queue,0},  {error_logger_queue_len,0},  {memory_total,20032952},  {memory_procs,6067544},  {memory_atoms,330312},  {memory_bin,467040},  {memory_ets,465936}]},  {mem_summary,[{bytes_in,0},                {bytes_out,0},                {gc_count,2},                {gc_words_reclaimed,256},                {reductions,130454},                {scheduler_usage,[{1,0.9252873563218391},                {2,0.147239263803681},                {3,0.13218390804597702},                {4,0.14285714285714285}]}]}] 

3.1. 根据 error_logger_queue_len process_count run_queue绘制以下表:

[Erlang_Question33]使用recon从网页查看Erlang运行状态

3.2. 根据上面的memory_total,memory_procs,memory_atoms,memory_bin,memory_ets绘制:

[Erlang_Question33]使用recon从网页查看Erlang运行状态

3.3.根据scheduler_usage绘制:

[Erlang_Question33]使用recon从网页查看Erlang运行状态

3.4根据bytes_in,bytes_out绘制:

[Erlang_Question33]使用recon从网页查看Erlang运行状态

2> recon_web_status:get_recon_info(proc_count). [{proc_count,[{memory,[{<<"application_controller">>,602096},            {<<"0.26.0">>,372368},            {<<"recon_server">>,372328},            {<<"code_server">>,284656},            {<<"kernel_sup">>,197384},            {<<"0.159.0">>,88632},            {<<"erl_prim_loader">>,88552},            {<<"error_logger">>,75904},            {<<"init">>,67896},            {<<"0.45.0">>,55064}]},   {bin_memory,[{<<"kernel_sup">>,396661},    {<<"erl_prim_loader">>,27958},    {<<"0.26.0">>,7408},    {<<"0.159.0">>,5527},    {<<"0.45.0">>,1264},    {<<"application_controller">>,947},    {<<"user">>,852},    {<<"recon_server">>,454},    {<<"lager_event">>,278},    {<<"cowboy_clock">>,203}]},   {reductions,[{<<"recon_server">>,43125661},    {<<"erl_prim_loader">>,1328265},    {<<"0.159.0">>,243664},    {<<"code_server">>,196114},    {<<"application_controller">>,56899},    {<<"timer_server">>,53145},    {<<"kernel_sup">>,48774},    {<<"cowboy_clock">>,30740},    {<<"file_server_2">>,24547},    {<<"init">>,17949}]},   {total_heap_size,[{<<"application_controller">>,75112},         {<<"recon_server">>,46421},         {<<"0.26.0">>,46421},         {<<"code_server">>,35462},         {<<"kernel_sup">>,24503},         {<<"0.159.0">>,10958},         {<<"erl_prim_loader">>,10957},         {<<"error_logger">>,9358},         {<<"init">>,8370},         {<<"0.45.0">>,6771}]}]}] 

3.5根据上面的memory, bin_memory,reductions, total_heap_size绘制:

[Erlang_Question33]使用recon从网页查看Erlang运行状态

3> recon_web_status:get_recon_info(port). [{port_summary,[{<<"efile">>,5},                 {<<"tcp_inet">>,2},                 {<<"2/2">>,1},                 {<<"tty_sl -c -e">>,1}]}]

3.6.根据 port_summary绘制:

[Erlang_Question33]使用recon从网页查看Erlang运行状态

4> recon_web_status:get_recon_info(inet_count). [{inet_count,[{sent_oct,[]},               {recv_oct,[{<<"Port0.4012">>,1205},{<<"Port0.3695">>,0}]},               {sent_cnt,[]},               {recv_cnt,[{<<"Port0.4012">>,72},{<<"Port0.3695">>,0}]}]}]

3.7.根据sent_oct, recv_oct, sent_cnt, recv_cnt绘制:

[Erlang_Question33]使用recon从网页查看Erlang运行状态

5>recon_web_status:get_recon_info(alloc_memory). [{used,20804344},  {allocated,32247216},  {unused,11269856},  {allocated_types,[{binary_alloc,2786160},   {driver_alloc,164720},   {eheap_alloc,6763376},   {ets_alloc,1475440},   {fix_alloc,426864},   {ll_alloc,19923784},   {sl_alloc,164720},   {std_alloc,934768},   {temp_alloc,655960}]},  {allocated_instances,[{0,9094640},       {1,6305264},       {2,1246704},       {3,15664624},       {4,984560}]}] 

3.8根据alloc_memory绘制:

[Erlang_Question33]使用recon从网页查看Erlang运行状态

6> recon_web_status:get_recon_info(cache_hit_rates). [{cache_hit_rates,[{<<"instance1">>,[602,1113]},                    {<<"instance3">>,[148,213]},                    {<<"instance0">>,"OV"},                    {<<"instance2">>,[7,13]},                    {<<"instance4">>,[0,0]}]}]

3.9根据cache_hit_rates绘制:

[Erlang_Question33]使用recon从网页查看Erlang运行状态

4.参考文档

cowboy 建立websocket: http://ninenines.eu/docs/en/cowboy/HEAD/guide/ws_handlers/

highcharts: http://www.highcharts.com/

posted @ 2015-08-09 16:15 学贵有恒 阅读( ... ) 评论( ... )编辑 收藏

刷新评论刷新页面返回顶部

博客园首页 博问 新闻 闪存 程序员招聘 知识库

Copyright ©2015 学贵有恒

Brick walls are there for a reason :they let us prove how badly we want things

正文到此结束
Loading...