1. 项目背景与核心需求
校园公告系统是每所高校必备的基础设施,但传统方案常面临几个痛点:公告更新不及时、师生接收渠道分散、高峰期系统卡顿。我在某高校信息化部门工作时,就经常接到"为什么没收到选课通知"的投诉。通过分析发现,现有系统主要依赖网页轮询和邮件推送,实时性和可靠性都难以保证。
这个项目采用Flask+Redis组合,主要解决三个核心问题:
- 实时推送:利用Redis的发布订阅机制,实现公告秒级触达
- 多端同步:同时支持微信服务号、APP、网页等多渠道推送
- 高并发处理:借助Redis内存数据库特性,轻松应对选课等高峰时段
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术选型解析
2.1 为什么选择Flask
作为轻量级Python框架,Flask特别适合这类需要快速迭代的教育类项目。我们做过对比测试:
- 开发效率:用Flask实现REST API比Django节省40%代码量
- 扩展性:通过Blueprint可以模块化添加功能(如新增成绩查询模块)
- 性能:在4核8G服务器上,Flask处理静态公告页面的QPS能达到1200+
提示:建议使用工厂模式创建app对象,便于后期扩展多环境配置
2.2 Redis的五大应用场景
在这个系统中,Redis不仅用作缓存,还承担了多个关键角色:
- 实时推送引擎(Pub/Sub模式)
python复制# 公告发布示例
r = redis.StrictRedis()
r.publish('campus_news', json.dumps({
'title': '停电通知',
'content': '5月20日8:00-12:00主校区停电',
'target': ['teacher', 'student']
}))
- 热点数据缓存
- 将频繁访问的公告内容缓存300秒
- 使用Hash类型存储结构化数据
- 分布式锁
python复制# 防止并发修改公告
with r.lock('edit_lock', timeout=5):
update_announcement()
- 访问计数器
python复制# 记录公告阅读量
r.zincrby('announcement:views', announcement_id)
- 延迟队列
- 用于定时发送的公告(如考试提醒)
3. 系统架构设计
3.1 整体架构图
code复制[Web前端] <-HTTP-> [Flask应用层]
| |
[MySQL] [Redis]
| |
[管理后台] [推送服务]
3.2 关键数据结构设计
MySQL表结构:
sql复制CREATE TABLE announcements (
id BIGINT PRIMARY KEY,
title VARCHAR(100) NOT NULL,
content TEXT,
publisher INT,
priority TINYINT DEFAULT 0,
start_time DATETIME,
end_time DATETIME,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Redis存储方案:
- 热点数据:
announcement:{id}为key的Hash - 分类索引:
type:{notice|news|emergency}:ids为key的Set - 用户已读记录:
user:{uid}:read为key的Set
4. 核心功能实现
4.1 实时推送服务
采用多线程消费Redis消息:
python复制def message_listener():
pubsub = r.pubsub()
pubsub.subscribe('campus_news')
for message in pubsub.listen():
if message['type'] == 'message':
data = json.loads(message['data'])
# 微信推送
wechat_push(data)
# APP推送
app_push(data)
# 短信通知
if data['priority'] > 1:
sms_push(data)
4.2 分级推送策略
根据公告类型采用不同推送方式:
- 普通通知(优先级0):仅APP站内信
- 重要通知(优先级1):+微信模板消息
- 紧急通知(优先级2):+短信+电话提醒
4.3 阅读状态同步
使用Redis Bitmap实现百万级用户已读状态记录:
python复制# 标记已读
r.setbit(f'announcement:{aid}:read', user_id, 1)
# 统计阅读量
r.bitcount(f'announcement:{aid}:read')
5. 性能优化实践
5.1 缓存策略优化
采用多级缓存方案:
- 内存缓存:高频访问的公告内容(TTL 5分钟)
- Redis缓存:全量公告数据(TTL 1小时)
- 本地存储:用户最近查看的10条公告
5.2 连接池配置
Flask-Redis最佳实践:
python复制app.config['REDIS_URL'] = 'redis://:password@master:6379/0'
app.config['REDIS_POOL'] = ConnectionPool(
max_connections=50,
socket_timeout=5
)
5.3 压力测试结果
使用Locust模拟3000并发用户:
- 公告列表API:平均响应时间78ms
- 详情页API:平均响应时间112ms
- 推送延迟:<500ms(含第三方渠道)
6. 踩坑经验分享
- Redis内存暴涨问题
- 现象:运行一周后Redis占用8G内存
- 原因:未设置过期时间的用户行为数据
- 解决:对所有非核心数据设置TTL
- 消息堆积导致延迟
- 现象:高峰期推送延迟达5分钟
- 解决:增加消费者进程 + 消息批量处理
- 缓存穿透防护
python复制# 使用布隆过滤器防止缓存穿透
if not bloom_filter.exists(key):
return None
- 事务一致性方案
- 采用Redis事务+MySQL事务的二阶段提交
- 关键操作记录操作日志用于补偿
7. 扩展功能建议
- 智能推送:基于用户画像的个性化推荐
- 数据看板:实时展示推送效果数据
- 多校区支持:通过Redis Cluster实现
- 离线消息:使用Redis Stream存储未送达消息
这个系统在某高校实际运行8个月后,公告到达率从63%提升至98%,IT部门关于"没收到通知"的投诉量下降90%。最让我意外的是,Redis的Pub/Sub机制在保持高可用的同时,资源消耗仅为传统轮询方案的1/5。
