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 单/多线程分析(三)

相关推荐
我太想进步了C~~1 小时前
Prompt Design(提示词工程)入门级了解
前端·人工智能·算法
crary,记忆1 小时前
如何理解 React的UI渲染
前端·react.js·ui·前端框架
苏打水com1 小时前
Day1-3 夯实基础:HTML 语义化 + CSS 布局实战(对标职场 “页面结构搭建” 核心需求)
前端·css·html·js
zengshitang5201 小时前
ACRN 实战应用:在一台电脑上同时安装Windows10、Ubuntu22.04、Ubuntu PREEMPT_RT实时系统并流畅运行
linux·运维·ubuntu
m0_740043731 小时前
mapState —— Vuex 语法糖
java·前端·javascript·vue.js
哟哟耶耶1 小时前
WebPage-postcss-px-to-viewport前端适配
前端·javascript·postcss
7澄11 小时前
Java Web 底层解析:Servlet 执行流程、Tomcat 工作原理与自定义 Tomcat 实现
java·前端·servlet·tomcat·自定义tomcat·tomcat执行流程·servlet执行流程
水星灭绝1 小时前
win11下desktop-docker安装gitlab-ce
docker·容器·gitlab
拾忆,想起1 小时前
Dubbo延迟加载全解:从延迟暴露到延迟连接的深度优化
前端·微服务·架构·dubbo·safari