实战--积分投票系统血泪教训

来源:互联网 发布:网络综艺点击量 编辑:程序博客网 时间:2024/04/29 04:06

好几天没有写博客了,一直忙这写这个积分投票-兑换礼包系统.有很多血泪的教训来分享下: 
之前,我一直是写手机接口的,跟前端基本上没有交集,即使有也是给内部提供管理平台: 
1.实时性:大量的操作是建立在memcache缓存的基础上的,mysql数据库是为了提供数据持久性和记录日志的.因此查询之前会先访问缓存,如果缓存不存在或者失效,去访问数据库. 


2.数据量比较大:数据库的索引没有建立到最好. 


3.权限的问题,不是所有人都拥有权限可以投票,于是我把拥有权限的用户id放入了一个数组中并放在缓存,同步到数据库里面,最后发现这次投票人数特别多,每次查询一个用户的权限,需要把所有人的权限都拿出来,使用in_array(),来判断,主管发现后,果断改啊,每个用户使用独立的key来保存是否拥有权限. 

4.安全性:从前端传递过来的参数要假设是不可靠的,在兑换礼包的时候,我从前端传递过来了礼包的类型和要扣除的积分,放入数据库中,哎!首先悲剧的就是要扣除的积分不能是传递过来的,而是根据礼包的类型来判断.并且要把礼包的类型做出范围配置来检查是否合法.刚写完程序的时候,主管看了看然后请求了一个url: www.example.com/?type=6&score=1,本来第六个礼包要扣除积分80个,结果现在只扣除1个积分用户就领取到了第六个礼包.然后要判断礼包只有六中type应该大于1,小于7.写成配置文件来判断如下:

/** * @brief 将礼包对应扣除的积分写成配置,不要相信用户提交的数据, * @return array(); */public function getTypes() {    return array(            11 => 5,    //礼包1对应扣除的积分5,同下            12 => 10,            13 => 20,            14 => 30,            15 => 50,            16 => 80    );}

5.防止刷积分的处理:如果用机器大量快速请求,有可能出现服务器挂掉,且出现一个人领取多个礼包,因此将用户id:uid和礼包类型:type做唯一索引: 
UNIQUE KEY unique_uid_type (uid,type), 
在memcache中存入一个1s过期的key,保证一个uid每秒只能领取一次礼包.

6.一些非实时的数据,采用数据查询时从缓存中读取,不存在再从数据库读取;增删改时清除该key的缓存.下次从数据库读取.结果由于只改变了查询的时候的缓存的key,没有改 增删改 数据时缓存的key,导致数据全部从数据库中读取..因此一定要保证,写入缓存和读取缓存的key保持一致.否则...

7.由于有很多页面,需要共享用户的信息,而用户信息需要经过处理,就把用户的信息放到了__construct()里面,也就是说所有的页面都会处理用户信息,结果有几个页面是不使用用户信息的...

8.命名的规范:对缓存命名时必须遵循团队规范,否则可能会和其他开发人员发生缓存key冲突.

9.特殊字符的编码处理:用户名是utf-8编码的,而程序中是gbk编码的,结果转码后发现,用户名凌乱了.处理办法:copy到txt文档中使用记事本打开,重新复制一遍,很多的用户名中会出现特殊字符比如双引号等,使用:htmlspecialchars();

10.数据表中增加一个create_time,用来记录时间排除bug

11.缓存设置的时间要根据具体的业务逻辑来设计,比如下面的场景:用户投票和兑换积分一般时间不会超过十分钟,因此,一些非实时的缓存的过期时间设置成10分钟就够了

12.将所有权限的检测封装到一个函数中统一处理,是代码更简洁方便

13.jsonencode()不能处理gbk编码:jsonencode('gbk','utf-8',$array);

这次的任务做的太失败了,太凌乱了,写出来的总结感觉也很凌乱,心情不爽,以后慢慢改吧!记录下来做日志,防止再犯同样的错误

1 0
原创粉丝点击