Go微服务实战|第0章:环境配置

  • 原创
  • Madman
  • /
  • /
  • 0
  • 1856 次阅读

Go 微服务实战.png

Synopsis: 我在公司有一台性能强劲的服务器安装了 ESXi,并创建一个 CentOS 7 虚拟机。我准备在该虚拟机上创建 Golang 的开发环境,我的笔记本是 Win10 系统,并安装了 Visual Studio Code 编辑器,我将通过 VSCode SSH 远程连接 CentOS 7,来开发 Golang 代码

1. CentOS 7 安装 Go-1.12

如何安装 CentOS 7 请参考:http://www.madmalls.com/blog/post/customize-centos-7-3-autoinstall-iso/

1.1 安装 go-1.12

# wget https://dl.google.com/go/go1.12.5.linux-amd64.tar.gz
# tar -C /usr/local -xzf go1.12.5.linux-amd64.tar.gz

1.2 设置环境变量

# echo -e "export GOROOT=/usr/local/go" >> /etc/profile
# echo -e "export GOPATH=$HOME/go" >> /etc/profile
# source /etc/profile

# echo -e "export PATH=$GOPATH/bin:$GOROOT/bin:$PATH" >> /etc/profile
# source /etc/profile

1.3 验证

# go version
# go env

2. Remote Development 的前期安装

2019 年 5 月 3 日,微软发布了支持 Visual Studio Code 远程开发的官方插件 Remote Development,但目前还只能在 Visual Studio Code Insiders 版本中使用,相信不久的将来就会添加到正式版的 Visual Studio Code 中了(说明: 现在 正式版 也能用远程开发功能了)

2.1 安装 Git

首先我们需要安装 2.0 以上版本的 Git for Windows,下载可执行的安装程序一路 Next 即可

2.2 安装 Visual Studio Code Insiders

访问 https://code.visualstudio.com/insiders/ 下载安装程序然后安装即可

2.3 安装 OpenSSH Client

参考:https://code.visualstudio.com/docs/remote/troubleshooting#installing-a-supported-ssh-client

Windows 10 1809 最新更新已经包含了 OpenSSH 客户端和服务器程序,所以你需要通过 Windows 10 更新助手 来升级你的操作系统

升级完成后,一般已经安装好了 OpenSSH 客户端,可以通过 设置 - 应用 - 应用和功能 - 管理可选功能 查看到,如果没有安装,则可以点击 添加功能 按钮:

Win10 OpenSSH Client

可以在 PowerShell 中进行验证:

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

PS C:\Users\wangy> ssh
usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface]
           [-b bind_address] [-c cipher_spec] [-D [bind_address:]port]
           [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11]
           [-i identity_file] [-J [user@]host[:port]] [-L address]
           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
           [-Q query_option] [-R address] [-S ctl_path] [-W host:port]
           [-w local_tun[:remote_tun]] destination [command]
PS C:\Users\wangy>

3. 配置 SSH 免密登录

假设远程 CentOS 主机的 IP 为 192.168.40.128,我们现在可以在 Win10 上通过 OpenSSH 客户端连接它:

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

PS C:\Users\wangy> ssh root@192.168.40.128
The authenticity of host '192.168.40.128 (192.168.40.128)' can't be established.
ECDSA key fingerprint is SHA256:lfy/yNW6dbMofAEaCfpz36UnYatsIsw+PMs3NLiHnbs.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.40.128' (ECDSA) to the list of known hosts.
root@192.168.40.128's password:
Last login: Tue May  7 12:20:31 2019 from 172.17.0.151
[root@CentOS ~]# whoami
root
[root@CentOS ~]#

这种方式需要输入用户名和密码,后续 VSCode 远程连接时很不方便,我们可以通过 SSH 密钥认证从而实现免密登录,请参考: https://www.ssh.com/ssh/public-key-authentication

3.1 生成 SSH 密钥对

打开 Git Bash 或者 PowerShell 都行(因为我们刚安装了 OpenSSH Client,已经有 ssh-keygen 等命令了),可使用 -C 选项指定公钥的说明信息:

$ ssh-keygen -t rsa -b 4096 -C "wangy-win10-pc"

一直回车确认即可,密钥对默认保存在 C:\Users\你的Win10用户名\.ssh 目录下,其中 id_rsa私钥(Private Key),要小心保管;id_rsa.pub公钥(Public Key),待会要上传到远程 CentOS 上的,实现基于 SSH 无密码登录 CentOS。同理,如果你在 Github 上有代码仓库,也是先要将公钥上传过去,才能无密码使用 Git 命令操作远程仓库

3.2 上传公钥到远程主机 CentOS 中

可以通过 XftpWinSCP 等工具将 2.1 中生成的公钥 id_rsa.pub 上传到远程主机 CentOS 中,假设上传到了 /root 目录。然后在 CentOS 中执行如下命令:

# cd /root
# mkdir ~/.ssh && chmod 700 ~/.ssh
# touch ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys
# cat id_rsa.pub >> ~/.ssh/authorized_keys

此时,你从 Win10 中再次用 PowerShell 去远程连接 CentOS 时,不再需要密码:

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

PS C:\Users\wangy> ssh root@192.168.40.128
Last login: Tue May  7 15:36:14 2019 from 172.17.0.151
[root@CentOS ~]#

4. 安装 Remote Development 插件

打开 Visual Studio Code Insiders,按 Ctrl + Shit + X 快捷键,打开扩展商店,搜索 Remote Development,安装第一个扩展插件即可

5. 连接远程主机

注意: 远程主机目前只支持 x86_64 Linux 系统

5.1 Remote-SSH: Connect to Host

Ctrl + Shit + P 快捷键,打开 命令面板,输入 Remote-SSH: Connect to Host... 回车确认,然后输入要连接的远程主机信息,比如 root@192.168.40.128,回车即可,因为我们配置了基于 SSH 秘钥免密码登录,所以后续连接远程主机的过程中不会要求我们输入密码

它会打开一个新窗口,成功连接远程 CentOS 主机后,我们就可以通过 Visual Studio Code Insiders 的菜单 File > Open... 或者 File > Open Workspace... 来打开远程主机上的文件夹或工作区

5.2 Remote-SSH: Open Configuration File

如果你经常要通过 Visual Studio Code Insiders 远程访问同一个 Linux 主机,那么 4.1 的步骤就略显繁琐了,我们可以通过指定配置文件来记录需要经常访问的远程主机信息

Ctrl + Shit + P 快捷键,打开 命令面板,输入 Remote-SSH: Open Configuration File... 回车确认,然后假设选择 C:\Users\你的Win10用户名\.ssh\config 配置文件,输入以下内容:

Host CentOS
    User root
    HostName 192.168.40.128

2 配置SSH远程连接主机

6. Go Modules 管理依赖

Go 1.12 版本开始,官方推荐使用 Go Modules 来管理依赖,我们的 Go 代码不必强制放在 $GOPATH/src 目录下了

假设我们在 Github 中创建了一个新项目 grpc-go-tutorial,克隆到远程主机 CentOS 中:

# cd ~
# git clone git@github.com:wangy8961/grpc-go-tutorial.git

然后通过 5.1 章节的方法,在 Win10 笔记本中通过 VSCode 远程打开这个目录,增加一个新的 Go 源代码文件 app.go

package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080
}

直接运行时,会报错:

[root@CentOS grpc-go-tutorial]# go run app.go
app.go:3:8: cannot find package "github.com/gin-gonic/gin" in any of:
    /usr/local/go/src/github.com/gin-gonic/gin (from $GOROOT)
    /root/go/src/github.com/gin-gonic/gin (from $GOPATH)

因为它需要第三方依赖 gin

6.1 go mod init

首先需要使用 go mod init 命令初始化:

[root@CentOS grpc-go-tutorial]# ls
app.go  README.md
[root@CentOS grpc-go-tutorial]# go mod init
go: creating new go.mod: module github.com/wangy8961/grpc-go-tutorial
[root@CentOS grpc-go-tutorial]# ls
app.go  go.mod  README.md
[root@CentOS grpc-go-tutorial]# cat go.mod 
module github.com/wangy8961/grpc-go-tutorial

go 1.12

然后,你再执行 go rungo build 命令时,Go Modules 会自动帮你查找依赖并下载到本地,非常方便!

[root@CentOS grpc-go-tutorial]# go run app.go 
go: finding github.com/gin-gonic/gin v1.4.0
go: downloading github.com/gin-gonic/gin v1.4.0
go: extracting github.com/gin-gonic/gin v1.4.0
go: finding github.com/golang/protobuf v1.3.1
go: finding github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3
go: finding github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
go: finding github.com/stretchr/testify v1.3.0
go: finding github.com/mattn/go-isatty v0.0.7
go: finding github.com/json-iterator/go v1.1.6
go: finding github.com/modern-go/reflect2 v1.0.1
go: finding golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c
go: finding gopkg.in/yaml.v2 v2.2.2
go: finding gopkg.in/go-playground/assert.v1 v1.2.1
go: finding gopkg.in/go-playground/validator.v8 v8.18.2
go: finding github.com/ugorji/go v1.1.4
go: finding github.com/stretchr/objx v0.1.0
go: finding github.com/pmezard/go-difflib v1.0.0
go: finding github.com/davecgh/go-spew v1.1.0
go: finding golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223
go: finding gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
go: finding golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
go: finding golang.org/x/text v0.3.0
go: finding golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a
go: downloading github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3
go: downloading github.com/golang/protobuf v1.3.1
go: downloading github.com/ugorji/go v1.1.4
go: downloading github.com/mattn/go-isatty v0.0.7
go: downloading gopkg.in/yaml.v2 v2.2.2
go: downloading gopkg.in/go-playground/validator.v8 v8.18.2
go: extracting github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3
go: extracting gopkg.in/go-playground/validator.v8 v8.18.2
go: extracting github.com/mattn/go-isatty v0.0.7
go: downloading golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223
go: extracting gopkg.in/yaml.v2 v2.2.2
go: extracting github.com/golang/protobuf v1.3.1
go: extracting github.com/ugorji/go v1.1.4
go: extracting golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /ping                     --> main.main.func1 (3 handlers)
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080

此时你再查看 go.mod 文件的内容:

[root@CentOS grpc-go-tutorial]# cat go.mod 
module github.com/wangy8961/grpc-go-tutorial

go 1.12

require github.com/gin-gonic/gin v1.4.0 // indirect

同时还会生成 go.sum 文件,它包含了各依赖包的版本控制信息

6.2 go mod tidy

如果你将 Go 源代码分享给其它人,只需要同时包含 go.modgo.sum 文件就行,对方执行 go mod tidy 就会自动拉取所需要的第三方依赖

7. 配置 VSCode

7.1 通用扩展

在 VSCode 扩展商店中安装如下插件:

  • 主题: One Dark Pro
  • 图标: vscode-icons
  • 火焰特效: power mode

修改用户个人配置 settings.json

{
    // 禁用要发送给 Microsoft 的使用情况数据和错误。
    "telemetry.enableTelemetry": false,
    // 禁用要发送给 Microsoft 的故障报表,此选项需重启才可生效
    "telemetry.enableCrashReporter": false,
    // 主题,默认是Default Dark+
    "workbench.colorTheme": "One Dark Pro",
    // 主题图标,默认是vs-seti
    "workbench.iconTheme": "vscode-icons",
    // 字体系列
    "editor.fontFamily": "'Source Code Pro', Consolas, 'Courier New', monospace",
    // 字体大小
    "editor.fontSize": 18,
    // 行高
    "editor.lineHeight": 24,
    // 在一定数量的等宽字符后显示垂直标尺。输入多个值,显示多个标尺。若数组为空,则不绘制标尺
    "editor.rulers": [
        80,
        120
    ],
    // 覆盖当前所选颜色主题中的编辑器颜色和字体样式,去除斜体的注释样式
    "editor.tokenColorCustomizations": {
        "textMateRules": [
            {
                "name": "Comments",
                "scope": "comment, punctuation.definition.comment",
                "settings": {
                    "fontStyle": ""
                }
            },
            {
                "name": "js/ts italic",
                "scope": "entity.other.attribute-name.js,entity.other.attribute-name.ts,entity.other.attribute-name.jsx,entity.other.attribute-name.tsx,variable.parameter,variable.language.super",
                "settings": {
                    "fontStyle": ""
                }
            },
            {
                "name": "js ts this",
                "scope": "var.this,variable.language.this.js,variable.language.this.ts,variable.language.this.jsx,variable.language.this.tsx",
                "settings": {
                    "fontStyle": ""
                }
            }
        ]
    },
    // 启用powermode插件,输入时有火焰特效
    "powermode.enabled": true,
    "powermode.presets": "flames",
    // 编辑器失去焦点时自动保存更新后的文件
    "files.autoSave": "onFocusChange",
    // 使用的代理设置。如果没有设置,将从 http_proxy 和 https_proxy 环境变量中获取
    // "http.proxy": "socks5://127.0.0.1:1080", // 或者,"http.proxy": "http://127.0.0.1:1081", 或者 "http.proxy": "https://127.0.0.1:1081",
}

7.2 Go 扩展

打开 VSCode,按 Ctrl + Shit + X 快捷键,打开扩展商店,搜索 go,安装第一个扩展插件即可。请务必阅读 Go modules support in Visual Studio Code,默认使用 Google 的 Language Server gopls

[root@CentOS ~]# go get -u -v golang.org/x/tools/cmd/gopls

然后,按 Ctrl + Shit + P 快捷键,打开命令面板,输入 Preferences: Open Workspace Settings

{
    // The only setting you need in Go extension version 0.10.0 and above to use gopls
    "go.useLanguageServer": true,
}

8. (可选) Docker 快速创建 Golang 开发环境

CentOS 如何安装 Docker 请参考 http://www.madmalls.com/blog/post/visualizing-docker-containers-and-images/

8.1 Docker容器内使用代理

后续启动 Golang 容器内需要安装依赖,有一些依赖比如 golang.org/x/sys 等需要借助 梯子/科学上网 才能访问,所以我们需要先配置远程主机 CentOS 能够使用代理。安装 Shadowsocks 服务端请参考: http://www.madmalls.com/blog/post/build-shadowsocks-server-on-centos/ ,现在要为 CentOS 7 安装 Shadowsocks 客户端,并配置全局代理:

1. 安装 epel 源
# yum install -y epel-release

2. 安装 pip 工具
# yum install -y python-pip

3. 更改 pip 的安装源为国内的源,比如 aliyun
# mkdir ~/.pip
# vi ~/.pip/pip.conf

添加内容如下:
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/

[install]
trusted-host=mirrors.aliyun.com

4. 升级 pip 工具
# pip install --upgrade pip

5. 安装 shadowsocks 客户端
# pip install git+https://github.com/shadowsocks/shadowsocks.git@master

查看 sslocal 命令在哪个位置?
# whereis sslocal
/usr/bin/sslocal

6. 创建 shadowsocks 配置文件
# vi /etc/shadowsocks.json

内容如下:
{
  "server": "Shadowsocks服务端的IP或域名",
  "server_port": Shadowsocks服务端的端口,
  "password": "Shadowsocks服务端的密码",
  "local_address": "127.0.0.1",
  "local_port": 1080,
  "timeout": 300,
  "method": "Shadowsocks服务端的加密方式"
}

7. 创建 shadowsocks 服务
# vi /etc/systemd/system/shadowsocks.service

内容如下:
[Unit]
Description=Shadowsocks Client
[Service]
TimeoutStartSec=0
ExecStart=/usr/bin/sslocal -c /etc/shadowsocks.json
[Install]
WantedBy=multi-user.target

8. 启动 shadowsocks 服务
# systemctl enable shadowsocks.service
# systemctl start shadowsocks.service
# systemctl status shadowsocks.service

9. 验证,如果返回 shadowsocks 服务端的 IP 则正常
# curl --socks5 127.0.0.1:1080 http://httpbin.org/ip

此时,我们还必须手动指明使用 socks5 代理才能使用 shadowsocks:

[root@CentOS ~]# curl cip.cc
IP  : 211.162.126.xxx
地址  : 中国  广东  深圳
运营商 : 鹏博士/联通

数据二 : 广东省深圳市 | 鹏博士长城宽带

数据三 : 中国广东省深圳市 | 鹏博士

URL : http://www.cip.cc/211.162.126.xxx

也就是说你执行 curl www.google.com 时还是无法下载谷歌的首页,因为 curl 命令默认是使用 HTTP 协议,必须设置 CentOS 中全局使用 HTTP 代理到 socks5 上去才行,可以使用 Privoxy

1. 安装 Privoxy
# yum install -y privoxy

2. 修改 privoxy 配置文件
# vi /etc/privoxy/config

确保存在 listen-address  127.0.0.1:8118 这一行内容(没有被注释掉),并在它的后面添加(注意最后有个点号 .):
forward-socks5t / 127.0.0.1:1080 .

3. 启动 privoxy 服务
# systemctl enable privoxy.service
# systemctl start privoxy.service
# systemctl status privoxy.service

4. 配置代理的环境变量
# echo -e "export http_proxy=http://127.0.0.1:8118" >> /etc/profile
# echo -e "export https_proxy=http://127.0.0.1:8118" >> /etc/profile
# source /etc/profile

5. 验证,说明已经使用了 shadowsocks 服务端的代理 IP
[root@nkocs03 ~]# curl cip.cc
IP  : 95.163.198.xxx
地址  : 美国  加利福尼亚州  洛杉矶
运营商 : it7.net

数据二 : 俄罗斯

数据三 : 俄罗斯莫斯科莫斯科

URL : http://www.cip.cc/95.163.198.xxx

最后,根据 Docker 官方文档的说明 Configure Docker to use a proxy server,我们的 Docker 版本为 18.09.0,所以需要创建 ~/.docker/config.json 文件:

# mkdir ~/.docker
# vi ~/.docker/config.json

内容如下:
{
  "proxies":
  {
    "default":
    {
      "httpProxy": "http://127.0.0.1:8118",
      "httpsProxy": "http://127.0.0.1:8118"
    }
  }
}

启动一个容器测试(注意: 一定要指定 --net host,不然容器内找不到 127.0.0.1:8118):

[root@CentOS ~]# docker run -it --net host --rm golang:1.12
root@CentOS:/go# curl cip.cc
IP  : 95.163.198.xxx
地址  : 美国  加利福尼亚州  洛杉矶
运营商 : it7.net

数据二 : 俄罗斯

数据三 : 俄罗斯莫斯科莫斯科

URL : http://www.cip.cc/95.163.198.xxx
root@CentOS:/go# exit
exit

8.2 启动容器

需要将 Go 源代码目录和 GOPATH 以外部卷的方式加载到容器中去:

# mkdir -pv ~/go/{bin,pkg,src}
# docker run -d \
  --name go \
  -it \
  --net host \
  --rm \
  -v ~/go:/go \
  -v ~/grpc-go-tutorial:/app \
  golang:1.12

8.3 进入容器

# docker exec -it go /bin/bash
未经允许不得转载: LIFE & SHARE - 王颜公子 » Go微服务实战|第0章:环境配置

分享

作者

作者头像

Madman

如需 Linux / Python 相关问题付费解答,请按如下方式联系我

0 条评论

暂时还没有评论.