模板渲染
现在的web项目大多数是前后端分离的,我们可以先从看看以前的模板渲染是怎么在Gin框架上使用的,模板是网页在后端程序渲染好后直接发送到用户的浏览器,浏览器的网页几乎不做任何操作,有利于SEO,网页的渲染速度也快很多。
Gin使用模板渲染时候需要指定匹配静态文件的路径,打包编译的时候把所有的文件都打包进去。
最近自己做了一个非常简单的demo,展示一个课程的几个静态页面,使用了模板渲染,总结回顾一下,首先新建一个TemplateTest文件夹,在该文件夹下新建main.go文件输入一下内容:
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.LoadHTMLGlob("tem/**/*") //**代表文件夹,*代表文件,要指定到最底层的文件才不会报错
r.GET("/index", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "hello 土味挖掘机", //可以证明这个框架是正常的
})
})
r.GET("/class", func(c *gin.Context) {
class := c.DefaultQuery("class", "1") //接受url参数
c.HTML(http.StatusOK, "class"+class+".html", gin.H{"title": class}) //拼接模板文件路径,传递渲染参数
})
r.Run()
}
复制代码
然后在TemplateTest下新建一个tmp文件夹,再在tmp文件夹下新建一个文件夹html放置html文件,新建几个html文件如下图所示:
然后执行两个命令初始化项目的go.mod和下载依赖包:
go mod init TemplateTest
复制代码
go mod tidy
复制代码
直接在项目根目录直接运行go run main.go
并访问index路由,再测试访问class路径,并且class参数
完美运行,r.LoadHTMLGlob("tem/**/*")
这句代码是指模板的文件夹,所以返回的时候指定路径的时候是直接指定文件名的,没有前面的class文件夹和tem文件夹,还可以使用engine.Static("./static", "static")
注册静态文件,在html中直接使用static
指定静态文件的位置。
多段构建
好了,项目写好了,我们来尝试使用docker打包这个项目,先做一个简陋的一段打包示范看看镜像有多大,后面再看看使用多端打包的镜像有多大。
在项目根目录新建一个Dockerfile文件输入一下内容:
#编译和运行都是用这个镜像
FROM golang:alpine
#设置工作路径
WORKDIR /build
#把项目所有文件复制到镜像的根目录文件夹中
ADD . ./
# 设置Go语言的环境变量,打开Go Module模式。设置包下载源,有利于快速下载包
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn
#下载go.mod里面的包
RUN go mod download
#编译
RUN go build -o gin_docker .
#打开端口
EXPOSE 8080
#运行项目
ENTRYPOINT ["./gin_docker"]
复制代码
在使用docker命令读取Dockerfile内容生成镜像
docker build -t gin:v1 .
复制代码
尝试从这个镜像运行一个容器
docker run -itd --name gin -p 8080:8080 gin:v1
复制代码
运行测试成功
但是缺点就是打包的镜像太大了,就这么几十行的代码,几个文件和文件夹,占用400MB的空间
在学习docker的时候,学习了它的多段构建,是docker17.05之后的新特性,之前用php打包镜像没有遇到这个事情,但是在Go这里正巧遇到,就正好用上它,因为Go是编译型语言,需要编译成二进制文件后才能运行,我们可以把编译的镜像和运行的镜像分开,现在我把Dockerfile文件改一下,看看下面的示例,很清楚简单:
##
# ---------- building ----------
##
#编译用这个镜像
FROM golang:alpine AS builder
#设置工作路径
WORKDIR /build
#把项目所有文件复制到镜像的根目录文件夹中
ADD . ./
# 设置Go语言的环境变量,打开Go Module模式。设置包下载源,有利于快速下载包
ENV GO111MODULE=on \
GOPROXY=https://goproxy.cn
#下载go.mod里面的包
RUN go mod download
#编译
RUN go build -o gin_docker .
##
# ---------- run ----------
##
#换一个镜像
FROM alpine:latest
#采用相同的工作目录
WORKDIR /build/
#把编译好的文件复制到到运行镜像的目录下
COPY --from=builder /build .
#打开端口
EXPOSE 8080
#运行项目
ENTRYPOINT ["./gin_docker"]
复制代码
打包v2镜像:
docker build -t gin:v2 .
复制代码
运行容器(删掉之前的容器,不然会端口冲突):
docker run -itd --name gin -p 8080:8080 gin:v2
复制代码
完美运行,镜像大小相差了20倍
可见编译的时候需要很多依赖关系文件,运行时就是二进制文件,基本不需要什么依赖。可以看出使用多段构建可以节省很多储存成本和时间成本。