zl程序教程

您现在的位置是:首页 >  其他

当前栏目

Docker 部署Go Web应用

2023-04-18 15:01:22 时间

随着Go的逐渐流行,基于性能、高效及稳定部署,越来越多的企业开始将其应用框架移植至Go平台。本文主要基于Goland开发平台和Docker容器环境运行,简要介绍Go语言开发的Web项目的容器化部署相关操作。

以下Demo主要简单实现登陆、注册等相关功能,具体如下:

部分源码如下:

package main

import (
  "crypto/md5"
  "database/sql"
  "encoding/json"
  "fmt"
  _"github.com/go-sql-driver/mysql"
  "io"
  "net/http"
)

func main() {
  mux := http.NewServeMux()
  mux.HandleFunc("/login", login)
  mux.HandleFunc("/register", register)
  http.ListenAndServe(":9090", mux) //监听9090端口
}

type result struct { //定义返回数据格式
  Code int
  Msg  string
  Data []string
}

func login(w http.ResponseWriter, r *http.Request) { //登陆
  w.Header().Set("Access-Control-Allow-Origin", "*") //允许跨域
  r.ParseForm()
  username, found1 := r.Form["username"]
  password, found2 := r.Form["password"]
  if !(found1 && found2) {
    io.WriteString(w, "请勿非法访问")
    return
  }
  db, err := sql.Open("mysql", "root@tcp(192.168.1.1:3306)/demo?charset=utf8") //登陆msyql
  if err != nil {
    fmt.Println(err)
  }
  defer db.Close()

  var post_data PostData
  post_data.user_name = username[0]
  post_data.pass_word = password[0]

  var filter_data FilterData = post_data
  post_data = filter_data.formatData()

  var row *sql.Row
  row = db.QueryRow("select * from users where username = ? and password = ?", post_data.user_name, post_data.pass_word)
  var user_name, pass_word string
  var id int
  err = row.Scan(&id, &user_name, &pass_word) //遍历结果
  if err != nil {
    arr := &result{
      500,
      "登陆失败",
      []string{},
    }
    b, json_err := json.Marshal(arr) //json化结果集
    if json_err != nil {
      fmt.Println("encoding faild")
    } else {
      io.WriteString(w, string(b)) //返回结果
    }
  } else {
    arr := &result{
      200,
      "登陆成功",
      []string{},
    }
    b, json_err := json.Marshal(arr) //json化结果集
    if json_err != nil {
      fmt.Println("encoding faild")
    } else {
      io.WriteString(w, string(b)) //返回结果
    }
  }
}

func register(w http.ResponseWriter, r *http.Request) { //注册
  w.Header().Set("Access-Control-Allow-Origin", "*") //允许跨域
  r.ParseForm()
  username, found1 := r.Form["username"]
  password, found2 := r.Form["password"]
  if !(found1 && found2) {
    io.WriteString(w, "请勿非法访问")
    return
  }
  db, err := sql.Open("mysql", "root@tcp(192.168.1.1:3306)/demo?charset=utf8")
  if err != nil {
    io.WriteString(w, "连接数据库失败")
    return
  }
  defer db.Close() //在返回前关闭资源(延迟)

  var post_data PostData
  post_data.user_name = username[0]
  post_data.pass_word = password[0]

  var filter_data FilterData = post_data
  post_data = filter_data.formatData()

  _, err = db.Exec("insert into users(username, password) values(?,?)", post_data.user_name, post_data.pass_word) //插入数据
  if err != nil {
    arr := &result{
      500,
      "注册失败",
      []string{},
    }
    b, json_err := json.Marshal(arr) //json化结果集
    if json_err != nil {
      fmt.Println("encoding faild")
    } else {
      io.WriteString(w, string(b)) //返回结果
    }
  } else {
    arr := &result{
      200,
      "注册成功",
      []string{},
    }
    b, json_err := json.Marshal(arr) //json化结果集
    if json_err != nil {
      fmt.Println("encoding faild")
    } else {
      io.WriteString(w, string(b)) //返回结果
    }
  }
}

type FilterData interface { //定义数据接口
  formatData() PostData
}

type PostData struct { //定义传递数据结构体
  user_name string
  pass_word string
}

func (post_data PostData) formatData() PostData { //格式化数据
  post_data.pass_word = mdFormat(post_data.pass_word)
  return post_data
}

func mdFormat(data string) string { //对字符串进行md5加密
  t := md5.New()
  io.WriteString(t, data)
  return fmt.Sprintf("%x", t.Sum(nil))
}

程序运行结果:

至此,一个简单的Go Web程序开发完成,现在我们将其进行容器化部署。

编写Dockerfile文件,具体内容如下所示:

[administrator@JavaLangOutOfMemory go-Pro ]% vi Dockerfile
FROM golang:latest

ENV GO111MODULE=on 
    CGO_ENABLED=0 
    GOOS=linux 
    GOARCH=amd64

WORKDIR /build

COPY . .

RUN go build -o appDemo .

WORKDIR /dist

RUN cp /build/appDemo .

EXPOSE 9090

CMD ["/dist/appDemo"]

在项目目录下,执行下面的命令创建镜像,并指定镜像名称为:go-web-appdemo,具体如下所示:

[administrator@JavaLangOutOfMemory go-Pro ]% docker build . -t go-web-appdemo      
Sending build context to Docker daemon  22.36MB
Step 1/9 : FROM golang:latest
 ---> 1463476d8605
Step 2/9 : ENV GO111MODULE=on     CGO_ENABLED=0     GOOS=linux     GOARCH=amd64
 ---> Using cache
 ---> ffaaa4db652f
Step 3/9 : WORKDIR /build
 ---> Using cache
 ---> d540d5215e29
Step 4/9 : COPY . .
 ---> 2ce72619b717
Step 5/9 : RUN go build -o appDemo .
 ---> Running in d6541a17758c
 ... ...
Successfully built 2ce72619b717
Successfully tagged go-web-appdemo:latest

此时,go-web-appdemo容器镜像已构建完成,启动容器,如下所示:

[administrator@JavaLangOutOfMemory go-Pro ]% docker run -itd -p 9090:9090 --name luga-go-web-appdemon go-web-appdem

再次通过浏览器访问,结果如下:

至此,一个简单的Go Web容器构建完成,并运行成功。