项目介绍
在日常生活中,各种抽奖活动都是很常见的,比如年会抽奖,刮刮乐,体育彩票,双色球,支付宝,微信中的抢红包, 微博抢红包,支付宝集福卡等,这些都大大丰富了我们的生活,当然,我基本上是没搞到什么奖,年会抽奖也把我漏了。。。,下面我就讲带大家来揭秘一下各种抽奖活动的实现, 代码将以 golang 实现
抽奖系统的业务介绍
- 抽奖活动的业务需求,既复杂又多变
- 奖品类型和改路设置
- 如何公平抽奖,安全发奖
抽奖系统的技术挑战
- 网络并发编程,数据读写的并发安全性问题
- 高效的抽奖和发奖, 提高并发性能
- 系统优化, 这么把 redis 更好的利用起来
抽奖活动之企业抽奖
package main
import (
"fmt"
"math/rand"
"net/http"
"strings"
"sync"
"time"
)
//全局变量,存储用户列表
var userList []string
//锁
var mu sync.Mutex
//当前系统当前抽奖人数
func count(w http.ResponseWriter, r *http.Request) {
count := len(userList)
countStr := fmt.Sprintf("当前总共参与人数: %d\n", count)
w.Write([]byte(countStr))
}
//导入用户名单
func importUser(w http.ResponseWriter, r *http.Request) {
strUsers := "小明,张三,李四,王五,周六,周日,卷福,斯瓦辛格,李小龙"
users := strings.Split(strUsers, ",")
count1 := len(userList)
for _, u := range users {
u = strings.TrimSpace(u)
if len(u) > 0 {
mu.Lock()
userList = append(userList, u)
mu.Unlock()
}
}
//用户数量
count2 := len(userList)
str := fmt.Sprintf("当前总共参与人数: %d, 成功导入用户数:%d\n", count1, count2)
w.Write([]byte(str))
}
//抽奖
func lucky(w http.ResponseWriter, r *http.Request) {
count := len(userList)
if count > 1 {
//生成随机数
seed := time.Now().UnixNano()
index := rand.New(rand.NewSource(seed)).Int31n(int32(count))
user := userList[index]
//重新组织 userList 删除取出的那个
mu.Lock()
userList = append(userList[0:index], userList[index+1:]...)
mu.Unlock()
w.Write([]byte("当前中奖用户:" + user))
fmt.Sprintf("当前中奖用户: %s\n", user)
}
}
func main() {
//切片
userList = []string{}
//初始化 锁
mu = sync.Mutex{}
//定义访问路由
http.HandleFunc("/", lucky)
http.HandleFunc("/import", importUser)
http.HandleFunc("/count", count)
//监听端口,启动服务器
http.ListenAndServe(":8080", nil)
}