1. 项目概述:多租户架构的城市路灯运维共享服务平台
这个项目构建了一个基于Python后端(Vue前端)的城市路灯智能运维管理系统,采用多租户架构实现不同城市/区域管理方的数据隔离与资源共享。我在实际开发中发现,市政设施运维领域存在严重的"数据孤岛"现象——每个城市的路灯管理数据独立存储,无法进行跨区域故障模式分析和资源调度优化。
通过Django+Flask双后端配合Vue前端的混合架构,我们实现了:
- 多租户数据隔离(每个城市管理方独立数据库)
- 运维工单共享(相邻城市可协作处理紧急故障)
- 设备效能分析(聚合多城市数据训练预测模型)
关键创新点:用Flask微服务处理实时IoT数据流,Django主服务管理核心业务逻辑,两者通过RabbitMQ消息队列进行数据同步。
2. 技术架构解析
2.1 多租户实现方案
采用"SaaS模式+独立Schema"的混合架构:
python复制# Django models.py 租户识别中间件
class TenantMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
hostname = request.get_host().split(':')[0]
tenant = Tenant.objects.filter(domain=hostname).first()
if tenant:
request.tenant = tenant
connection.set_schema(tenant.schema_name)
return self.get_response(request)
配套的数据库路由策略:
python复制# database_routers.py
class TenantRouter:
def db_for_read(self, model, **hints):
if hasattr(model, '_tenant'):
return model._tenant.schema_name
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
return db == 'default'
2.2 前后端分离实践
Vue前端采用如下架构:
- 路由级动态加载:按租户需求加载功能模块
- 权限控制方案:RBAC+ABAC混合模型
- 状态管理:Vuex模块化+持久化方案
axios请求拦截器示例:
javascript复制// src/utils/request.js
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 5000
})
service.interceptors.request.use(
config => {
if (store.getters.tenantId) {
config.headers['X-Tenant-ID'] = store.getters.tenantId
}
return config
}
)
3. 核心功能实现
3.1 路灯设备接入层
采用Flask处理IoT设备上报数据:
python复制# flask_app/device_api.py
@app.route('/api/v1/device/<device_id>/status', methods=['POST'])
def device_status(device_id):
data = request.get_json()
current_app.logger.info(f"Device {device_id} status: {data}")
# 实时写入Redis
r = redis.StrictRedis(host='redis', port=6379)
r.hset(f"device:{device_id}", mapping={
'voltage': data['voltage'],
'current': data['current'],
'brightness': data['brightness'],
'timestamp': datetime.now().isoformat()
})
# 异步处理
channel = current_app.extensions['channel']
channel.basic_publish(
exchange='device_events',
routing_key='status.update',
body=json.dumps({'device_id': device_id, **data})
)
return jsonify({'status': 'ok'})
3.2 运维工单系统
Django实现的多租户工单流转:
python复制# tickets/models.py
class Ticket(models.Model):
PRIORITY_CHOICES = [
(1, '紧急'),
(2, '高'),
(3, '中'),
(4, '低')
]
tenant = models.ForeignKey(Tenant, on_delete=models.CASCADE)
device = models.ForeignKey(Device, on_delete=models.PROTECT)
creator = models.ForeignKey(User, related_name='created_tickets')
assignee = models.ForeignKey(User, null=True, related_name='assigned_tickets')
priority = models.IntegerField(choices=PRIORITY_CHOICES)
description = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
resolved_at = models.DateTimeField(null=True)
class Meta:
indexes = [
models.Index(fields=['tenant', 'priority']),
models.Index(fields=['tenant', 'device']),
]
4. 部署架构与性能优化
4.1 云原生部署方案
mermaid复制graph TD
A[Vue S3] -->|CDN| B(CloudFront)
C[Django ECS] --> D(RDS PostgreSQL)
E[Flask ECS] --> F(ElastiCache Redis)
G[IoT Device] --> H(API Gateway)
H --> E
D -->|Schema| J(Tenant A)
D -->|Schema| K(Tenant B)
4.2 关键性能指标
通过Locust进行的压力测试结果:
| 场景 | RPS | 平均响应时间 | 错误率 |
|---|---|---|---|
| 设备状态上报 | 1250 | 38ms | 0.02% |
| 工单创建 | 420 | 210ms | 0% |
| 跨租户查询 | 180 | 450ms | 0.5% |
优化措施:
- Redis缓存热点数据
- 数据库连接池配置
- 异步任务队列处理
5. 开发环境配置指南
5.1 PyCharm专业版配置
-
安装Python插件和Vue.js插件
-
配置Django支持:
- 设置Django项目根目录
- 指定manage.py路径
- 启用Django模板支持
-
运行配置示例:
xml复制<!-- .idea/runConfigurations/Django_Server.xml -->
<component name="ProjectRunConfigurationManager">
<configuration name="Django Server" type="Python.DjangoServer">
<module name="streetlight_platform" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="DJANGO_SETTINGS_MODULE" value="core.settings.dev" />
</envs>
<option name="SDK_HOME" value="$PROJECT_DIR$/venv/bin/python" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="launchJavascriptDebuger" value="false" />
<option name="port" value="8000" />
<option name="host" value="0.0.0.0" />
<option name="additionalOptions" value="" />
<option name="browserUrl" value="" />
<option name="runTestServer" value="false" />
<option name="runNoReload" value="false" />
<option name="useCustomRunCommand" value="false" />
<option name="customRunCommand" value="" />
</configuration>
</component>
5.2 常见问题排查
- 跨域问题解决方案:
python复制# Django settings.py
CORS_ALLOWED_ORIGINS = [
"http://localhost:8080",
"http://127.0.0.1:8080"
]
# Vue vue.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true
}
}
}
}
- 数据库连接泄漏检测:
python复制# Django settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'OPTIONS': {
'connection_health_checks': True,
'timeout': 20,
}
}
}
6. 项目演进路线
6.1 技术债清理计划
- 接口文档自动化(Swagger+Redoc)
- 单元测试覆盖率提升(pytest+cov)
- 日志集中化管理(ELK Stack)
6.2 功能扩展方向
- 基于TensorFlow的故障预测
- 区块链技术用于设备身份认证
- 数字孪生可视化平台
在实际开发中,我们发现多租户系统的最大挑战不是技术实现,而是业务模型设计。如何平衡数据隔离与资源共享,需要根据具体业务场景不断调整架构方案。
