likes
comments
collection
share

golang项目工程实践

作者站长头像
站长
· 阅读数 23

背景

这几年一直都是在golang相关的服务端开发,经历过几个项目组,发现一些好的实践和一些不好的实践。这里把好的实践总结一下。

仓库与项目规范

  • 仓库规范

一个团队一个仓库,比如GoTeam,所有模块放在下面,每个模块的命名用短横线分隔,比如: demo-server, 以-server结尾。其中,协议文件单独放在以proto命名的仓库中, 公共proto放在proto/common 下, 各个server的proto放在各自的目录下,比如proto/demo-server/demo-service.proto,公共库放在common仓库下面。这样我们的项目目录就是:

GoTeam
-proto
--common
---common.proto
---common.pb.go
--demo-server
---demo-service.proto
---demo-service.pb.go
-gocommon
--common
-demo-server

模块名之所以按照这种规范定义,是因为后面建CI/CD流水线的时候,有一个规范的命名和目录接口,方便建立统一的模板。

  • 项目部署规范

项目是通过k8s平台去部署的,建立项目名和workload的命名,也需要规范起来。一般来说,一个团队的项目下的模块可以放在一个项目下面,但是要区分环境,比如开发环境,测试环境,预发布环境,正式环境。每个环境作为一个项目,这样我们就有了4个项目:

GoTeam_后端_开发环境
GoTeam_后端_测试环境
GoTeam_后端_预发布环境
GoTeam_后端_正式环境

然后各个模块就可以在各个项目下单独建一个workload, 命名规范和仓库名类似,但是正式环境会有多地部署,需要加上地域后缀做区分,比如:

GoTeam_后端_正式环境
- demo-server-gz
- demo-server-nj
- demo-server-tj

备注:把各个模块放到一起,易于管理,比如加权限的时候不会因为有多项目(每个模块一个项目的方式)而加多次。

框架与公共库

  • rpc框架

我们选择的rpc框架是grpc, 主要考虑是开源的,社区完善,有完善的文档和资料,支持http2, 性能足够好。

  • 序列化协议

protocol buffer, 这个就不解释了。

  • 公共库

我们维护了一个公共库,封装一些组件的使用,比如log, config, mysql, kafka, redis, es, 错误码定义与处理等。其中,配置最好用配置中心,配置中心的配置更易于管理,安全性和时效性也好。

  • 自动生成代码

提前创建好一个demo-server, 将公共库的一些基本能力,如日志,配置,拦截器放在demo-server里,然后根据这个demo-server可以通过脚本,基于proto协议文件生成新的服务代码。

分支管理

特性开发的分支管理有两种方式。

一种是基于开关的主干开发模式,这种开发模式是适用于一个模块只有很少人参与开发,一般2-3人以内。基于开关的主干开发模式优点是不用维护多个分支,分支合并的时候冲突解决,它需要维护一些功能开关,每个新特性如果对已有逻辑有影响,则需要新维护一个功能开关。

另外一种是基于分支的特性开发,分支开发,新特性开发拉一个分支,分支开发完成合入到master分支,这里为了避免其他人把你的合入master特性代码发布线上,这里引入一个test分支,待测试的代码都合入测试分支,有修改先在feature分支上修改,修改完成后合入test分支,最后测试通过,将feature分支的代码合入master分支。

CI/CD流水线建设

  • 创建服务流水线模板

k8s平台虽然时候可以手动创建服务,但是每次手动创建服务的过程也挺繁琐的,比如需要配置镜像地址,配置端口,基础配置文件,环境变量等。k8s平台会提供一些接口,可以通过流水线创建一个模板,新服务创建的时候自动创建,并部署到对应的集群上。

  • 服务更新

服务的更新也可以由流水线触发,这里有两种模式,一种是基于master或者test代码的发布,比如一个feature分支开发完成之后,合入test分支或者master分支,会自动触发测试环境部署流水线。如果要发布线上,需要先手动触发预发布更新流水线,并且在预发布流水线上创建一个tag。更新正式环境的时候,可以用预发布创建好的tag进行发布更新。

日志监控与告警

  • 日志

业务系统是不用感知日志系统的存在,正常用日志库打日志即可。在我们服务的基础镜像里,会包含filebeat进程,自动采集日志并发送到ES上。为了方便查询,日志打印的时候需要按照固定的规范,比如可以支持解析trace_id列,后需要查日志的时候可以根据trace_id进行日志查询

日志的索引最好按照业务线进行创建,并且是天级日志,这样可以通过trace_id将各个模块的日志都能串起来,方便跟踪一个请求的所有日志。

  • 监控

监控也是依赖日志,filebeat识别出,对于监控类型的日志,特定的前缀,并且消息体用json格式,将日志记录发往ES(监控索引,方便kibana配置面板), 另外也会发送到kafka, 后续发送到专门的监控平台或者统计平台。

关键的监控项包括:

  1. 接口成功率

2)接口平均耗时,最大耗时等

  1. 接口调用量

  • 告警

我们不可能一直盯着监控,当服务异常的时候,通过发消息的方式告警出来,最好将告警通过机器人的方式发送到群里,并且明确指出这个接口是谁负责的,最好也能打印出报错的trace_id,方便查问题。

转载自:https://juejin.cn/post/7397030700455723049
评论
请登录