python 数据库性能提升 - TCP聊天+传输文件服务器服务器套接字v2.7
TCP聊天+传输文件服务器服务器套接字v2.7
刚创建服务器的时候为了后期便于管理, 主要也是MySQL对我不适合, 跨平台使用, 一打包还有得装, 所以直接自己做了个
这是我写的服务器的数据库代码, 可见一看就能看出来, 数据库只存在于单个文件data.json中, I/O十分频繁, 用户信息文件存于运行内存中, 在小数据的情况下速度快, 但到数据存于一定程度, 性能断崖式下跌, 且 在taskmgr(任务管理器)
中内存一举超过了 1.78G的pycharm, 成为第一.
提升性能的方法:
变量使用
set
– 可变,无序的,不重复的元素集合 (不可出现
list
,set
,bytearray
等无__hash__(self)哈希值的类)– set 的 时间复杂度为 O1, list 的 时间复杂度为 On.
– set内部存储元素必是可hash的,而且还是不可重复的.
当每一个set中的元素都有一个独立hash的编码,虽然外面看元素是乱序的,但是内部其实是hash编码的排序,当运行时是通过编码查询,所以会如此之快(warning:是有可能出现hash冲突,但是极少)避免单文件频繁调用I/O
用户建立文件夹, 一个文件夹对应一个用户的md5值(sha256的都行), 这是为了创建文件夹时候避免非法字符的出现.
类似于文件传输服务器, 传来的文件最好解压, 分割切片
只将用户名存于运行内存中, 节省空间, 一般数据库也不会大于几TB, 把密码, 注册时间这些杂七杂八的东西放在文件夹下面
行了, 后面的直接不用看了, 按左上角的退出键退出吧
这是data.py代码(全部data.py 在gitcode - https://gitcode.net/m0_60394896/python/-/blob/05267ff4f3c2267954dc87e505d034229eaa0f98/server/data.py)
from json import load, dump
from os import path, mkdir
from hashlib import md5
from time import timedef encode(data: str):m = md5()m.update(data.encode('utf8'))return m.hexdigest()file = '.\clients\data.json'
folder = '.\clients'
if not path.exists(folder):mkdir(folder)class data:def __init__(self):if path.exists(file):with open(file, 'r') as f:self.data = load(f)else:self.data = {}def __get__(self, username, default=None) -> tuple:return self.data.get(username, default)def __in__(self, username) -> bool:return username in self.data.keys()def __write__(self) -> None:with open(file, 'w') as f:dump(self.data, f, indent=4)def __register__(self, username, password, time: (int, float) = time()) -> None:...self.__write__()def __login__(self, username, password) -> bool:return self.data[username][0] == encode(password)def get_time(self, username):return self.data[username][1]def handler(self, type: int, username: str, password: str):...
文章目录
- 测试
- 提升性能
所有版本记录:
v1.0
: TCP聊天服务器套接字|PyQt5+socket(TCP端口映射+端口放行)+logging+Thread(含日志,html)+anaconda打包32位exe(3.4万字)|python高阶
v1.1
: python TCP套接字服务器v1.1-新增服务端命令功能及修改bug(socket+PyQt5)
v1.2
: python TCP服务器v1.2 - 服务端新增用户登录注册(json, md5加密)
v1.3
: python TCP服务器v1.3 - 服务器抗压测试及关闭套接字处理
v1.4
: python TCP服务器v1.4 - 客户端连接服务器异常(异常情况分类)处理
v1.5
: PyQt5可编辑下拉框(comboBox):editable - python TCP服务器v1.5 - 客户端连接界面增加自定义参数(设置超时, 连接地址可选)
v1.6
: Python TCP服务器v1.6 - multiprocessing多进程及Ctrl-c(SIGINT)退出
v1.7
: Python TCP服务器v1.7 - PyQt5 server服务端来临
v1.8
: python TCP服务器v1.8 - PyQt5登录界面美化+淡入淡出
v1.9
: socketTCP协程文件+信息传递 - TCP聊天文件服务器v1.9 - 划时代的版本更新(4.6万字)
v2.0
: TCP聊天文件服务器v2.0 - 重大bug修复+PyQt5文件传输可视化
v2.1
: TCP聊天文件服务器v2.1 - 服务端线程管理(threading.enumerate)
v2.2
: TCP聊天文件服务器v2.2 - 服务端客户端套接字解决分包/粘包问题 - SocketQueue继承以及减少冗余
v2.3
: gzip的使用 - TCP聊天文件服务器v2.3 - 文件传输建立缓存制度和.gz的解压缩/压缩解决运行内存过大
v2.4
: 网络传输测速 - TCP聊天+传输文件服务器服务器套接字v2.4 - socket协程文件传送测速
v2.5
: TCP聊天+传输文件服务器服务器套接字v2.5 - socket测速规范已经gzip的弃用
v2.6
: TCP聊天+传输文件服务器服务器套接字v2.6 - 登录注册界面更新 - loading界面应用
测试
增加数据库 用户登录注册的时候还是在 v1.2
,
import itertools
from threading import Threaddef threading(Daemon, name=None, **kwargs):thread = Thread(**kwargs)thread.setDaemon(Daemon)if name:thread.setName(name)thread.start()return threaddata = data()
print(data.handler(0, "tqm", "asdf"))a = 0for u in itertools.product("qwertyuiop[]asdfghjkl;'\\zxcvbnm,./`12345678900-", repeat=6):p = "阿斯蒂芬asdf"a += 1if a % 400 == 0:data.handler(1, "".join(u), "".join(p), _show_detail=True)print(a)else:data.handler(1, "".join(u), "".join(p), _show_detail=False)if a > 1000000:sys.exit(a)
2022-06-20 12:49:00,951 - data.py[line:51] - INFO: Execute the function User handle, timeit 0.000
(False, '用户不存在!', '')
2022-06-20 12:49:01,743 - data.py[line:51] - INFO:
Execute the function User handle, timeit 0.002
2022-06-20 19:11:20,572 - data.py[line:145] - INFO: size: 799.9Mb(8319541 bytes)
... ...
2022-06-20 19:14:37,143 - data.py[line:51] - INFO: Execute the function User handle, timeit 2.496
2022-06-20 19:14:37,144 - data.py[line:145] - INFO: size: 800.0Mb(8354830 bytes)
2022-06-20 19:17:45,165 - data.py[line:51] - INFO: Execute the function User handle, timeit 2.531
2022-06-20 19:17:45,165 - data.py[line:145] - INFO: size: 800.0Mb(8385887 bytes)
在运行了长达3, 8400次迭代后, 连一个注册用户都已经超过了秒的单位.
提升性能
set | list |
---|---|
add | append |
from json import load, dump, decoder
from os import path, mkdir, listdir
from hashlib import md5
from time import time
import logginglogging.basicConfig(level=logging.DEBUG,format="%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
logger = logging.getLogger(__name__)def _mkdir(_folder):try:if not path.exists(_folder):mkdir(_folder)return Trueexcept NotImplementedError:logger.exception("")return Falsedef encode(_data: str):m = md5()m.update(_data.encode('utf8'))return m.hexdigest()def timeit(objname: str, ign=True):def setup_function(func_name):def _exec_function(*args, _show_detail=True, **kwargs):startime = time()_resp = func_name(*args, **kwargs)if _show_detail:logger.info("Execute the function %s%s, timeit %0.3f" % (objname.title(), "" if ign else f" (at {str(func_name)})", time() - startime))return _respreturn _exec_functionreturn setup_functionfolder = r'.\clients'
_mkdir(folder)data = set()
if path.isdir(folder):try:data = set(listdir(folder))except decoder.JSONDecodeError:passdef __in__(username) -> bool:return username in datadef register(username, password, register_time: (int, float) = time()) -> None:global datadata.add(username)user_path = path.join(folder, encode(username))print(user_path, _mkdir(user_path))_mkdir(user_path)with open(path.join(user_path, "user.json"), "w") as f:dump({"username": username, "password": password, "register_time": int(register_time)}, f, indent=4)def login(username, password) -> bool:with open(path.join(path.join(folder, encode(username)), "user.json"), "r") as f:_data = load(f)return _data.get("username", "") == username and _data.get("password", "") == passworddef get_time(username):with open(path.join(path.join(folder, encode(username)), "user.json"), "r") as f:return load(f).get("register_time")@timeit("User Handle")
def handler(_type: int, username: str, password: str):username = username.strip()if not username:return False, "未填写用户名!", ""password = password.strip()if not password:return False, "未填写密码!", ""if not 2 <= len(username) <= 12:return False, "用户名需在2~12位之间!", ""if not 4 <= len(password) <= 10:return False, "密码需在4~10位之间!", ""if _type == 0: # loginif not __in__(username):return False, "用户不存在!", ""if not login(username, password):return False, "用户名 / 密码错误!", ""return True, "欢迎回来, " + username, usernameelif _type == 1: # registerif __in__(username):return False, "已存在用户!", ""register(username, password)return True, "初来乍到, " + username, username
就是将每个用户的用户名的md5值存于文件夹, user.json
放信息
python 数据库性能提升 - TCP聊天+传输文件服务器服务器套接字v2.7相关推荐
- TCP聊天+传输文件服务器服务器套接字v2.6 - 登录注册界面更新 - loading界面应用
TCP聊天+传输文件服务器服务器套接字v2.6 更改的地方: 主要是客户端界面更改 注册, 登录界面 (都知道啊, v1.8的改进后输入用户名, 到了主界面的时候才能输入密码, 但现在是直接输入用户名 ...
- MFC基于TCP协议的CSocket类套接字服务器端代码示范
MFC基于TCP协议的CSocket类套接字服务器端代码示范 https://blog.csdn.net/txwtech/article/details/93417667 转载于:https://ww ...
- 前端学习(1856)vue之电商管理系统电商系统之安装mysql出现mysql报错:Can’t start server: Bind on TCP/IP port: 通常每个套接字地址(协议/网络地址
2020-07-26T11:44:29.778919Z 0 [ERROR] [MY-010262] [Server] Can't start server: Bind on TCP/IP port: ...
- Python网络编程——使用TCP方式传输文件
TCP文件下载器 客户端 需求:输入要下载的文件名,从服务器端将文件拷贝到本地 步骤: 1.创建TCP套接字,绑定端口 2.连接服务端 3.输入要下载的文件名 4.将文件名编码,并发送到服务端 5.接 ...
- 微服务架构 性能提升_如何通过无服务器架构提高性能
微服务架构 性能提升 by Domenico Angilletta 通过多梅尼科·安吉列塔(Domenico Angilletta) 如何通过无服务器架构提高性能 (How to boost your ...
- python中http协议编程_python网络编程、套接字、HTTP协议
网络编程 网络目的 : 数据的传输 网络数据传输是一个复杂的过程 OSI 七层模型 --> 网络通信标准化流程 应用层 : 提供用户服务,具体内容由特定程序规定 表示层 : 数据的压缩优化 会话 ...
- python socket清空接收缓冲区_Python网络编程——修改套接字发送和接收的缓冲区大小...
很多情况下,默认的套接字缓冲区大小可能不够用.此时,可以将默认的套接字缓冲区大小改成一个更合适的值. 1. 代码 # ! /usr/bin/env python # -*- coding: utf-8 ...
- 网络协议OSI、TCP/IP协议、Socket套接字和第三方AsyncSock的使用等解析
一.网络协议定义 1.OSI参考模型:全称(Open System Interconnection), 开放式系统互联参考模型.是一个逻辑上的定义,一个规范,它把网络协议从逻辑上分为七层,只要目的是为 ...
- 网络七层协议 五层模型 TCP连接 HTTP连接 socket套接字
socket(套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程 ...
最新文章
- appium+python自动化45-夜神模拟器连不上(adb server version (36) doesn't match this client (39); killing...)...
- 【Linux】一步一步学Linux——lastb命令(99)
- hive与hbase的以及mongodb和cassandra区别整理
- php html标签闭合,php截取字符串,完美html自动闭合
- C# 离线使用nuget
- mysql mos login_MySQL 中常用的函数
- Django---Cookie Session 分页
- access游戏库不显示 ea_EAAccess服务Steam平台售价一览 EAAccess服务常见问题解答
- 近 45 亿元拿下开源服务器 Nginx,F5 买断应用交付未来?
- 抽象类的成员特点 学习笔记
- Typora下载链接
- 我国大部地区遭罕见寒潮 23省区应急响应
- Gradle使用Junit5进行test
- python知道章节答案_智慧树知道Python数据分析与数据可视化答案,章节期末教程考试网课答案...
- Java基础之《netty(28)—TCP粘包拆包原理》
- Cannot deserialize instance of `com.xxx.project.biz.domain.xxx` out of START_ARRAY token;
- 智能分析网关微信端告警消息推送的开发流程
- 恢复误删excel工作薄中的表格
- Spring IoC 和 AOP
- R语言 绘图 (ggplot2)