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.
使用的框架:
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 实现

说明:
2.1.为什么要分成system_info 和recon_info?
  system_info是指Node中基本不会变化的那些指标:
  

  因为他们基本不会变化,所以只会在连接建立时传一次就行了。
  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绘制以下表:

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

3. 3.根据scheduler_usage绘制:

3.4 根据bytes_in,bytes_out绘制:

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绘制:

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绘制:

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绘制:

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绘制:

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绘制:

4. 参考文档

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

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

---------------------------------------------------------------------------------------------------------------------

inside the beam scheduler

[Erlang33]使用recon从网页查看Erlang运行状态的更多相关文章

  1. 查看cics 运行状态

     查看cics 运行状态cicscp -v status all 

  2. 利用 SQL Monitor 查看语句运行状态步骤

    利用 SQL Monitor 查看语句运行状态步骤 1.确定语句被 SQL Monitor 监控 SQL> SELECT * FROM GV$SQL_MONITOR WHERE sql_id=' ...

  3. linux下查看Memcached运行状态

    查看Memcached运行状态的命令是:echo stats | nc 127.0.0.1 11211 查看memcached状态的基本命令,通过这个命令可以看到如下信息: STAT pid 2245 ...

  4. 查看crontab运行状态

    cron服务是linux的内置服务,但它不会开机自动启动.可以用以下命令启动和停止服务: /sbin/service crond start/sbin/service crond stop/sbin/ ...

  5. 在dos下查看memcache运行状态

    在dos命令行下查看memcache运行状态,操作很简单,只需cmd下输入:telnet IP 端口号->stats  ,如果本机器不支持telnet还需安装,可以百度telnet的安装方法. ...

  6. mongostat查看mongodb运行状态使用命令介绍

    mongostat是mongodb自带的一个用来查看mongodb运行状态的工具 使用说明 mongostat -h   字段说明 启用后的状况是这样的 insert query update del ...

  7. docker基础——自定义镜像、创建私有仓库、查看 docker 运行状态

    一.自定义镜像 1,案例1 要求:请自定义一个 docker 镜像,基于 hub.c.163.com/library/centos,要求创建出来的镜像在生成容器的时候,可以直接使用 ifconfig ...

  8. LINUX命令行如何查看memcache运行状态

    (附加)如何查看memcache服务器端版本:  ./memcached  -h memcache的运行状态可以方便的用 stats 命令显示. 首先用telnet 127.0.0.1 11211这样 ...

  9. 用web查看hadoop运行状态

    转载--http://www.weixuehao.com/archives/621 我们安装完hadoop,下面我们从视觉上看看hadoop怎么玩的. 我们可以在win7系统上,通过web界面,在浏览 ...

随机推荐

  1. Thinkphp 联表查询 表名要全名

    我有2个表 表1. 表2 已知表2的user_id 查询满足 表2.wb_id=表1.id 表1的内容 最佳答案 i 2013年11月15日 $result = M()->table(array ...

  2. 四.jQuery源码解析之jQuery.fn.init()的参数解析

    从return new jQuery.fn.init( selector, context, rootjQuery )中可以看出 参数selector和context是来自我们在调用jQuery方法时 ...

  3. 通过日志查看Web Api详细运行过程

    1. 通过Nuget安装System.Web.Http.Tracing. 2. 通过HttpConfiguration,注册SystemDiagnosticsTraceWriter public st ...

  4. SPM——How to use github

    In this semester, we take a class called 'Software Project Management'. And in this class, we have l ...

  5. BeanUtils.copyProperties不能copy复杂对象List的解决方式

    需要注意的就是把List拆分,遍历add,然后把list设置到返回对象中 package test.test; import java.util.ArrayList; import java.util ...

  6. MonoBehaviour.OnValidate

    [MonoBehaviour.OnValidate] This function is called when the script is loaded or a value is changed i ...

  7. BaseAnimation是基于开源的APP,致力于收集各种动画效果(最新版本1.3) (转)

    声明:部分动画来源于网络,本人只是想方便收集在一起,如果不妥请及时与我联系!谢谢 为了统一BaseAnimationApp签名,一定要方便以后大家自动更新...防止签名冲突,不能及时更新 1.3源码下 ...

  8. innodb count优化测试

    对于索引优化真的是门课题,先来研究下最平常的问题,innodb引擎下 怎么让count(*)快一点. 首先需要清楚 innodb 默认是对主键建立聚簇索引,如果没有主键,那就是对具有唯一且非空值的索引 ...

  9. mybatis开发Dao的Mapper动态代理方式

    1. 开发规范Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体跟Dao原始方法中接口实现类的方法相 ...

  10. Photoshop中的高斯模糊、高反差保留和Halcon中的rft频域分析研究

    在Halcon的rft变换中,我们经常可以看到这样的算子组合: rft_generic (Image, ImageFFT2, 'to_freq', 'none', 'complex', Width) ...