某城商行上云记:引入Serverless后运维成本降六成开发周期缩短一半
一、一个被”告警”淹没的夜晚
张总盯着手机屏幕,凌晨两点,他的运维团队刚处理完第37条告警。这是他们本月遇到的第三次大规模故障——某城商行的核心账务系统,偏偏在这个节骨眼上,又双叒叕崩了。
“再这样下去,明年预算真顶不住了。”张总对旁边的CTO说。
这不是他第一次说这句话。过去三年,这家银行的运维团队从50人扩到了120人,但问题没少,反而越来越多。每年IT预算里,有超过60%花在了维护上,真正用于业务创新的钱,掰着手指头数都数得出来。
“我们得变一变。”CTO说,”上云,用Serverless。”
张总愣了一下。Serverless?这词儿他听说过,但总觉得是互联网公司的东西,银行能用吗?
二、传统架构的”重”,重在哪里
要理解Serverless,先得理解他们过去有多”重”。
这家银行的IT架构,说白了就是一堆服务器堆出来的。核心业务跑在几台大型机上,外围系统分散在几十台物理服务器上,每套系统都有自己的运维团队、自己的监控、自己的备份方案。
举个例子,他们有一个”信贷审批系统”,背后是:
- 2台应用服务器(跑Java)
- 2台数据库服务器(Oracle主备)
- 2台缓存服务器(Redis集群)
- 1台消息队列服务器(RocketMQ)
- 配套的负载均衡、防火墙、监控系统…
加起来,光这台信贷系统就要养4个DBA、3个运维工程师。而且最头疼的是,不管信贷业务量是大是小,这些服务器都得24小时开着。
平时业务量少的时候,这些服务器60%的算力都在空转,但钱照样在烧。
遇到高峰期(比如每年春季的信贷冲量),服务器不够用了,又得紧急采购、扩容,周期至少两个月。
“这就像一个餐厅,哪怕半夜没客人,也得开着灯、开着空调、养着一堆厨师和服务员。”CTO在一次内部会议上打了个比方。
三、上云:从”质疑”到”尝试”
上云这个话题,早在三年前就提过,但一直没推得动。
主要原因有三个:
- 顾虑一:数据安全。银行业务涉及大量敏感数据,”数据放别人那里,能放心吗?”这是老板们最关心的。
- 顾虑二:系统兼容性。很多遗留系统是十年前甚至更早建的,直接搬到云上,风险太大。
- 顾虑三:团队能力。现有运维团队习惯了运维服务器,突然要他们转向运维”服务”,能不能适应?
这次能推动,有几个关键因素:
- 监管环境变化:央行和银保监会相继出台了鼓励金融科技创新的政策,明确支持银行稳妥推进云计算应用。
- 同业案例增多:几家股份制银行和城商行已经完成了云迁移,效果不错。
- 成本压力实在太大:去年IT运维成本同比增长了40%,但业务增长只有15%,这个账谁都会算。
最终,CTO提出了一个”分步走”的方案:
第一步:选一个非核心系统试点,用Serverless架构重构,看效果。 第二步:如果效果好,再逐步推广到更多系统。 第三步:等团队适应后,再考虑核心系统的迁移。
选哪个系统做试点呢?大家一致同意——信贷审批系统。
原因很简单:这个系统业务量大、高峰期明显、日常算力利用率低,是Serverless最能发挥优势的典型场景。
四、Serverless到底是什么?
在讲具体改造之前,先通俗地解释一下Serverless。
很多人听到”Serverless”,第一反应是:”没有服务器?那代码跑在哪里?”
其实Serverless不是没有服务器,而是你不需要管服务器了。
打个比方:
- 传统模式:你开餐厅,得自己买地、盖房子、买设备、招厨师服务员。不管来不来客人,这些开销都在。
- Serverless模式:你直接租一个共享厨房,按使用量和时长付费。来一个客人,厨房就为你服务一个客人;没客人,你一分钱都不用付。厨师、清洁、设备维护,全都不用你管。
在技术层面,Serverless的核心是函数计算。你把业务逻辑拆成一个个独立的”函数”,每个函数完成一个具体的小任务。然后交给云平台,平台自动帮你:
- 根据请求量自动扩容或缩容
- 你只需要为实际使用的计算资源付费
- 平台负责底层运维、监控、故障恢复
五、改造过程:从”一盘散沙”到”精兵简政”
5.1 第一步:拆解功能,识别可以”函数化”的模块
原来的信贷审批系统,是一个单体应用,所有功能都耦合在一起。要改成Serverless,首先要做”拆解”。
他们把系统拆成了以下核心函数:
| 函数名 | 功能 | 触发方式 |
|---|---|---|
submitLoan |
接收信贷申请 | API网关 |
validateCredit |
验证申请人征信 | 定时任务 |
calculateRisk |
计算风险评分 | 消息队列 |
approveLoan |
审批通过 | 事件触发 |
sendNotification |
发送通知短信 | 事件触发 |
recordLog |
记录审批日志 | 异步调用 |
拆完之后,每个函数都是独立的,可以单独部署、单独扩展。
5.2 第二步:用代码说话
改造前,处理一笔信贷申请,需要几秒到几十秒,中间要调用多个微服务,还要排队等数据库资源。
改造后,用Serverless函数来实现:
# 改造前:单体应用,手动管理资源和状态
def handle_loan_application(applicant_data):
# 1. 验证基本信息
if not validate_basic_info(applicant_data):
return {"status": "error", "msg": "基本信息不完整"}
# 2. 查询征信(需要等待数据库响应)
credit_score = db.query(
"SELECT score FROM credit_table WHERE id = ?",
[applicant_data['id_card']]
)
# 3. 计算风险评分(复杂计算,需要CPU资源)
risk_score = calculate_risk(credit_score, applicant_data['income'])
# 4. 审批决策
if risk_score < 30:
status = "approved"
else:
status = "rejected"
# 5. 写数据库
db.execute(
"INSERT INTO loan_records VALUES (?, ?, ?)",
[applicant_data['id_card'], risk_score, status]
)
# 6. 发送通知
send_sms(applicant_data['phone'], status)
return {"status": status, "risk_score": risk_score}
# 改造后:Serverless函数,每个函数只做一件事
import json
import boto3 # 实际项目中用云厂商的SDK
# 函数1:接收申请
def submit_loan(event, context):
"""API网关触发,接收信贷申请"""
data = json.loads(event['body'])
# 异步写入消息队列,不阻塞返回
sqs = boto3.client('sqs')
sqs.send_message(
QueueUrl='loan-queue-url',
MessageBody=json.dumps(data)
)
return {
'statusCode': 200,
'body': json.dumps({'message': '申请已受理'})
}
# 函数2:验证征信
def validate_credit(event, context):
"""SQS触发,从队列读取申请,验证征信"""
for record in event['Records']:
body = json.loads(record['body'])
# 调用外部征信接口(可能耗时,但没关系,函数会自动重试)
credit_result = call_credit_api(body['id_card'])
# 结果写入临时表,供下一步使用
write_to_temp_table(body['id_card'], credit_result['score'])
# 函数3:计算风险
def calculate_risk(event, context):
"""定时触发,处理所有待审批的申请"""
# 读取临时表数据
pending = read_temp_table()
for item in pending:
# 风险计算逻辑
risk_score = compute_risk_score(
item['credit_score'],
item['income'],
item['loan_amount']
)
# 写入审批表
write_approval(item['id_card'], risk_score)
# 函数4:审批决策
def approve_loan(event, context):
"""事件触发,根据风险评分做决策"""
# 从审批表读取
approval = read_approval()
result = {
'approved': approval['risk_score'] < 30,
'risk_score': approval['risk_score']
}
# 写入最终结果
write_final_result(approval['id_card'], result)
# 触发通知函数
trigger_notification(approval['id_card'], result['approved'])
return result
# 函数5:发送通知
def send_notification(event, context):
"""事件触发,发送审批结果通知"""
data = json.loads(event['body'])
# 调用短信服务
sms_client = boto3.client('sns')
sms_client.publish(
PhoneNumber=data['phone'],
Message=f"您的信贷申请{'已通过' if data['approved'] else '未通过'}, 风险评分: {data['risk_score']}"
)
代码看起来多了,但每个函数都是独立的、可测试的、可复用的。 更重要的是,当业务高峰来临时,云平台会自动为每个函数分配更多计算资源,而不用人工干预。
5.3 第三步:数据层改造
Serverless架构下,数据库也要相应调整。他们做了两个关键改变:
- 用托管数据库替代自建数据库:不再自己维护MySQL集群,而是使用云厂商提供的RDS服务,自动备份、自动扩容、自动监控。
- 引入NoSQL用于高频读写场景:对于信贷申请这类写入量大、查询模式简单的场景,改用云原生NoSQL数据库,性能提升明显。
六、效果:数据不会说谎
改造完成后,张总最关心的两个指标,发生了变化:
6.1 运维成本下降60%
| 成本项目 | 改造前(月) | 改造后(月) | 降幅 |
|---|---|---|---|
| 服务器及运维人力 | 80万 | 32万 | 60% |
| 软件许可费 | 25万 | 0(改用开源+托管服务) | 100% |
| 机房电力及空调 | 15万 | 0(上云后无需机房) | 100% |
| 故障处理及应急采购 | 10万 | 3万 | 70% |
| 合计 | 130万 | 35万 | 73% |
更直观的解释是:
以前养120人的运维团队,现在只需要30人。剩下的90个人,有的转岗做业务开发,有的离职,但总体人力成本大幅下降。而且,Serverless模式下,云平台负责底层运维,他们只需要关注业务逻辑,不用半夜起来处理服务器故障了。
6.2 开发周期缩短50%
原来的信贷审批系统,每次新增一个功能,从需求到上线,平均需要6-8周:
- 需求分析:1周
- 开发:2-3周
- 测试:1-2周
- 部署上线:1周(还要协调运维团队)
改造后,同样的流程:
- 需求分析:1周(不变)
- 开发:1-2周(Serverless函数独立,开发并行)
- 测试:0.5-1周(单元测试覆盖率高)
- 部署上线:0.5周(一键部署,无需协调运维)
从平均7周缩短到平均3周,缩短了近60%。
而且,当业务高峰期来临时(比如每年春季信贷冲量),云平台会自动扩容,不需要人工提前采购服务器、做压力测试、写扩容方案。
七、挑战:不是所有问题都消失了
当然,这次上云改造也不是一帆风顺的。
7.1 团队适应期
最大的挑战不是技术,而是人。
原来的运维团队习惯了”守着一堆服务器”的工作模式,突然让他们转向Serverless,很多人一开始很迷茫:”服务器都不管了,我们还能干啥?”
CTO的做法是:
- 组织培训:邀请云厂商的技术专家,给团队做Serverless架构培训。
- 岗位转型:把一部分运维人员转型为”云架构师”和”DevOps工程师”,负责云资源管理和自动化运维。
- 外部引进:招聘了3名有云原生经验的工程师,带动团队氛围。
经过三个月的适应期,团队基本 transition 完成了。
7.2 遗留系统的兼容
信贷审批系统改完后,他们发现一个问题:很多老系统还是单体架构,和新的Serverless系统对接不上。
解决办法是做一个“适配层”:
# 遗留系统适配层
class LegacySystemAdapter:
"""将老系统的API包装成Serverless函数可以调用的形式"""
def __init__(self):
# 连接老系统的数据库
self.old_db = connect_old_database()
def get_credit_info(self, id_card):
"""适配老系统的征信查询接口"""
result = self.old_db.execute(
"SELECT * FROM credit WHERE id_card = ?",
[id_card]
)
return {
'score': result['score'],
'history': result['history'],
'source': 'legacy_system'
}
def submit_application(self, data):
"""适配老系统的申请提交接口"""
# 数据格式转换
converted_data = self.convert_format(data)
# 调用老系统接口
response = self.old_db.execute(
"INSERT INTO applications VALUES (...)",
converted_data
)
return {'application_id': response['id']}
这个适配层让新老系统可以共存,逐步替换。
7.3 安全和合规
银行业务对安全和合规要求极高。上云后,他们做了以下事情:
- 私有云部署:选择银行私有云,而不是公有云,确保数据不出银行内部网络。
- 加密传输:所有数据传输使用TLS 1.3加密。
- 访问控制:严格的IAM权限管理,最小权限原则。
- 审计日志:所有操作都有日志记录,便于事后审计。
- 合规认证:系统通过了等保三级认证和金融行业相关合规检查。
八、更深层的变化:不只是省钱
回过头看,这次上云改造带来的变化,远不止”省钱”和”提速”。
8.1 业务响应速度质的飞跃
过去,当业务部门提出一个新需求(比如”我想做一个面向年轻人的信用贷产品”),IT部门第一反应是:这个需求涉及哪些系统?需要多少人?排期多久?
现在,业务部门说需求,IT部门的反应是:这个需求可以拆成哪些函数?需要调用哪些云服务?多久能上线?
从”评估 feasibility”到”评估 implementation”,思维模式彻底转变了。
8.2 试错成本大幅降低
Serverless模式下,新功能的试错成本极低。因为:
- 不需要预先采购服务器
- 按实际使用量付费
- 可以快速上线、快速验证、快速调整
比如,他们想测试一个新的信贷产品设计,可以在一周内上线一个MVP版本,收集用户反馈,然后根据反馈调整。过去,这样的尝试可能因为”开发周期太长”而直接被否决。
8.3 人才结构优化
过去,运维团队是”大头”,开发团队相对较小。现在,情况反过来了:
- 开发团队:从30人增加到60人
- 运维团队:从120人减少到30人(部分转岗)
这意味着,银行的IT能力重心,从”维持系统运转”转向了”创新业务”。
九、给其他银行的建议
张总在总结这次上云经验时,说了几点建议:
9.1 不要试图”一步到位”
“我们一开始也想过,把核心系统全搬到云上,一劳永逸。后来发现,这不现实。最好的方式是分步走,先试点,再推广。”
9.2 选对试点系统
“试点系统要有代表性,最好是有明显的资源利用率不均、高峰期和低谷期差异大的特点。信贷审批系统就符合这些条件。如果试点选了一个全年都满负荷的系统,Serverless的优势就体现不出来。”
9.3 重视团队转型
“技术改造只是第一步,人才转型才是关键。我们花了三个月做培训和文化建设,才让团队真正适应Serverless模式。”
9.4 安全合规不能放松
“上云不代表可以降低安全标准。相反,因为架构变了,安全策略也要跟着调整。我们在改造过程中,专门聘请了安全顾问,确保每一个环节都合规。”
十、后记:一个关于”转型”的故事
三个月后,张总又在处理告警了。
但这次不一样。
告警不是来自服务器宕机,而是来自一个新功能的性能监控——某个Serverless函数的响应时间超过了预期。他点开监控面板,看到函数运行在云平台上,自动扩展到了100个实例,负载分布均匀,一切正常。
他调整了一下函数的超时时间,告警就消失了。
整个过程,不到五分钟。
“以前遇到这种事,我得打电话叫运维团队,等他们排查、定位、重启服务,至少两个小时。”张总笑着说,”现在,我只是做了一个配置调整。”
他望向窗外,城市的灯火次第亮起。这家城商行,正在从”传统银行”向”科技银行”转型。
Serverless不是终点,而是一个新的起点。
本文基于真实行业案例改编,具体数据和细节已做脱敏处理。
