每次开车去商场最头疼的就是找车位,高峰期转悠20分钟找不到空位是常态。去年我参与了一个商业综合体的停车场改造项目,发现传统停车管理存在三个致命问题:一是车主无法预知车位余量,二是停车场资源分配不均衡,三是人工调度效率低下。这就是我们开发这套智能预约推荐系统的初衷。
这个基于Django的微信小程序系统,核心功能是通过实时数据采集和智能算法,让车主能提前预约指定区域车位,系统根据历史数据动态推荐最优停车方案。项目上线后,该商场平均找车时间从15分钟降至3分钟,车位周转率提升40%。下面我就从技术选型到算法优化的全过程做个复盘。
后端选择Django主要基于三个考量:一是其自带的Admin系统能快速搭建停车场管理后台;二是ORM层对多类型数据库的良好支持(我们同时用了MySQL和Redis);三是REST framework可以快速构建小程序所需API。实测证明,在2000QPS的压力下,Django+uWSGI+Nginx的组合能保持响应时间在300ms以内。
小程序端采用原生开发+WeUI组件库,重要考虑是:
系统数据流有三个关键路径:
python复制# 典型推荐逻辑代码片段
class ParkingSpotQuerySet(models.QuerySet):
def recommend_spots(self, user_pos, pref_type):
return self.filter(
status='vacant',
spot_type=pref_type
).annotate(
distance=Func(user_pos, F('location'), function='ST_Distance')
).order_by('distance')[:3]
停车场高峰期会出现多人同时抢同一个车位的场景。我们测试发现,单纯依赖数据库事务会导致20%的预约冲突。最终方案是采用Redis分布式锁+数据库乐观锁双重保障:
python复制def make_reservation(user_id, spot_id):
redis_lock = RedisLock(f'spot_{spot_id}', timeout=10)
try:
with redis_lock:
spot = ParkingSpot.objects.select_for_update().get(pk=spot_id)
if spot.status == 'vacant':
Reservation.objects.create(
user=user_id,
spot=spot,
expire_time=timezone.now()+timedelta(minutes=15)
)
spot.status = 'reserved'
spot.save()
return True
except LockError:
log.warning(f'Spot {spot_id} lock contention')
return False
重要提示:必须设置合理的锁超时时间,我们通过压力测试确定10秒是最优值,过短会导致正常业务失败,过长会影响系统吞吐量。
第一版采用简单距离排序,但用户反馈推荐车位经常需要绕行。迭代后的算法加入三个维度:
python复制def calculate_score(spot, user):
base_score = 1000 - spot.distance
if user.preference == 'charging' and spot.has_charger:
base_score += 500
if spot.near_exit and user.history.get('quick_exit'):
base_score += 300
return base_score - spot.route_complexity * 50
初期车位列表API响应时间高达1.2秒,通过以下措施降至180ms:
select_related预加载外键关系status字段添加条件索引python复制@cache_page(60 * 2, key_prefix='spot_list')
@cache_control(public=True)
def spot_list(request):
# 查询逻辑...
小程序必须使用微信支付,但停车场场景有两个特殊需求:
我们最终采用这样的计费逻辑:
python复制def calculate_fee(reservation):
duration = timezone.now() - reservation.start_time
base_hours = duration.total_seconds() // 3600
extra_quarters = ceil((duration.total_seconds() % 3600) / 900)
return (
settings.BASE_RATE * base_hours
+ settings.QUARTER_RATE * extra_quarters
)
地磁传感器的数据采集遇到三个典型问题:
我们在设备管理模块专门增加了健康度看板:
python复制class DeviceHealthView(APIView):
def get(self, request):
critical = Sensor.objects.filter(
last_report__lt=timezone.now()-timedelta(minutes=5)
).count()
return Response({
'offline_count': critical,
'battery_low': Sensor.objects.filter(
battery_level__lt=20
).count()
})
真实运营中发现一些设计时没考虑到的情况:
为防止黄牛刷车位,我们实施了:
python复制def update_credit(user, action):
rules = {
'cancel': -2,
'overtime': -5,
'illegal_park': -10,
'complete': +1
}
user.credit_score = max(
0,
user.credit_score + rules.get(action, 0)
)
user.save()
停车场数据涉及用户轨迹隐私,我们采取:
python复制class ParkingRecord(models.Model):
plate_number = EncryptedCharField(max_length=20) # 加密存储
entry_time = models.DateTimeField()
exit_time = models.DateTimeField(null=True)
这套系统经过半年迭代,目前日均处理预约订单1.2万笔,高峰期并发达到1500+。最大的体会是:智能停车不是简单的"有位可停",而是要构建人、车、场三者之间的动态平衡。下一步我们正在试验基于强化学习的动态定价模型,让停车场资源利用率再提升一个台阶。