目录

golang + docker 写服务的部分感受

以前写用 go 语言主要是为了代替 c 语言写算法。直到最近几年 docker,k8s 等容器化部署方式的普及,java写的服务越发感觉臃肿,因此有计划用go实现服务。

使用 go 写服务的原因

以前写的服务大部分是 java 实现的,但是随着容器化部署的普及,Java写的服务越来越大,打包起来也特别麻烦

在封装java服务的image时,需要打包的有

  1. jvm(jar或jdk)
  2. tomcat(或jetty等)
  3. 服务相关jar包

这几项加起来很容易就能到 200-300M,如果碰上引用较多的巨无霸包,轻松破 400M,即使使用从 java11 开始的特性,只打包用到的模块,占用空间也不小,而且如果使用了 springboot 等全家桶的话配置起来还比较麻烦。

而用golang编译服务的话,只用一个文件即可实现上面3部分的内容,纯服务打包后基本也就 5-6M

有前端代码的话,前端代码也可以很方便的打包进二进制文件中。

技巧
虽然磁盘占用看似不是十分重要,但是某些无状态的编译发布情况下,每次都要重新编译发布,这时体积小的,结构简单的会更有优势

用golang写服务的优点

下面结合我的感受说一下用golang写服务的优点

  1. 可使用协程,执行速度快,内存占用小
  2. 编译出来的时机器码,发布内容足够小,编译出来的只有一个可执行文件
  3. 跨平台编译,甚至直接在 linux 环境中可编译 windows 下可执行的文件
  4. 不再依赖其他虚拟机等,部署方便,能很好的配合 k8s、 docker 等发布
  5. 资源依赖 github 等,开源组件多

缺点

当然用go也是需要一些付出的,使用过程中也有很多感觉相当麻烦的地方

  1. 部分语言的设计较为奇怪
  2. 可用资源太多导致轮子太多……需要一定的技巧把各种轮子合并在一起
  3. 满屏err处理
  4. 缺少泛型支持(最新版本已支持)

部分使用感受

代码结构

golang说简单也简单,但是复杂起来也是真复杂,看 github 上的代码结构,除了都放根目录的,基本上很难找到两个相同结构的代码。这里我基本参考了 golang-standards/project-layout 。这套结构和以前写过的语言有很大不同,例如以功能分文件夹(包),而不是层级。 举例 java 工程中 service,controller 等包结构看不到了,而是纵向拆分到了不同以功能分类的文件夹中。

对接口的使用

golang接口感觉设计的特别巧,可以先写实现再写接口,灵活程度极高,使用方式多样。

例如可以把目前使用的库的方法抽象成接口,可以不用实现接口就能直接使用方法,如果某天准备换另一个库,再进行实现。

Error及日志记录处理

首先特别吐槽一下 golang 里面 error 的处理方式,一页代码里至少有一半在处理错误。这里我目前也没啥好接口办法。

另一个问题是错误日志的记录,默认的error过于简单,只是个接口,不能记录堆栈信息,我后来用的 juju/errors 可以弥补一些原生err的问题。

Rest服务

其实 golang 已经封装了很大一部分功能。建议使用比较小的框架,例如 gin 或 echo等。这些框架只是对golang原生框架的一个封装,都是及其轻量级的。我建议使用 echo,因为gin没有错误的统一处理,在err满天飞的情况下更加显得雪上加霜。而 echo 有相应的错误统一处理,和一些集成在内部的中间件,可以直接用,稍微方便一些。

其他

其实能写的还有很多,要睡觉了,下次再说……