# cgidemo 本工程是网关demo。 ## 编译依赖 * 共有第三方包工程:[golangpkgs](http://gitlab.chejinjia.cn/repository/commons/golangpkgs.git) ## 必要操作 ```shell # 取出共有第三方包工程,其中 /path/to 需要自己指定 # *** 如果其它工程做了软链接,则不需重复以下三步 *** mkdir -P /path/to/repository/commons cd /path/to/repository/commons git clone http://gitlab.chejinjia.cn/repository/commons/golangpkgs.git # 建立业务工程,并关联golangpkgs mkdir -p /path/to/repository/projects/src export GOPATH=/path/to/repository/projects cd /path/to/repository/projects/src ln -s /path/to/repository/commons/golangpkgs/vendor/ . # 如果其它工程做了软链接,则忽略此行 git clone git@gitlab.chejinjia.cn:repository/your_project.git # 本工程的链接 go build ... ``` ## RPC(微服务)的引入流程 **1. 在[rpc_protocols](http://gitlab.chejinjia.cn/repository/microservices/rpc_protocols)中找到需要使用的RPC(微服务)目录(如`arith`)** **2. 将目录(如`arith`)拷贝到自身工程的`rpc_apis`目录** `rpc_apis/arith/` **3. 创建rpc的客户端文件** `rpc_apis/arith/client.go` ```go package arith import ( "context" "fmt" "time" "github.com/smallnest/rpcx/client" "github.com/smallnest/rpcx/protocol" "github.com/smallnest/rpcx/share" ) type ArithXClient struct { xcli client.XClient } func (a *ArithXClient) Init(etcdAddrs []string, basePath, servicePath string) { opt := client.Option{ Retries: 1, RPCPath: share.DefaultRPCPath, ConnectTimeout: 10 * time.Second, SerializeType: protocol.JSON, CompressType: protocol.None, BackupLatency: 10 * time.Millisecond, } d := client.NewEtcdDiscovery(basePath, servicePath, etcdAddrs, nil) a.xcli = client.NewXClient(servicePath, client.Failtry, client.RandomSelect, d, opt) } func (a *ArithXClient) Add(ctx context.Context, req *ArithMulReq) (reply ArithMulReply, err error) { err = a.xcli.Call(ctx, "Add", req, &reply); return } func (a *ArithXClient) Mul(ctx context.Context, req *ArithMulReq) (reply ArithMulReply, err error) { err = a.xcli.Call(ctx, "Mul", req, &reply); return } ``` **4. 初始化一个RPC Client** 在`rpc_apis/init.go`添加以下内容 ```go package rpc_apis import ( "cgidemo/rpc_apis/arith" "cgidemo/common.in/config" ) var Arith *arith.ArithXClient func Init(etcdAddrs []string, conf *config.Configure) { Arith = &arith.ArithXClient{} Arith.Init(etcdAddrs, conf.Rpc.BasePath, conf.Rpc.Arith.Name) } ``` # 关于日志 ## 日志使用步骤 **1. 在要打印日志的包目录下,拷贝一份logger.go,并修改logger所属包名:** ``` ./controllers/ctrl_v1 └── logger.go ./controllers/ctrl_v2 └── logger.go ./common.in/task └── logger.go ``` **2. 在`main.go`中添加如下代码:** ```go // 通用logger commonLogger := logger.InitLogger(runmode, fmt.Sprintf("logs/%s.log", appname), maxSize, maxBackups, maxAge, disableStacktrace) // 单独设置 accessLogger := logger.NewInfoLogger(runmode, fmt.Sprintf("logs/%s-access.log", appname), maxSize, maxBackups, maxAge) // 设置需要使用logger的地方 // common日志 ctrl_v1.SetLogger(commonLogger) ctrl_v2.SetLogger(commonLogger) // access日志 task.SetLogger(accessLogger) ``` ## 错误日志规范 ```go l.Error("业务", zap.String("操作", "操作名称"), zap.String("参数或字段", "参数列表以及值"), zap.String("error", err.Error())) ``` #### mysql 错误日志 ```go l.Error("mysql", zap.String("sql", "SELECT from c_device"), // 操作+表名 zap.String("fields", utils.MarshalJsonString(field1, value1, field2, value2)), zap.String("error", err.Error())) ``` #### redis 错误日志 ```go l.Error("redis", zap.String("cmd", "SETEX"), // 命令 zap.String("args", utils.MarshalJsonString(key, seconds, value)), zap.String("error", err.Error())) ``` #### 调用rpc 错误日志 ```go l.Error("rpc", zap.String("call", "Arith.Add"), // 注册名.方法名 zap.String("args", utils.MarshalJsonString(req)), zap.String("error", err.Error())) ``` #### 内部函数调用 错误日志 ```go l.Error("func", zap.String("call", "Add"), // 函数名 zap.String("args", utils.MarshalJsonString(arg1, arg2, arg3)), zap.String("error", err.Error())) ```