| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> tornado服务某个实例核吃满问题 -> 正文阅读 |
|
[网络协议]tornado服务某个实例核吃满问题 |
tornado底层epoll陷入死循环,cpu100% 该进程所有fd详情信息:其中fd对应信息如下所示
堆栈一直在循环打印下面的信息(10,35,36,37,15,39,11,38) 疑惑点
fd:10,35,31用lsof查出来的数据:
--------------------------------------------------------------------------------------------------------------------------------- 新进展: 进程号:41 strace堆栈信息:循环打印下面的信息,显示一直循环调用。这这个socket都是客户端的连接,并且已经发送完数据 netstat:查看这几个socket,tcp状态信息(显示接受队列有数据,但是不读取) 通过strace命令分析tornado底层机制 1.web:tornado,service:one thread(单实例) 服务启动的状态 socket信息: r-x------ 1 zxj zxj 64 2月 26 16:01 0 -> pipe:[13412432] l-wx------ 1 zxj zxj 64 2月 26 16:01 1 -> pipe:[13412433] l-wx------ 1 zxj zxj 64 2月 26 16:01 2 -> pipe:[13412434] lrwx------ 1 zxj zxj 64 2月 26 16:01 3 -> socket:[13403746] lrwx------ 1 zxj zxj 64 2月 26 16:01 4 -> anon_inode:[eventpoll] lrwx------ 1 zxj zxj 64 2月 26 16:02 5 -> socket:[13403747] lrwx------ 1 zxj zxj 64 2月 26 16:01 6 -> socket:[13403748] 0,1,2:标准的输入输出和错误流 3:监听socket 4.epoll句柄(epoll_create返回的句柄fd) 5,6:不清楚是干什么用的 netstat 状态 netstat -p | grep 7246 Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name unix 3 [ ] 流 已连接 13403748 7246/python3.8 unix 3 [ ] 流 已连接 13403747 7246/python3.8 lsof: lsof -p 7246 ython3.8 7246 zxj 0r FIFO 0,12 0t0 13412432 pipe python3.8 7246 zxj 1w FIFO 0,12 0t0 13412433 pipe python3.8 7246 zxj 2w FIFO 0,12 0t0 13412434 pipe python3.8 7246 zxj 3u IPv4 13403746 0t0 TCP localhost:http-alt (LISTEN) python3.8 7246 zxj 4u a_inode 0,13 0 10692 [eventpoll] python3.8 7246 zxj 5u unix 0xffff9cad2e347800 0t0 13403747 type=STREAM python3.8 7246 zxj 6u unix 0xffff9cad2e340c00 0t0 13403748 type=STREAM epfd里面目前只注册了listen socket的读事件 sreace: strace: Process 7246 attached epoll_wait(4, 没有任何读写事件发生,阻塞 (1)正常连接和关闭 strace: 监听到客户端连接,创建一个socket:fd=7 和客户端通信,请求完成后,并没有关闭socket:fd=7,应该是会复用 epoll_wait(4, [{EPOLLIN, {u32=3, u64=19828060119367683}}], 2, -1) = 1 accept4(3, {sa_family=AF_INET, sin_port=htons(41198), sin_addr=inet_addr("127.0.0.1")}, [16], SOCK_CLOEXEC) = 7 getsockname(7, {sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0 ioctl(7, FIONBIO, [1]) = 0 accept4(3, 0x7ffc93b1caa0, 0x7ffc93b1ca8c, SOCK_CLOEXEC) = -1 EAGAIN (Resource temporarily unavailable) epoll_wait(4, [], 2, 0) = 0 recvfrom(7, "GET /test2 HTTP/1.1\r\nUser-Agent:"..., 65536, 0, NULL, NULL) = 231 mmap(NULL, 262144, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7eff5208d000 epoll_ctl(4, EPOLL_CTL_ADD, 7, {EPOLLIN, {u32=7, u64=19828060119367687}}) = 0 epoll_wait(4, [], 3, 0) = 0 sendto(7, "HTTP/1.1 200 OK\r\nServer: Tornado"..., 199, 0, NULL, 0) = 199 setsockopt(7, SOL_TCP, TCP_NODELAY, [1], 4) = 0 setsockopt(7, SOL_TCP, TCP_NODELAY, [0], 4) = 0 epoll_wait(4, [], 3, 0) = 0 epoll_wait(4, [], 3, 0) = 0 recvfrom(7, 0x25f52c0, 65536, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable) epoll_wait(4, (2)客户端非正常关闭 网络状态: tcp 1 0 localhost:http-alt localhost:41198 CLOSE_WAIT 7246/python3.8 unix 3 [ ] 流 已连接 13403748 7246/python3.8 unix 3 [ ] 流 已连接 13403747 7246/python3.8 python3.8 7246 zxj 7u IPv4 13454501 0t0 TCP localhost:http-alt->localhost:41198 (CLOSE_WAIT) strace:发现客户端socket异常后关闭socket,并重红黑树里面删去 epoll_wait(4, [{EPOLLIN, {u32=7, u64=19828060119367687}}], 3, 3600000) = 1 recvfrom(7, "GET /test1 HTTP/1.1\r\nContent-Typ"..., 65536, 0, NULL, NULL) = 515 epoll_ctl(4, EPOLL_CTL_DEL, 7, 0x7ffc93b1c650) = 0 epoll_wait(4, [], 2, 0) = 0 epoll_wait(4, [], 2, 0) = 0 epoll_ctl(4, EPOLL_CTL_ADD, 7, {EPOLLIN, {u32=7, u64=19828060119367687}}) = 0 epoll_wait(4, [], 3, 0) = 0 select(0, NULL, NULL, NULL, {35, 0}) = 0 (Timeout) write(1, "xxxxx", 5) = 5 write(1, "\n", 1) = 1 sendto(7, "HTTP/1.1 200 OK\r\nServer: Tornado"..., 199, 0, NULL, 0) = 199 setsockopt(7, SOL_TCP, TCP_NODELAY, [1], 4) = 0 setsockopt(7, SOL_TCP, TCP_NODELAY, [0], 4) = 0 epoll_wait(4, [{EPOLLIN|EPOLLERR|EPOLLHUP, {u32=7, u64=19828060119367687}}], 3, 0) = 1 recvfrom(7, "", 65536, 0, NULL, NULL) = 0 epoll_ctl(4, EPOLL_CTL_DEL, 7, 0x7ffc93b1bfb0) = 0 close(7) = 0 epoll_wait(4, [], 2, 0) = 0 epoll_wait(4, [], 2, 0) = 0 epoll_wait(4, 2.tornado+gevent (1):使用,monkey.patch()替换阻塞的系统调用 发现:一个实例的场景下,time.Sleep(),不会阻塞,这个时候两个请求打过来,服务端陷入 while true: ? ?epoll_wait()的循环调用里面,cpu吃到100%,但是不理解的是,为啥无法处理listen socket的连接请求 cpu:100% (2)gevent 使用gevent.spawn(),内部使用阻塞的系统调用 两个请求打过来,能正常处理listen socket的连接请求 (3)gevent 内部死循环 因为GIL锁,实例CPU陷入cpu循环调用,cpu100%,而且无法进入到epoll的IO_loop里面 综上所述:猜测上述形成的原因是使用了monkey.patch,但是没有使用gevent.spawn,调用阻塞系统调用导致的 下一个需要澄清的问题:进入io_loop,并且监听socket fd里面有可读事件,但是没法处理 |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 7:34:49- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |