nodejs问题是怎么样排查的
nodejs问题是怎么样排查的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
成都创新互联公司专注于庐阳网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供庐阳营销型网站建设,庐阳网站制作、庐阳网页设计、庐阳网站官网定制、小程序开发服务,打造庐阳网络公司原创品牌,更为您提供庐阳网站排名全网营销落地服务。
相信大家都遇到过Error: read ECONNRESET这个错误。虽然通过ECONNRESET错误码我们很容易查到这个错误意味着什么,但是通过源码和分析工具进行一次彻底的分析,会让你更加了解这个错误的产生和原理。更让人神清气爽。
下面分为两个部分,首先通过nodejs源码分析这个错误产生的原因,然后通过网络工具抓包的方式捕获这个错误。
1 源码分析
我们从建立一个tcp连接成功后,nodejs执行的操作开始分析(net.js)。
这是连接成功后执行的nodejs回调。回调里执行了新建一个socket表示和客户端通信的对象。我们看new Socket做了什么事情。
new Socket的主要逻辑有
1 保存和客户端通信的handle(socket)
2 注册读回调
3 注册读事件
我们先看第三点
socket是可读可写的流,read(0)直接调用可读流的函数,可读流提供了抽象的逻辑,具体的读取操作由子类实现(实现_read函数,可读取的read会调用_read函数)。我们看一下Socket类_read函数的实现。
直接调用handle的readStart函数。因为我们这里使用的是tcp服务。所以handle对应的实现在tcp_wrap.cc里。但是我们发现tcp_wrap.cc没有readStart函数。一路往父类找,最终在stream_wrap.cc找到了该函数。
该函数直接调用libuv的uv_read_start函数,三个入参分别是
1 uv_tcp_t结构体
2 分配内存保存读取的数据
3 读取后执行的回调(包括读取失败)
继续往下走。
这时候nodejs就在底层注册了一个可读事件,等到有数据或者发送出错的时候,会触发上层回调(虽然只注册了可读事件,但是如果有错误发生,epoll会返回POLLIN和POLLERR事件)。这时候客户端发送了一个rst。这时候会执行libuv的回调uv__stream_io(而不是nodejs传进来那个,那个read_cb,read_cb是由libuv回调的)
接着我们看uv_read
重点在read函数,我们不妨多看点代码,看一下rst和read在linux下的实现。
上面是操作系统收到一个rst包时的操作。设置对应socket的错误信息为ECONNRESET,并设置状态为close。如果这时候用户执行read会怎样呢?
read函数会直接把错误信息返回给调用方。我们回到libuv中,当libuv调用read函数的时候,返回了错误码ECONNRESET。然后libuv执行nodejs的read_cb回调。如果我们还记得的话,nodejs提供的回调是OnUvRead。
nodejs套了很多层,不过我们还是找到了他,最后的MakeCallback(env->onread_string(), arraysize(argv), argv)就是执行js层的onread函数。这个函数我们一开始的时候也提到了。回到net.js。
nodejs的onread函数执行了destroy函数。这里就不具体展开,destroy做的事情就是调用_destroy函数。然后emit一个error事件,并传入一个Error对象(包含了错误码和系统调用函数等信息)。触发error事件的时候,我们就输出了read ECONNRESET。至此,整个源码分析过程结束。
2 抓包分析
登录服务器,使用tcpdump工具,主要是过滤出想要的数据包。这里找出有问题的那几个ip。过滤条件设置为
tcpdump -i any -q -A -nn src ip1 or dst ip1 or src ip2 or dst ip2 -w tcp.cap
保存为cap文件,然后下载到wireshark分析(linux下分析会比较麻烦点)。最后发现同一个时间点,抓包和日志系统都输出了相关的错误。
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。
名称栏目:nodejs问题是怎么样排查的
标题URL:http://ybzwz.com/article/jpgsei.html