那些用 go 做业务系统的公司或者个人,真的感受都资源节省,开发效率提升了吗?

10 天前
 xiaocaiji111

接触 go 至少 5 年了。一直关注 go 的发展,期间也用 go 做过不少工具,最近一年引入了生产用来开发业务系统。简单的 api 项目非常简单轻量,但是需要手动处理的东西也很多。

生产中使用的是 gin 框架,依赖注入使用 wire ,也编写了很多工具类,该有的都有了。处理复杂场景时依然显得力不从心,也有很多令人疑惑的地方。在 java 中通过一个注解来切面,就可以实现关键接口日志的记录。比如 @Log("删除管理员")。而在 go 中就麻烦很多,需要为每个接口添加中间件,想获取后面执行方法的参数和返回值也相当困难。我们记录日志,也不可能只能记一句话,还需要操作人信息和操作参数及结果。

编译速度没有想象的快,很多时候改动文件多了后,要半天,当然没有改动,第二次启动就快的多了(我们用的 goland )。

二进制启动快,这是优点,但是好像并没有带来什么收益,只是从一个开发人员角度来看,启动很快,很爽,对业务并没有带来什么收益。因为发布的流程是很复杂的,并不是扔上去就直接给用户用,相比较验收等流程来说,1 秒和 10 秒 50 秒几乎忽略不计。

二进制包下,这也是优点,2 阶段构建,我们使用 docker 镜像可以达到整体就 20m 左右,而同样的 springboot 达到 130m 左右(进一步模块化可以达到 80 左右)。但是服务器和制品库之间都是内网,几乎没有感受到明显差别,只对第一次拉取镜像有点用,后续镜像层拉过的都不会重复拉取。

内存占用 go 真的很低,20m 左右,springboot 启动就要给 512 避免内存溢出,当前 128 甚至 64 也可以启动,但是就不能用了。我们的业务服务器都是 2 核 4G ,感觉 go 有点浪费的感觉。

大内存,这点 go 做的不好,固定频率的 GC 在大内存占用时停顿明显。毛刺明显,而不像 java 可以根据业务选择合适的垃圾收集器,调优下很平滑。go 甚至没有提供可以选择的参数。

编程体验,都说 go 好,但是我不这么认为,对于工具类,简单 api 项目,go 确实很好。简单。不需要任何复杂的依赖。但是对于有一定复杂度的项目,感觉 go 的内置库相当匮乏。比如在 java 中可以使用 stream 等一套下来就是最终的数据。而在 go 中即使借助外部库,也需要多步才能完成(别跟我说自己写一个,你去写)。

另外就是 error 问题,写的时候一步一处理。很稳健。但是也很烦。过几天回来看代码,只能看到满屏的 if err != nil 。正常的业务逻辑已经湮没在 error 的海洋里。又臭又长(等等,这个不是说的 java ?)

类型推断,声明变量时不用写类型。有好处也有坏处,好处是少巧几个字母,坏处也显而易见。比如,某个 controller 层调用 service 层代码。user := us.GetUser(ctx, uid),此时如果我想看下返回的数据结构必须到 service 层看,这层是看不到的,也点不进去,像 java UserResp user = us.GetUser(uid),直接点击 UserResp 就能快速到定义。而 go 层次一多就很烦,需要一层层,一层层到最后返回值的地方才能看到。

依然有空指针,nil pointer 。特别是解引用时遇到最多。比如*user.name

半吊子泛型,虽然 java 的泛型实现的也不怎样,但是作为程序员是不关心字节码层面和机器码层面如何实现的,只关心有无,好不好用。

生态,go 的生态云原生基础设施比较多(不是说云原生就是 go ,云原生概念反而是 spring 后面的公司提出来的),业务相关的比较少。而 java 就很多了,很多基金会的组件也很优秀,多如牛毛,java 不仅仅是一门语言,现在说 java 基本是说其对应的生态,包括 kotlin ,java 等等,选择太多甚至出现选择困难症。

说这些不是踩 go ,也不是吹捧 java 。各有各有优势的地方。在工作中依然会大量使用这两种语言。这里只是表达下自己工作中的感受,为后来者选择做个参考。

14070 次点击
所在节点    Go 编程语言
129 条回复
defunct9
10 天前
扔到 k8s 里就知道好处了。
hshe
10 天前
java 是方便。很多现场集成非常好的日志,切面等等。
但是 Go 选对框架也是很重要的,比如可以使用 go-kratos 框架,中间件也能做到 aop 的效果,目前使用感受,最接近 java spring cloud
rrfeng
10 天前
「而在 go 中就麻烦很多,需要为每个接口添加中间件」

每个接口?
StinkyTofus
10 天前
我也不喜欢用 Go 去写 web 服务, 缺胳膊少腿的, 好多都要自己实现, 真的很累, 而且自己写的东西, 测试不够难免也有 bug ,不如 java 的生态丰富。

如果只是写个极小的工具, 不需要依赖什么服务, 那么用 go 编译成二进制还是挺爽的, 资源占用很低。
picone
10 天前
如果你用 Spring 的思路来写 Go 当然觉得 Go 这也不好那也不好

- 错误问题,见仁见智。我偏向于需要显式地知道这个错误从哪里捕获处理。
- 类型推断,你不喜欢你可以全部都 var 显式声明类型。

我认为 Go 是 C 的进化版,如果把它拿来和 C 比显然地好很多,很多语法特性也能理解为什么这么设计了。
FoxRiverMan
10 天前
扔到 k8s 里就知道好处了。
seers
10 天前
k8s 里面打开 hpa ,流量来了 java 还在呼哧呼哧启动,go 这边已经在接受流量了
StinkyTofus
10 天前
@StinkyTofus #4 我最近研究了一下 java 的 native 编译 Quarkus , 内存占用也极低, 简单测试了一下, 大部分 web 用的库都可以正常工作, 当然依然不敢用到生产环境, 怕有坑。
xiaocaiji111
10 天前
@rrfeng 关键接口,并不是每个接口都需要加,不能放在组上,需要加的每个要单独加,目前没想到很好的办法
ryalu
10 天前
啊对对对,你说的对
xiaocaiji111
10 天前
@StinkyTofus 有坑,我有个群,都是生产用这个的,确实很多坑,还是需要别人再踩踩。
me1onsoda
10 天前
@rrfeng 可能我 go 写的少,确实是这样吧,写 router 的时候不都要指明中间件?
kiripeng
10 天前
洋葱模型花点时间就可以丢进去了,主要还是前期得花时间写好框架流程
xiaocaiji111
10 天前
@picone 主要是每层都要处理,而在 java 中下面一层抛出就不需要了。最外层捕获就行。好处就是代码干净,坏处就是不知道有没有处理,怎么处理的。要到最外层看下。当然一般 web 都会有个全局异常处理兜底。go 显式处理也有好处,每一步都知道自己干了什么,下一步改怎么干。坏处就是代码变的很长,干扰读代码的流程。
tianice
10 天前
性能和编码体验需要平衡
PiersSoCool
10 天前
有了 AI 我觉得都差不多了...体力活基本上不用写了,改改就行,以后语言简洁性的争论估计就没啥了
wysnxzm
10 天前
"go 有问题是你不会用"
"其他语言有问题是语言辣鸡"
NewYear
10 天前
@seers

“java 还在呼哧呼哧启动”

我这边使用的 OA 系统是致远 OA (服务器是 java ),难以想象服务器启动过程要 5 分钟……
jonsmith
10 天前
没有完善的 web 框架,自己搭确实费时间
hshe
10 天前
我现在都在用 Rust 开发 Web 微服务后台,还在纠结 Go

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1052043

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX