39 KiB
39 KiB
In [ ]:
import threading
import requests
from queue import Queue
from time import time,sleep
import os
# 配置信息
ip = "http://localhost:8080"
resource_paths = [
"/static/index.2da1efab.css",
"/static/js/chunk-vendors.js",
"/static/js/index.js",
"/static/js/pages-login-index.js"
]
# 创建下载结果队列
download_results = Queue()
def download_resource(path, thread_name):
"""下载单个资源的线程函数"""
try:
url = ip + path
start_time = time()
response = requests.get(url)
# 模拟浏览器行为:检查状态码和内容类型
if response.status_code != 200:
result = f"线程 {thread_name}: {path} 下载失败, 状态码 {response.status_code}"
else:
# 简略显示内容(实际应用中应保存文件)
content_preview = response.text[:50].replace('\n', ' ') + "..." if len(response.text) > 50 else response.text
# 模拟浏览器解析CSS/JS的时间延迟
process_time = 0.1 if any(ext in path for ext in ['.css', '.js']) else 0.0
result = (
f"线程 {thread_name}: 成功下载 {path}\n"
f"类型: {'CSS' if '.css' in path else 'JS' if '.js' in path else '其他'}\n"
f"大小: {len(response.text)/1024:.1f} KB\n"
f"耗时: {time()-start_time:.3f}秒\n"
f"内容预览: {content_preview}"
)
# 添加处理延迟,模拟浏览器执行
sleep(process_time)
except Exception as e:
result = f"线程 {thread_name}: {path} 下载异常 - {str(e)}"
download_results.put(result)
def simulate_browser_download(max_workers=6):
"""模拟浏览器并发下载行为"""
print(f"模拟浏览器行为 - 并发下载线程数: {max_workers}")
print("=" * 60)
threads = []
for i, path in enumerate(resource_paths):
# 使用线程名标识资源类型
thread_name = f"资源#{i+1}"
# 创建并启动线程
t = threading.Thread(
target=download_resource,
args=(path, thread_name),
name=thread_name
)
t.start()
threads.append(t)
# 控制最大并发数,模拟浏览器的连接限制
if len(threads) >= max_workers:
for t in threads:
t.join()
threads = []
# 等待剩余的线程完成
for t in threads:
t.join()
# 打印结果
while not download_results.empty():
print(download_results.get())
print("-" * 60)
print("完成")
if __name__ == "__main__":
print("浏览器静态资源请求模拟器")
print("=" * 60)
simulate_browser_download()
In [ ]:
from faker import Faker
import random
import json
from datetime import datetime
# 初始化Faker生成器(简体中文)
fake = Faker('zh_CN')
# 定义固定值
TEAM_ID = 106
PLAN_ID = 131
# 常见民族列表
ETHNIC_GROUPS = ["汉", "壮", "满", "回", "苗", "维吾尔", "土家", "彝", "蒙古", "藏", "布依",
"侗", "瑶", "朝鲜", "白", "哈尼", "哈萨克", "黎", "傣", "畲", "傈僳", "仡佬",
"东乡", "高山", "拉祜", "水", "佤", "纳西", "羌", "土", "仫佬", "锡伯", "柯尔克孜",
"达斡尔", "景颇", "毛南", "撒拉", "布朗", "塔吉克", "阿昌", "普米", "鄂温克", "怒",
"京", "基诺", "德昂", "保安", "俄罗斯", "裕固", "乌兹别克", "门巴", "鄂伦春", "独龙",
"塔塔尔", "赫哲", "珞巴"]
# 疾病列表(健康状态)
HEALTH_CONDITIONS = [
"无", "近视", "弱视", "鼻炎", "哮喘", "过敏体质", "蛀牙",
"肥胖", "发育迟缓", "ADHD", "缺铁性贫血", "维生素缺乏",
"易感冒体质", "偏瘦", "过敏(花粉)", "过敏(尘螨)", "过敏(牛奶)",
"消化不良", "多动症", "抽动症", "癫痫", "小儿麻痹", "乙肝病毒携带"
]
# 艺术特长
ART_TALENTS = ["无", "钢琴", "小提琴", "绘画", "书法", "舞蹈", "声乐", "戏剧表演",
"摄影", "编程", "动画制作", "模型制作", "手工艺术"]
# 体育特长
SPORTS_TALENTS = ["无", "游泳", "篮球", "足球", "乒乓球", "羽毛球", "田径",
"武术", "跆拳道", "空手道", "轮滑", "滑板", "自行车", "健美操"]
# 科技特长
TECH_TALENTS = ["无", "机器人编程", "电子制作", "3D打印", "人工智能", "网页设计",
"科学实验", "天文观测", "植物培养", "动物观察", "航模制作"]
# 职业列表
OCCUPATIONS = ["医生", "教师", "工程师", "程序员", "设计师", "建筑师", "销售经理",
"会计", "律师", "公务员", "记者", "警察", "消防员", "厨师", "商人",
"自由职业", "个体经营者", "银行职员", "人力资源", "市场营销"]
# 公司类型
WORKPLACES = [
"国有企业", "民营企业", "外资企业", "合资企业", "政府机关",
"事业单位", "学校", "医院", "设计事务所", "律师事务所",
"科技公司", "互联网公司", "金融机构", "建筑公司", "零售企业"
]
# 小学名称
PRIMARY_SCHOOLS = [
"第一实验小学", "第二实验小学", "育才小学", "阳光小学", "希望小学", "和平小学",
"实验小学分校", "新世纪小学", "东方小学", "先锋小学", "星光小学", "明德小学"
]
def generate_id_num(birthday):
"""生成符合规则的身份证号"""
# 生成前6位(地区码,使用真实的地区码)
region_codes = ["110101", "110105", "110106", "110107", "310112", "330102", "440106", "440304"]
# 出生日期码(8位)
birth_code = birthday.replace("-", "")
# 顺序码(3位)
sequence_code = str(random.randint(101, 998))
# 生成校验码(1位)
base = region_codes[random.randint(0, len(region_codes)-1)] + birth_code + sequence_code
weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
checksum_map = {0: '1', 1: '0', 2: 'X', 3: '9', 4: '8', 5: '7', 6: '6', 7: '5', 8: '4', 9: '3', 10: '2'}
total = 0
for i in range(17):
total += int(base[i]) * weight[i]
checksum = checksum_map[total % 11]
return base + checksum
def generate_student_data():
"""生成单个学生数据"""
# 基础信息
sex = random.choice(["男", "女"])
# 生日 (2010-2015年出生)
birthday = fake.date_between(start_date="-15y", end_date="-8y").strftime("%Y-%m-%d")
# 生成符合规则的身份证号
id_num = generate_id_num(birthday)
# 计算年龄(仅用于展示)
birth_year = int(birthday[:4])
current_year = datetime.now().year
age = current_year - birth_year
# 生成学生信息
data = {
"teamId": TEAM_ID,
"stuName": fake.name(), # 学生姓名
"idNum": id_num, # 身份证号
"formerName": random.choices(["无", fake.last_name() + fake.first_name()], weights=[0.8, 0.2])[0], # 曾用名
"sex": sex, # 性别
"nation": random.choice(ETHNIC_GROUPS), # 民族
"birthday": birthday, # 生日
"finishSchool": random.choice(PRIMARY_SCHOOLS), # 毕业学校
"file": None, # 文件
"hkadr": fake.province() + "/" + fake.city() + "/" + fake.district(), # 户口所在地
"homeAddress": fake.address(), # 家庭住址
"health": random.choice(HEALTH_CONDITIONS), # 健康状况
"artisticSpecialty": random.choice(ART_TALENTS), # 艺术特长
"artisticAchievements": "无", # 艺术成就
"technologicalSpecialty": random.choice(TECH_TALENTS), # 科技特长
"technologicalAchievements": "无", # 科技成就
"sportsSpecialty": random.choice(SPORTS_TALENTS), # 体育特长
"sportsAchievements": "无", # 体育成就
"planId": PLAN_ID, # 计划ID
"imageUrl": "", # 图片URL
"schoolCode": "G" + id_num[:-1], # 学籍号
"age": age, # 年龄(仅用于展示)
"email": fake.email() if random.random() > 0.7 else "", # 邮箱
"height": str(random.randint(130, 170)), # 身高
"weight": str(random.randint(25, 60)), # 体重
"measurements": f"{random.randint(60, 90)},{random.randint(60, 90)},{random.randint(60, 90)}" # 三围
}
# 生成监护人信息
guardian_prefix = fake.last_name()
# 监护人1 - 通常为父母之一
relationship_choices = ["父亲", "母亲", "爷爷", "奶奶", "外公", "外婆"]
relationship = random.choice(relationship_choices[:2]) # 主要选择父母
data.update({
"guardian1Name": guardian_prefix + ("先生" if relationship == "父亲" else "女士"), # 监护人1姓名
"guardian1Relationship": relationship, # 关系
"guardian1IdCardNumber": generate_id_num(fake.date_between(start_date="-55y", end_date="-25y").strftime("%Y-%m-%d")), # 身份证号
"guardian1Contact": fake.phone_number(), # 联系方式
"guardian1Occupation": random.choice(OCCUPATIONS), # 职业
"guardian1Workplace": random.choice(WORKPLACES) # 工作单位
})
# 监护人2 - 可能是另一位家长或其他人
if relationship == "父亲":
guardian2_relationship = "母亲"
else:
guardian2_relationship = random.choices(
["父亲", "爷爷", "奶奶", "外公", "外婆", "其他亲属"],
weights=[0.7, 0.1, 0.1, 0.05, 0.05, 0.1]
)[0]
data.update({
"guardian2Name": guardian_prefix + (
"先生" if guardian2_relationship in ["父亲", "爷爷", "外公"] else "女士"
), # 监护人2姓名
"guardian2Relationship": guardian2_relationship, # 关系
"guardian2IdCardNumber": generate_id_num(fake.date_between(start_date="-55y", end_date="-25y").strftime("%Y-%m-%d")), # 身份证号
"guardian2Contact": fake.phone_number() if guardian2_relationship != "无" else "", # 联系方式
"guardian2Occupation": random.choice(OCCUPATIONS) if guardian2_relationship != "无" else "", # 职业
"guardian2Workplace": random.choice(WORKPLACES) if guardian2_relationship != "无" else "" # 工作单位
})
return data
def generate_students():
student = generate_student_data()
return studentIn [ ]:
from faker import Faker
import random
import json
from datetime import datetime
import threading
import requests
from time import time, sleep
import uuid
from concurrent.futures import ThreadPoolExecutor, as_completed
# 初始化Faker生成器(简体中文)
fake = Faker('zh_CN')
# 定义固定值
TEAM_ID = 106
PLAN_ID = 131
# 常见民族列表
ETHNIC_GROUPS = ["汉", "壮", "满", "回", "苗", "维吾尔", "土家", "彝", "蒙古", "藏", "布依",
"侗", "瑶", "朝鲜", "白", "哈尼", "哈萨克", "黎", "傣", "畲", "傈僳", "仡佬",
"东乡", "高山", "拉祜", "水", "佤", "纳西", "羌", "土", "仫佬", "锡伯", "柯尔克孜",
"达斡尔", "景颇", "毛南", "撒拉", "布朗", "塔吉克", "阿昌", "普米", "鄂温克", "怒",
"京", "基诺", "德昂", "保安", "俄罗斯", "裕固", "乌兹别克", "门巴", "鄂伦春", "独龙",
"塔塔尔", "赫哲", "珞巴"]
# 疾病列表(健康状态)
HEALTH_CONDITIONS = [
"无", "近视", "弱视", "鼻炎", "哮喘", "过敏体质", "蛀牙",
"肥胖", "发育迟缓", "ADHD", "缺铁性贫血", "维生素缺乏",
"易感冒体质", "偏瘦", "过敏(花粉)", "过敏(尘螨)", "过敏(牛奶)",
"消化不良", "多动症", "抽动症", "癫痫", "小儿麻痹", "乙肝病毒携带"
]
# 艺术特长
ART_TALENTS = ["无", "钢琴", "小提琴", "绘画", "书法", "舞蹈", "声乐", "戏剧表演",
"摄影", "编程", "动画制作", "模型制作", "手工艺术"]
# 体育特长
SPORTS_TALENTS = ["无", "游泳", "篮球", "足球", "乒乓球", "羽毛球", "田径",
"武术", "跆拳道", "空手道", "轮滑", "滑板", "自行车", "健美操"]
# 科技特长
TECH_TALENTS = ["无", "机器人编程", "电子制作", "3D打印", "人工智能", "网页设计",
"科学实验", "天文观测", "植物培养", "动物观察", "航模制作"]
# 职业列表
OCCUPATIONS = ["医生", "教师", "工程师", "程序员", "设计师", "建筑师", "销售经理",
"会计", "律师", "公务员", "记者", "警察", "消防员", "厨师", "商人",
"自由职业", "个体经营者", "银行职员", "人力资源", "市场营销"]
# 公司类型
WORKPLACES = [
"国有企业", "民营企业", "外资企业", "合资企业", "政府机关",
"事业单位", "学校", "医院", "设计事务所", "律师事务所",
"科技公司", "互联网公司", "金融机构", "建筑公司", "零售企业"
]
# 小学名称
PRIMARY_SCHOOLS = [
"第一实验小学", "第二实验小学", "育才小学", "阳光小学", "希望小学", "和平小学",
"实验小学分校", "新世纪小学", "东方小学", "先锋小学", "星光小学", "明德小学"
]
def generate_id_num(birthday):
"""生成符合规则的身份证号"""
# 生成前6位(地区码,使用真实的地区码)
region_codes = ["110101", "110105", "110106", "110107", "310112", "330102", "440106", "440304"]
# 出生日期码(8位)
birth_code = birthday.replace("-", "")
# 顺序码(3位)
sequence_code = str(random.randint(101, 998))
# 生成校验码(1位)
base = region_codes[random.randint(0, len(region_codes)-1)] + birth_code + sequence_code
weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
checksum_map = {0: '1', 1: '0', 2: 'X', 3: '9', 4: '8', 5: '7', 6: '6', 7: '5', 8: '4', 9: '3', 10: '2'}
total = 0
for i in range(17):
total += int(base[i]) * weight[i]
checksum = checksum_map[total % 11]
return base + checksum
def generate_student_data():
"""生成单个学生数据"""
# 基础信息
sex = random.choice(["男", "女"])
# 生日 (2010-2015年出生)
birthday = fake.date_between(start_date="-15y", end_date="-8y").strftime("%Y-%m-%d")
# 生成符合规则的身份证号
id_num = generate_id_num(birthday)
# 计算年龄(仅用于展示)
birth_year = int(birthday[:4])
current_year = datetime.now().year
age = current_year - birth_year
# 生成学生信息
data = {
"teamId": TEAM_ID,
"stuName": fake.name(), # 学生姓名
"idNum": id_num, # 身份证号
"formerName": random.choices(["无", fake.last_name() + fake.first_name()], weights=[0.8, 0.2])[0], # 曾用名
"sex": sex, # 性别
"nation": random.choice(ETHNIC_GROUPS), # 民族
"birthday": birthday, # 生日
"finishSchool": random.choice(PRIMARY_SCHOOLS), # 毕业学校
"file": None, # 文件
"hkadr": fake.province() + "/" + fake.city() + "/" + fake.district(), # 户口所在地
"homeAddress": fake.address(), # 家庭住址
"health": random.choice(HEALTH_CONDITIONS), # 健康状况
"artisticSpecialty": random.choice(ART_TALENTS), # 艺术特长
"artisticAchievements": "无", # 艺术成就
"technologicalSpecialty": random.choice(TECH_TALENTS), # 科技特长
"technologicalAchievements": "无", # 科技成就
"sportsSpecialty": random.choice(SPORTS_TALENTS), # 体育特长
"sportsAchievements": "无", # 体育成就
"planId": PLAN_ID, # 计划ID
"imageUrl": "", # 图片URL
"schoolCode": "G" + id_num[:-1], # 学籍号
"age": age, # 年龄(仅用于展示)
"email": fake.email() if random.random() > 0.7 else "", # 邮箱
"height": str(random.randint(130, 170)), # 身高
"weight": str(random.randint(25, 60)), # 体重
"measurements": f"{random.randint(60, 90)},{random.randint(60, 90)},{random.randint(60, 90)}" # 三围
}
# 生成监护人信息
guardian_prefix = fake.last_name()
# 监护人1 - 通常为父母之一
relationship_choices = ["父亲", "母亲", "爷爷", "奶奶", "外公", "外婆"]
relationship = random.choice(relationship_choices[:2]) # 主要选择父母
data.update({
"guardian1Name": guardian_prefix + ("先生" if relationship == "父亲" else "女士"), # 监护人1姓名
"guardian1Relationship": relationship, # 关系
"guardian1IdCardNumber": generate_id_num(fake.date_between(start_date="-55y", end_date="-25y").strftime("%Y-%m-%d")), # 身份证号
"guardian1Contact": fake.phone_number(), # 联系方式
"guardian1Occupation": random.choice(OCCUPATIONS), # 职业
"guardian1Workplace": random.choice(WORKPLACES) # 工作单位
})
# 监护人2 - 可能是另一位家长或其他人
if relationship == "父亲":
guardian2_relationship = "母亲"
else:
guardian2_relationship = random.choices(
["父亲", "爷爷", "奶奶", "外公", "外婆", "其他亲属"],
weights=[0.7, 0.1, 0.1, 0.05, 0.05, 0.1]
)[0]
data.update({
"guardian2Name": guardian_prefix + (
"先生" if guardian2_relationship in ["父亲", "爷爷", "外公"] else "女士"
), # 监护人2姓名
"guardian2Relationship": guardian2_relationship, # 关系
"guardian2IdCardNumber": generate_id_num(fake.date_between(start_date="-55y", end_date="-25y").strftime("%Y-%m-%d")), # 身份证号
"guardian2Contact": fake.phone_number() if guardian2_relationship != "无" else "", # 联系方式
"guardian2Occupation": random.choice(OCCUPATIONS) if guardian2_relationship != "无" else "", # 职业
"guardian2Workplace": random.choice(WORKPLACES) if guardian2_relationship != "无" else "" # 工作单位
})
return data
def generate_students():
student = generate_student_data()
return student
# 配置信息
BASE_URL = "http://localhost:8080"
STATIC_PATHS = [
"/static/index.2da1efab.css",
"/static/js/chunk-vendors.js",
"/static/js/index.js",
"/static/js/pages-login-index.js"
]
# 用户数据生成
USER_AGENTS = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15",
"Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15",
"Mozilla/5.0 (Linux; Android 12; SM-G991B) AppleWebKit/537.36",
"Mozilla/5.0 (iPad; CPU OS 15_5 like Mac OS X) AppleWebKit/605.1.15"
]
def generate_user_data(user_id):
"""生成模拟用户数据"""
return {
"id": user_id,
"session_id": str(uuid.uuid4()),
"user_agent": random.choice(USER_AGENTS),
"request_count": 0,
"start_time": time()
}
def simulate_user_session(user_id):
"""模拟一个用户的完整会话"""
user_data = generate_user_data(user_id)
print(f"👤 用户 {user_id} 开始会话, Session ID: {user_data['session_id']}")
start = time()
# 使用线程池请求所有静态资源
with ThreadPoolExecutor(max_workers=len(STATIC_PATHS)) as executor:
futures = {}
# 提交所有静态资源请求任务
for path in STATIC_PATHS:
url = BASE_URL + path
future = executor.submit(
fetch_resource,
url,
user_data
)
futures[future] = path
# 等待所有静态资源加载完成
for future in as_completed(futures):
path = futures[future]
try:
result = future.result()
print(f"✅ 用户 {user_id} 资源 {path} 加载完成: {result}")
except Exception as e:
print(f"❌ 用户 {user_id} 资源加载失败: {str(e)}")
end = time()
# 所有静态资源加载完成后访问百度提交数据
print(f"📊 用户 {user_id} 加载所有静态资源耗时: {end - start:.3f}秒")
print(f"🚀 用户 {user_id} 开始看表单")
submit_to_baidu(user_data)
return user_data
def fetch_resource(url, user_data):
"""模拟用户获取单个资源"""
# 更新用户请求计数
user_data["request_count"] += 1
# 生成请求头
headers = {
"User-Agent": user_data["user_agent"],
"X-Session-Id": user_data["session_id"],
"X-Request-Count": str(user_data["request_count"]),
"Accept-Encoding": "gzip, deflate"
}
# 添加随机延迟(0.1-0.5秒)模拟网络波动
sleep(random.uniform(0.1, 0.5))
try:
# 执行资源请求
start_time = time()
response = requests.get(url, headers=headers)
elapsed_time = time() - start_time
if response.status_code != 200:
return f"错误状态码: {response.status_code} | 耗时: {elapsed_time:.3f}秒"
# 提取文件名
file_name = url.split('/')[-1]
return f"文件: {file_name} | 大小: {len(response.text)/1024:.1f}KB | 耗时: {elapsed_time:.3f}秒"
except Exception as e:
return f"请求异常: {str(e)}"
def submit_to_baidu(user_data):
"""提交数据到百度"""
# 构造提交数据
payload = generate_students()
sleep(random.uniform(5, 20))
print(f"🎉 用户 {user_data['id']} 提交数据 ")
try:
# 提交到百度
start_time = time()
response = requests.post(
"http://band.hxzhxy.cn/register/student/add", # 模拟的百度提交API
json=payload,
headers={
"User-Agent": user_data["user_agent"],
"X-Session-Id": user_data["session_id"],
"Content-Type": "application/json"
}
)
elapsed_time = time() - start_time
# 记录用户总用时
total_time = time() - user_data["start_time"]
if response.status_code == 200:
print(f"🎉 用户 {user_data['id']} 数据提交成功! | 提交耗时: {elapsed_time:.3f}秒 | 总用时: {total_time:.3f}秒")
return True
else:
print(f"⚠️ 用户 {user_data['id']} 提交失败: 状态码 {response.status_code} | 总用时: {total_time:.3f}秒")
return False
except Exception as e:
print(f"‼️ 用户 {user_data['id']} 提交异常: {str(e)}")
return False
def simulate_multiple_users(num_users=10):
"""模拟多个用户并发访问"""
print(f"🎬 开始模拟 {num_users} 个用户并发访问...")
print("=" * 70)
with ThreadPoolExecutor(max_workers=num_users) as executor:
# 提交所有用户会话任务
futures = [executor.submit(simulate_user_session, i+1) for i in range(5)]
# 等待所有用户完成并收集结果
results = []
for future in as_completed(futures):
try:
user_data = future.result()
results.append(user_data)
except Exception as e:
print(f"用户会话异常: {str(e)}")
# 生成性能报告
print("\n" + "=" * 70)
print("🏁 所有用户已完成操作! 性能摘要:")
print("-" * 70)
total_time = 0
total_requests = 0
completed_submissions = 0
for user in results:
session_time = time() - user["start_time"]
total_time += session_time
total_requests += user["request_count"]
print(f"用户 {user['id']:2d} | 用时: {session_time:.3f}秒 | 请求数: {user['request_count']}")
print("\n汇总统计:")
print(f"- 平均用时: {total_time/len(results):.3f}秒/用户")
print(f"- 总请求数: {total_requests}次")
print(f"- 用户提交率: {completed_submissions}/{len(results)}")
print("=" * 70)
if __name__ == "__main__":
simulate_multiple_users(num_users=10)🎬 开始模拟 10 个用户并发访问... ====================================================================== 👤 用户 1 开始会话, Session ID: 679e3877-56ac-4791-a1e5-880468dc1d87 👤 用户 2 开始会话, Session ID: 96acf953-61d0-4499-900e-482f75112453 👤 用户 3 开始会话, Session ID: 588c0b3d-05ec-438e-a327-bc51fbc3927a 👤 用户 4 开始会话, Session ID: 52eb7ae8-d1b7-48ae-a0f2-8b1bd384d5b8 👤 用户 5 开始会话, Session ID: 42561435-6a9c-4eac-8282-ce4dd7d11547 👤 用户 6 开始会话, Session ID: ee1daae1-584b-409c-affe-d14ad170d309 👤 用户 7 开始会话, Session ID: 43901a21-0c91-45a5-9c98-b6fddd2dcb50 👤 用户 8 开始会话, Session ID: e8ad6873-751f-4f81-8409-cf1c34ee50ee 👤 用户 9 开始会话, Session ID: ae1d258d-545e-4c45-8b81-d9a8ba3d94e8 👤 用户 10 开始会话, Session ID: fed2a8aa-a697-4e4b-b433-11a9edbe1640 ✅ 用户 5 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.032秒 ✅ 用户 2 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.040秒 ✅ 用户 4 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.040秒 ✅ 用户 2 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.057秒 ✅ 用户 9 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.038秒 ✅ 用户 4 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.044秒 ✅ 用户 6 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.034秒 ✅ 用户 1 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.036秒 ✅ 用户 9 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.029秒 ✅ 用户 10 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.037秒 ✅ 用户 1 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.033秒 ✅ 用户 6 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.040秒 ✅ 用户 4 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.040秒 ✅ 用户 10 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.040秒 ✅ 用户 8 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.051秒 ✅ 用户 8 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.032秒 ✅ 用户 2 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.038秒 ✅ 用户 10 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.077秒 ✅ 用户 7 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.053秒 ✅ 用户 10 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.047秒 📊 用户 10 加载所有静态资源耗时: 2.305秒 🚀 用户 10 开始看表单 ✅ 用户 5 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.066秒 ✅ 用户 6 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.046秒 ✅ 用户 4 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.069秒 📊 用户 4 加载所有静态资源耗时: 2.348秒 🚀 用户 4 开始看表单 ✅ 用户 7 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.055秒 ✅ 用户 7 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.055秒 ✅ 用户 6 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.069秒 📊 用户 6 加载所有静态资源耗时: 2.391秒 🚀 用户 6 开始看表单 ✅ 用户 3 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.043秒 ✅ 用户 9 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.057秒 ✅ 用户 1 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.055秒 ✅ 用户 8 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.057秒 ✅ 用户 3 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.063秒 ✅ 用户 7 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.085秒 📊 用户 7 加载所有静态资源耗时: 2.434秒 🚀 用户 7 开始看表单 ✅ 用户 1 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.073秒 📊 用户 1 加载所有静态资源耗时: 2.450秒 🚀 用户 1 开始看表单 ✅ 用户 3 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.037秒 ✅ 用户 3 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.059秒 📊 用户 3 加载所有静态资源耗时: 2.487秒 🚀 用户 3 开始看表单 ✅ 用户 2 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.049秒 📊 用户 2 加载所有静态资源耗时: 2.507秒 🚀 用户 2 开始看表单 ✅ 用户 9 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.051秒 📊 用户 9 加载所有静态资源耗时: 2.519秒 🚀 用户 9 开始看表单 ✅ 用户 8 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.040秒 📊 用户 8 加载所有静态资源耗时: 2.527秒 🚀 用户 8 开始看表单 ✅ 用户 5 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.043秒 ✅ 用户 5 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.035秒 📊 用户 5 加载所有静态资源耗时: 2.542秒 🚀 用户 5 开始看表单