基于Python的Web容器开发

引言

在这里先聊一聊Python的优劣性,优势就是代码简单,但是劣势也很明显,那就是1核忙到死,其它核看热闹,所以各取所需吧。

容器

加载机制

包文件动态加载插件

plugins_path = os.listdir(os.path.join(root_path, "plugins"))
    for item in plugins_path:
        if not item.endswith('.py'):
            continue
        try:
            pyname = item.replace(".py", "")
            module = importlib.import_module(f'plugins.{pyname}').Entry()
            desc = module.bootstrap()
            interface = desc["webkit"].keys() if 'webkit' in desc else {}
            for key in interface:
                pv.set_var('interface.webkit', f'/{pyname}/{key}', module)
                logger.debug("服务注册成功 [g] " + pyname + "/" + key)
            interface = desc["webkit_cj"].keys() if 'webkit_cj' in desc else {}
            for key in interface:
                pv.set_var('interface.webkit_cj', f'/{pyname}/{key}', module)
                logger.debug("服务注册成功 [p] " + pyname + "/" + key)
            if 'autorun' in desc and desc.get('autorun'):
                threading.Thread(target=(lambda: module.start())).start()
        except Exception as e:
            import traceback
            logger.error(f"插件注册失败{item} 详情{e}")
2023-06-06 15:20:40:798077 [DEBUG] Python.FileServer.server --> 服务注册成功 [g] base_web/get_current_user
2023-06-06 15:20:40:799077 [DEBUG] Python.FileServer.server --> 服务注册成功 [p] base_web/login
2023-06-06 15:20:40:800077 [DEBUG] Python.FileServer.server --> 服务注册成功 [p] base_web/logoff
2023-06-06 15:20:40:803077 [DEBUG] Python.FileServer.server --> 服务注册成功 [g] file_server/download
2023-06-06 15:20:40:804231 [DEBUG] Python.FileServer.server --> 服务注册成功 [p] file_server/mkdir
2023-06-06 15:20:40:804231 [DEBUG] Python.FileServer.server --> 服务注册成功 [p] file_server/list_dir
2023-06-06 15:20:40:805077 [DEBUG] Python.FileServer.server --> 服务注册成功 [p] file_server/upload
2023-06-06 15:20:40:805077 [DEBUG] Python.FileServer.server --> 服务注册成功 [p] file_server/file_bind
2023-06-06 15:20:40:806077 [DEBUG] Python.FileServer.server --> 服务注册成功 [p] file_server/get_file
2023-06-06 15:20:40:815294 [DEBUG] Python.FileServer.server --> 服务注册成功 [g] module_manager/get_modules_info
2023-06-06 15:20:40:815294 [DEBUG] Python.FileServer.server --> 服务注册成功 [g] module_manager/get_base_info

能力

  • 处理静态页面
  • 响应GET请求
  • 响应POST请求
  • 识别GET、POST请求参数
  • Session机制
  • 模块化程序

安全机制

根据cookie中的session查找本地变量中是否存在这个人,每个请求均经过这个地方,如果调试模式,不进行登录校验。

if cfg.get_config("debug"): return True
        cookies = self.get_cookies()
        sessions = pv.get_obj("session")
        if 'bn-session' not in cookies.keys(): return False
        if (cookies['bn-session'] in sessions.keys() and
                sessions[cookies['bn-session']]['deadline'] > datetime.datetime.now().timestamp() and
                sessions[cookies['bn-session']]['client_ip'] == self.client_address[0]):  # 没有过期 并且还是这个IP
            sessions[cookies['bn-session']]['deadline'] = (
                    datetime.timedelta(minutes=30) + datetime.datetime.now()).timestamp()  # 更新session过期时间
            return True
        else:
            return False

没登陆的用户,只能跳转到登录页,如果登陆了,访问登录页,就跳转到首页。

def security_audit(self):
        file_path = os.path.join(root_path, static_path, self.path[1:])  # 先当作静态资源处理
        redirect = ""
        if self.path.endswith("/"):  # 默认页面
            file_path = os.path.join(root_path, static_path, self.path[1:], "index.html")  # 路径下默认页面
        if self.check_login():
            if self.path == '/login.html':
                file_path = os.path.join(root_path, static_path, "redirection.html")
                redirect = "index.html"
        else:
            if self.path != '/login.html':
                if not self.path.endswith(".js"):
                    file_path = os.path.join(root_path, static_path, "redirection.html")
                    redirect = "login.html"
        return file_path, redirect

接口类

import datetime
from utils import configure
from utils import public_variable
from utils import logger
from utils import algorithm
from utils import dbUtils


class Entry:
    __base_web = None  # 固定写法

    def __new__(cls, *args, **kwargs):
        if cls.__base_web is None:  # 变量名要求和文件名一致 以基础web服务为例
            cls.__base_web = object.__new__(cls)  # 变量名要求和文件名一致 以基础web服务为例
            cls.logger = logger.Logger() # 日志对象
            cls.configure = configure.Config() # 系统配置对象
            cls.pv = public_variable.PublicVariable() # 内置变量对象
            cls.db = dbUtils.DBUtils() # 数据库对象
        return cls.__base_web

    def bootstrap(self):
        app = {
            "name": "web控制台基础服务框架",  # 接口整体大类名称
            "description": "提供系统管理的基础服务",  # 接口提供服务的描述
            "version": "1.0",  # 接口版本
            "webkit": {  # GET请求
                "get_current_user": {  # 接口路径
                    "desc": "获取当前登录用户",  # 接口描述
                    "return": "json"  # 接口返回值
                }
            },
            "webkit_cj": {  # post请求
                "login": {  # 接口路径
                    "desc": "系统登录",  # 接口描述
                    "return": "json"  # 接口返回值
                },
                "logoff": {  # 接口路径
                    "desc": "退出登录",  # 接口描述
                    "return": "json"  # 接口返回值
                }
            },
        }
        return app
    def login(self, request, args): # request 为 请求对象, args是参数对象
            if(args['username'] == "123" and args['password'] =="123":
        return {"code": 0, "msg": "鉴权成功"}
        else:
                return {"code": -1, "msg": "鉴权失败"}

    def logoff(self, request, args):
        cookies = request.get_cookies()
        sessionid = cookies["bn-session"]
        sessions = self.pv.get_obj("session")
        if sessionid in sessions.keys():
            del sessions[sessionid]
            result = {"code": 0, "msg": "退出登录"}
        else:
            result = {"code": 1, "msg": "登陆状态异常"}
        return result

压力测试

# 非登陆情况访问首页
>ab -n 1000 -c 100 http://127.0.0.1:5555/index.html

This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        ZunMX_Simple_Server/1.0.0
Server Hostname:        127.0.0.1
Server Port:            5555

Document Path:          /index.html
Document Length:        721 bytes

Concurrency Level:      100
Time taken for tests:   66.679 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      904000 bytes
HTML transferred:       721000 bytes
Requests per second:    15.00 [#/sec] (mean)
Time per request:       6667.895 [ms] (mean)
Time per request:       66.679 [ms] (mean, across all concurrent requests)
Transfer rate:          13.24 [Kbytes/sec] received

Connection Times (ms)
min  mean[+/-sd] median   max
Connect:        0   67 171.4      0     516
Processing:     2 6277 1157.0   6614    7143
Waiting:        2 3438 1890.0   3555    7133
Total:          2 6344 1157.3   6616    7143

Percentage of the requests served within a certain time (ms)
50%   6616
66%   6623
75%   6628
80%   6632
90%   7128
95%   7135
98%   7140
99%   7141
100%   7143 (longest request)


# 携带登录用户的cookie
>ab -n 1000 -c 100  -C bn-session=a72dcb9c6583054655b6806d82e62b75 http://127.0.0.1:5555/index.html
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        ZunMX_Simple_Server/1.0.0
Server Hostname:        127.0.0.1
Server Port:            5555

Document Path:          /index.html
Document Length:        3964 bytes

Concurrency Level:      100
Time taken for tests:   65.941 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      4147000 bytes
HTML transferred:       3964000 bytes
Requests per second:    15.17 [#/sec] (mean)
Time per request:       6594.105 [ms] (mean)
Time per request:       65.941 [ms] (mean, across all concurrent requests)
Transfer rate:          61.42 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   66 170.3      0     516
Processing:     3 6229 1158.4   6584    7112
Waiting:        2 3369 1857.5   3059    6604
Total:          3 6294 1160.2   6591    7117

Percentage of the requests served within a certain time (ms)
  50%   6591
  66%   6602
  75%   6607
  80%   6615
  90%   7090
  95%   7105
  98%   7109
  99%   7111
 100%   7117 (longest request)

# 调用GET接口(获取模块信息)
>ab -n 1000 -c 100  -C bn-session=a72dcb9c6583054655b6806d82e62b75 http://127.0.0.1:5555/module_manager/get_base_info
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        ZunMX_Simple_Server/1.0.0
Server Hostname:        127.0.0.1
Server Port:            5555

Document Path:          /module_manager/get_base_info
Document Length:        155 bytes

Concurrency Level:      100
Time taken for tests:   69.239 seconds
Complete requests:      1000
Failed requests:        415
   (Connect: 0, Receive: 0, Length: 415, Exceptions: 0)
Total transferred:      568210 bytes
HTML transferred:       389890 bytes
Requests per second:    14.44 [#/sec] (mean)
Time per request:       6923.855 [ms] (mean)
Time per request:       69.239 [ms] (mean, across all concurrent requests)
Transfer rate:          8.01 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   69 174.2      0     516
Processing:     2 6533 1245.3   7107    7656
Waiting:        2 3541 1963.7   3558    7145
Total:          3 6602 1249.7   7108    7656

Percentage of the requests served within a certain time (ms)
  50%   7108
  66%   7118
  75%   7134
  80%   7137
  90%   7614
  95%   7631
  98%   7646
  99%   7650
 100%   7656 (longest request)


# 调用POST接口(登录)
>ab -n 1000 -c 100  -T application/json -p post.json -H "Content-Type: application/json" -H "Cache-Control: no-cache" -C bn-session=a72dcb9c6583054655b6806d82e62b75 http://127.0.0.1:5555/base_web/login
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        ZunMX_Simple_Server/1.0.0
Server Hostname:        127.0.0.1
Server Port:            5555

Document Path:          /base_web/login
Document Length:        84 bytes

Concurrency Level:      100
Time taken for tests:   68.341 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      259000 bytes
Total body sent:        331000
HTML transferred:       84000 bytes
Requests per second:    14.63 [#/sec] (mean)
Time per request:       6834.061 [ms] (mean)
Time per request:       68.341 [ms] (mean, across all concurrent requests)
Transfer rate:          3.70 [Kbytes/sec] received
                        4.73 kb/s sent
                        8.43 kb/s total

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   68 173.3      0     515
Processing:    14 6430 1236.8   6628    7648
Waiting:       13 3458 1952.9   3556    7117
Total:         14 6498 1238.3   6633    7648

Percentage of the requests served within a certain time (ms)
  50%   6633
  66%   7126
  75%   7134
  80%   7138
  90%   7151
  95%   7157
  98%   7625
  99%   7638
 100%   7648 (longest request)

评价

下面的是IIS的web容器,差距差的不是一点半点。

>ab -n 1000 -c 100  http://127.0.0.1:89/reg.html
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        Microsoft-IIS/10.0
Server Hostname:        127.0.0.1
Server Port:            89

Document Path:          /reg.html
Document Length:        4362 bytes

Concurrency Level:      100
Time taken for tests:   0.135 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      4674000 bytes
HTML transferred:       4362000 bytes
Requests per second:    7392.24 [#/sec] (mean)
Time per request:       13.528 [ms] (mean)
Time per request:       0.135 [ms] (mean, across all concurrent requests)
Transfer rate:          33741.53 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       1
Processing:     2   12   1.9     13      14
Waiting:        0    7   3.4      7      14
Total:          2   13   1.9     13      14

Percentage of the requests served within a certain time (ms)
  50%     13
  66%     13
  75%     13
  80%     13
  90%     14
  95%     14
  98%     14
  99%     14
 100%     14 (longest request)

截图

登录接口错误情况

主页

接口文档

评论 0

还没有评论,来说点什么吧。

提交后需要审核才会公开。