Commit 29b6d86fdeb4f3f61c1d0a0bcd8e562ea27d9442

Authored by zhangqijia
1 parent 69d286a7

update plugin doc

1 all: gen game 1 all: gen game
2 IMGTIME := $(shell date "+%G%m%d_%H%M%S") 2 IMGTIME := $(shell date "+%G%m%d_%H%M%S")
3 -pname = plugin-$(IMGTIME).so  
4 - 3 +pname = plugin-$(IMGTIME)
  4 +race = -race
  5 +#DEBUG = -gcflags "-l -N"
  6 +DEBUG=
5 gen: 7 gen:
6 protoc -I./protos --go_out=./protos --go-grpc_out=./protos ./protos/*proto 8 protoc -I./protos --go_out=./protos --go-grpc_out=./protos ./protos/*proto
7 protoc-go-inject-tag -input=./pb/*.pb.go 9 protoc-go-inject-tag -input=./pb/*.pb.go
@@ -9,20 +11,20 @@ gen: @@ -9,20 +11,20 @@ gen:
9 test: 11 test:
10 go run cmd/test/client.go 12 go run cmd/test/client.go
11 http: 13 http:
12 - go run -race cmd/httpserver/http.go cmd/httpserver/AccountAction.go 14 + go run $(race) cmd/httpserver/http.go cmd/httpserver/AccountAction.go
13 15
14 game: 16 game:
15 go run -race cmd/gameserver/*.go 17 go run -race cmd/gameserver/*.go
16 build: 18 build:
17 - go build -race -o bin/account cmd/http.go  
18 - go build -race -o bin/game cmd/gameserver/*.go  
19 - go build -race -o bin/test cmd/test/client.go 19 + go build $(race) -o bin/account cmd/http.go
  20 + go build $(race) -o bin/game cmd/gameserver/*.go
  21 + go build $(race) -o bin/test cmd/test/client.go
20 regame:plugin 22 regame:plugin
21 lsof -i:8850 | grep "agent" | grep -v grep | awk '{print $$2}' | xargs -I {} kill -USR1 {} 23 lsof -i:8850 | grep "agent" | grep -v grep | awk '{print $$2}' | xargs -I {} kill -USR1 {}
22 24
23 plugin: 25 plugin:
24 cd bin && rm -rf ./plugin*.so && cd - 26 cd bin && rm -rf ./plugin*.so && cd -
25 - go build -race --buildmode=plugin -o bin/$(pname) cmd/gameserver/plugin/*.go  
26 - cd bin && ln -s $(pname) plugin.so && cd - 27 + go build $(race) $(DEBUG) --buildmode=plugin -o bin/$(pname).so cmd/gameserver/plugin/*.go #--ldflags="-pluginpath=$(pname)"
  28 + cd bin && ln -s $(pname).so plugin.so && cd -
27 29
28 .PHONY: all build protos test cert plugin 30 .PHONY: all build protos test cert plugin
29 \ No newline at end of file 31 \ No newline at end of file
@@ -7,16 +7,15 @@ @@ -7,16 +7,15 @@
7 * 日志 7 * 日志
8 * 集群 8 * 集群
9 * 分布式 9 * 分布式
  10 +* 热更
10 11
11 12
12 -技术点  
13 -* golang 热更  
14 -  
15 -组件名字 13 +技术点:
16 * mongo 14 * mongo
  15 +* redis
17 * etcd 16 * etcd
18 * proto + models 查询 17 * proto + models 查询
19 -* redis 18 +* golang plugin
20 19
21 ## 目录结构 20 ## 目录结构
22 ```text 21 ```text
@@ -60,17 +59,20 @@ $ go get google.golang.org/grpc/cmd/protoc-gen-go-grpc @@ -60,17 +59,20 @@ $ go get google.golang.org/grpc/cmd/protoc-gen-go-grpc
60 $ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc 59 $ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc
61 ``` 60 ```
62 ## 文档 61 ## 文档
63 -[证书制作](doc/cret.md)  
64 -[包组成结构](doc/proto.md)  
65 - 62 +* [证书制作](doc/cret.md)
  63 +* [包组成结构](doc/proto.md)
  64 +* [go plugin热更的使用](doc/plugin.md)
66 65
67 ## Usage 66 ## Usage
68 -编译 & 运行 游戏服 & 登录服务 67 +### 编译 & 运行 && 游戏服 & 登录服务
69 ```shell 68 ```shell
70 -$ make account  
71 $ make game 69 $ make game
  70 +$ make account
72 ``` 71 ```
  72 +
73 测试 73 测试
74 ```shell 74 ```shell
75 $ make test 75 $ make test
76 -```  
77 \ No newline at end of file 76 \ No newline at end of file
  77 +```
  78 +
  79 +###
78 \ No newline at end of file 80 \ No newline at end of file
cmd/gameserver/plugin/plugin.go
@@ -15,13 +15,13 @@ func init() { @@ -15,13 +15,13 @@ func init() {
15 func GetActionMap() map[interface{}]interface{} { 15 func GetActionMap() map[interface{}]interface{} {
16 logger.Debug("init protocode...") 16 logger.Debug("init protocode...")
17 am := make(map[interface{}]interface{}) 17 am := make(map[interface{}]interface{})
18 - am[uint32(pb.ProtoCode_LoginReq)] = LoginRpc 18 + am[uint32(pb.ProtoCode_LoginReq)] = "LoginRpc"
19 19
20 return am 20 return am
21 } 21 }
22 22
23 func LoginRpc(msg components.IMessage) (int32, interface{}) { 23 func LoginRpc(msg components.IMessage) (int32, interface{}) {
24 - //logger.Debug("11111111cmd: %v, msg: %s", msg.GetHeader().GetMsgID(), msg.GetData()) 24 + logger.Debug("11111111cmd: %v, msg: %s", msg.GetHeader().GetMsgID(), msg.GetData())
25 req := pb.LoginReq{} 25 req := pb.LoginReq{}
26 if err := proto.Unmarshal(msg.GetData(), &req); err != nil { 26 if err := proto.Unmarshal(msg.GetData(), &req); err != nil {
27 logger.Error("loginRpc err: %v", err) 27 logger.Error("loginRpc err: %v", err)
cmd/gameserver/plugin/plugin_test.go 0 → 100644
@@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
  1 +package main
  2 +
  3 +import (
  4 + "plugin"
  5 + "pro2d/common/logger"
  6 + "testing"
  7 +)
  8 +
  9 +func TestGetActionMap(t *testing.T) {
  10 + p, err := plugin.Open("./bin/plugin.so")
  11 + if err != nil {
  12 + logger.Error("open error: ", err)
  13 + return
  14 + }
  15 + logger.Debug("open success")
  16 + symbol, err := p.Lookup("GetActionMap")
  17 + if err != nil {
  18 + logger.Error(err)
  19 + return
  20 + }
  21 + logger.Debug("%v", symbol)
  22 +}
common/components/plugin.go
@@ -59,9 +59,12 @@ func (p *Plugin) GetAction(cmd uint32) interface{} { @@ -59,9 +59,12 @@ func (p *Plugin) GetAction(cmd uint32) interface{} {
59 } 59 }
60 60
61 func (p *Plugin) SetActions(am map[interface{}]interface{}) { 61 func (p *Plugin) SetActions(am map[interface{}]interface{}) {
  62 + p.Actions.Range(func(key, value interface{}) bool {
  63 + p.Actions.Delete(key.(uint32))
  64 + return true
  65 + })
62 for k, v := range am { 66 for k, v := range am {
63 cmd := k.(uint32) 67 cmd := k.(uint32)
64 - p.Actions.Delete(cmd)  
65 p.Actions.Store(cmd, v) 68 p.Actions.Store(cmd, v)
66 } 69 }
67 } 70 }
common/components/server.go
@@ -115,12 +115,6 @@ func (s *Server) SetTimerCallback(cb TimerCallback) { @@ -115,12 +115,6 @@ func (s *Server) SetTimerCallback(cb TimerCallback) {
115 } 115 }
116 116
117 func (s *Server) Start() error { 117 func (s *Server) Start() error {
118 - if s.plugins != nil {  
119 - if err := s.plugins.LoadPlugin(); err != nil {  
120 - return err  
121 - }  
122 - }  
123 -  
124 port := fmt.Sprintf(":%d", s.port) 118 port := fmt.Sprintf(":%d", s.port)
125 l, err := net.Listen("tcp", port) 119 l, err := net.Listen("tcp", port)
126 if err != nil { 120 if err != nil {
@@ -34,7 +34,7 @@ server_game: @@ -34,7 +34,7 @@ server_game:
34 port: 8850 34 port: 8850
35 pool_size: 1 35 pool_size: 1
36 debugport: 6061 36 debugport: 6061
37 - # plugin_path: "./bin/plugin.so" 37 + plugin_path: "./bin/plugin.so"
38 mongo: 38 mongo:
39 <<: *default-mongo 39 <<: *default-mongo
40 dbname: "game" 40 dbname: "game"
doc/plugin.md 0 → 100644
@@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
  1 +
  2 +## 热更golang有状态服务
  3 +1. golang是有状态的
  4 +2. 数据+逻辑代码分离
  5 +3. 主要热更的是逻辑代码
  6 +
  7 +
  8 +## 启用插件
  9 +1. 启用插件, 配置文件 conf.yaml, 填入插件.so文件的路径
  10 +```
  11 +server_game:
  12 + plugin_path: "./bin/plugin.so"
  13 + mongo:
  14 + <<: *default-mongo
  15 + dbname: "game"
  16 +```
  17 +2. 编译程序 & 插件.
  18 +```shell
  19 +$ make plugin
  20 +```
  21 +* 程序和插件需要同一个golang的环境。
  22 +* golang对同一个插件只能加载一次。可以修改.so文件名字 + 软连接的方式来处理
  23 +
  24 +
  25 +## 写插件代码
  26 +插件中的代码主要是对线上程序 `协议=>逻辑` 的热更.
  27 +
  28 +比如我们要修改游戏服务协议号为`1`的逻辑。 则在`cmd/gameserver/plugin/plugin.go`文件中修改。
  29 +1. 在函数`GetActionMap`中增加一行
  30 +```
  31 +am[uint32(1)] = HotRpc
  32 +```
  33 +2. 增加函数`HotRpc`
  34 +```
  35 +func HotRpc(msg components.IMessage) (int32, interface{}) {
  36 +}
  37 +```
  38 +
  39 +3. 编译插件 & 可以参考Makefile:plugin
  40 +```Makefile
  41 +IMGTIME := $(shell date "+%G%m%d_%H%M%S")
  42 +pname = plugin-$(IMGTIME).so
  43 +plugin:
  44 + cd bin && rm -rf ./plugin*.so && cd -
  45 + go build -race --buildmode=plugin -o bin/$(pname) cmd/gameserver/plugin/*.go
  46 + cd bin && ln -s $(pname) plugin.so && cd -
  47 +```
  48 +
  49 +4. 把插件放到指定位置, 并给游戏服发送热更指令。可以参考Makefile:regame
  50 +```Makefile
  51 +regame:plugin
  52 + lsof -i:8850 | grep "agent" | grep -v grep | awk '{print $$2}' | xargs -I {} kill -USR1 {}
  53 +```
0 \ No newline at end of file 54 \ No newline at end of file