环境: ASP.NET, SQLSERVER, 服务器端单应用,单数据库。
场景:客户端应用调用后台服务的会员支付扣款接口,完成会员折扣、账单流水、会员余额变更等操作。
问题:在高峰期多客户端调用该接口时,出现部分调用处理时间长的问题。如正常接口调用在0.1s左右返回,但高峰时段(午市)1000多笔订单中会出现20笔左右耗时长达几秒甚至几十秒。
因此,想请教下该如何优化?
接口业务代码:
支付扣款接口主要处理:查找会员、查询优惠信息、记录账单信息、记录其他流水信息。
写数据库时,但是将上述步骤返回的sql语句作为一个事务提交处理,同时为了保证订单的唯一性,对写操作加锁。代码大致如下:
// get sql objects
lock(obj){
DB.Execute(sqlobjs);
}
自己能想到方案:
- 使lock的范围尽可能的小,但现只对数据库写入加锁,无法再缩小范围;
- 减少sqlobjects的操作集,如只保留会员余额变动、账单记录,其余的如账单详情使用其他的异步线程处理;
说明:因为接口挂在一大型ERP应用下,我怀疑是否在某个时间点由于ERP对数据库的操作,导致该接口的SQL操作慢,但因为对SQLServer性能监测方面不是太熟悉,也没个定论。
之前也没有这种并发的程序设计经验,在此希望各位朋友能给点意见和推荐一些并发方面的阅读资料。
在此感谢!
分布式失误+微服务改造,大体的思路我觉得是这个,具体的实施方案看业务
1.查询会员或者优惠信息等可以提请处理放置于redis或者内存中,减少支付时的前置查询时间,扣款时即可做到内存计算扣款
2.后置的添加消费记录,增加积分,商品等相关信息的修改等可以引入消息队列处理,由具体的服务去做
总的来说流程拆分,微服务改造,然后注意整个事务,比如核心的支付扣款无法分布式处理,因为需要等待扣款结果和事务确认,其它的还是可以拆分的