某传统零售企业IT成本骤降70%背后Serverless架构如何破解企业上云难题
这家传统零售企业的故事,说起来有点让人唏嘘。
老王是这家连锁超市集团的CTO,手下管着三十多套系统,从门店POS到仓储管理,从会员CRM到供应链平台,每一套都是十几年前搭建的。那时候公司还没什么”IT现代化”的概念,能跑起来就不错了。结果这些年业务越做越大,系统却越来越臃肿,运维团队每天忙得脚不沾地,服务器费用却像滚雪球一样越来越大。
去年年底,公司高层突然下了个死命令:IT预算砍一半,但系统稳定性不能掉链子。老王当时脸都绿了。
被压垮的IT团队
先说说这家企业当时的处境,你可能觉得有点夸张,但这是很多传统零售企业的真实写照。
他们的机房里躺着两百多台物理服务器,跑的无非就几类应用:Web服务器、数据库服务器、缓存服务器、消息队列服务器。看起来井井有条,但实际上每台服务器都”一鱼多吃”——白天高峰期够用,晚上高峰期过去,资源闲置率高达70%。
更头疼的是季节性波动。他们做生鲜零售,每逢春节、中秋这种节点,订单量能翻三倍,平时就老老实实趴在基础水平上。为了应对峰值,老王每年都要申请扩容预算,买新服务器、加存储,结果大部分时间这些设备都在”休眠”。
去年的IT账单大概是这样:
| 项目 | 年度费用 | 占比 |
|---|---|---|
| 硬件采购与维护 | 320万 | 28% |
| 云资源租赁 | 180万 | 16% |
| 运维人力成本 | 280万 | 24% |
| 机房租金与电力 | 150万 | 13% |
| 软件授权与许可 | 170万 | 15% |
| 合计 | 1100万 | 100% |
三百多人的IT团队,其中运维占了将近一半,天天忙着重启服务器、扩容磁盘、处理故障告警。有一次双十一前夕,主数据库因为连接数爆满直接挂掉,老王带着团队熬了整整三十六个小时,恢复的时候人都是飘的。
公司财报上,IT费用占营收比例已经到了8.7%,远超行业平均的4.2%。高层坐不住了。
第一次上云的弯路
听到”降本增效”的号召,老王第一个反应就是上云。他以为把服务器迁到阿里云或者腾讯云,费用肯定能降下来——毕竟云服务器是按量付费的,不用买硬件,不是挺香吗?
结果第一次上云,花了整整八个月,多花了将近两百万,问题一个没解决,还添了新问题。
为什么?因为他们是”搬箱子上云”。
具体来说,就是把物理机上的应用完整迁移到云上的ECS实例里,服务器还是那些服务器,架构还是原来的架构,唯一的区别是从机房搬到了云端。数据库还是跑在云上的虚拟机里,负载均衡还是照搬原来的配置,甚至监控告警的规则都没怎么改。
更糟糕的是,云厂商的计费方式比传统IDC复杂得多——按量付费的ECS、包年包月的ECS、流量费用、存储费用、数据传输费用、API调用费用……老王团队的财务对账员对着账单看了三天,愣是没搞清楚钱都花哪儿了。
第一年云上的账单:
| 项目 | 月度费用 | 说明 |
|---|---|---|
| ECS计算资源 | 12万 | 比原来物理机多30% |
| 云数据库RDS | 4.5万 | 业务量大,实例规格不敢降 |
| 对象存储OSS | 1.8万 | 图片、视频资料堆积如山 |
| CDN带宽 | 3.2万 | 门店多,访问分散 |
| 负载均衡SLB | 0.8万 | 必须配置 |
| 数据流转费 | 2.1万 | 跨可用区传输 |
| 其他(监控、日志等) | 1.5万 | 杂项 |
| 月度合计 | 25.9万 | 年化约310万 |
比原来机房还贵了将近一半。原因很简单:云资源按量计费,没有闲置成本的概念,你跑多少就算多少;原来机房里闲置的70%资源是”免费的”,云上则没有这个”免费午餐”。
那次失败让老王团队对”上云”这两个字都有了心理阴影。
Serverless的转机
转机出现在今年年初,行业峰会上有人分享了某个电商客户用Serverless架构重构业务的案例,IT成本降了60%以上。老王当场就记下了联系方式,会后拉着对方聊了整整一下午。
他当时最关心两个问题:第一,Serverless到底靠不靠谱?第二,成本真的能降这么多?
对方是个做生鲜电商的,规模和老王的企业差不多。他们聊的细节里,有几个点让老王眼前一亮。
Serverless到底是什么
很多人听到Serverless就以为是”没有服务器”,其实这是个误解。Serverless的真正含义是:开发者不用关心服务器,平台自动帮你管理 everything。
用老王团队的技术总监小李的话说,Serverless就像是”叫网约车”和”买车”的区别。买车你需要自己保养、加油、停车、处理违章,网约车你只管上车出发,其他的全交给平台。
具体来说,Serverless有三类产品形态,老王的企业最后三种都用上了:
1. FaaS(函数即服务)—— 代码级执行,按调用次数和运行时间计费。
比如他们有个场景:每次用户打开APP查看商品推荐,后端需要调用用户画像服务、商品库、排序算法,最后返回推荐列表。这个请求的处理逻辑可以写成一个函数,触发条件就是”用户发起请求”。不用启动一个完整的Web服务器,不用维护一个进程,函数直接执行,跑完就销毁,费用按毫秒算。
2. BaaS(后端即服务)—— 开箱即用的后端能力,免运维。
比如用户注册登录,传统做法是搭一套鉴权服务,维护Session、Token、密码加密逻辑。用Serverless的BaaS,直接调用云厂商提供的认证服务,注册、登录、权限管理全都有现成的,企业只需专注业务逻辑。
3. 全托管数据库—— 自动扩缩容,自动备份,自动优化。
之前的关系型数据库一直是运维团队的噩梦。慢查询、连接数爆满、主从延迟……每次出问题都手忙脚乱。全托管数据库把这些问题全解决了,云厂商帮你做索引优化、自动分区、读写分离,企业只需关心SQL写得对不对。
选型:为什么不全面上Serverless?
老王团队很清醒,没有盲目追求”全Serverless”。他们做了一个评估矩阵:
| 应用类型 | 流量特征 | 推荐方案 | 原因 |
|---|---|---|---|
| 会员积分系统 | 高峰期集中,平时极低 | FaaS | 按调用付费,不跑不花钱 |
| 商品详情页渲染 | 波动大,有突发流量 | FaaS + CDN | 边缘计算就近响应 |
| 订单创建与支付 | 业务核心,要求稳定 | 容器服务 + 弹性伸缩 | 需要状态保持 |
| 用户数据画像 | 查询频繁,数据量大 | 全托管数据库 | 免运维,自动优化 |
| 文件存储(图片/视频) | 持续增长,访问随机 | 对象存储 | 按量计费,便宜 |
| 消息通知(短信/推送) | 事件驱动 | 消息队列 | 异步解耦,削峰填谷 |
这个选型思路很重要——Serverless不是银弹,但它特别适合那些流量波动大、突发频繁、平时负载低的场景。而这家传统零售企业恰恰就是这类场景的”重灾区”。
改造过程:从订单系统动刀
改造不是一蹴而就的,老王团队先从最痛的痛点入手——订单系统。
订单系统的过去式
改造前的订单系统架构是这样的:
用户下单 → API网关(Nginx集群)→ 订单服务(Tomcat集群,8台ECS)
→ 库存服务(Java应用,3台ECS)
→ 支付服务(.NET应用,2台ECS)
→ 消息队列(自建RocketMQ,3台ECS)
→ 数据库(自建MySQL主从,2台ECS)
八台ECS跑订单服务,其中四台专门给高峰期用。正常工作日,这四台”高峰服务器”的CPU利用率不到15%,但每天24小时开着,费用一分不少。订单高峰出现在每天晚上七点到九点、周末上午十点到十二点,这两个时间段CPU经常飙到90%以上,触发告警后运维要手动扩容。
更麻烦的是,订单服务、库存服务、支付服务三个应用部署在不同的ECS上,每次更新代码都要分别部署,经常出现”订单服务升级了,库存服务还是旧版本”导致的不一致问题。
改造后的架构
改造后,订单系统的核心链路变成了这样:
用户下单 → API网关(全托管)→ 订单FaaS函数 → 全托管数据库
→ 库存FaaS函数 → 全托管数据库
→ 支付FaaS函数 → 全托管数据库
→ 消息队列(全托管)
关键变化有三点:
第一,订单、库存、支付三个服务拆成独立的FaaS函数。
每个函数就是一个独立的处理单元,比如”创建订单”这个功能,就是一个函数;”扣减库存”是另一个函数;”发起支付”又是第三个函数。它们之间通过消息队列解耦,调用方完全感知不到后端的实现细节。
# 订单创建函数示例(伪代码)
def handle_create_order(event, context):
order_id = generate_order_id()
user_id = event['userId']
items = event['items']
# 校验库存(异步,不阻塞主流程)
trigger_async('deduct_stock', {
'orderId': order_id,
'items': items
})
# 写入订单数据库
save_to_order_db(order_id, user_id, items)
# 返回订单号
return {'orderId': order_id, 'status': 'created'}
第二,数据库换成全托管的无服务器数据库。
以前的自建MySQL需要自己管主从同步、慢查询优化、连接池配置。换成全托管数据库后,这些全交给平台。
-- 数据库表结构不变,业务代码无需修改
CREATE TABLE orders (
order_id VARCHAR(32) PRIMARY KEY,
user_id BIGINT NOT NULL,
total_amount DECIMAL(10,2),
status TINYINT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user (user_id),
INDEX idx_status_time (status, created_at)
);
全托管数据库会自动根据查询模式优化索引,自动处理连接池,自动在主库故障时切换从库。运维团队再也不用半夜爬起来处理数据库挂了的问题。
第三,消息队列从自建换成全托管。
之前的自建RocketMQ集群需要三台ECS,运维成本不低。换成全托管消息队列后,企业只需要在代码里配置好Topic和队列,其他的全交给平台。
// 消息发送示例
@Autowired
private RocketMQTemplate rocketMQTemplate;
public void sendOrderCreatedEvent(String orderId) {
OrderCreatedEvent event = new OrderCreatedEvent();
event.setOrderId(orderId);
event.setTimestamp(System.currentTimeMillis());
rocketMQTemplate.syncSend("ORDER_CREATED_TOPIC", event);
}
改造的效果
改造完成后,订单系统的性能不降反升,关键指标如下:
| 指标 | 改造前 | 改造后 | 变化 |
|---|---|---|---|
| 订单创建平均耗时 | 320ms | 85ms | ↓ 73% |
| 峰值处理能力 | 500单/秒 | 2000单/秒 | ↑ 300% |
| 系统可用性 | 99.5% | 99.99% | ↑ |
| 部署频率 | 每周1次 | 每天多次 | 更灵活 |
| 故障恢复时间 | 平均30分钟 | < 1分钟 | ↓ 97% |
最让老王惊喜的是成本。改造后订单系统的月度IT费用从原来的8.7万降到了1.2万,降幅86%。原因很简单:原来八台ECS全年无休地跑,现在只在有请求的时候才产生费用,凌晨三点到早上六点的低峰期,费用几乎为零。
全面推广:三波推进策略
订单系统的成功让老王有了底气,接下来就是全面推广。他们没有搞”大爆炸式”迁移,而是分了三波推进。
第一波:营销系统先行
营销系统的特点是”脉冲式流量”——平时没什么人访问,一到促销活动就流量暴涨。典型的场景是”限时秒杀”,活动开始前系统完全空闲,活动开始后流量瞬间暴增十倍甚至几十倍。
改造前,营销团队每次搞活动都要提前一周申请临时扩容,活动结束后再释放资源。但经常出现两个问题:一是扩容不够,活动开始几分钟就撑不住;二是活动提前结束,临时服务器白开了好几天。
改成Serverless之后,所有营销活动的接口都写成FaaS函数:
# 秒杀活动接口函数
def handle_seckill_order(event, context):
activity_id = event['activityId']
user_id = event['userId']
product_id = event['productId']
quantity = event.get('quantity', 1)
# 校验库存(从全托管Redis读取,原子操作)
stock_key = f"stock:{activity_id}:{product_id}"
remaining = redis.decrement(stock_key)
if remaining < 0:
return {'success': False, 'reason': '售罄'}
# 创建订单
order_id = create_order(user_id, product_id, quantity)
# 发送消息(异步通知仓储系统)
send_message('ORDER_CREATED', {
'orderId': order_id,
'userId': user_id,
'productId': product_id,
'quantity': quantity
})
return {'success': True, 'orderId': order_id}
这个函数没有固定大小的服务实例,流量来了就自动创建执行环境,流量走了就自动销毁。秒杀活动开始时,可能瞬间有上万并发,平台会自动扩容到足够的实例数;活动结束后,实例自动回收,费用归零。
第一波改造后,营销系统的成本从每月4.3万降到了0.6万,降幅86%。
第二波:数据报表系统
报表系统是另一块”肥肉”。老王的企业有三百多家门店,每天产生的销售数据、库存数据、会员数据需要汇总分析,生成各种报表。
改造前,报表系统依赖一台高性能的ECS实例,专门跑ETL(数据抽取-转换-加载)任务和报表生成。问题是:数据量在持续增长,这台实例的配置年年升级,但总是跟不上——月初和季度末是高峰期,报表系统经常卡住,业务部门天天催。
改成Serverless数据流之后,整个ETL过程完全托管:
# 数据流配置示例
data_pipeline:
source:
type: database
connection: orders_db # 连接全托管数据库
schedule: "0 2 * * *" # 每天凌晨2点执行
transform:
type: faaS
function: etl_sales_summary
runtime: python3.9
timeout: 300s
memory: 2048MB
sink:
type: warehouse
connection: data_warehouse
table: daily_sales_summary
每次触发时,平台自动分配计算资源,跑完就释放。报表生成时间从原来的45分钟缩短到了8分钟,而且每次都能稳定完成。
报表系统的成本从每月2.1万降到了0.3万,降幅86%。
第三波:门店IoT数据采集
这是最后一块,也是最有技术含量的部分。他们的三百多家门店里,每个收银台、冷柜、货架都有传感器,实时采集温度、湿度、设备状态、客流数据等信息。
改造前,这些数据通过MQTT协议上报到自建的物联网平台,需要维护一批专门处理消息的服务器。问题是:门店数量在持续增长,每新开一家店就要扩容;数据有突发性——比如某家店的冷柜温度异常报警,会瞬间产生大量数据,容易把服务器打垮。
改成Serverless物联网平台后,所有门店设备的上报数据直接接入全托管的IoT服务:
// 设备上报处理函数
public void handleDeviceMessage(DeviceMessage message) {
String deviceId = message.getDeviceId();
String payload = message.getPayload();
// 解析消息
DeviceData data = JsonUtils.fromJson(payload, DeviceData.class);
// 判断是否需要告警
if (data.getTemperature() > 8.0) {
alertService.sendAlert(deviceId, "温度异常: " + data.getTemperature() + "°C");
}
// 写入时序数据库
timeseriesDb.save(data);
// 触发 downstream 处理(可选)
triggerFunction("processStoreData", Map.of("deviceId", deviceId));
}
平台自动处理设备连接、消息路由、数据存储,企业完全不用管基础设施。新开门店只需要在平台上注册设备,剩下的全自动。
IoT数据处理的成本从每月1.8万降到了0.2万,降幅89%。
成本对比:一张表看懂变化
三波改造完成后,整个IT架构的成本变化是惊人的:
| 项目 | 改造前(月度) | 改造后(月度) | 降幅 |
|---|---|---|---|
| 计算资源 | 18万 | 3.2万 | ↓ 82% |
| 数据库 | 6万 | 1.5万 | ↓ 75% |
| 消息队列 | 2万 | 0.4万 | ↓ 80% |
| 存储 | 4万 | 2.8万 | ↓ 30% |
| 带宽与CDN | 5万 | 3.5万 | ↓ 30% |
| 运维人力 | 8万 | 2.5万 | ↓ 69% |
| 合计 | 43万 | 13.9万 | ↓ 68% |
年化节省约350万,正好是老王承诺的”砍一半”目标。
更关键的是,运维团队从三百多人精简到了五十多人,剩下的人不再忙着重启服务器、扩容磁盘,而是专注于业务优化和系统创新。小李现在带团队做的第一件事,是用Serverless搭了一套智能补货系统——根据历史销售数据和天气、节假日等因素,自动预测每家门店的下周进货量,把缺货率从12%降到了3%。
Serverless不是万能药
老王团队的成功有借鉴意义,但也要说几句大实话:Serverless不是银弹,它有自己的适用边界。
适合用Serverless的场景:
- 流量波动大、有突发峰值的应用
- 开发迭代频繁、需要快速上线的场景
- 后台任务、ETL、数据处理等批处理工作
- 低频访问的接口或服务
- 内部工具和原型验证
不太适合Serverless的场景:
- 需要长期保持连接的应用(如WebSocket服务)
- 对延迟极其敏感的核心交易系统(微秒级要求)
- 有复杂状态管理需求的应用
- 合规要求严格的金融行业核心系统(部分场景)
- 计算密集型任务(如视频转码、大规模训练)
老王团队在改造时也踩过坑。有一次把一套实时库存同步服务迁移到Serverless,结果因为冷启动延迟(函数第一次被调用时需要几秒初始化),导致库存数据延迟了10多秒才更新,引发了连锁反应。后来他们调整了策略:核心链路保留容器部署,非核心链路全面Serverless化。
给传统企业的几点建议
如果你也是传统企业的IT负责人,正在考虑上云或者Serverless化,老王团队的经验可以给你一些参考:
1. 不要追求”一步到位”
全面迁移风险太大,建议从非核心、流量波动大的系统开始试点,积累经验后再推广到核心业务。
2. 关注”遗留成本”
Serverless的按量计费模式对低负载场景特别友好,但如果你有一些7×24小时持续运行的服务,可能传统容器部署反而更划算。算好账,别为了Serverless而Serverless。
3. 重视代码改造
从传统架构迁移到Serverless,不是简单地把代码搬到云上就行。需要重新设计接口、调整部署方式、优化函数粒度,这一步省不得。
4. 建立可观测性体系
Serverless环境下,传统监控手段基本失效。需要建立基于日志、指标、链路的可观测性体系,才能快速定位问题。
5. 培养新技能
Serverless运维和传统运维差别很大,团队需要学习函数编排、事件驱动架构、无状态设计等新技能。老王团队的做法是让每个人都轮流参与改造,边做边学。
尾声
去年年底那个”砍一半IT预算”的死命令,今年年初已经成了历史。现在老王的IT团队不仅没裁员,反而招聘了十几个新人——都是做数据科学和AI应用的,公司想把零售数据和AI结合起来,搞智能选品、精准营销、动态定价。
老王在行业峰会上分享这个案例时,说了句话让我印象很深:”Serverless不是让我们少雇人,而是让我们把人力花在对的地方。以前我们一半的人在管服务器,现在一半的人在想怎么用数据帮公司赚钱。”
这家企业的故事还没有结束。按照他们的规划,明年还要把核心的订单履约系统也迁移到Serverless架构,目标是把整体IT成本再降30%。至于剩下的70%——那是公司准备投到新技术研发上的预算。
从”管服务器”到”用数据”,这就是Serverless给传统企业带来的最大价值。它解决的不仅仅是成本问题,更是企业数字化转型的路径问题。
