本文的完整代码见https://github.com/changjixiong/goNotes/tree/master/redisnote ,https://github.com/changjixiong/goNotes/tree/master/utils 及https://github.com/changjixiong/goNotes/tree/master/reflectinvoke如果文中没有显示链接说明链接在被转发的时候被干掉了,请搜索找到原文阅读。
概述
排行榜在各种互联网应用中广泛存在。本文将用一个范例说明如何利用redis和consul实现可水平扩展的等级排行榜服务。
redis的使用
实现排行榜有2个地方需要用到redis:
1.存储玩家的排行信息,这里使用的是Sorted Sets,代码如下
err := Rds.ZAdd(
PlayerLvRankKey,
redis.Z{
Score: lvScoreWithTime(playerInfo.Lv, time.Now().Unix()),
Member: playerInfo.PlayerID,
},
).Err()
其中lvScoreWithTime根据玩家等级及到达的时间计算score用于排名,等级相同的情况下,先到达等级的计算分值大于后达到的。
2.存储玩家自身的信息(名字,ID等),用于在排行榜中显示,毕竟仅仅只有排行的ID是不够的。这里采用hashset,代码如下
// ma的类型为map[string]string
err := Rds.HMSet(fmt.Sprintf("playerInfo:%d", playerID), ma).Err()
服务器端
先初始化redis连接
rdsClient := redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%d", "127.0.0.1", 6379),
Password: "123456",
DB: 0,
})
playercache.Rds = rdsClient
rankservice.Rds = rdsClient
增加初始玩家信息(略)。
注册服务器接口,此部分详细说明请参考《golang通过反射使用json字符串调用struct的指定方法及返回json结果》http://changjixiong.com/reflect-invoke-method-of-struct-and-get-json-format-result/
reflectinvoke.RegisterMethod(rankservice.DefaultRankService)
将服务注册到consul,此部分详细说明请参考《golang使用服务发现系统consul》http://changjixiong.com/use-consul-in-golang/
go registerServer()
在端口9528上开启服务用于结构client请求并返回结果
ln, err := net.Listen("tcp", "0.0.0.0:9528"