Python写web服务器,听起来像是个老生常谈的话题。但你真去翻开源码,会发现事情没那么玄乎。HTTP协议说白了就是文本往来,你监听一个端口,收到"GET / HTTP/1.1"这样的字符串,回一段HTML,浏览器就给你渲染页面了。就这么简单。
我试过用标准库里的http.server模块搭个最简单的服务。二十行代码不到,能跑。但那个东西性能惨不忍睹,并发请求一来就卡死。后来我改用WSGI,再后来直接上Flask,框架帮你把路由、请求解析、响应封装全干了。可框架用久了,人容易变傻——你忘了底层其实就是一个socket在循环读数据。
真正让我开窍的是自己手写一遍。用socket模块监听8080端口,accept一个连接,recv接收字节流,解析出请求行和headers,然后根据路径返回不同内容。那感觉跟拆玩具一样,零件都在你手里,怎么拼自己说了算。我写了个返回当前时间的小服务,浏览器一刷新,时间就变。那一刻你会突然明白,所谓的web服务,本质就是"监听-接收-处理-响应"的死循环。
性能问题躲不开。Python的GIL锁让多线程成了摆设,但对付小流量绰绰有余。我拿ab工具压过,单进程每秒能扛两百来个请求,够个人博客用了。你要是贪心,可以上异步。asyncio配合aiohttp,或者干脆用uvicorn跑FastAPI,性能能翻好几倍。不过说实话,真到那个量级,你早该换Go或者Rust了,没必要在Python这棵树上吊死。
有个细节特别有意思——HTTP/1.1默认开启keep-alive,意味着连接不会马上断开。你得在响应头里加Content-Length,否则客户端不知道消息到哪结束。很多人栽在这上面,返回内容乱码或者页面一直转圈。我调试时吃过这亏,最后用curl -v看原始响应才发现少了这个头。这种坑,文档里写得明明白白,但不亲手踩一遍,你根本记不住。
写服务器最上头的时刻,是看到自己的程序在局域网里被手机访问。电脑开着服务,手机连同一个WiFi,输入电脑的IP加端口,页面刷出来了。那种感觉挺奇妙——你写的代码正在另一块屏幕上工作。虽然Flask一个命令就能搞定同样的事,但亲手从socket开始搭起来的东西,哪怕再简陋,也带着一股手作的温度。
最后说点实用的。你要是想练手,别一上来就抄别人的代码。先写个能返回"Hello World"的socket服务,再慢慢加功能:解析查询参数、处理POST请求、支持静态文件。每一步都会踩坑,但踩坑才是学习最快的方式。网上教程一大堆,可真正动手敲一遍,比看十遍都管用。Python的生态决定了它不适合搞高并发,但做个工具、搭个内网服务、给硬件设备当个控制台,绰绰有余。