应用的规范定义是一个权衡的过程,你不能一下把规范定义得太死,太死了导致无法很好的在不同团队推广,最后可能导致规范失去信用。你也不能把规范定义得太泛,导致人们不知道如何下手。
在经历了传统部署(使用Ansible自动化部署应用到虚拟机)和Kubernetes的部署(使用Helm实现自动化部署)后,我们总结出一套云原生应用规范。它无关语言,无关框架,无关部署方式。
定义此云原生应用规范,我们有以下几个目的:
- 节约人员沟通成本:你不需要像以前那样需要反复的问对方的服务的端口;
- 节约运维成本:因为应用是标准的,所以,对于所有的应用,只需要使用统一的部署方式、统一的监控方式;
- 节约开发新应用的成本:根据规范,我们可以搭建各种语言或者框架的工程的脚手架;
以下是规范正文:
业务端口规范
所有的Pod或部署在虚拟机上的应用要求:
- http协议的服务使用8000端口
- grpc协议的服务使用9000端口
- 如果有其它协议可以在此添加
所有的Service:使用80端口
实践Tips1:遗留工作通常没有统一的端口,我们可以在部署环节通过环境变量来覆盖应用本身的端口来实现统一端口的目的。
实践Tips2:对于虚拟机上的部署,过去,一台机器上我们常常部署多个应用,所以要求每个应用的端口都不能相同。我们的做法,缩小虚拟机的配置,一个虚拟机只部署一个应用。
监控端口规范
监控端口统一使用:30000。监控端口与业务端口分离是基于安全的考虑而设计。而且监控端口只允许内部访问。
- 提供Prometheus监控接口
/private/prom
:返回 prometheus标准数据结构; - 提供优雅停机接口
/private/shutdown
:POST请求即代表发起停机操作; - 提供健康检查的接口
/private/health
:http code返回200代表健康; - 提供应用ready接口(可以与健康检查接口相同)
/private/ready
:http code返回200代表ready; - 提供实时修改日志级别的接口:/private/loggers 。这个接口,我们可以参考Java的Logback框架的实现。
Docker镜像规范
- 提供 curl 命令行,因为我们需要使用命令进行优雅机器:
curl -XPOST <http://127.0.0.1:30000/private/shutdown
; - 应用需要提供应用进程的环境配置入口。比如JVM应用需要提供 JAVA_OPTS 的环境变量设置
实践Tips:实际工作中,可创建一些基础镜像方便开发人员使用。
日志规范
日志要求统一输出到console。输入日志统一使用json结构。json结构中必须包含字段:
- @timestamp: 日志打印时间
- thread_name:进程名
- level:日志级别
- appId: 应用标识,同一个namespace全局唯一
- namespace:用于隔离app,租户的功能
- env:环境标识
- ver:应用版本
- msg:帮助debug问题的
- traceId: 其实就是traceId
同时,我们建议使用以下通用字段:
- event:代表事件,建议不要使用带空格的字符串
- method:方法名
- result:代表执行结果,可以是方法的返回结果,也可以http方法的response
- req:代表请求参数体
以下是日志示例:
{"@timestamp":"2021-07-15T17:24:07.912+08:00","userName":"Foobar","thread_name":"http-nio-8080-exec-150","level":"INFO","appId":"UserService","env":"prod","ver":"v1.0-5598","event":"register_user"}
实践Tips1:在实际工作,我们需要为不同的语言实现符合此日志规范的框架。
实践Tips2:日志规范需要配合日志处理环节考虑,在日志处理环节没有准备好之前,保持原样是更明智的选择。
小结
此规范已经在我们团队实践一年多。正在向其它团队延伸的过程。不敢说它是一套面面俱到的规范,但是它是一套能在一些团队进行落地的规范。
每个人都存在认知不足的情况,我也是人,所以我也不例外。此规范只是版本1.0。将来发现不足,持续改进。
Last modified on 2024-02-26