Go 跨平台(机器)部署这么方便的吗?

2018-12-17 10:23:58 +08:00
 imherer
这几天不忙就看了下 go,然后用 beego 写了个 demo

我是在 mac 上开发的,尝试部署在 Linux 和 Windows 上,我发现只需要直接 build 为对应平台的版本就行了,在对应的机器上不需要安装 go 运行环境吗?

像 Node.js 或者 Python 甚至.NET ,在部署在都得在需要部署的机器上提前安装好环境,go 不需要,直接 build 然后把 build 出来的文件丢到服务器上就行了?这么方便的吗?

另外还有几个问题请教一下大佬:

1.go 最后打包出来的可执行文件永远只有一个吗?有没有可能根据我的业务逻辑分别打包成几大块(例如:main、lib1、lib2 ),虽然好像这样意义也不大?

2.写代码前需要设置 GOPATH。假如我有多个项目的话 GOPATH 是不是也得设置多个?那 GOBIN 好像只能设置一个啊。
对于多个项目你们是怎么弄的?还是 GOPATH 只有一个,在 src 下建不同的文件夹来区分项目吗,最后通过 go build 指定路径来打包吗?

3.假如我现在打包出来一个文件为 main,在 Linux 执行它的方式为./main (是这样的吧)

4.go 有没有类似 Node.js 下的 pm2 这种守护进程管理工具? 你们在服务器上怎么部署的 go ?总不可能是 nohup 吧

最后:刚接触,可能有些地方问的不对的还请各位大佬见谅!
12895 次点击
所在节点    程序员
92 条回复
AlphaTr
2018-12-17 12:32:45 +08:00
1. Go 有 Plugin 机制,可以编译多个,也支持 -buildmode=shared 编译,但还是觉得编译为一个文件最方便;

2. Go 1.11 以上支持 go mod,开发上现在基本不用关心 gopath 了;

3. 编译的就是可执行文件,同样可以放在 PATH 目录内执行;

4. systemd 管理;
CRVV
2018-12-17 13:01:46 +08:00
@trait
“不信任这些新人的内存管理水平”

1. 不是信任不信任的问题,而是手动管理内存要付出更多的开发成本,很多项目不乐意花这个钱

2. 你好像把内存管理想得太简单了。在某些情况下,即使是老人也一样管理不好内存,或者手动管理内存的运行时开销不比 GC 小
比如
https://software.intel.com/en-us/forums/intel-moderncode-for-parallel-architectures/topic/295279
Narcissu5
2018-12-17 13:17:17 +08:00
ahead of time 编译,java 的 graal 也可以做到。不过应该没有运行时优化,猜的哈
trait
2018-12-17 13:29:20 +08:00
@CRVV
1. 把新手与内存管理隔绝降低开发成本就是 go 做的,需要精确控制的场景 gc 省下的那点钱跟性能等优势比起来不值一提
2. 我从没把内存想简单,新手就是水平太差,没能力管理内存,所谓的老手真的是老手?至于你发那帖,读完主楼和回复并没发现 gc 在内存管理上有什么过人之处
dany813
2018-12-17 13:36:35 +08:00
插眼
ixiaohei
2018-12-17 13:42:04 +08:00
@iwtbauh 程序体积大占用内存就一定多么?系统都是分页的,实际占用内存很小的,很多都在 swap 上。另外内存相对于 cpu 真心便宜的;全部静态连接在一起,反而是 go 跨平台最大优势,没有依赖,那种裁剪的 linux,和嵌入式 arm 上直接拖过去就可以跑,爽的不要不要的。
limers
2018-12-17 13:42:15 +08:00
插眼
isCyan
2018-12-17 13:48:08 +08:00
可是 golang 内存占用还是很小
dacapoday
2018-12-17 13:52:05 +08:00
@iwtbauh #18 现实情况是内存和存储空间成本 远低于 部署成本,又不是嵌入式环境,可执行文件总比各种多媒体资源文件体积小吧。而现实中各种 库依赖 发行版依赖 版本不兼容,依然需要打包依赖配置依赖路径,搭建编译部署环境费时费力,而且相关知识不易传授培训给非开发人员,不然 docker 也不会火。
qieqie
2018-12-17 13:52:49 +08:00
可以链接 C 的 shared library,也可以 build,但不是主流,go 的主流库都是源代码 distribute 的。
cgo 交叉编译对熟悉 gcc/g++的其实也没有麻烦到哪里去。用 pkg-config 管理好依赖,就多一步 CGO_ENABLED=1 CC=... CXX=...
上面还有说体积 /内存的,源码依赖的 go build 只会编译可以被执行到的代码,而通过 cgo 链接二进制库的你同样可以使用-Wl,--gc-sections 这样的 linker flag。
Mrun
2018-12-17 14:08:13 +08:00
go 跨平台编译时优势
ptyfork
2018-12-17 14:49:50 +08:00
@heimeil

> 另外 Golang 不是不用装环境,而是环境都在编译的二进制文件里面了,你会发现 Go 编译出来的二进制比.NET 之类的大太多了。

你这比较的时候,.Net 还是要装环境啊, 不想装.net 环境,而是像 Go 一样把环境都打上,最后的安装包只会更大。
iamwh1temark
2018-12-17 14:56:02 +08:00
我感觉还好吧,有了 Docker 之后这个应该不算问题了.
yuikns
2018-12-17 15:01:53 +08:00
要求 disable cgo 才能不需要 runtime。
一般我输出 linux 然后丢 docker 里面。一个 image 几 M 到几十 M,特好用。
neoblackcap
2018-12-17 15:02:41 +08:00
@iwtbauh Google 内部用 golang 又不多,C++依然是他们的头号语言,紧接着是 Java,Golang 怎么样对他们又没有什么影响
iwtbauh
2018-12-17 15:31:28 +08:00
@ixiaohei #46

请注意看,我没说第 2 条和第 4 条有因果关系吧。(我没说是程序体积大导致内存占用大啊)

占用内存大是因为“重复的代码被多次载入主存”,因为如果我假设标准库 libgolang .so 文件(等)存在,那么 libgolang .so 只会载入主存一次,这就是操作系统的 cow 机制,即使系统中运行数个 golang 程序。然而因为静态编译,这部分代码只能重复载入主存。(而这一部分还不小)

换入磁盘在大部分情况下对于解决这个问题的意义不大(并不是说 swap 无用,只是对这种情况是用处不大的),因为这些程序执行 libgolang .so 中的代码(或访问数据)时,必须再从磁盘上重新换回到主存,这样只会导致系统缺页中断增多,拖慢系统性能。

另外,你也说了嵌入式系统,在嵌入式系统中更应该减少外存和主存的占用。

@dacapoday #49

注意看,我说的前提是“如果系统中大部分程序都是 golang ”。毕竟 golang 设计者差不多就是这样想的。原因见上。
iwtbauh
2018-12-17 15:36:47 +08:00
@neoblackcap #55

其实也不少,比如 dl.google.com 这个

主要是 Google 太富了,在硬件上使劲氪金,导致我等穷人非常难受。

chrome 内存泄漏因为内存大看不出来

chromium (还是 aosp ?) 的工具链直接丢进 git 里面简直疯了
kwanCCC
2018-12-17 15:37:48 +08:00
rpm
hlwjia
2018-12-17 15:41:37 +08:00
是只有我不知道“插眼”什么意思吗
pursuer
2018-12-17 15:47:21 +08:00
@iwtbauh 我个人觉得除了静态编译的内存消耗,动态加载目前也还不太行,plugin 一直不支持 windows,而且一共就实现了两个函数,Open 和 Lookup,用起来手感和 dlopen 和 dlsym 差不多,相比较我可能更喜欢 Windows COM 里 CoCreateInstance,QueryInterface 那套(但用 C++写会比较痛苦)或者 Java 的 ClassLoader 这样的

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

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

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

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

© 2021 V2EX