50、【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 单/多线程分析(二)

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

上篇 blog
【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 单/多线程分析(一)

分析了 Python http.server 模块默认启用的是多线程模型,并对单线程启动做了测试,下面继续

Python http.server 单/多线程分析

首先是之前 blog 提到,启动了 slow_server.py 之后,在终端输入

bash 复制代码
time curl http://localhost:2027/a

去查询该 Web 服务的响应时间如下

可以看到需要 10s 的时间 Web 服务才能响应,这和 SlowHandler 里面定义的 10s 休眠时间是一样的

这里的一个小技巧是,访问 \a 这样一个不存在的页面,只返回一个 404 错误码,不然 curl 返回的内容可就太多了

然后再接着做一个测试,在输入 time curl http://localhost:2027/a 的同时,在另一个终端再输入 time curl http://localhost:2027/b,模拟并发访问的情况

可以看到,访问 \a 页面的等待时间依旧是 10s(因为是先点开访问的)

而后点开访问 \b 页面的等待时间则来到了 18s(不是 10s)

这就足以说明,\a 页面访问的处理,阻塞了 \b 页面访问的处理,这就是上篇 blog 里提到的 HTTPServer 继承了 TCPServer 默认的单线程同步处理能力

再来看下,如果是多线程启动,修改 slow_handler.py 如下

python 复制代码
#!/usr/bin/env python3

from http.server import ThreadingHTTPServer, SimpleHTTPRequestHandler
import time

class SlowHandler(SimpleHTTPRequestHandler):
    def do_GET(self):
        print(f"Handling {self.path} ... (will sleep 10s)")
        time.sleep(10)  # 模拟耗时操作
        """Serve a GET request."""
        f = self.send_head()
        if f:
            try:
                self.copyfile(f, self.wfile)
            finally:
                f.close()

server = ThreadingHTTPServer(('localhost', 2028), SlowHandler)
server.serve_forever()

其实就是把 HTTPServer 给换成 ThreadingHTTPServer,然后端口换一下

其他地方不变,再次运行 slow_handler.py,然后在两个终端分别输入 time curl http://localhost:2028/a 和 time curl http://localhost:2028/b 同时访问两个页面

可以看到,访问 \a 页面的时间是 10s(先访问)

而访问 \b 页面的时间也同样是 10s(后访问)

可以看到,在多线程下,出现并发操作同时访问,两者的时间基本一致,因为访问 \b 页面时会新开一个线程进行处理,而不用等待 \a 页面访问结束

OK,再说一个有意思的点,上篇 blog 里提到,当前的 Python 版本为 v3.12.3,此时默认的是启动多线程 Web 访问,http.server 作为 Python 里的标准库模块,其源码在 CPython 仓库中

GitHub 地址:https://github.com/python/cpython/blob/main/Lib/http/server.py

国内访问 GitHub 比较慢,可以参考下 Gitee 的同步镜像仓库(Gitee 官方维护,自动同步 GitHub 仓库的镜像,更新及时,可信度高 )

Gitee 地址:https://gitee.com/mirrors/cpython/

点击标签

找到 v3.6.15 版本(21年9月),这是 v3.6 的最后一个版本

可以看到这个时候,http.server 模块默认启动的,还是单线程 Web 服务

而到了 v3.7.0 版本时(v3.7 的第一个版本)

http.server 模块被改成了默认多线程启动

所以 python -m http.server 在 Python < v3.7 时无法并发处理请求,只有等一个请求处理完,才能轮到下一个,所以只要有一个请求慢(比如大文件下载、time.sleep),整个服务器对外表现就是卡住了,用户体验不好,所以这里 Python 3.7 是一个分水岭,官方为了提升开发体验,把命令行服务器升级为多线程


OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 单/多线程分析(三)

相关推荐
java1234_小锋4 小时前
【技术专题】HTML5 网页技术 - HTML5 Canvas 基础以及动画入门
前端·html·html5
知了学历孙老师7 小时前
小自考的校考和统考,出题方和难度差在哪
java·大数据·前端
ShineWinsu9 小时前
对于JavaScript:操作元素的解析
开发语言·前端·javascript·面试·web·dom·元素
福兮说10 小时前
JSON 格式正确,数据就可靠吗?我用一份自编配置检查类型与空值
java·前端·json
JANGHIGH10 小时前
基于ADE20K数据集的SETR模型训练
ubuntu
丰色木夕11 小时前
Ubuntu22.04下源码编译安装USD-Brep
c++·ubuntu·nvidia·usd-brep
程序员老赵12 小时前
Docker 部署青龙面板:轻松搭建定时任务管理平台
前端·docker·开源
Swot12 小时前
Asciidoctor 公式数字下标错位问题:原因分析与解决方案
前端
Swot12 小时前
leo-editor 中将 Markdown 内容转成 asciidoc 格式
前端
狒狒AI12 小时前
Remotion / GSAP+Three / HyperFrames / Skia 四栈实测:代码渲染知识视频的选栈方法(附开源技能)
前端·人工智能·aigc