本文的完整代码见 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,代码如下

运行情况

  consul上注册了2个自定义的服务,一个是名为serverNode的echo服务(来源 《go使用服务发现系统consul》),另一个是本文的排行榜服务rankNode。

  服务器接收到的请求片段

get: {"func_name":"AddPlayerExp","params":[4,41]}

get: {"func_name":"AddPlayerExp","params":[2,35]}

get: {"func_name":"AddPlayerExp","params":[5,27]}

get: {"func_name":"GetPlayerByLvRank","params":[0,3]}

  客户端在consul中查找到服务并连接rankNode_1

services ----------------------------------------------------------

&{consul consul [] 8300 false}

&{rankNode_1 rankNode [serverNode] 9528 127.0.0.1 false}

&{serverNode_1 serverNode [serverNode] 9527 127.0.0.1 false}

choose ------------------------------------------------------------

rankNode_1 &{rankNode_1 rankNode [serverNode] 9528 127.0.0.1 false}

  客户端收到的回应片段

get: {"func_name":"AddPlayerExp","data":[true],"errorcode":0}

get: {"func_name":"AddPlayerExp","data":[true],"errorcode":0}

get: {"func_name":"AddPlayerExp","data":[true],"errorcode":0}

get: {"func_name":"GetPlayerByLvRank","data":[[{"player_id":3,"player_name":"玩家3","exp":57,"lv":4,"online":true},{"player_id":2,"player_name":"玩家2","exp":31,"lv":4,"online":true},{"player_id":1,"player_name":"玩家1","exp":69,"lv":3,"online":true}]],"errorcode":0}

一点说明

  为什么说是可水平扩展的排行榜服务呢?文中已经看到,目前有2个自定的服务注册在consul上,client选择了rankNode_1,那么如果注册了多个rankNode,则可以在其中某些节点不可用时,client可以选择其他可用的节点获取服务,而当不可用的节点重新可用时,可以继续注册到consul以提供服务。