notes

安装 Go

直接去官网下载

编辑器

使用vscode编辑器,在扩展中安装go插件。

go插件参考

vscode输入command+shift+p弹出命令框,找到Go: Install/Update Tools,点击安装全部的插件,如果安装失败请看这里

注意:使用go module的方式插件有些插件会失效,应该下载后面带gomod的插件,如gocode-gomod

配置gopath

go中有两个全局变量需要配置,goroot和gopath。

goroot可以不用设置,默认指向安装的位置。

gopath也可以不设置,默认是~/go目录。

包管理工具

go的包管理工具有十几种,有点乱,我们这里选择用1.11版本之后官方自带的go module作为包管理工具,也省去了额外安装的麻烦。

使用go modules之前需要初始化,使用go mod init <YourProjectName>初始化,项目根目录会生成一个go.mod文件,里面记录了依赖的第三方包,然后用go mod tidy命令可以安装项目中使用到的全部第三方包,如项目中import了iris:


import "github.com/kataras/iris"

go mod tidy执行成功后,会生成一个go.sum文件,里面存储着模块版本的校验值。

下载完成后,项目可以跑了,但是我们并没有在项目目录中发现第三方模块,它们被下载到哪了呢?

实际上,第三方包被下载到了$gopath/pkg/mod这个目录。所有项目都是统一下载到这里的。

机制的我看出来了,如果不设置gopath就是统一管理第三方依赖,如果想要每个项目单独管理依赖,就需要每个项目单独设置一遍gopath

个人倾向于每个项目单独一个依赖目录(受其他语言影响),但是目前还发现简单的方式给每个项目自动设置gopath。

注意:main.go文件必须放在项目根目录,不然build会失败。

简单的部署

一般build编译出来的二进制文件只能在当前系统运行,如果开发人员用mac开发,部署到linux上的话是运行不了的,在一个平台下编译另一个平台的二进制文件叫做交叉编译。如在mac上编译出linux平台的文件:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build

编译出来的二进制文件直接上传到linux服务器,就可以运行了。

注意:Go程序只要在特定平台编译好了,把文件拷贝过去就好了,linux执行不需要安装go的环境。但是如果程序里面读取了一些配置文件的话,需要把配置文件也拷过去

集成CI/CD

这里直接放代码,都在注释里

# 自己做了一个go环境镜像,在官方go镜像基础上安装了ssh-agent
image: hqqsk8/go

before_script:
  # 预先装 ssh-agent
  - 'which ssh-agent || ( apk update && apk add openssh-client)'
  # 启动服务
  - eval $(ssh-agent -s)
  # 将私钥写入deploy.key 文件
  - echo "$SSH_PRIVATE_KEY" > ~/deploy.key
  # 配置较低权限
  - chmod 0600 ~/deploy.key
  # 注入密钥
  - ssh-add ~/deploy.key
  - mkdir -p ~/.ssh
  - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
  - export APP_ENV=testing

stages:
  - prepare # 下载第三方依赖并生成cache
  - test    # 从cache中下载第三方依赖并生成二进制文件
  - build   # 把二进制文件拷贝到linux镜像里生成新的镜像push到gitlab
  - deploy  # 到部署服务器上拉去上一步生成的镜像,运行

# 下载第三方依赖并生成cache
build-cache:
  stage: prepare
  # 这一步主要是生成缓存给后续几步使用
  cache:
    key: "$CI_COMMIT_REF_NAME"
    paths:
      - go_modules
  before_script: []
  script:
    # 把第三方库的下载路径设置到当前项目的go_modules目录
    - export GOPATH=$CI_PROJECT_DIR/go_modules
    # 设置mod下载代理,可以提高下载速度并能下载到墙外的包
    - export GOPROXY=https://gocenter.io
    # 下载第三方依赖
    - go mod tidy
  when: manual
  only:
    - develop

# 从cache中下载第三方依赖并生成二进制文件
build-package:
  stage: test
  cache:
    key: "$CI_COMMIT_REF_NAME"
    policy: pull
    paths:
      - go_modules
  before_script: []
  script:
    # 给下面build的时候到当前项目的go_modules目录去找依赖
    - export GOPATH=$CI_PROJECT_DIR/go_modules
    # 可能需要go mod tidy,所以设置一下
    - export GOPROXY=https://gocenter.io
    - if [ ! -d "go_modules" ]; then
    - go mod tidy
    - fi
    # 构建二进制包
    - go build -o build/app
  only:
    - develop
  tags:
    - mainland
  # artifacts表示把生成的二进制包上传到gitlab上,共后续步骤下载使用
  artifacts:
    name: "build"
    untracked: false
    expire_in: 60 mins
    paths:
      - build

# 把二进制文件拷贝到linux镜像里生成新的镜像push到gitlab
build-image:
  stage: build
  image: docker:latest
  dependencies:
    - build-package
  cache: {}
  before_script: []
  script:
    # 登录gitlab的docker中心
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
    # 根据dockerfile构建image
    - docker build -t $CI_REGISTRY_IMAGE:latest .
    # 推送到gitlab上
    - docker push $CI_REGISTRY_IMAGE:latest
    # 移除runner中的image
    - docker rmi $CI_REGISTRY_IMAGE:latest
  only:
    - develop
  tags:
    - mainland

# 部署
deploy:
  stage: deploy
  variables:
    SERVER: $DEPLOY_SERVER
    SERVER_PATH: "/data/huangqiangqiang/golang"
  dependencies: []
  cache: {}
  script:
    # 预先创建项目目录
    - ssh $SERVER "mkdir -p $SERVER_PATH/$CI_PROJECT_NAME"
    # 把docker-compose等文件传过去
    - scp -r deploy/testing/* $SERVER:$SERVER_PATH/$CI_PROJECT_NAME
    # 登录gitlab的docker
    - ssh $SERVER "docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY"
    # 创建container运行
    - ssh $SERVER "export COMPOSE_HTTP_TIMEOUT=120 && export DOCKER_CLIENT_TIMEOUT=120 && export PROJECT_NAME=$CI_PROJECT_NAME && cd $SERVER_PATH/$CI_PROJECT_NAME && docker-compose pull app && docker-compose stop && docker-compose rm -f && docker-compose up -d --build"
  only:
    - develop
  environment:
    name: testing
    url: https://test.tthigo.com:10001
  tags:
    - mainland

提交镜像到dockerhub

上一步中自制镜像提交到dockerhub,参考这里

关于”too many open files”

升级到 go 1.13 版本的项目改动

私有库安装方式变化 从1.12版本升到1.13版本后,使用 go mod tidy 安装项目中的私有库,报 410 gone 错误。

解决方法:设置两个go变量

go env -w GOPROXY=direct
go env -w GOSUMDB=off