0%

背景

传统项目上线过程为将编译后的项目安装包手动部署到对应服务器上。近年容器化技术普及,将应用程序与容器化技术结合,提高应用管理能力及快速扩缩容能力。

具体动作如下

  1. Golang程序编写
  2. 项目维护Dockerfile文件,定义程序编译及运行命令
  3. 打包docker镜像
  4. 通过docker镜像启动docker容器
  5. 访问容器中Golang程序

docker命令

先了解常见docker命令

  1. 镜像基础命令

    1
    2
    3
    docker images # 获取本机镜像列表
    docker pull 镜像名称:tag # 从远程仓库拉取对应tag镜像到本地,具体镜像可在https://hub.docker.com 查看
    docker rmi 镜像id # 删除本地镜像
  2. 容器基础命令

    1
    2
    3
    4
    5
    6
    docker ps # 查看正在运行的容器
    docker ps -a # 查看所有构建的容器
    docker rm -v 容器id # 删除指定容器
    docker exec -it 容器id /bin/bash # 进入指定id的容器内部(/bin/bash 解释器需要跟进镜像对应改变,又可能是/bin/sh)
    docker start 容器id # 启动容器
    docker stop 容器id # 停止容器
  3. 创建容器

    1
    docker run -d -p 8080:8080 -v /Users/zhangmengnan/docker_test/ext_file:/mnt/engine/server/logs --name gin-server-0.0.1 镜像id

    根据基础镜像构建一个容器

    • -d 构建容器后,后台运行
    • -p 创建端口映射 宿主端口:容器端口
    • -v 创建磁盘挂载, 宿主路径:容器路径,注意宿主路径内容会覆盖容器路径
    • –name 给创建的容器指定名字

Golang与docker结合

基于镜像部署Golang程序

此方式逻辑为,将Golang项目整体拷贝到docker容器中,编译,然后运行。最终容器内文件如图

1) 创建Golang项目

1
2
3
4
5
go-docker-test
- Dockerfile
- server.go
- go.mod
- go.su

创建go项目,项目结构如上, server.go如下

1
2
3
4
5
6
7
8
9
10
11
12
13
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()
}

2) 编写Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#依赖镜像
FROM golang:1.19-alpine

#作者信息
MAINTAINER "zhangmengnan"

# 配置模块代理
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.cn,direct

#工作目录
WORKDIR /opt
# 将当前目录内容拷贝到容器的/opt目录
ADD . /opt

#在Docker工作目录下执行命令,编译服务
RUN go build -o server ./server.go

#声明服务端口
EXPOSE 8080

#执行项目的命令,启动服务
CMD ["/opt/server"]

3) 基于Dockerfile构建镜像

在项目根目录下执行命令,构建镜像

1
2
3
docker build -t 镜像名字 .
例如
docker build -t test-gin .

运行完成后 使用 docker images 即可看到构建的镜像

4) 基于镜像创建容器

镜像创建成功后,需要使用镜像创建运行对应容器,成功会打印创建的容器id

1
docker run -d -p 8080:8080 test-gin

基于 test-gin这个镜像,构建容器并后台运行,且指定端口映射。 成功后使用 docker ps 可以看到运行的该容器

5) 启动容器及服务

  1. 测试服务是否正常

    浏览器访问 http://localhost:8080/ping 响应正常

  2. 容器启动后可以通过命令可以进入容器中

    1
    docker exec -it 容器id /bin/sh
  3. 可以关闭和重启容器

编译镜像和部署镜像分离

前面的方式有个问题是编译镜像和运行镜像是同一个,会将项目源码暴露出去。现在将服务编译使用一个镜像,然后将编译后的结果拷贝到运行容器中。

最终容器内列表如下

1) 创建Golang项目

项目结构如下

1
2
3
4
5
6
7
go-docker-from-to
- Dockerfile
- build.sh
- go.mod
- go.sum
- server.go
- start.sh

项目代码 server.go

1
2
3
4
5
6
7
8
9
10
11
12
13
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()
}

项目编译脚本 build.sh

1
go build -o server server.go

项目启动脚本 start.sh

1
2
3
#!/bin/sh

./server >> ./logs/a.log

1) 修改Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#依赖镜像
FROM golang:1.19-alpine3.18 as builder

#作者信息
MAINTAINER "zhangmengnan"

# 配置模块代理
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.cn,direct

#工作目录
WORKDIR /mnt/engine
ADD . .

#在Docker工作目录下执行命令, 编译
RUN ./build.sh

FROM golang:1.19-alpine3.18

# 指定工作目录
WORKDIR /mnt/engine/server

# 创建日志目录
RUN mkdir /mnt/engine/server/logs

# 从编译机器拷贝二进制和启动脚本
COPY --from=builder /mnt/engine/server .
COPY --from=builder /mnt/engine/start.sh .

#执行项目的命令
CMD ["./start.sh"]

2) 基于Dockerfile构建镜像

执行命令基于dockerfile构建镜像

1
2
3
docker build -t 镜像命令:镜像tag .
例如
docker build -t gin-server:gin-server-0.0.1 .

3) 创建容器

命令创建且后台运行容器,指定端口映射,挂载磁盘,将日志挂载到本机

1
docker run -d -p 8080:8080 -v /Users/zhangmengnan/docker_test/ext_file:/mnt/engine/server/logs --name gin-server-0.0.1 gin-server:gin-server-0.0.1

小结

通过上述方法可实现Go程序和docker结合,且可以避免源码暴露

背景:

记录hexo创建及发布blog过程

过程

1)本地创建一篇博客

1
hexo new 文章标题

会在 $博客目录/source/_posts 下产生 <文章标题.md> 文件

2)编写博客

在md文件中编写博客

3)本地预览

1
hexo server 

执行该命令,本地启动http服务,预览编写的博客

4)推到远程

确认博客无问题后,推送到远程

1
hexo deploy -g

编译本地静态文件后,推送到远程,稍等一会即可访问自己的博客

背景:

测试blog

背景:

发现mysql 连接数有大量增长情况,老是报警,分析连接数

Mysql

解释几个Mysql参数

1
2
3
4
5
6
7
8
9
10
11
12
mysql> show status like  'Threads%';

Threads_cached: mysql 服务器 缓存的线程, 服务对接客户端的连接请求, 计算方法: 8 + (max_connections / 100), 基本默认为9
Threads_connected: 客户端和 mysql服务端连接成功的连接数
Threads_created: 服务端一共创建的连接数、即线程数
Threads_running: 服务端正在运行的线程数

mysql> select @@max_connections;
151 该函数返回的是 mysql服务端最大连接数

mysql> select CONNECTION_ID();
该方法返回的是 连接id 即线程的id,复用同一个线程,也会分配不同的ID

mysql参数官网参数解释

CONNECTION_ID()官网描述

阅读全文 »

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

阅读全文 »