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


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

相关推荐
nie_xl1 分钟前
VS/TRAE中设置本地maven地址的方法
运维·服务器·前端
LV技术派8 分钟前
适合很多公司和团队的 AI Coding 落地范式(三)
前端·ai编程·cursor
CheungChunChiu10 分钟前
# Xorg 配置与 modesetting 驱动详解:从设备节点到显示旋转
android·linux·ubuntu·显示·xserver
一只小bit10 分钟前
Qt 对话框全方面详解,包含示例与解析
前端·c++·qt·cpp·页面
m0_7482546610 分钟前
Angular 2 模板语法概述
前端·javascript·angular.js
专注VB编程开发20年11 分钟前
EDGE估计没有switch到frame的做法
前端·edge·vba
_oP_i18 分钟前
Chrome浏览器自动下载的AI模型文件
前端·chrome
小小前端--可笑可笑19 分钟前
【Three.js + MediaPipe】视频粒子特效:实时运动检测与人物分割技术详解
开发语言·前端·javascript·音视频·粒子特效
奔跑的web.20 分钟前
JavaScript 对象属性遍历Object.entries Object.keys:6 种常用方法详解与对比
开发语言·前端·javascript·vue.js
OEC小胖胖25 分钟前
09|DOM Renderer 的 Host 层:从 Fiber 到真实 DOM 的落地
前端·前端框架·react·开源库