云数据库Redis兼容开源Redis,本文通过简单的示例,为您演示通过云数据库Redis实现在线游戏中的积分排行榜功能。

体验开发者云实验室

您可以通过开发者云实验室,免费获取一台配置了CentOS 7.7的ECS实例(云服务器)和一个Redis 5.0数据库实例,根据云实验室的教程,使用Java语言实现基于Redis数据库的游戏玩家积分排行榜功能。更多信息,请体验云实验室

环境说明

云产品 说明
ECS实例
  • 操作系统为Ubuntu 16.04.6。
  • 网络类型为专有网络,且与Redis实例属于同一专有网络。
Redis实例 网络类型为专有网络,且与ECS实例属于同一专有网络。
说明 如果Redis实例与ECS的专有网络不同,您可以更换Redis实例的专有网络,具体操作,请参见 更换专有网络VPC或交换机;如果网络类型不同,解决方法请参见 ECS实例与Redis实例的网络类型不同时如何连接

操作步骤

  1. 设置Redis实例的白名单,保障ECS实例和Redis实例可以互通。
    1. 获取ECS实例的内网IP地址。具体操作,请参见查询ECS实例的IP地址
    2. 将获取到的ECS内网IP地址添加至Redis实例的白名单中。具体操作,请参见设置IP白名单
  2. 登录ECS实例。具体操作,请参见连接方式概述
  3. 在ECS实例中,执行下述命令安装环境。
    sudo apt-get update
    sudo apt-get install openjdk-8-jdk
    apt install maven
  4. 执行下述命令,下载并解压示例代码。
    wget https://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/assets/attach/120287/cn_zh/1615470698355/source.tar.gz
    tar xvf source.tar.gz && cd source
  5. 执行vim src/main/java/test/GameRankSample.java命令,按照要求修改示例代码中各参数的值。
    说明 执行命令后,系统将进入编辑界面,输入 a可进入编辑模式。
    图 1. 参数配置示例
    参数配置示例
    参数 说明
    String host 分别填入Redis实例的专有网络连接地址与端口号,关于如何获取连接地址和端口号,请参见查看连接地址
    port
    String authString 账号的密码(该账号需具备读写权限),根据选取账号的不同,密码的填写格式有一定区别。关于如何创建账号,请参见创建与管理账号
    说明
    • 默认账号(即以实例ID命名的账号):直接填写密码即可。
    • 新创建的账号:密码格式为<user>:<password>。例如自定义账号为testaccount,密码为Rp829dlwa,密码需填写为testaccount:Rp829dlwa。
  6. 按下Esc键退出编辑模式,输入:wq并按回车键保存配置并退出编辑界面。
  7. 执行下述命令,运行示例代码。
    mvn clean package assembly:single -DskipTests
    java -classpath target/demo-0.0.1-SNAPSHOT.jar test.GameRankSample

执行结果

示例代码注释

package test;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;

public class GameRankSample {

  static int TOTAL_SIZE = 20;

  public static void main(String[] args) {
    //连接地址,可通过Redis控制台获取
    String host = "r-gs50a75e1968****.redis.hangzhou.rds.aliyuncs.com";

    int port = 6379;
    Jedis jedis = new Jedis(host, port);
    try {
      //实例密码
      String authString = jedis.auth("Pass!123"); //password
      if (!authString.equals("OK")) {
        System.err.println("AUTH Failed: " + authString);
        return;
      }
      //Key(键)
      String key = "Game name: Keep Running, Alibaba Cloud!";
      //清除可能的已有数据
      jedis.del(key);
      //模拟生成若干个游戏玩家
      List<String> playerList = new ArrayList<String>();
      for (int i = 0; i < TOTAL_SIZE; ++i) {
        //为每个玩家随机生成一个ID
        playerList.add(UUID.randomUUID().toString());
      }
      System.out.println("Inputs all players ");
      //记录每个玩家的得分
      for (int i = 0; i < playerList.size(); i++) {
        //随机生成数字,模拟玩家的游戏得分
        int score = (int) (Math.random() * 5000);
        String member = playerList.get(i);
        System.out.println("Player ID:" + member + ", Player Score: " + score);
        //将玩家ID和分数添加到相应键的SortedSet中。
        jedis.zadd(key, score, member);
      }
      //输出打印全部玩家排行榜
      System.out.println();
      System.out.println("       " + key);
      System.out.println(" Ranking list of all players");
      //从对应key的SortedSet中获取已经排好序的玩家列表
      Set<Tuple> scoreList = jedis.zrevrangeWithScores(key, 0, -1);
      for (Tuple item : scoreList) {
        System.out.println(
          "Player ID:" +
          item.getElement() +
          ", Player Score:" +
          Double.valueOf(item.getScore()).intValue()
        );
      }
      //输出打印前五名玩家的信息
      System.out.println();
      System.out.println("       " + key);
      System.out.println("       Top players");
      scoreList = jedis.zrevrangeWithScores(key, 0, 4);
      for (Tuple item : scoreList) {
        System.out.println(
          "Player ID:" +
          item.getElement() +
          ", Player Score:" +
          Double.valueOf(item.getScore()).intValue()
        );
      }
      //输出打印特定玩家列表
      System.out.println();
      System.out.println("         " + key);
      System.out.println(" Players with scores from 1,000 to 2,000");
      //从对应key的SortedSet中获取已经积分在1000至2000的玩家列表
      scoreList = jedis.zrangeByScoreWithScores(key, 1000, 2000);
      for (Tuple item : scoreList) {
        System.out.println(
          "Player ID:" +
          item.getElement() +
          ", Player Score:" +
          Double.valueOf(item.getScore()).intValue()
        );
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      jedis.quit();
      jedis.close();
    }
  }
}