项目总结1

背景:这是一个活动,按照流程操作能够领取兑换券,高峰期每分钟会有上百个请求领到兑换券。

从数据库层面上解决并发问题

整个项目的唯一难点就是保证多个用户对兑换券的合理竞争,在这个过程中,必须有一道“关卡”将这些请求排序,让它们有序的进行访问,这跟秒杀活动有点像,只不过程度上来说没有那么激烈,所以我们采用了数据库层面上来保证。

之所以将这道“关卡”设在数据库一是比较好理解、二是比较容易实现、三是因为数据库是唯一安全的“关卡”(流程为请求—》web/JVM—》memcache—》数据库,因为存在多个JVMmemcache虽然是唯一的但也没有数据库安全)。具体来说,是根据数据库的unique机制来保证的,我们在代码层面将这道“关卡”抽象出“兑换券分配器”,数据模型如下:

字典表,兑换券:

id

key

1

xxx

2

xxx

保存用户是否领取过兑换券的表,相当于兑换券的分配器:

id

uidunique

1

123456

2

NULL

像秒杀这种活动基本思想都是对同一时刻大量的请求进行排序,可以设置多个“关卡”(还可以用C或者shell实现某一时间段对http请求进行排序),一层一层的将请求流进行剥离,最终减小数据库层面的压力,当然,实际情况可能比这复杂的多。

 

动态上线问题

像活动之类的上线一般都不是立即生效的,有具体的活动时间,所以需要动态上线(这名字听起来有点别扭),这时候最好有一个后台的开关。因为一旦上线,这个开关都会被频繁访问,所以最好放在缓存中。

重定向无法带参数的问题

在开发过程中碰到一个难题,可以这样来理解:有两个页面ABA页面是重定向到B页面的,B页面的访问可能来自A页面,但更多的时候是来自其他页面,怎么让B页面知道是从A页面跳转过来的呢?因为将参数直接写在URL是不安全的,所以最后决定使用memcache,在A页面的时候设置标记到memcache,然后在显示B页面的时候用一个ajax请求到controller,在controller里我从memcache里找这个标记,如果有这个标记,就表示是从A跳转过来的,然后删除它防止下次生效;如果没有就表示是从其他页面跳转过来的。因为用户操作不确定性以及memcache会失效的原因,所以这个办法也不是非常完美。

 

尽可能的测试,甚至不惜多写一些代码

因为活动是在活动期间打开的,所以你上线了并不知道你打开活动后,一切是否正常,如果不正常就来不及修复了。为此,我不惜修改了代码的逻辑,在后台设置了此活动的“超级测试员”,他不受活动开关以及活动次数的限制,能够走完整个活动流程,随时随地进行测试。我相信,这个功能是最出色的,因为它不再让我担心受怕。

尽可能将变化的因素分离出来动态管理

有一些东西是变化的,就算产品告诉你,这个已经确定了,但是你不能保证他不反悔,如果你代码写死了,你就必须重新上线一次,要知道,上线是要经过老大们审批的,各种麻烦。所以,为了将我们程序员“懒惰”品质发扬光大,最好将这些变化因素设置成动态可变的,比如活动的时间,活动的开关等等。

日志很重要

不管做什么,做完美不容易,就算你考虑的再全面,你也可能面临用户的投诉。当收到投诉的时候,我们首要任务是安抚用户,让用户满意,然后查找问题,给用户和自己一个交代,以免下次重复犯错。在这个查找问题的过程中,日志就显得特别重要,比如有用户投诉没收到兑换券,我看代码发现在分配兑换券入口的前面有N多个异常可能会抛出,但这些异常的抛出却直接返回,没有进行任何的异常记录,这个时候你就会觉得很无助。

 

时刻保持对数据的敏感,记录必要数据,证明自身的价值

动肯定是有目标的,往往这些跟产品是挂钩了的,就比如这个活动,你肯定很想知道它到底对产品目标起了多大的作用,这个时候就需要数据作为支持,最好记录下每半个小时消耗多少个兑换码。这只是冰山一角,提醒我们以后在开发中务必保持对产品数据的敏感性。

猜你喜欢

转载自cantellow.iteye.com/blog/1189524
今日推荐