Go是一种静态类型,编译后可以在各种系统环境中运行,对于高性能分布式系统领域而言,Go语言无疑比大多数其它语言有着更高的开发效率。
现在微服务的流行,让Go程序跑起来更方便。本次记录参照Go基础教程的示例实现。让Go程序跑在Docker容器中,并使用docker Health check健康检查功能。
项目main.go代码:
package main
import (
"flag"
"fmt"
"log"
"net/http"
)
func homehandler(w http.ResponseWriter, r *http.Request) {
log.Println("http request.")
fmt.Fprintln(w, "Golang Web server is running. ")
}
func pinger(port string) error {
resp, err := http.Get("http://localhost:" + port)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("server is not return 200 stauts code.")
}
return nil
}
func main() {
var port string
var ping bool
flag.StringVar(&port, "port", "8000", "server port")
flag.StringVar(&port, "p", "8000", "server port")
flag.BoolVar(&ping, "ping", false, "check server live")
flag.Parse()
//检查状态
if ping {
if err := pinger(port); err != nil {
log.Printf("ping server error: %v\n", err)
}
return
}
http.HandleFunc("/", homehandler)
log.Println("http server run on " + port + " port")
log.Fatal(http.ListenAndServe(":"+port, nil))
}
Dockerfile文件内容:
FROM plugins/base:multiarch
add helloworld /bin/
EXPOSE 8000
HEALTHCHECK --start-period=5s --interval=30s --timeout=30s --retries=3 \
CMD ["/bin/helloworld", "-ping"]
ENTRYPOINT ["/bin/helloworld"]
打包程序Makefile文件内容:
build_linux_amd64:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -a -o release/linux/amd64/helloworld
build_linux_i386:
CGO_ENABLED=0 GOOS=linux GOARCH=i386 go build -v -a -o release/linux/i386/helloworld
docker:
docker build -t helloworld .
打包GO程序,因为系统使用64位的所以选择编译:
[root@docker-ce test]# make build_linux_amd64 Makefile
使用基础镜像,因为够小可以事先拉下来:
docker build \
--label org.label-schema.build-date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--label org.label-schema.vcs-ref=$(git rev-parse --short HEAD) \
--file docker/Dockerfile.linux.multiarch \
--tag plugins/base:multiarch .
打包成Docker镜像
[root@docker-ce test]# make docker Makefile
docker build -t helloworld .
Sending build context to Docker daemon 6.674MB
Step 1/5 : FROM plugins/base:multiarch
---> 92bf59f52f26
Step 2/5 : add release/linux/amd64/helloworld /bin/
---> d9db90fb34d9
Step 3/5 : EXPOSE 8080
---> Running in 34bf95cf6370
Removing intermediate container 34bf95cf6370
---> 0946fe4e1006
Step 4/5 : HEALTHCHECK --start-period=5s --interval=30s --timeout=30s --retries=3 CMD ["/bin/helloworld", "-ping"]
---> Running in 06d32d4e7b9c
Removing intermediate container 06d32d4e7b9c
---> ecdd5067e9ae
Step 5/5 : ENTRYPOINT ["/bin/helloworld"]
---> Running in 5c232e917e21
Removing intermediate container 5c232e917e21
---> 232ac0d24f85
Successfully built 232ac0d24f85
Successfully tagged helloworld:latest
make: Nothing to be done for `Makefile'.
打包后的镜像大小,其它就是Go程序大小差不多了。
[root@docker-ce test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworld latest 232ac0d24f85 2 minutes ago 6.96MB
plugins/base multiarch 92bf59f52f26 About an hour ago 293kB
启动容器查看效果,通过当前的控制台查看效果:
[root@docker-ce test]# docker run -p 3000:8000 helloworld
2019/06/26 09:05:10 http server run on 8000 port
查看启动后的容器,刚才开始程序(health: starting)
[root@docker-ce ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
639169df414c hello "/bin/helloworld" 7 seconds ago Up 5 seconds (health: starting) 8080/tcp, 0.0.0.0:4000->8000/tcp nifty_jones
过30秒左右就可以看到效果了,使用JSON格式化容易看。
[root@docker-ce ~]# docker inspect --format '{{json .State.Health}}' 639169df414c | python -m json.tool
{
"FailingStreak": 0,
"Log": [
{
"End": "2019-06-26T14:13:04.613608178+08:00",
"ExitCode": 0,
"Output": "",
"Start": "2019-06-26T14:12:59.50654346+08:00"
}
],
"Status": "healthy"
}
访问Docker主机的Ip加端口即可看到效果:
curl http://localhost:4000