最近在上字节跳动的后端青训营,在写结业项目搜索引擎时用到了 jieba 库,而这个库不支持交叉编译,所以我用了两天时间踩了各种坑才成功在 Ubuntu 环境下编译并部署,值得整理成一篇博客。

一些约定 链接到标题

Ubuntu版本:20.04

Go版本:1.18.1

WSL2:Ubuntu 20.04.4

Go 环境搭建 链接到标题

基础操作 链接到标题

更新 apt库 链接到标题

$ apt-get update

安装 Go 链接到标题

$ sudo apt-get install golang-go

验证版本 链接到标题

$ go version

此时我们发现安装的是 1.14 之类的老版本,并不符合我们约定的 1.18.1 这样的新版本要求,所以我们只能卸载这个 Go,重新下载我们指定的新版本。

卸载 Go 链接到标题

先通过 $ go env 命令来得到 GOROOT 的地址,然后 $ sudo rm -rf {GOROOT} 来卸载。

指定版本下载 链接到标题

下载 Go 链接到标题

$ wget https://dl.google.com/go/go1.18.1.linux-amd64.tar.gz

当然如果没有梯子这条命令只能换来一个 timeout 的提示,此时我们有两个选择:

  • 换国内源

$ wget https://studygolang.com/dl/golang/go1.18.1.linux-amd64.tar.gz

  • 手动下载然后放到 Ubuntu 系统下的某个路径

解压安装 Go 链接到标题

我们先cd到下载或是存放刚刚得到的安装包的目录,然后通过命令解压到目标位置(即 GOROOT 目录):

$ sudo tar -zxvf go1.18.1.linux-amd64.tar.gz -C /usr/local/lib/

此时我们验证版本发现就是我们想要的 1.18.1 版本了。

img1

配置环境变量 链接到标题

我们先打开全局变量配置文件:

$ vim ~/.profile

然后在末尾输入响应的环境配置:

export GOROOT=/usr/local/lib/go
export PATH=$PATH:$GOROOT/bin

export GOPATH=/opt/gowork
export PATH=$PATH:$GOPATH/bin

最后重新加载环境:

$ source ~/.profile

当然也可以通过下面的方法来配置:

$ sudo tee -a ~/.profile << EOF
> export GOROOT=/usr/local/lib/go
> export GOPATH=/opt/gowork
> export PATH=\$PATH:\$GOROOT/bin:\$GOPATH/bin
> EOF
$ source ~/.profile

配置 Go 的代理 链接到标题

因为墙的原因,国内想直接通过默认路径获取依赖是几乎不可以的,我们可以通过下面的命令来配置:

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct

也可以这样:

$ sudo tee -a ~/.profile << EOF
> export GO111MODULE=on
> export GOPROXY=https://goproxy.cn,direct
> EOF
$ source ~/.profile

编译 链接到标题

将源码放到 Ubuntu 的某个目录下后,我们先 cd 到该目录。

然后执行

$ go build -o {project_name}

如果需要使用管理员命令 sudo 的话,就需要重新设置一遍 sudo go env 的 proxy 配置了(因为不知道管理员和普通用户权限有区别我在这一步上卡了一整天)。

编译好后就可以看到一个没后缀的文件了。

特殊情况 链接到标题

jieba 库底层是用 C++ 编写的,所以在编译时需要 C++ 环境,我们需要执行:

$ sudo apt-get install g++

部署 链接到标题

这一步我们需要用到tmux,先下载安装:

$ sudo apt-get install tmux

然后运行:

$ tmux

这时我们会跳到一个新的窗口,cd 到我们准备部署的根目录下,执行命令运行编译好的文件:

$ ./{project_name}

最后我们按下 ctrl+b d 或者输入命令来分离会话:

$ tmux detach

tmux 的一些常用操作 链接到标题

$ tmux new -s <session-name> //新建会话
$ exit //退出
$ tmux detach //分离会话
$ tmux ls //查看当前所有会话
$ tmux attach -t <session-name> //接入某个已存在的会话,也可以用会话id来代替会话名
$ tmux kill-session -t <session-name> //杀死某个会话,也可以用会话id来代替会话名
$ tmux switch -t <session-name> //切换会话,也可以用会话id来代替会话名
$ tmux rename-session -t 0 <new-name> //重命名会话0

tmux 的一些常用快捷键 链接到标题

Ctrl+b d:分离当前会话。
Ctrl+b s:列出所有会话。
Ctrl+b $:重命名当前会话。

一些其他的抱怨 链接到标题

jieba 库是需要一个文件依赖的,而不知道为什么我在服务器端无法自动生成该文件依赖。WSL2 上编译的程序也因为缺少依赖无法在服务器端正常处理请求。最终只能在代码里添加一个指定路径来存放这些文件依赖,然后拖来 WSL2 上自动生成的,这才能让项目跑起来,实在是有些反人类了。