带你用Go实现二维码小游戏(下)
本篇文章我们进入项目最后的部署和监控搭建阶段,这一节会有很少的编码量,但是却能够带来最实用的知识和技术,快来阅读吧~
5 Docker镜像打包部署
接下来就到了我们项目的部署阶段,优雅的项目必须要搭配优雅的部署方式!
5.1 为什么要用Docker部署
Docker镜像打包部署Go项目带来了诸多好处,这些好处主要体现在以下几个方面:
1)环境一致性
Docker容器包含了Go项目所需的所有依赖项(如库、运行时等),确保在开发、测试和生产环境中运行的一致性,从而避免了“在我的机器上可以运行”的问题。
2)高效资源利用
Docker容器与虚拟机相比更加轻量,能够在相同硬件资源下运行更多的应用实例。
3)易于部署和管理
Docker容器可以打包Go项目及其所有依赖项,包括库、框架和工具等,无需手动安装和配置各种依赖项,简化了项目的部署和维护过程。
4)提升安全性和隔离性
每个Docker容器在独立的环境中运行,互不干扰,提高了系统的稳定性和安全性。Docker提供了多层次的安全机制,如命名空间、控制组和安全模块,确保容器的隔离性和安全性。
5.2 编写Dockerfile
下面我们就编写Dockerfile进行项目打包的预备阶段,先看一个Dockerfile的模板:
# 使用官方的Python基础镜像
FROM python:3.9-slim# 设置工作目录
WORKDIR /app# 复制当前目录的所有文件到工作目录中
COPY . /app# 安装Python依赖包
RUN pip install --no-cache-dir -r requirements.txt# 暴露应用程序的端口(如果适用)
EXPOSE 5000# 定义环境变量(如果需要)
ENV NAME World# 运行应用程序的命令
CMD ["python", "app.py"]
内容解释:
1)FROM python:3.9-slim
:这行指定了基础镜像。这里使用官方的Python 3.9 slim版镜像,slim版表示它去除了很多不必要的库,使得镜像更轻量。
2)WORKDIR /app
:设置工作目录为/app
。所有后续的指令(如COPY
和RUN
)都会在这个目录下执行。
3)COPY . /app
:将当前上下文(通常是Dockerfile所在的目录)的所有内容复制到工作目录/app
中。
4)RUN pip install --no-cache-dir -r requirements.txt
:使用pip安装requirements.txt
中列出的所有Python依赖包。--no-cache-dir
选项用于防止pip缓存,确保每次构建时都安装最新的依赖包。
5)EXPOSE 5000
:声明容器运行时会监听的端口。这里假设应用程序在5000端口上运行。需要注意的是,EXPOSE
指令不会实际发布端口,它只是提供一个信号,说明容器使用的网络端口。
6)ENV NAME World
:设置环境变量NAME
的值为World
。环境变量可以在应用程序中通过os.getenv('NAME')
等方式读取。
7)CMD ["python", "app.py"]
:指定容器启动时执行的命令。这里使用python app.py
启动Python应用程序。CMD
指令可以被docker run
命令行中的参数覆盖。
然后在项目的根目录新建Dockerfile:
# 使用最新的Ubuntu作为基础镜像
FROM golang:latest# 设置工作目录
WORKDIR /app# 将Go代码复制到容器中
COPY . /app# 编译Go代码
RUN go env -w GOPROXY=https://goproxy.io
RUN go mod tidy
RUN go build -o myapp# 设置容器启动时执行的命令
ENTRYPOINT ["/app/myapp"]
5.3 构建并启动Docker镜像
在项目的根目录,也就是Dockerfile所在目录下执行
docker build -t qrcode
构建完成之后我们使用docker image命令查看:
docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE
qrcode latest d330b8d8e269 7 seconds ago 1.11GB
启动Docker:
docker run -d -p 8081:8081 qrcode
6 监控搭建
本节我们将进行一个比较好玩的操作,就是进行服务器监控搭建,从监控对象角度可以区分为整个机器的监控和服务接口的监控,下面我们就分别讲述下这两种监控如何搭建。
6.1 为什么要进行服务器监控?
服务器监控是确保系统稳定运行、数据安全、资源优化和成本控制的关键环节。通过实时监测性能指标、检测安全风险、预测未来需求,服务器监控能有效提高服务质量,降低运营成本,满足合规要求,确保业务连续性。
6.2 常用的监控工具
6.2.1 监控工具
常用的监控工具及其作用如下:
Zabbix:作为一款开源监控软件,支持大规模部署和数据监控,提供灵活的告警机制和强大的数据采集能力。适合复杂的IT环境,减少维护成本。
Nagios:主要用于监控网络、服务器及应用程序,具有模块化架构和低资源利用率的特点。适合资源有限的小型到中型企业,确保系统稳定运行。
Prometheus:专注于时间序列数据的监控与告警,适合动态环境中的容器化应用程序监控。提供高效的时间序列数据库和灵活的查询语言,助力DevOps和SRE团队。
SolarWinds:具备出色的网络流量监控和服务器性能监控能力,帮助企业实时了解网络健康状态。适合大中型企业,提高网络管理效率。
这些监控工具各有特色,能够满足不同企业的监控需求。
6.2.2 可视化工具
Grafana是一个开源的数据可视化和监控平台,它允许用户通过创建动态仪表板来监视和分析数据。Grafana支持与多种数据源(如Elasticsearch、InfluxDB、Prometheus等)集成,使得它能够展示来自这些数据源的数据。Grafana的核心功能包括数据采集、仪表盘设计、图表展示和告警通知。
此外,Grafana还具有日志分析、网络流量监控、安全监控以及能源管理等作用。作为一个流行的数据可视化和监控工具,Grafana具有开源性、丰富的功能以及灵活性等优点,适用于多种不同的监控场景。
6.3 将接口进行监控
6.3.1 总体步骤
要使用Prometheus监控Go HTTP接口的请求总量和QPS,一般有以下几个步骤:
1)安装和配置Prometheus。
2)在Go应用程序中暴露指标:使用Prometheus客户端库(如github.com/prometheus/client_golang
)来暴露HTTP接口请求相关的指标。
3)配置Prometheus抓取任务:在Prometheus配置文件中添加一个作业(job),以抓取Go应用程序暴露的指标。
4)使用Prometheus或Grafana可视化数据。
##### 6.3.2 代码实现
1)下载Prometheus
首先是Prometheus下载地址:
https://prometheus.io/download/
2)Go项目添加Prometheus依赖
然后在项目根目录下载依赖
go get -u github.com/prometheus/client_golang/prometheus
3)代码改造
新增对象
var (requestsTotal = prometheus.NewCounter(prometheus.CounterOpts{Name: "qrcode_http_requests_total",Help: "Total number of HTTP requests",})
)func init() {prometheus.MustRegister(requestsTotal)
}
改造接口:
func runHttp() {// ......mux := http.NewServeMux()mux.HandleFunc("/qrcode/gen", withMetricsHandler(uploadFileHandler))//......mux.Handle("/metrics", promhttp.Handler())_ = http.Serve(listen, mux)
}func withMetricsHandler(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {return func(w http.ResponseWriter, r *http.Request) {defer func() {requestsTotal.Inc()}()f(w, r)}
}
4)配置Prometheus
然后配置Prometheus的配置文件prometheus.yml
scrape_configs:# 新增如下配置- job_name: 'qrcode' static_configs: - targets: ['localhost:8081'] # 确保这是你的Go应用程序的地址和端口
5)测试
访问:http://localhost:9090/
6)优化
如果想区分接口进行监控,需要进行优化:
var (requestsTotalVec = prometheus.NewCounterVec(prometheus.CounterOpts{Name: "qrcode_http_requests_total_vec",Help: "Total number of HTTP requests",}, []string{"uri"})
)func init() {prometheus.MustRegister(requestsTotalVec)
}
接口层面:
func withMetricsHandler(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {return func(w http.ResponseWriter, r *http.Request) {defer func() {requestsTotalVec.WithLabelValues(r.URL.Path).Inc()}()f(w, r)}
}
7)Prometheus查询语句
qrcode_http_requests_total // 请求总量irate(qrcode_http_requests_total[5m]) // 返回过去5分钟内HTTP请求数量的瞬时变化率,单位为每秒qrcode_http_requests_total_vec // 请求总量irate(qrcode_http_requests_total_vec{uri="/success"}[5m]) // 返回过去5分钟内URI的路径为/success的HTTP请求数量的瞬时变化率,单位为每秒
7 总结
到这里我们就完成了《Go语言实现二维码小游戏》从设计、接口开发再到监控运维的全部过程,希望你能从中学到东西,当然有些地方做的还不是很完善,因此在后续可能会更新一篇文章主要针对已有项目的优化,也希望屏幕前正在阅读的你能够留言给出优化建议。