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

8 天前
 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 。各有各有优势的地方。在工作中依然会大量使用这两种语言。这里只是表达下自己工作中的感受,为后来者选择做个参考。

13929 次点击
所在节点    Go 编程语言
129 条回复
BBCCBB
8 天前
资源可能节省了, 开发效率大概率降低了. 语言特性的缺失就要开发人员手动做更多的事情了
GooMS
8 天前
性能越高人做的也多
singer
8 天前
@xiaocaiji111 #9 java 不也得单独处理不加的日志的情况吗
Mystery0
8 天前
公司有个服务,他的逻辑是接收 kafka 消息,然后根据逻辑存储数据到 db ,然后调用另一个服务发短信邮件,最后通过 kafka 发送通知消息给下游服务( Java )。然后压测的时候我这边消息没有堆积,处理没有报错,cpu 曲线刚开始发力呢,下游服务给我说被消息干死了。
当然这只是一个较为极端的例子,下游服务的业务较重,还有其他的逻辑处理。

回到我自己的东西上,Java 服务写了个 api 服务,吃内存 300m+( sb 全家桶),go 写了个类似的 api 服务,吃内存几十 m ,我组的 k3s ,node 普遍是 2c4g ,你说我该选哪个
povsister
8 天前
我看到你说的:go 没有提供 gc 调整手段就已经不想看了…
ballast 在 1.19 成为 MemoryLimit 特性都不知道吗,五年就这水平?
sophos
8 天前
关于切面这个点,可以看看这个项目: https://github.com/go-kod/kod
在依赖注入的基础上,支持 Interceptor ,不需要侵入到业务代码 :-) 有兴趣的话,欢迎试用
twitchgg
8 天前
用 go 主要实现网络相关的东西,比如需要调用系统 netlink ,没有用 go 写过 web 相关的东西都是 gRPC ,总觉得 go 用来写业务有些不合适
Hellert
8 天前
@povsister 没必要这样说话
masterclock
8 天前
1. 生成中使用 echo ,好像没啥工具类,偶尔有个中间件,似乎没啥其他需求。
1. 编译速度感觉相比早期版本下降了,可用是错觉?不过一般十几秒内吧,再长就是 CGO 或者出问题了。
1. 二进制启动快,这个最重要啊
1. 二进制包小,这个用处一般,但跑在边缘小尺寸设备特别有用,否则尺寸、流量、性能都是问题
1. 内存占用低,省钱、大大地省钱
1. GC ,业务不敏感,不关心
1. 编程体验,其实我喜欢 rust ,不过团队没法推,Java 太啰嗦,Kotlin 不错
1. error 问题,确实是个问题,但我不喜欢混淆 error 、exception ,用 java 还是一样,rust 挺好
1. 类型推断,java 麻烦,user := us.GetUser(ctx, uid) vs code 下可以直接挑掉 GetUser 地返回类型吧?
1. 依然空指针,对,所有更喜欢 rust
1. 泛型,半吊子,语言的第一版没跟着一起出来,后来加的泛型似乎都不好用
1. 生态,我们够用,不够的用 java 的 [doge]

早期用 Scala ,ZIO 、doobie 等真是赞,但团队推不开,2.1x 、3.0 版本等一番折腾,放弃
abc950309
8 天前
@povsister 有调整手段,GO_GC 相关参数可以看下

性能还是好很多的,1c 接 20k qps 的服务都能做出来,感觉主要是没有 Spring 全家桶的 overhead ,内存用量也少很多。创业公司的小服务用 Go 能省不少服务器的钱,当然 Java 程序员一般便宜一些,这个哪个省的多就要权衡了。
guanzhangzhang
8 天前
go 又不是只能写 web ,很多 cli tool ,四层服务 daemon ,最近看到一个僵尸网络就是 go 写的,天然交叉编译,不依赖外部环境
cmdOptionKana
8 天前
规模小的项目,Go 还是很有优势的。

Java 千好万好,那是项目足够大,或者有钱不用节省资源的时候才能体现优势。
yooomu
8 天前
用 go 写业务纯折磨,集合用 java stream 一把梭处理完了,go 还在考虑中间变量怎么命名。用合适的工具干合适的事
xiaocaiji111
8 天前
@povsister 说这话的时候,要想一下,别人并不是没网,也肯定查阅过相关资料的,能调和 java 的能调是不一样的。
abcde123456789
8 天前
上周末接了个小活

增删改查四个接口

让 gpt 帮我写的,用 go

然后打包直接给个 exe ,不用配置运行环境,给他们直接运行去了,这点是很爽的。

几百大钞入手
wujianhua22
8 天前
有两句话说:
1 、换个顺手的 IDE 工具,能帮你加快效率
2 、看看别人怎么实现的,目前来看你的 go 的水平不是特别高,所以多看看别人写的源代码是个很不错的方法
povsister
8 天前
@xiaocaiji111
你的字里行间并没有让我觉得你是完整的调研过各种语言的优缺点才做出的选择

就拿延迟这一项来说,如果你无法容忍 GC 带来的毛刺,那么选择无 GC 语言才是你的出路。
退一步讲,究竟是什么场景要吃掉大量内存造成 GCspike 你也并没有解释。
2024 年了,连 JVM 都进入 ZGC 一把梭的年代下,居然还有人在纠结 GC tune ?到底是代码写的太屎导致要在 GC 擦屁股还是其他原因我持保留意见。

再拿语言层面来说,go 在 better C 这一点上我认为非常成功,跨平台,交叉编译,不依赖 glibc ,体验都是非常好的。所以,你更多的是让我觉得:你是在试图弄清楚一把黄油刀为什么没有瑞士军刀那么多功能和易用。
所以,问题又回到选型上来。

现实问题没有既要又要,如果没有,最好的办法就是你去把它写出来。哦原来你说:“别跟我说自己写一个,你去写“

那我觉得没什么好说的了。
InkStone
8 天前
变量类型那一条,应该说是 IDE 太烂了。Java 也支持 var ,但像样点的 IDE 都可以把变量类型显示出来的,甚至包括 VSCode 装对了插件都可以

(看到楼主用的是 Goland ,我很难想象都 2024 年了 JB 家的 IDE 居然连这种基本功能都不支持么?
version
8 天前
做中台等固定业务的中间件稳定字段业务还行..以销售主导客户主导的需求..那就是深坑了..预到不好..后期就是发个版本或者兼容都要成了 数据库修改维护大师了..
开发效率自然是慢了..比起 php java
但是架构师需要从语言方面掌握主导权..未来编程卷后.就看中小公司老板反应了..要低成本还是高大上的架构.
wujianhua22
8 天前
@InkStone goland 的强大他可能还没了解透,当然一把再好用的刀,在杀猪匠的手里也就只能杀猪呐。

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

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

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

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

© 2021 V2EX