云原生项目实践DevOps(GitOps)+K8S+BPF+SRE,从0到1使用Golang开发生产级麻将游戏服务器—第8篇

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 云原生项目实践DevOps(GitOps)+K8S+BPF+SRE,从0到1使用Golang开发生产级麻将游戏服务器—第8篇

介绍



这将是一个完整的,完全践行 DevOps/GitOpsKubernetes 上云流程的 Golang 游戏服务器开发的系列教程。


这个系列教程是对开源项目 Nanoserver 的完整拆解,旨在帮助大家快速上手 Golang(游戏)服务器后端开发。通过实践去理解 Golang 开发的精髓 —— Share memory by communication(通过通信共享内存)


同时这个项目可能还会涉及到 Linux 性能调优(BPF 相关的工具)和系统保障(SRE)的相关的工作。


Step-By-Step 开发 Mahjong Server


  • 单体架构理解 Mahjong Server 业务 -> Nano Distributed Game Server(分布式) + 微服务 改造。
  • Demo:go-mahjong-server


牌(Tiles)抽象



定义 Tile struct


微信图片_20220611153244.png


type Tile struct {
  Id    int
  Suit  int
  Rank  int
  Index int
}


  • Id108 张牌,用 0~107 标识每一张牌。
  • Suit:三种花色,用 0~2 标识每一种花色(0:,1:,2:)。
  • Rank9 种点数,用 1~9 标识(如:1条,9条,1筒,9筒,1万,9万等…)。
  • Index:索引(条:1~9,筒:11~19,万:21~29)。


通过一张表来理解


三种花色,每种类型牌的索引(Index):


条(1 ~ 9) 筒(11 ~ 19) 万(21 ~ 29)
1 1条 11 1筒 21 1万
2 2条 12 2筒 22 2万
3 3条 13 3筒 23 3万
4 4条 14 4筒 24 4万
5 5条 15 5筒 25 5万
6 6条 16 6筒 26 6万
7 7条 17 7筒 27 7万
8 8条 18 8筒 28 8万
9 9条 19 9筒 29 9万


所有牌(这里是 108 张)的 ID 编号:


(0 ~ 35) (36 ~ 71 (72 ~ 107
0 1条 36 1筒 72 1万
1 1条 37 1筒 73 1万
2 1条 38 1筒 74 1万
3 1条 39 1筒 75 1万
4 2条 40 2筒 76 2万
5 2条 41 2筒 77 2万
6 2条 42 2筒 78 2万
7 2条 43 2筒 79 2万
8 3条 44 3筒 80 3万
9 3条 45 3筒 81 3万
10 3条 46 3筒 82 3万
11 3条 47 3筒 83 3万
12 4条 48 4筒 84 4万
13 4条 49 4筒 85 4万
14 4条 50 4筒 86 4万
15 4条 51 4筒 87 4万
16 5条 52 5筒 88 5万
17 5条 53 5筒 89 5万
18 5条 54 5筒 90 5万
19 5条 55 5筒 91 5万
20 6条 56 6筒 92 6万
21 6条 57 6筒 93 6万
22 6条 58 6筒 94 6万
23 6条 59 6筒 95 6万
24 7条 60 7筒 96 7万
25 7条 61 7筒 97 7万
26 7条 62 7筒 98 7万
27 7条 63 7筒 99 7万
28 8条 64 8筒 100 8万
29 8条 65 8筒 101 8万
30 8条 66 8筒 102 8万
31 8条 67 8筒 103 8万
32 9条 68 9筒 104 9万
33 9条 69 9筒 105 9万
34 9条 70 9筒 106 9万
35 9条 71 9筒 107 9万


编码实战



通过 ID 获取 Tile

一个算术问题,没啥好说的。

  • 三种花色,每种有 9 类不同的牌,每类又有 4 张相同的牌。

internal/game/tile.go


func TileFromID(id int) *Tile {
  if id < 0 {
    panic("illegal tile id")
  }
  var (
    tmp = id / 4
    h   = tmp / 9
    v   = tmp%9 + 1
    i   = h*10 + v
  )
  return &Tile{Suit: h, Rank: v, Index: i, Id: id}
}


编写单元测试函数


TileFromID 函数上右击选择 Generate Unit Tests For Function,我们编写它的单元测试函数。


微信图片_20220611153249.png

internal/game/tile_test.go


func TestTileFromID(t *testing.T) {
  type args struct {
    id int
  }
  tests := []struct {
    name string
    args args
    want *Tile
  }{
    // 定义一堆用例
    {"1条", args{id: 0}, &Tile{Suit: 0, Rank: 1, Index: 1, Id: 0}},
    {"1条", args{id: 1}, &Tile{Suit: 0, Rank: 1, Index: 1, Id: 1}},
    {"1条", args{id: 2}, &Tile{Suit: 0, Rank: 1, Index: 1, Id: 2}},
    {"1条", args{id: 3}, &Tile{Suit: 0, Rank: 1, Index: 1, Id: 3}},
    {"9条", args{id: 35}, &Tile{Suit: 0, Rank: 9, Index: 9, Id: 35}},
    {"1筒", args{id: 36}, &Tile{Suit: 1, Rank: 1, Index: 11, Id: 36}},
    {"1筒", args{id: 37}, &Tile{Suit: 1, Rank: 1, Index: 11, Id: 37}},
    {"1筒", args{id: 38}, &Tile{Suit: 1, Rank: 1, Index: 11, Id: 38}},
    {"1筒", args{id: 39}, &Tile{Suit: 1, Rank: 1, Index: 11, Id: 39}},
    {"9筒", args{id: 71}, &Tile{Suit: 1, Rank: 9, Index: 19, Id: 71}},
    {"1万", args{id: 72}, &Tile{Suit: 2, Rank: 1, Index: 21, Id: 72}},
    {"1万", args{id: 73}, &Tile{Suit: 2, Rank: 1, Index: 21, Id: 73}},
    {"1万", args{id: 74}, &Tile{Suit: 2, Rank: 1, Index: 21, Id: 74}},
    {"1万", args{id: 75}, &Tile{Suit: 2, Rank: 1, Index: 21, Id: 75}},
    {"9万", args{id: 107}, &Tile{Suit: 2, Rank: 9, Index: 29, Id: 107}},
  }
  for _, tt := range tests {
    t.Run(tt.name, func(t *testing.T) {
      if got := TileFromID(tt.args.id); !reflect.DeepEqual(got, tt.want) {
        t.Errorf("TileFromID() = %v, want %v", got, tt.want)
      }
    })
  }
}


执行:


cd internal/game/mahjong 
go test -v tile_test.go tile.go mahjong.go


微信图片_20220611153349.png

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
10天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
42 2
|
20天前
|
jenkins Devops Java
DevOps实践:Jenkins在持续集成与持续部署中的价值
【10月更文挑战第27天】在快速发展的软件开发领域,DevOps实践日益重要。Jenkins作为一款流行的开源自动化服务器,在持续集成(CI)和持续部署(CD)中扮演关键角色。本文通过案例分析,探讨Jenkins在Java项目中的应用,展示其自动化构建、测试和部署的能力,提高开发效率和软件质量。
42 2
|
10天前
|
运维 安全 Devops
DevOps实践中的安全审核和合规性
DevOps实践中的安全审核和合规性
|
10天前
|
监控 安全 Devops
DevOps实践中,如何平衡开发速度和安全审核的效率?
DevOps实践中,如何平衡开发速度和安全审核的效率?
|
10天前
|
Kubernetes 监控 负载均衡
深入云原生:Kubernetes 集群部署与管理实践
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术以其弹性、可扩展性成为企业IT架构的首选。本文将引导你了解如何部署和管理一个Kubernetes集群,包括环境准备、安装步骤和日常维护技巧。我们将通过实际代码示例,探索云原生世界的秘密,并分享如何高效运用这一技术以适应快速变化的业务需求。
36 1
|
12天前
|
存储 监控 Devops
DevOps实践:持续集成/持续部署(CI/CD)的实战指南
DevOps实践:持续集成/持续部署(CI/CD)的实战指南
|
13天前
|
运维 安全 Devops
DevOps实践中的安全审核和合规性
DevOps实践中的安全审核和合规性
|
12天前
|
Kubernetes 负载均衡 调度
Kubernetes集群管理与编排实践
Kubernetes集群管理与编排实践
|
12天前
|
Kubernetes Cloud Native 前端开发
Kubernetes入门指南:从基础到实践
Kubernetes入门指南:从基础到实践
24 0
|
15天前
|
运维 Devops jenkins
DevOps实践之持续集成与持续交付
【10月更文挑战第32天】在软件开发的快节奏世界中,DevOps已经成为提升效率和质量的关键策略。通过将开发(Development)和运维(Operations)紧密结合,DevOps促进了更快速的软件发布和更高的可靠性。本文将深入探讨DevOps的核心组成部分——持续集成(CI)和持续交付(CD),并展示如何通过实际代码示例实现它们,以帮助团队构建更加高效和稳定的软件发布流程。

热门文章

最新文章

下一篇
无影云桌面