优惠券优惠的思路以及实践

前言:最近做关于优惠券的开发,但是发现优惠券量大了之后,性能完全跟不上,库中存200万条优惠券,发一张券竟然需要5分钟之久,然后我就着手优化,最终到发一张券只需要15毫秒左右,现在把整个思路以及代码贴出来,供大家一起讨论和学习。

简介

主要实现优惠券促销活动,首先创建活动,然后创建券组,采用预处理的方式提前进行制券,在第一版本主要实现,功能的基本业务。然后在分支实现,大数量和高并发问题。

分支1.1

1:解决优惠券编码重复问题,原先采用的是获取数据库所有的券,然后去比对是否重复,如果库数据量达百万的时候就会出现非常缓慢,而且会 出现经常制券失败等,所以此版本舍弃原先采用随机数的模式,通过推特的雪花算法来避免唯一,但是依然保留优惠券前缀和后缀。

2:由原来的异步采用线程修改为线程池,以为高并发时候存在大量的线程占内存空间。

3:由原来制券采用for循环模式修改为批量制券,而且采用分配插入优惠券,一批次目前定为5000.

4:加入消息队列(采用rabbitMQ)对于某一批次添加失败,把失败的放入对列中,通过队列进行补救,已到达高可用。避免大批量优惠券来回重新导入 消息队列对于异常信息拒绝解决并重返消息队列中,配置2个消费者以避免其中一个服务异常,消息处理出现死循环

分支1.2

1:加入操作日志

目的:跟踪热点数据,查询日志快速跟踪应用程序中的慢查询或慢操作,为后面的优化奠定基础

2:加入异常日志

目的:快速的获取线程的异常问题,通过日志中的数据能快速修改

3:采用技术 通过aop和rabbitmq中间件来做,这样减少由于日志问题给程序带来的效率问题

未做优化效率统计

采用数据库mysql

数据:添加25个有效活动,每个活动下分别有2个券组,每个券组下制券是5万张。优惠券表中250万条记录

业务:一个会员消费同时满足这25个活动要送50张优惠券。

统计:整个发券过程经过10次统计得出大约消耗是306s,其中每次获取优惠券耗时6s。如果多次循环必然带来性能的瓶颈

更新优惠券状态大约耗时是0.5s,从上我们可以看出我们的性能问题主要出在获取优惠券上。所以才1.3版本主要通过程序来解决这个问题

分支1.3

目的:通过程序代码和优化数据库来提高性能

具体方案:

1:以前获取券组下所有的优惠券现在修改为每次只获取100条(经测试统计得出发送50张券消耗时间是106s,每次获取优惠券大约耗时是2s多,整体性能提升近3倍)

2:优化sql,加入组合索引(统计得出发送50张优惠券消耗总时间是2.5s,每次获取优惠券大约耗时是0.015s,整体的性能提升了近42倍)

3:加入本地缓存(如果一次性获取的优惠券先放入map中,那么下次如果还有就不需要从库中获取优惠券。统计发现:10件商品,每件商品发50张优惠券

不加本地缓存效率耗时是7.5s,加入本地缓存后耗时约5.5s,整体性能提升了2s)

效果分析:

4:对于发券采用批量更新来替代for循环(由上面的约5.5s性能提升为大约4.8s)

分支1.4

目的:通过异步和消息队列来进行发券

具体方案:

1:通过异步进行发券,这样可以提高cpu的利用率,同时通过消息队列来保证稳定性,避免出现异常导致返回前端发券成功,但是异步制券时候出现异常在发500张优惠券的时候效率大约提升了0.5s

2:对代码进行一次重构

原则:把大方法修改小方法,每个小方法处理一个业务,比如获取活动,那么这个方法的职责就是获取活动,同时每个小方法尽量有返回值,这样可以增加代码的可读性

分支1.5

1:采用redis做缓存,取当天有效的活动,活动下券组,券组下500张券存入缓存中。

2:加入定时任务,在每天12点时候更新缓存(这个时间可以通过热点数据来监控)

3:统计结果发现:

加入缓存后发送500张优惠券耗时只有2.7s,比之前的4.8s快了2.1s,大大的提升了性能

总结:代码我就不贴,大家可以自己去看。感兴趣的朋友可以在这个基础继续研发学习。在版本1.6可能加入分库分表,目前想采用的是当当的sharding-jdbc

源码地址

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • PHP生成唯一的促销/优惠/折扣码(附源码)

    每一个电子商务网站,现在有一种或多种类型的优惠/折扣/优惠券系统,给大家分享一下如何在PHP生成唯一的促销/折扣码.主要是实现一个优惠码系统,可用于跟踪用户来自某些特定的来源,例如有些主机促销的时候链接到别的页面会有优惠码生成,还有更多的促销代码等.因此,今天将讨论这样一个优惠码的实现过程 考虑的需求 代码应该很容易记住,因此保持短的长度是一个好主意,使用户可以很容易地记住它 没有特殊字符!它应该是字母数字组合,因为它会永远是为用户更容易记住 长度推广/折扣代码的正确.没有一个标准的长度,因为它

  • 使用Nopcommerce为商城添加满XX减XX优惠券功能

    公司的电商网站要做个优惠券的功能,nop框架,但我接触nop时间不多,最后还是为了功能而完成了.这中间肯定有很多小问题. Nopcommerce自带的促销功能感觉不是很好,首先优惠券功能放在购物车页面的,如果直接下单就用不了优惠.其次nop的优惠还必须要输入优惠券码很麻烦,最后不满足现在电商主流的单笔订单满XX减XX优惠券功能.但是nop提供了很多基础的方法,我们只要稍作更改就可以达到我们想要的. 优惠券首先需要和用户挂钩,用户可以领取和查看自己的优惠券.优惠券的功能nop基本已经实现了,但是没

  • 优惠券优惠的思路以及实践

    前言:最近做关于优惠券的开发,但是发现优惠券量大了之后,性能完全跟不上,库中存200万条优惠券,发一张券竟然需要5分钟之久,然后我就着手优化,最终到发一张券只需要15毫秒左右,现在把整个思路以及代码贴出来,供大家一起讨论和学习. 简介 主要实现优惠券促销活动,首先创建活动,然后创建券组,采用预处理的方式提前进行制券,在第一版本主要实现,功能的基本业务.然后在分支实现,大数量和高并发问题. 分支1.1 1:解决优惠券编码重复问题,原先采用的是获取数据库所有的券,然后去比对是否重复,如果库数据量达百

  • Vue.js项目前端多语言方案的思路与实践

    目录 一.通常有哪些内容需要处理 二.基本思路 三.具体实践中的一些细节 1.获取当前应该采用何种语言的getLang模块的实现 2.Vux组件的多语言包的配置 3.vux-loader的配置 4.自定义组件内外文案的多语言化 5.vuex-i18n的实现 6.图片的多语言化 7.在当前页面通过按钮切换当前语言后,如何更新当前页面的内容? 8.Yaml中特殊字符的转义 总结 前端的国际化是一个比较常见的需求.但网上关于这一方面的直接可用的方案却不多.最近刚做了一版基于Vue.js的多语言实现,在

  • 问个高难度的复杂查询(在一个时间段内的间隔查询)

    我想在一个时间段内然后按照间隔时间来查询数据 select * from 监控温度表 where 监控温度表.时间 between '" + Str(dtStart.Value) + "'AND '" + Str(dtEnd.Value) + "'order by id 这个是在一个时间段内查询,现在要加个时间间隔来查询,不知所云,望高手解答 其中dtStart.Value和dtEnd.Value是DTPicker1控件 举例:比如说我查询时间段在 2007-1-5

  • Python爬虫_城市公交、地铁站点和线路数据采集实例

    城市公交.地铁数据反映了城市的公共交通,研究该数据可以挖掘城市的交通结构.路网规划.公交选址等.但是,这类数据往往掌握在特定部门中,很难获取.互联网地图上有大量的信息,包含公交.地铁等数据,解析其数据反馈方式,可以通过Python爬虫采集.闲言少叙,接下来将详细介绍如何使用Python爬虫爬取城市公交.地铁站点和数据. 首先,爬取研究城市的所有公交和地铁线路名称,即XX路,地铁X号线.可以通过图吧公交.公交网.8684.本地宝等网站获取,该类网站提供了按数字和字母划分类别的公交线路名称.Pyth

  • 基于django2.2连oracle11g解决版本冲突的问题

    上次用django2.2和oracle11g,在migrate的时候发生了版本冲突,最终将Oracle升级到了12c才解决问题 那么到底能不能用别的方法来解决这个冲突呢?想了个解决思路,实践一下: 用django2.2连Oracle12c环境下做migrate,创建基础表 将基础表导出,再导入到Oracle11g数据库中 用django2.2连Oracle11g 实施步骤 1.用django2.2连Oracle12c环境下做migrate,创建基础表 在前文中已经完成,连接到数据库,可以看到有1

  • PHP如何限制定时任务的进程数量

    前言 现在的工作中,经常要写一些脚本做一些异步的操作. 一般是大量的数据修改,或者解决部分并发问题. 为了能够稳定的做好数据处理,一般情况下会用定时脚本的方式. 那么问题来了. 可能存在的问题 当我们处理大量数据的时候,脚本的执行时间可能很长,或者重复处理某条数据(写错的情况下). 为了避免数据的重复处理.运行脚本过多导致服务器压力过大等问题,我们需要限制脚本的运行数量. 如何做 思路一 查询某种标识的进程数量,如果超过一定数量,则直接退出,不处理. 思路二 记录每次的PID,可以使用 文件.r

  • 怎样优化今日头条IOS安装包

    前言 今日头条 iOS 端从 2016 年起就关注到了安装包大小的问题,并启动了包大小优化.2017 年,我们将当时的经验发表为技术文章 <干货|今日头条iOS端安装包大小优化-思路与实践>[1]. 如今三年过去了.今日头条在继续探索包大小优化时实践了更多思路,包括构建配置.图片压缩.__TEXT 段迁移.二进制段压缩等.这些优化项在业务入侵较少的前提下给今日头条带来了显著的包大小收益.同时,整个业界在包大小优化上也产出了更多方案.因此我们更新文章,期待与大家共同交流包大小优化这件事. 表格:

  • 使用SpringSecurity 进行自定义Token校验

    背景 Spring Security默认使用「用户名/密码」的方式进行登陆校验,并通过cookie的方式存留登陆信息.在一些定制化场景,比如希望单独使用token串进行部分页面的访问权限控制时,默认方案无法支持. 在未能在网上搜索出相关实践的情况下,通过官方文档及个别Stack Overflow的零散案例,形成整体思路并实践测试通过,本文即关于该方案的一个分享. 参考官方文档 SpringSecurity校验流程 基本的SpringSecurity使用方式网上很多,不是本文关注的重点. 关于校验

  • 后端代码规范避免数组下标越界

    目录 抛出问题 回答问题 举个栗子 解题思路 解题实践 实践1: 实践2: 抛出问题 数组下标越界真的是开发过程中的痛,除了在开发过程中各种判断是否设置,是否为空,还有其他优雅的办法解决吗? 回答问题 肯定是有的 举个栗子 比如,我有一个工具性质的方法如下: 我怎么保证 $batchUserCover[$userid]['pickedFootprint'] 和 $batchFootprintList[$userid]['list'] 不会有下标越界的问题呢? //批量获得图片故事 优先精选故事

  • JavaScript架构前端不能没有监控系统原因

    目录 监控系统 前端监控具体能解决什么问题? 异常报错问题 性能检测问题 运营反馈工具 为什么要选择自研? 自研前端监控的技术栈 监控系统 提到监控系统,大部分同学首先想到的是后端监控.很明显,比如检测服务器性能,数据库性能,API 的访问流量,以及各种服务的运行情况等等,都与后端息息相关.而前端更多承担的是 UI 展现的角色,主要关注页面怎么排版设计,好像没什么需要监测的地方,因此一直以来都没有涉及到监控的概念. 于是呢大家就一致认为:只要后端稳定可控,应用就是稳定可控的,可实际情况真的是这样

随机推荐