【Python】简单Web框架从零开始(一):Web服务

简介: 一、前言 使用Python可以很方便的搭建一个网站,有很多现成的Web框架可以使用例如:Django,Tornado,web.py,web2py,Flask,Bottle等等。我几年前使用Tornado框架为项目做过一个多人协作的管理平台,后来为了想深入学习就自己写了一个简单的Web框架,并在新项目中投入使用已有1年左右,虽然没有上面提到的那些框架那么强大,但也勉强够用。这次刚好有时间做一个简单的记录。

【Python】简单Web框架从零开始(一):Web服务


一、前言


   使用Python可以很方便的搭建一个网站,有很多现成的Web框架可以使用例如:DjangoTornadoweb.pyweb2pyFlaskBottle等等。我几年前使用Tornado框架为项目做过一个多人协作的管理平台,后来为了想深入学习就自己写了一个简单的Web框架,并在新项目中投入使用已有1年左右,虽然没有上面提到的那些框架那么强大,但也勉强够用。这次刚好有时间做一个简单的记录。


二、简单Web服务


   下图展示了我这次要写的Web框架简单示意图,包含有哪些模块,以及它们的调用层级,模板渲染模块会在后面有空的时候再贴进来。


微信截图_20220424002021.png


    浏览器向Web服务器发送请求,这个请求使用TCP协议发送到服务器,因此服务器也需要使用TCP协议才能收到请求,创建一个简单的TCP服务器就像下面代码展示的那样。


tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server.bind(("0.0.0.0", 80))
tcp_server.listen(5)
while True:
    client, addr = tcp_server.accept()
    print(u"...接收到连接:", addr)
    while True:
        data = client.recv(1024)
        if not data:
             break
        client.send('hello')
    client.close()
tcp_server.close()


  打开浏览器输入http://127.0.0.1就会看到hello信息。当然作为Web服务器处理请求需要有一定的效率,上面的代码如果同时有多个请求时,只能逐个进行响应,如果采用I/O多路复用以及引入线程池的话,效果会更好一点。下面的代码引入了采用I/O多路复用的select模块,以及将接收数据投递到线程池中进行处理。这样做可以较好的提升Web服务器的处理性能。


class SimpleHttpServer:
    def __init__(self, host, port=80):
        self.http_host = host
        self.http_port = port
        self.http_running = False
        self.http_pool = thread_pool.ThreadExecutor(4)
        self.sock_selector = selectors.DefaultSelector()
        self.http_sock = socket.socket()
    def _setup_server(self):
        self.http_sock.bind((self.http_host, self.http_port))
        self.http_sock.listen(5)
        self.http_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)
        ex_data = {"address":(self.http_host, self.http_port), "callback":self._on_new_connected}
        self.sock_selector.register(self.http_sock, selectors.EVENT_READ, ex_data)
        return True        
    def _start_forever(self):
        while self.http_running:
            try:
                events = self.sock_selector.select()
                for obj, mask in events:
                    callback = obj.data["callback"]
                    self.sock_selector.unregister(obj.sock)
                    self.http_pool.submit(callback, obj.sock, obj.data)
            except KeyboardInterrupt as e:
                self.http_running = False
    def _on_new_connected(self, sock, data):
        client, address = sock.accept()
        ex_data = {"address":address, "callback":self._on_client_request}
        self.sock_selector.register(client, selectors.EVENT_READ, ex_data)
        self.sock_selector.register(sock, selectors.EVENT_READ, data)
    def _on_client_request(self, sock, data):
        raw = sock.recv(4096)
        sock.sendall("hello")
        sock.close()
    def start_server(self):
        if not self._setup_server():
            return False
        self.http_running = True
        self._start_forever()
        return True


   我用JMeter创建500用户进行并发测试,Throughput大概可以到400/秒,我使用的还是我的10年前的I3双核笔记本进行测试的,开太多用户反而是JMeter太耗了


微信截图_20220424002133.png


三、后记


   我的开发环境是Python 2.7 64位,如果使用Python3的可以直接使用自带的selectorsThreadExecutor模块,另外这次大概会分两到三期写完。最后我会把代码上传到GitHub上面,如果有兴趣欢迎留信息交流。


欢迎微信搜索"游戏测试开发"关注一起沟通交流。

相关文章
|
16天前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
60 6
|
16天前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
103 45
|
10天前
|
Java 测试技术 持续交付
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
本文重点讲解如何搭建App自动化测试框架的思路,而非完整源码。主要内容包括实现目的、框架设计、环境依赖和框架的主要组成部分。适用于初学者,旨在帮助其快速掌握App自动化测试的基本技能。文中详细介绍了从需求分析到技术栈选择,再到具体模块的封装与实现,包括登录、截图、日志、测试报告和邮件服务等。同时提供了运行效果的展示,便于理解和实践。
46 4
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
|
4天前
|
关系型数据库 数据库 数据安全/隐私保护
Python Web开发
Python Web开发
19 6
|
7天前
|
Go UED
Go Web服务中如何优雅平滑重启?
在生产环境中,服务升级时如何确保不中断当前请求并应用新代码是一个挑战。本文介绍了如何使用 Go 语言的 `endless` 包实现服务的优雅重启,确保在不停止服务的情况下完成无缝升级。通过示例代码和测试步骤,详细展示了 `endless` 包的工作原理和实际应用。
24 3
|
8天前
|
JSON Go UED
Go Web服务中如何优雅关机?
在构建 Web 服务时,优雅关机是一个关键的技术点,它确保服务关闭时所有正在处理的请求都能顺利完成。本文通过一个简单的 Go 语言示例,展示了如何使用 Gin 框架实现优雅关机。通过捕获系统信号和使用 `http.Server` 的 `Shutdown` 方法,我们可以在服务关闭前等待所有请求处理完毕,从而提升用户体验,避免数据丢失或不一致。
14 1
|
9天前
|
开发框架 前端开发 JavaScript
利用Python和Flask构建轻量级Web应用的实战指南
利用Python和Flask构建轻量级Web应用的实战指南
31 2
|
11天前
|
机器学习/深度学习 自然语言处理 API
如何使用阿里云的语音合成服务(TTS)将文本转换为语音?本文详细介绍了从注册账号、获取密钥到编写Python代码调用TTS服务的全过程
如何使用阿里云的语音合成服务(TTS)将文本转换为语音?本文详细介绍了从注册账号、获取密钥到编写Python代码调用TTS服务的全过程。通过简单的代码示例,展示如何将文本转换为自然流畅的语音,适用于有声阅读、智能客服等场景。
55 3
|
12天前
|
SQL 安全 PHP
探索PHP的现代演进:从Web开发到框架创新
PHP是一种流行的服务器端脚本语言,自诞生以来在Web开发领域占据重要地位。从简单的网页脚本到支持面向对象编程的现代语言,PHP经历了多次重大更新。本文探讨PHP的现代演进历程,重点介绍其在Web开发中的应用及框架创新,如Laravel、Symfony等。这些框架不仅简化了开发流程,还提高了开发效率和安全性。
20 3
|
11天前
|
前端开发 JavaScript 开发工具
从框架到现代Web开发实践
从框架到现代Web开发实践
22 1