系统运维


Erlang通用模板接入文档

<p>[TOC]</p> <p>Tips: 公网consul注册地址:124.222.148.13:8500 公网pushgateway注册地址:124.222.148.13:9091 内网consul注册地址:192.168.1.96:8500 内网pushgateway注册地址:192.168.1.96:9091</p> <h1>一、背景</h1> <p>为了更好的对各项目组游戏进行服务监控,运维方目前已配合部分工作室负责人一同做出对erlang服务监控两种方案。目前都已测试完毕并且正在稳定运行,在监控中,通过对游戏平台以及服务端序列号进行筛选,可以很清楚的看见游戏erlang服务各节点状态、不仅限于内存使用信息、节点基础信息、系统基础信息等监控数据。因此,想把这两套监控方案分享到所有项目组进行参考使用,二选其一即可。</p> <h1>二、方案一</h1> <h2>【2.1】整体架构图</h2> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=51c52cda24c43861600086b5cc8849cd&amp;amp;file=file.png" alt="" /></p> <p><strong>流程简介:</strong></p> <ul> <li>游戏节点内启动<code>prom_mgr</code>进程,只负责定时进⾏数据采集并上报到gateway服务(类似⽇志上报)。promethes⾃动定时向gateway中间件拉取数据,拉取间隔1m。</li> <li>在注册服务时只需要pushgateway对注册方开放9091端口,注册方不需要暴露游戏服的端口。</li> </ul> <h2>【2.2】代码清单</h2> <ul> <li><code>prom_render.erl</code> :改造⾃开源第三⽅库https://github.com/deadtrickster/prometheus.erl,抽 离数据格式化的关键接⼝,⽐源库更轻量。 </li> <li><code>prom_mgr.erl</code>:定时进⾏指标收集及指标上报,收集的指标依赖于 Collector 模块的指标定义。 </li> <li><code>prom_vm.erl</code>:数据收集器,⽬前实现了节点内部分数据收集,可增加对指定进程的监控(cpu、 内存、队列)。 </li> <li><code>prom.hrl</code>:头⽂件。 <img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=2ab20824590620c62d5fa4d776eb0a8d&amp;amp;file=file.png" alt="" /></li> </ul> <p><strong>注:</strong>可通过“普罗米修斯指标说明.xlsx”查看所有指标名称、标签以及对应描述。</p> <h2>【2.3】接入步骤</h2> <ul> <li><strong>编译代码</strong>:记得关注<code>common.hrl</code>头⽂件,涉及到 <code>?ERR、?DEBUG、?INFO</code> </li> <li><strong>设置开服时启动</strong>:以诗悦旧框架举例,在<code>services.erl</code>模块,将<code>prom_mgr</code>设置启动,并<strong>优先于</strong>其他进程启动。优先启动的原因是我们可能需要对某些进程进⾏监控,此时需要<code>prom_mgr</code>已经启动完毕。</li> </ul> <pre><code>%% 例⼦1:arena_mgr.erl 某个需要被监控的进程,该进程有注册名 init([]) -&amp;gt; ?INFO(&amp;quot;[~w] 正在启动...&amp;quot;, [?MODULE]), process_flag(trap_exit, true), prom_mgr:register_vm_process(self()), ?INFO(&amp;quot;[~w] 启动完成&amp;quot;, [?MODULE]), {ok, #state{}}. %% 例⼦2:role.erl 某个需要被监控的进程,该进程有注册名。但因为有⼤量类似进程,增 加“组”概念⽅便批量注销。 init([]) -&amp;gt; ?INFO(&amp;quot;正在启动...&amp;quot;), process_flag(trap_exit, true), ?INFO(&amp;quot;启动完成&amp;quot;), prom_mgr:register_vm_process(self(), #{group =&amp;gt; role}), {ok, #state{}}. %% 例⼦3:battle.erl 某个需要被监控的进程,该进程没有注册名,在grafana界⾯看起来 信息不明显,所以增加⼀个desc。 init([]) -&amp;gt; ?INFO(&amp;quot;正在启动...&amp;quot;), process_flag(trap_exit, true), ?INFO(&amp;quot;启动完成&amp;quot;), Desc = bitstring:concat([Battle#battle.id]), prom_mgr:register_vm_process(self(), #{group =&amp;gt; battle, desc =&amp;gt; Desc}), {ok, #state{}}.</code></pre> <h2>【2.4】修改头文件</h2> <pre><code>%% TODO 需要配置的信息列表 %% 最终上报URL = ?gateway_url ++ &amp;quot;/job/&amp;quot; ++ ?job_name ++ &amp;quot;/instance/&amp;quot; ++ ?prom_p ++ ?prom_z %% gateway的地址 -ifdef(debug). -define(gateway_url, &amp;quot;http://soar.prom/gateway/metrics&amp;quot;). -else. -define(gateway_url, &amp;quot;http://soar.prom/gateway/metrics&amp;quot;). -endif. %% 项⽬标识 对应url -define(job_name, &amp;quot;soar&amp;quot;). %% 获取到区服名称的⽅法 -define(prom_p, env:get(platform)). %% 获取到区号的⽅法 -define(prom_z, env:get(zone_id)). %% 开启区服列表 -define(open_list, [{&amp;lt;&amp;lt;&amp;quot;dev&amp;quot;&amp;gt;&amp;gt;, 1}]). %% 推送定时时间(根据项⽬实际情况修改) -define(push_default_interval, 30 * 1000). %% 已注册的采集器 如果加了⾃定义指标模块 需要注册到这⾥ -define(registry_collector, [ prom_vm ]).</code></pre> <h1>三、方案二:Prometheus监控系统SDK</h1> <h2>【3.1】整体架构图</h2> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=ff6b4daf80e74ff334aff6042b2d18cf&amp;amp;file=file.png" alt="" /></p> <p><strong>本SDK集成Prometheus Exporter和Consul的Erlang SDK </strong></p> <ul> <li><strong>Prometheus Exporter</strong>:Prometheus定义的概念,提供一个HTTP服务端口,返回OpenMetrics标准的格 式化指标。 </li> <li><strong>Consul</strong>:consul是一个“服务发现”服务,Prometheus原生支持的组件。</li> </ul> <h2>【3.2】接入</h2> <ul> <li><strong>文件清单</strong></li> </ul> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=2a1eea5ff57350b8e43b1c75f314b7a0&amp;amp;file=file.png" alt="" /></p> <ul> <li><code>include/</code> 头文件 </li> <li><code>src/</code> 源码相关 <ul> <li><code>prometheus/ prometheus.erl</code>库,实现Prometheus的数据模型,附带几个Erlang VM的数 据采集器,<code>sy_game_expoter</code>的可视化表盘大部分数据都基于这些采集器。 </li> <li><code>prometheus_httpd/ prometheus-httpd</code>库,提供了http格式化相关库,并可以使用httpd 启动Expoter。 </li> <li><code>metrics/ Prometheus Exporter SDK</code>。本SDK使用了Erlang的httpd和cowboy两种方式实现 HTTP服务,默认以httpd方式启动,可通过修改sy_game_exporter模块的宏USE_COWBOY使 用cowboy。 </li> <li><code>service_discovery/</code> 服务发现SDK。</li> </ul></li> </ul> <h2>【3.3】配置</h2> <ul> <li>在<code>sy_game_exporter.hrl</code>头文件中需要修改<code>EXPORTER_GAME_NAME_CH</code>,<code>EXPORTER_GAME_NAME_EN</code>两个 宏,用于在服务发现中区分不同项目,建议修改为使用Erlang应用配置的方式配置。 </li> <li>在Erlang应用配置中,需要添加以下的prometheus配置使<code>sy_game_collector</code>采集器生效,添加<code>consul</code>配置指向服务地址</li> </ul> <pre><code>[ %% 原来的配置 {server_game, [...]}, %% 服务发现地址 {consul_cfg, [ {consul_host,&amp;quot;124.222.148.13&amp;quot;}, {consul_port, &amp;quot;8500&amp;quot;} ]}, %% 需要添加的配置 {prometheus, [ %% 采集器配置 {collectors, [ %% 项目定制 sy_game_collector, %% 自带,可关闭 prometheus_boolean, prometheus_counter, prometheus_gauge, prometheus_histogram, prometheus_mnesia_collector, prometheus_quantile_summary, prometheus_summary, %% 以下自带的采集器,提供了大部分通用可视化表盘的数据,所以开启 prometheus_vm_dist_collector, prometheus_vm_memory_collector, prometheus_vm_msacc_collector, prometheus_vm_statistics_collector, prometheus_vm_system_info_collector ]} ]} ]. </code></pre> <h2>【3.4】风险</h2> <ul> <li> <p>目前在以上述配置方式全开采集器的情况下长时间运行测试,服务端平稳运行,单次采集时间约30毫秒。 </p> </li> <li> <p>模拟遭受攻击的情况下,以高TPS请求端口,请求会不断堆积,导致最终节点OOM瘫痪。据此可酌情加入缓存、读写分离等策略规避风险。<strong>本SDK在HTTP请求处使用ets加了个10秒缓存,但是ets:lookup和 ets:insert是两个操作不是原子操作,极端情况下还是会有风险。如需规避极端情况建议用单进程写, http请求仅读取ets的方式。</strong></p> </li> <li>在自定义采集器的时候,注意不要加入性能消耗较大的逻辑,否则当单次请求耗时过高,在下次请求到来还未能处理完的的时候,就会陷入同上述一样OOM瘫痪的情况。</li> </ul> <h2>【3.5】自定义采集</h2> <ul> <li> <p>参照<code>sy_game_collector.erl</code>和<code>sy_game_metrics.erl</code>,自行开发采集器,并添加到Erlang应用配置中。 </p> </li> <li>参照附带的prometheus文档,设计grafana表盘,导出模板给运维组。</li> </ul> <h1>四、Prometheus入门文档参考</h1>

页面列表

ITEM_HTML