浅谈 OneAPM 在 express 项目中的实践

【编者按】OneAPM 运营团队,近日在 github 上发现了一篇文章,特别奉献给大家。本文作者王宇先生从2015年年初就开始使用我们的产品,也是OneAPM 的忠实用户。

OneAPM 是一个优秀的性能监控平台。为什么我们要使用性能监控呢? 并不是为了炫耀我有多么酷的玩具,仅仅因为我们希望在问题发生的第一时间就能知道。 在第一时间发现问题,把问题解决于无形之中,总比出了大麻烦通宵达旦加班舒服得多。

然而有的人喜欢说:「有些问题留着也不会有什么影响。」但我觉得服务端的事情, 凡是冒烟的地方,终究会着火的。

还有的人喜欢说:「我的代码绝对不可能有 bug 。」不过这只是吹牛逼。

废话不说了,直接上干货吧。

OneAPM 的监控服务主要分以下几块

  • Application Insight: 应用程序监控

  • Browser Insight: 浏览器客户端监控

  • Mobile Insight: 移动客户端监控

  • Infrastructure Insight: 服务器监控

使用 OneAPM 监控自己的项目,首先你需要去 OneAPM.com 注册一个开发者账号。

Application Insight 应用程序监控

登录平台以后根据自己项目的语言选择探针,我这里项目是用的 express,所以选择了 nodejs, 在 OneAPM 里面对怎么安装探针写得很详细,大概就是在项目的目录下运行

npm install OneAPM --registry http://npm.OneAPM.com

然后配置文件从 node_modules/OneAPM 里面拷出来,改一下 License Key ,就这么简单。

我们安装好探针以后,过几分钟让插件收集到数据,就能在面板里面看到各种图标。

首先需要关注的是 响应时间图表

response time

这个图表会对服务端耗时给一个大体印象,大家可以发现我们项目最慢的时候, 是发生在 8 月 18 号晚上左右,有请求大约 1.25s 才结束。紫色的占了绝大多数, 这些都是外部服务消耗的时间。

右上角的窗口叫做 apdex

apdex

这是一个评估用户满意度的指标,从这个指标可以看到用户是否满意我们的响应速度, 最右上角有 1[0.5] 可以看到我们 100% 的用户都满意我们的响应速度,小于 0.5 秒的请求, 我们称之为满意。我们这里是用的 OneAPM 的默认设置,小于 0.5 秒表示满意,0.5-2 秒是可容忍, 2秒以上则不满意。

cpm 图表

cpm

这个图表代表吞吐量

我们可以看到项目最高的时候,大概每分钟 80 次请求,平均每分钟 17.88 次请求。

web事务图表

web

这是一个很重要的图表,在这里我们能看到性能最差的几个 web 事务,我们通过 url, 能找到代码中对应的 controller 函数,从而找到这个接口中性能的瓶颈

我们来仔细看一个请求吧,第一条 express/POST/api/ex... (鼠标放上去可以显示全部的 url, 实际上这一条是这样的 Expressjs/POST/api/exams/signup-all)

我们可以点进去,查看接口的详细情况。

里面有一些仅对这个接口的吞吐量,执行时间等等的图表,具体含义和前面介绍的差不多 ,只不过考察的对象变成了唯一这一个接口。

我认为最重要的一个图表是 breakdown table

breakdown

这个图表反应了我们这个接口对外部应用(external),数据库( database )的调用情况。 从图表上可以发现,每次我们调用这个接口,我们会调用 37 次一个叫做 xxxxxtct.com 是 http 协议的 外部服务。执行的时间占到了 96.88%,另外查了 2 次数据库。分别占 0.49% 和 0.07%

看到这里,咱们就知道怎么优化啦~~拿我这个接口来说,这里的瓶颈主要是卡在发送 37 次 http 请求给 xxxxxtct.com 这个地方,这个 xxxxxtct.com 其实是我们自己的一个子系统,如果我在子系统里面写一个接口,把现在 37 个请求的内容合并,这个性能问题就完美的解决了。

另外 OneAPM 的 Application Insight 还给我们提供了,系统拓扑图,按 web 事务查找瓶颈的功能,按 sql 查找瓶颈的功能, 外部服务的具体执行时间(这个很重要,看谁在拖我们的后腿)以及后台服务的监控。

最后说一下错误率这个 table,这是我个人的经验

express 在抛出系统异常的时候,有可能会挂掉。下面举2个栗子

exports.show = function(req, res) {a.b //a == undefined
}

抛出异常

exports.show = function(req, res) {request.post({url: xxx-service.com}, function(err, response, body) {a.b //a == undefined})
} 

抛出异常,然后服务挂掉。

OneAPM 是被 express 程序启起来的,算是 express 进程的一个子进程,如果 express 挂掉了, OneAPM 也跟着挂了,所以,不可能有机会发回错误信息。 结论是只要在回调里面抛出的异常,任何探针都没有办法收集到错误, 因为在这一层无法做这件事情。

当然,我们虽然有 pm2 这样优秀的进程管理工具来帮我们,挂掉之后自动重启服务。。。 但我们需要在第一时间获得报错信息啊。。。。即使 pm2 的 errpr.log 里面会保留异常, 但谁又会没事专门盯着 error 这个日志看呢。

针对这个问题,我自己写了一段代码来收集错误日志,希望对大家有帮助。

var pm2 = require('pm2');
var Slack = require('slack-node');pm2.launchBus(function(err, bus) {console.log('connected');bus.on('log:err', function(data) {var webhookUri = "{你的slack webhook}";var slack = new Slack();slack.setWebhook(webhookUri);slack.webhook({channel: "#general",username: "cq-tct",icon_emoji: ":ghost:",text: data.data}, function(err, response) {console.log(response);});});});

把这一段保存为 err_notifier.js 放在项目根目录下,每次启完服务之后运行
node err_notifier.js 这样就能通过 slack 第一时间收到报错了。即使服务挂掉也能发过来。

这里用了另一个叫做 slack 的工具,slack 是一款即时通信的办公协作工具,相信大家或多或少都听说过 (就是创业半年估值 11 亿美元,一年变 28 亿那个家伙)。国外类似的还有 hipchat, 国内我不太清楚。

首先去 slack 申请一个 team, 然后创建一个 room,为 room 打开一个 webhook, 把 webhook 的地址赋值给 webhookUri, 这样我们无论在哪里,只要项目报错,就能第一时间 收到通过 slack 推送过来的错误日志。

当然,你可以把推送的工具改成,hipchat,邮件,短信,这个随大家高兴了。 关于 pm2 的 event monitor,还有更多事情可做,大家可以参考这里

https://github.com/xiaoyang2022/PM2/blob/dadf0f5806536ae95636ac929155c39b8bf030bb/doc/PROGRAMMATIC.md

最后

OneAPM 虽然可以帮大家在开发初期铺平道路,但也不意味着因为有了监控就可以胡作非为 (反正项目只要冒烟了,OneAPM 一目了然)。

我认为最靠谱的做法是: 严格遵守各种 style guide 来写代码 + 一个监控系统 + 100% 覆盖率的单元测试 + 几套集成测试 + 一套可靠的发布流程。

写在最后:OneAPM 非常感谢王宇先生对我们产品的支持,未来我们将更加努力,为用户提供更大的价值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544299.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【万字长文】Spring Cloud Alibaba 开箱即用!

互联网时代,面对复杂业务,讲究 分而治之。将一个大的单体系统拆分为若干个微服务,保证每个系统的职责单一,可以垂直深度扩展。但是一个个独立的微服务像一座座孤岛,如何将他们串联起来,才能发挥最大价值。这…

HDFS DataNode 设计实现解析

前文分析了 NameNode,本文进一步解析 DataNode 的设计和实现要点。 文件存储 DataNode 正如其名是负责存储文件数据的节点。HDFS 中文件的存储方式是将文件按块(block)切分,默认一个 block 64MB(该大小可配置&#xff…

芭比扣了!Nacos中服务删除不了,肿么办?

作者 | 磊哥来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone)前两天遇到了一个问题,Nacos 中的永久服务删除不了,折腾了一番,最后还是顺利解决了。以下…

Spring Cloud OpenFeign夺命连环9问,这谁受得了?

1、前言前面介绍了Spring Cloud 中的灵魂摆渡者Nacos,和它的前辈们相比不仅仅功能强大,而且部署非常简单。今天介绍一款服务调用的组件:OpenFeign,同样是一款超越先辈(Ribbon、Feign)的狠角色。文章目录如下…

玩转Nacos参数配置!多图勿点

作者 | 磊哥来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone)Nacos 中的参数有很多,如:命名空间、分组名、服务名、保护阈值、服务路由类型、临时实例等&#xff…

为什么wait/notify必须要和synchronized一起使用?

作者 | 磊哥来源 | Java面试真题解析(ID:aimianshi666)转载请联系授权(微信ID:GG_Stone)在多线程编程中,wait 方法是让当前线程进入休眠状态,直到另一个线程调用了 notify 或 notify…

Magento Add Fee or Discount to Order Totals

2019独角兽企业重金招聘Python工程师标准>>> In this tutorial, we will see how to add new line item to magento order totals. What this means is that, how to add an additional Fee or Discount, or any kind of charge to order total of the magento chec…

再见 Feign!推荐一款微服务间调用神器,跟 SpringCloud 绝配!

在微服务项目中,如果我们想实现服务间调用,一般会选择Feign。之前介绍过一款HTTP客户端工具Retrofit,配合SpringBoot非常好用!其实Retrofit不仅支持普通的HTTP调用,还能支持微服务间的调用,负载均衡和熔断限…

Spring Cloud Alibaba Nacos 的 2 种健康检查机制!

作者 | 磊哥来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone)Spring Cloud Alibaba Nacos 作为注册中心不止提供了服务注册和服务发现功能,它还提供了服务可用性监测的机制。…

Python之包管理工具

在Python环境中已经有很多成熟的包,可以通过安装这些包来扩展我们的程序。 例如,很多时候Python开发人员都会去PyPI网站去查找自己想要使用的包,然后进行安装。PyPI ( Python Package Index)是获得第三方 Python 软件包…

为什么wait和notify必须放在synchronized中?

作者 | 磊哥来源 | Java面试真题解析(ID:aimianshi666)转载请联系授权(微信ID:GG_Stone)在多线程编程中,wait 方法是让当前线程进入休眠状态,直到另一个线程调用了 notify 或 notify…

聊聊并发编程的10个坑

前言对于从事后端开发的同学来说,并发编程肯定再熟悉不过了。说实话,在java中并发编程是一大难点,至少我是这么认为的。不光理解起来比较费劲,使用起来更容易踩坑。不信,让继续往下面看。今天重点跟大家一起聊聊并发编…

macbook终端使用记(二)终端快捷键

为什么80%的码农都做不了架构师?>>> Command K清屏 Command T新建标签 Command M最小化窗口 Command W 关闭当前标签页 Command S 保存终端输出 Command D 垂直分隔当前标签页 Command Shift D 水平分隔当前标签页 Command shift {或}向左/向…

颜值爆表!Redis 官方可视化工具来啦,功能真心强大!

最近逛了一下Redis官方网站,发现Redis不仅推出了很多新特性,而且还发布了一款可视化工具RedisInsight。试用了一下感觉非常不错,最关键的是能支持RedisJSON之类的新特性,这是第三方工具无法比拟的。今天带大家体验一下RedisInsigh…

20个响应式网页设计中的“神话”误区

关于响应式网页的重要性我们已经证实了很长时间了,现在是该把焦点放到如何做出好的响应式网页设计的时候了。一起来看看吧! 虽然很多人都在谈论响应式网页,但并不是每个人都知道他们在说什么。很多时候你看到网上的一些信息也在挑战你对响应式…

MySQL 索引失效的 15 种场景!

背景 无论你是技术大佬,还是刚入行的小白,时不时都会踩到Mysql数据库不走索引的坑。常见的现象就是:明明在字段上添加了索引,但却并未生效。前些天就遇到一个稍微特殊的场景,同一条SQL语句,在某些参数下生效…

Java夺命21连问!(附答案)

大家好,我是磊哥。有位朋友工作三年,去面试,给大家整理一下面试题,并附上答案。Mysql索引在什么情况下会失效MySql的存储引擎InnoDB与MyISAM的区别Mysql在项目中的优化场景,慢查询解决等Mysql有什么索引,索…

SpringCloud Nacos + Ribbon 调用服务的 2 种方法!

作者 | 磊哥来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone)在 Nacos 中,服务调用主要是通过 RestTemplate Ribbon 实现的,RestTemplate 是 Spring 提供的 Rest…

SpringCloud Ribbon中的7种负载均衡策略!

作者 | 磊哥来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone)负载均衡通器常有两种实现手段,一种是服务端负载均衡器,另一种是客户端负载均衡器,而我们…

线程池是如何执行的?拒绝策略有哪些?

作者 | 磊哥来源 | Java面试真题解析(ID:aimianshi666)转载请联系授权(微信ID:GG_Stone)聊到线程池就一定会聊到线程池的执行流程,也就是当有一个任务进入线程池之后,线程池是如何执…