项目(4)——二次开发优化集卡系统

本次大版本开发是一个系统的二次开发,上一个人写不下去的系统转移到我这边,这种系统是最难维护的。就是上一个人写着写不下去,移交过来的系统。这种系统有以下几个特点:

   项目被几个人都维护过,导致历史逻辑和风格不一样。基本存在架构和数据表上的设计缺陷,导致逻辑异常复杂。不存在性能方面的设计,但是系统确实运行有点时间,导致几十万数据就开始卡卡顿。 
·       不存在高并发方面的设计考虑,连最基本的进程锁也没有。

       代码封装很差,一个方法200-500行到处都是。而且注释很少,所以上一个程序员开发时间周期远超预期。

       老板看着时间快到截止日期,直接强制从完不成的人手里将系统转移到我这边来。

   这就是外包项目习惯性的代码质量差,导致代码习惯性的难以维护,最后习惯性的烂尾一个常见情况。不过现在这种情况再逐步改善。一方面,大量的中小企业倒闭,释放了很多经验足够的进入外包,第二方面,代码质量差并不意味着速度快,只是意味着更难维护,第三更多的框架和硬性约束。代码质量就是有点保障。最明显的用框架的代码比原生手写代码更容易维护,基础漏洞也明显偏少。
  主要需求:将游戏里面的128个游戏角色迁移到小游戏里面,进行英雄集齐的活动,然后围绕这批游戏卡片,展开各种分享卡片活动,每日登录抽奖活动,视频观看随机奖励。由于是系统版本的升级,所以考虑的东西比较多。主要需求开发点:

常规的(每日签到 banner图  资讯  任务系统  领取奖励)
1.怪兽的管理  怪兽的图片很多 其中分每个怪兽有组合的属性 坦克 输出  疗愈  辅助  之类的多种组合属性,也有类似幼体 幻体  成熟这种唯一的属性,还有其他 归属种族  有的英雄属于好几个种族 。这里设计怪兽表的时候,就出现了一个问题,是简单定义一个字段比如cate  然后写入1,2,3 这种纯数字,然后映射属性,表示这个用户在这三个里面都是对应的,使用的是like字段,优势是简单,但是根本应对不了组合搜索,比如前端要搜索1,3的时候,直接搜不到结果。无法满足运营的需求。
 

2.每个用户都有自己的归属怪兽,这里怪兽表是点亮状态。每次点亮的时候,可以领取对应的点亮奖励。用户搜索的搜索的时候,是有点亮属性和未点亮属性的。一种设计是连表,每次都通过左连用户数据表查询数据(然后导致系统非常消耗资源),联表特别是联大表的数据操作,非常消耗运算资源。这是上个设计者给我留下的第二个问题


3.赠送的瞬发性,分享出去的卡片,由于一个卡片一次只能分享一次,同时只能被一个人领取。而领取的时候,采取的是领取成功后,直接add一次,但是可能这张赠送出去的卡片同时被俩个人add。设计者考虑不周,没有考虑这层

4. 领取的人一天只能领取三张,采用的事实时count ,导致实际领取的时候,时间超过了进程锁的时间

5.分享领取奖励的时候,没有并发限制,导致可以同时领取俩个奖励。

主要开发改动和优化设计,同时对新功能的拓展:
1.对怪兽属性表进行单独属性拆分,每个属性都用一个字段表示,不能为了组合方便,将属性全部放入一起。否则属性自由组合搜索的时候,根本搜不到结果。拆分后,直接where,就可以快速拿到结果。表设计出问题的时候,导致逻辑异常复杂。这里有个设计技巧,归属某个大类的字段比如position类定义字段的时候使用 position_1 position_2 进行定义 这样搜索字段的时候,就能实现数据库和变量的组合实现。上个设计者,就是因为发现拆分了字段还是无法实现自由组合搜索,干脆放到一个字段里面,试图用like的方式实现70%的效果,最少单独的like效果是可以实现,放弃了索引,放弃了自由组合。不过前端让人可以根据用户的点击,拼接成字符数组其实也可以实现。

2.查询怪兽的搜索,使用到了with   其实项目里面尽量不要使用连表操作。场景是用户的怪兽数据表里面记录了怪兽的id信息(只有id信息),然后用户对怪兽搜索,会将用户是否拥有该怪兽信息也返回出来。用户的怪兽表是很大,但是数据表很简单。设计者采用直观暴力的方式,直接用怪兽表join 用户拥有的怪兽表,然后对这张联表进行查询搜索。前面使用了like的搜索方式放弃了索引,叠加放弃了索引的情况下 join一张大表来查询数据,直接导致系统运行效率非常低。只有在数据量很小的情况下推荐使用join减少系统复杂度,大部分情况下都是建议在应用层对数据进行处理。改进方案,用户未登录搜索,直接单表查询怪兽(128个),用户登录,通过uid快速读取该uid拥有的怪兽id(uid是索引,而且表都是数字,只限定了一个字段的输出,所以效率超高)。这样运算压力全部跑到了应用层,应用层需要计算该怪兽是不是被用户拥有。

3.分享卡片的冲突问题,主要是一个人能点击俩次,导致第二次直接提示已经被领取,而实际第一次领取因为程序运行的缓慢,还在领取过程中,给网络不好点击了俩次的用户体验非常差,需要防止点击俩次情况(直接根据uid上进程锁)

点击分享的时候,需要在分享表上加已经分享的次数字段share_cout,已经被领取,否则需要判断次数的时候,上个设计者直接粗暴count,对分享链接被成功分享次数count  领取者次数也直接count,导致性能大幅度下降。这种设计的时候,需要在分享的时候,额外增加一个字段share_count,每次更新带上share_count 直接使用CAS算法。而对应的,领取的时候,用count出现了一个问题,用户同时点击领取不同卡片,可能导致用户领取超标,进程锁一般只锁3秒,而由于系统运行的复杂性,用户实际上可能偶发性的领取2张导致超标(这种场景已经非常罕见,但是偶尔会出现),初期设计者想不到解决办法,干脆直接不解决,导致总是有出现用户超标领的情况,系统卡顿超过3秒,就会超领。而其实解决这种,需要每次领取的时候,加入日期+uid作为唯一索引,没检测到就插入,检测到就用cas进行叠加。

4.用户订阅活动的展示,活动订阅表的设计实现,这是一个小型的搜索,但是发现里面涉及的搜索算法挺多,所以想到BOSS招聘里面搜索结果对你个人不准确的情况,因为确实很难排。


这个地方有好几重逻辑,一个活动分 上架时间,开始时间,技术时间,前端展示时间,前端下架时间了,推送时间,不再推送时间,被用户订阅时间。前端设定的需求是: 用户已经订阅(进行中,即将开始的)>活动进行中>活动即将开始>已经结束活动。主要是先拉取全部在线活动和即将开始活动还有已结束活动(正常列表),然后再根据用户的订阅权重对每个项目进行逻辑权限重排。需要用到多维数组的排序相关逻辑。

小结:用户量对系统复杂度的影响至关重要,很多低性能的系统设计在用户很少的时候,基本体现不出来,但是用户数量逐渐膨胀的时候,会发现各种问题。给别人修复BUG和中途接手其他人严重超工期的项目,难度比普通项目难度明显高一截。一个是你要理解原本的逻辑,第二个是原本逻辑出现结构性失误,改动非常大,第三个工期压缩的非常紧张,所以这种类型的单子都要有心理准备。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大梁来了

千山万水总是情,打赏一块行不行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值