選擇Skynet+Redis+Mysql作為游戲服務器框架


一個人做游戲,服務器的開發也就成了必然的事情

選擇服務器框架Skynet

選擇skynet的原因不僅僅是因為雲風是我的偶像,也有一下幾個原因

  • 輕量級,會lua就可以開發游戲邏輯
  • 有成熟的項目先例
  • 性能高效,可分布式

配置開發環境

本人用mac開發,windows建議安裝Linux虛擬機進行開發

配置 Skynet

  • clone Skynet下來,進入目錄,運行make macosx命令

配置 Mysql

下載Mysql

$ brew install mysql

啟動Mysql

$ brew services start mysql
$ mysql_secure_installation

按照提示設置用戶和密碼繼續

$ mysql -uroot -p

輸入密碼后成功鏈接mysql

測試

test目錄下有一個testmysql.lua 創建一個‘skynet’ database 並且配置好用戶密碼測試,這時有個鏈接問題

Client does not support authentication protocol requested by server

解決辦法如下:

方案一
USE mysql;
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '831015';
FLUSH PRIVILEGES;

root是用戶名,localhost是ip地址127.0.0.1都是特指本機,mysql_native_password是舊的密碼驗證機制,831015是密碼,最后別忘了分號;
運行testmysql.lua 鏈接成功

方案二

修改mysql配置文件:

[mysqld]
default_authentication_plugin=mysql_native_password

Redis 和 Mysql數據同步方案

整體思路

玩家登錄后讀取Mysql數據緩存到Redis中,邏輯操作再redis中進行,斷線后進行落地

Mysql表設計與必要信息

1.  user //id自增的角色信息,用來標識玩家
2.  money //主鍵為user id 做游戲,貨幣是必須的
3.  snode //記錄服務器信息,包括版本更新迭代信息
4.  role //一人多號,id自增
5.  item //主鍵為role id 

Redis表設計與Mysql映射

redis數據使用hashmap存儲與sql表的關系,以表名+分隔符+數據唯一id作為key來存儲
譬如說這條信息'role':${uid}:${rid},其中role為代表role表,${uid}代表此玩家uid作為可變參數${rid}作為此角id可變參數,玩家使用uid與rid作為邏輯參數,服務器查詢redis庫進行查詢驗證操作

實現方式

因為要修改redis表並且將redis中的數據落地到Mysql中,所以要增加必要的格式檢查以免程序操作失誤引起意外

  1. 服務器啟動時候分析MySQL表結構,將表結構信息緩存在全局常量里
  2. 修改redis使用剛才分析的表數據統一進行格式驗證
  3. 落地操作進行日志跟蹤

注意

服務器架構部署方案

使用框架自帶的watchdog服務+游戲類服務

部署設計思路

watchdog負責管理連接,從client開始連接到生成agent之前的socket data通信數據,轉發到SignInServer進行處理,完成后通知watchdog創建客戶端agent並保存,agent是客戶端代理,因為lua虛擬機天然的優秀隔離,用戶自身狀態保存在這里,使用時候取用。所有業務邏輯被agent轉發處理並回執,agent收到回執發給客戶端完成整個通信聲明周期

watchdog服務

修改了watchdogsocket data部分,游戲連接握手使用socket data進行轉發給SignInServer(自己實現的注冊服務)

游戲類服務

  • IDServer
  • SignInServer
  • DaoServer
  • LogicServer

IDServer

  • 全局的
  • 可分布式的
  • 無狀態

生成guid是門技術,單獨取出維護,方便以后拓展優化,因為精力有限,目前方式是開了一個協程周期(每分鍾)更新隨機種子,使用uuid進行id的生成

SignInServer

  • 全局的
  • 可分布式的
  • 無狀態

路由保存在watchdog中,每個客戶端連接后分配一個物理SignInServer服務器(可以本機,取決於自己),處理客戶端連接握手部分,使用狀態機進行狀態驅動,處理客戶端socket連接后數據,設置好超時時間,處理注冊和自動登錄邏輯

DaoServer

  • 全局的
  • 可分布式的
  • 無狀態

負責客戶端上線后的MySql數據拉取到Redis與斷線后Redis的落地到MySql操作

LogicServer

  • 全局的
  • 可分布式的
  • 無狀態

負責游戲邏輯,玩家狀態通過詢問agent獲取處理,如果是復雜玩法(如多人副本)可以新增一個有狀態服務進行拓展,不過有狀態服務要分布式的話要維護好與agent的連接關系

結束語

耗時三個月零零散散終於把自己的服務器部分完整了(。・∀・)ノ,已經開始做小游戲了,使用Unity,有完整的熱更流程,有完整的服務器部分,程序只有我自己,光桿司令,確實是比較累的,不過我會堅持的。萬一財富自由了呢
ε=ε=ε=( ̄▽ ̄)


PS:歡迎評論(。^▽^)

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM