/go-lottery

Golang 实现各式各样的抽奖逻辑后台

Primary LanguageGo

抽奖活动服务端 - Golang

TODO

  • 使用 go module
  • 各抽奖例子不再依赖 iris,独立成模块

6 种抽奖小栗子

关键点:奖品类型,数量有限,中奖概率,发奖规则
并发安全性问题:互斥锁,队列,CAS递减(atomic)
优化:通过三列减少单个集合的大小

govendor 包管理工具

安装

go get -u -v github.com/kardianos/govendor

初始化

# 在当前目录生成 vendor 文件夹
govendor init

导入项目依赖包

# 将项目使用的包导入 vendor 文件夹
# 缩写: govendor add +e
govendor add +external

本地同步依赖包

# 重新安装依赖包到 vendor 文件夹
govendor sync

数据设计 - MySQL

奖品表 - gift

字段 属性 说明
id int,pk,auto_increment 主键
title varchar(255) 奖品名称
prize_num int 奖品数量:0 无限;>0 限量;<0 无奖品
left_num int 剩余奖品数量
prize_code varchar(50) 0-9999 标识 100%,0-0 表示万分之一的中奖概率
prize_time int 发奖周期:D 天
img varchar(255) 奖品图片
display_order int 位置序号:小的排在前面
gtype int 奖品类型:0 虚拟币;1 虚拟券;2 实物-小奖;3 实物-大奖
gdata varchar(255) 扩展数据:如虚拟币数量
time_begin datetime 开始时间
time_end datetime 结束时间
prize_data mediumtext 发奖计划:[[时间 1,数量 1],[时间 2,数量 2]]
prize_begin datetime 发奖周期的开始
prize_end datetime 发奖周期的结束
sys_status smallint 状态:0 正常;1 删除
sys_created datetime 创建时间
sys_updated datetime 修改时间
sys_ip varchar(50) 操作人 IP

优惠券 - code

字段 属性 说明
id int,pk,auto_increment 主键
gift_id int 奖品 ID,关联 gift 表
code varcahr(255) 虚拟券编码
sys_created datetime 创建时间
sys_updated datetime 更新时间
sys_status smallint 状态:0 正常;1 作废;2 已发放

抽奖记录表 - result

字段 属性 说明
id int,pk,auto_increment 主键
gift_id int 奖品 ID,关联 gift 表
gift_name varchar(255) 奖品名称
gift_type int 奖品类型:同 gift.gtype
uid int 用户 ID
username varchar(50) 用户名
prize_code int 抽奖编号(4 位的随机数)
gift_data varchar(50) 获奖信息
sys_created datetime 创建时间
sys_ip varchar(50) 用户抽奖的 IP
sys_status smallint 状态:0 正常;1 删除;2 作弊

用户黑名单表 - black_user

字段 属性 说明
id int,pk,auto_increment 主键
username varchar(50) 用户名
black_time datetime 黑名单限制到期时间
real_name varchar(50) 联系人
mobile varchar(50) 手机号
address varchar(255) 联系地址
sys_created datetime 创建时间
sys_updated datetime 更新时间
sys_ip varchar(50) 用户抽奖的 IP

IP 黑名单表 - black_ip

字段 属性 说明
id int,pk,auto_increment 主键
ip varchar(50) IP 地址
black_time datetime 黑名单限制到期时间
sys_created datetime 创建时间
sys_updated datetime 更新时间

用户每日次数表 - user_day

字段 属性 说明
id int,pk,auto_increment 主键
uid int 用户 ID
day varchar(8) 日期:如 20180725
num int 次数
sys_created datetime 创建时间
sys_updated datetime 更新时间

缓存设计

基本要求

  • 目标:提高系统性鞥,减少数据库依赖
  • 原则:平衡好"系统性能、开发时间、复杂度"
  • 方向:数据读多写少,数据量有限,数据分散

使用位置

  • 奖品:数量少,更新频率低,最佳的全量缓存对象
  • 优惠券:一次性导入,优惠券编码缓存为 set 类型
  • 中奖记录:读写差不多,可以缓存部分统计数据,如:最新中奖记录,最近大奖发放记录等
  • 用户黑名单:读多写少,可以按照 uid 散列
  • IP 黑名单:类似用户黑名单,可以按照 IP 散列
  • 用户每日参与次数:读写次数差异没有用户黑名单那么明显,缓存后的收益不明显

系统目录

├── _demo - 抽奖程序栗子目录
├── bootstrap - 程序启动相关
├── comm - 公共代码
├── conf - 配置相关
├── cron - 定时任务
├── dao - 数据库相关操作
├── services - 数据服务类相关
├── dataSource - 数据源
├── utils - 通用工具
├── script - 独立运行的脚本
├── thrift - RPC thrift 相关的
├── vendor - 项目依赖包
└── weh - 网站相关
        ├── controllers - 控制器
        ├── middleware - 中间件
        ├── public - 静态文件
        ├── routes - 路由
        ├── views - 模板
        └── viewModels - 模板数据模型

commit 规范

  • [dev] + 新增的内容
  • [upd] + 更新的内容

未完待续。。。

如有错误,务必指出,谢谢 ^.^ !