<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          「GoCN酷Go推薦」使用GO語言啟動docker Container

          共 4027字,需瀏覽 9分鐘

           ·

          2021-11-26 22:42

          推薦背景

          在日常開發(fā)中,測試是不可避免的,在針對DAO層的代碼寫測試用例的時候,直接將依賴的存儲服務(wù)(比如mongodb)的client給mock掉,可能達不到檢驗代碼中語法或數(shù)據(jù)操作正確性的目的。如果在本地起一個相關(guān)的存儲服務(wù)又會由于不同的項目帶來環(huán)境的污染,并且測試代碼由于依賴本地環(huán)境可能導(dǎo)致多人協(xié)作困難。在云原生時代,你可能第一想到的就是利用docker container 來解決環(huán)境問題,而本文所推薦的就是用 go 語言來操作docker的開源項目。

          項目鏈接:https://github.com/moby/moby

          快速使用

          準(zhǔn)備環(huán)境

          安裝docker:https://www.docker.com/

          安裝

          //?安裝?docker?client
          go?get?github.com/docker/docker/client

          啟動mongo

          package?main

          import?(
          ?"context"
          ?"fmt"
          ?"github.com/docker/docker/api/types"
          ?"github.com/docker/docker/api/types/container"
          ?"github.com/docker/docker/client"
          ?"github.com/docker/go-connections/nat"
          )

          const?(
          ?mongoExposedPort?=?"27017/tcp"
          )

          func?main(){
          ?cli,?err?:=?client.NewEnvClient()?//?初始化?docker?client
          ?if?err?!=?nil{
          ??panic(err)
          ?}
          ?ctx?:=?context.Background()
          ?//?創(chuàng)建一個container
          ?resp,?err?:=?cli.ContainerCreate(ctx,
          ??&container.Config{
          ???Image:?"mongo:latest",?//?鏡像名:推薦提前下好
          ???ExposedPorts:?nat.PortSet{
          ????mongoExposedPort:?{},???//?暴露的端口號:可以使用想用命令啟動一個,然后通過docker ps 看
          ???},
          ??},
          ??&container.HostConfig{
          ???PortBindings:?nat.PortMap{
          ????mongoExposedPort:?[]nat.PortBinding{?//?端口映射:將容器里的 27017 映射到本機的 27017 端口
          ?????{
          ??????HostIP:?"127.0.0.1",
          ??????HostPort:?"0",?//?這個值如果是0,就會選一個未被占用的端口
          ?????},
          ????},
          ???},
          ??},
          ??nil,?//?網(wǎng)絡(luò)配置:默認將可以
          ??nil,?????//?平臺描述:不用傳
          ??"",?//?容器名:傳空會隨機分配
          ?)
          ?if?err?!=?nil{
          ??panic(err)
          ?}
          ?err?=?cli.ContainerStart(ctx,?resp.ID,?types.ContainerStartOptions{})?//?start?container
          ?if?err?!=?nil?{
          ??panic(err)
          ?}
          ?fmt.Println("container?start?...")

          ?result,?err?:=?cli.ContainerInspect(ctx,?resp.ID)
          ?if?err?!=?nil?{
          ??panic(err)
          ?}
          ?addr?:=?result.NetworkSettings.Ports[mongoExposedPort][0]?//?查看綁定到的地址
          ?fmt.Printf("binding?port:?%v\n",?addr)
          ?err?=?cli.ContainerRemove(ctx,resp.ID,types.ContainerRemoveOptions{?//?remove?container
          ??Force:?true,?//?強制刪除
          ?})
          ?if?err?!=?nil{
          ??panic(err)
          ?}
          ?fmt.Println("container?kill?...")
          }

          封裝容器運行的庫函數(shù)

          //?封裝在容器運行mongodb的函數(shù)
          package?mongotest

          import?(
          ?"context"
          ?"fmt"
          ?"github.com/docker/docker/api/types"
          ?"github.com/docker/docker/api/types/container"
          ?"github.com/docker/docker/client"
          ?"github.com/docker/go-connections/nat"
          ?"testing"
          )

          const?(
          ?mongoExposedPort?=?"27017/tcp"
          )

          func?RunWithMongo(m?*testing.M,?mongoURI?*string)?int{
          ?cli,?err?:=?client.NewEnvClient()?//?初始化?docker?client
          ?if?err?!=?nil{
          ??panic(err)
          ?}
          ?ctx?:=?context.Background()
          ?//?創(chuàng)建一個container
          ?resp,?err?:=?cli.ContainerCreate(ctx,
          ??&container.Config{
          ???Image:?"mongo:latest",?//?鏡像名:推薦提前下好
          ???ExposedPorts:?nat.PortSet{
          ????mongoExposedPort:?{},???//?暴露的端口號:可以使用想用命令啟動一個,然后通過docker ps 看
          ???},
          ??},
          ??&container.HostConfig{
          ???PortBindings:?nat.PortMap{
          ????mongoExposedPort:?[]nat.PortBinding{?//?端口映射:將容器里的 27017 映射到本機的 27017 端口
          ?????{
          ??????HostIP:?"127.0.0.1",
          ??????HostPort:?"0",?//?這個值如果是0,就會選一個未被占用的端口
          ?????},
          ????},
          ???},
          ??},
          ??nil,?//?網(wǎng)絡(luò)配置:默認將可以
          ??nil,?????//?平臺描述:不用傳
          ??"",?//?容器名:傳空會隨機分配
          ?)
          ?if?err?!=?nil{
          ??panic(err)
          ?}
          ?containerID?:=?resp.ID
          ?defer?func()?{
          ??err?=?cli.ContainerRemove(ctx,containerID,types.ContainerRemoveOptions{?//?remove?container
          ???Force:?true,?//?強制刪除
          ??})
          ??if?err?!=?nil{
          ???panic(err)
          ??}
          ?}()

          ?err?=?cli.ContainerStart(ctx,?containerID,?types.ContainerStartOptions{})?//?start?container
          ?if?err?!=?nil?{
          ??panic(err)
          ?}
          ?result,?err?:=?cli.ContainerInspect(ctx,?resp.ID)
          ?if?err?!=?nil?{
          ??panic(err)
          ?}
          ?addr?:=?result.NetworkSettings.Ports[mongoExposedPort][0]?//?查看綁定到的地址
          ?*mongoURI?=?fmt.Sprintf("mongodb://%s:%s",?addr.HostIP,?addr.HostPort)
          ?return?m.Run()
          }
          //?真實的測試代碼
          package?docker_demo

          import?(
          ?mongotest?"github.com/zrruirui/docker-demo/mongo"
          ?"os"
          ?"testing"
          )

          var?mongoURI?=?""

          func?TestMain(m?*testing.M){
          ?os.Exit(mongotest.RunWithMongo(m,?&mongoURI))
          }

          func?TestA(t?*testing.T){
          ?//?寫自己的單測代碼
          ?t.Log(mongoURI)
          }

          總結(jié)

          https://github.com/moby/moby 這個項目中有很多對容器的操作,在我的demo項目中只用了其中的很小一部分,用來解決單測 mock db問題,其他更復(fù)雜的功能有需要可自行查閱。

          感謝

          特別感謝 ccmouse 老師的講解,我是從他那里了解了這個庫并在日常開發(fā)中使用。


          《酷Go推薦》招募:


          各位Gopher同學(xué),最近我們社區(qū)打算推出一個類似GoCN每日新聞的新欄目《酷Go推薦》,主要是每周推薦一個庫或者好的項目,然后寫一點這個庫使用方法或者優(yōu)點之類的,這樣可以真正的幫助到大家能夠?qū)W習(xí)到

          新的庫,并且知道怎么用。


          大概規(guī)則和每日新聞類似,如果報名人多的話每個人一個月輪到一次,歡迎大家報名!戳「閱讀原文」,即可報名


          掃碼也可以加入 GoCN 的大家族喲~



          瀏覽 30
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一本无码在线播放 | 日本草逼网| 毛片A片中文字幕在线视频 | xxxx日本少妇 | 四虎av在线 |