docker学习——docker部署go程序

1.编写简单的go程序

cd /home
mkdir docker-go-test
cd docker-go-test
vi go-web-test.go

go-web-test.go:

package main

import (
	"log"
	"net/http"
)

func sayHello(w http.ResponseWriter, r *http.Request) {

	w.Write([]byte(r.Host +" : hello world"))
}
func main() {
	http.HandleFunc("/", sayHello)
	log.Println("服务启动成功 监听端口:8050")
	err := http.ListenAndServe("0.0.0.0:8050", nil)
	if err != nil {
		log.Fatal("ListenAndServe Err: ", err)
	}
}

2.编写Dokerfile

vi Dockerfile

Dockerfile:

FROM golang:latest

WORKDIR $GOPATH/src/docker-go-test
COPY . $GOPATH/src/docker-go-test
# 交叉编译 :此处编译为linux版本 go程序
# GOOS=darwin 为mac版本  GOOS=windows 为windows版本
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o go-web-test go-web-test.go

EXPOSE 8050
ENTRYPOINT ["./go-web-test"]

3.生成docker镜像

docker build -t docker-go-test .

生成镜像如下:
在这里插入图片描述

4.测试docker-go-test镜像

docker run -d -p 8050:8050 --name go-test docker-go-test

在这里插入图片描述

进入容器可查看到第2步Dockerfile操作的内容
在这里插入图片描述

访问测试:
在这里插入图片描述

5.docker-compose编排多个相同go服务

vi docker-compose.yml
version: '2'
services:
  go-test01:
    container_name: go-test01
    build:
      # context设定上下文跟目录,以此目录指定Dockerfile
      context: ./
      dockerfile: Dockerfile
    ports:
      - "9010:8050"
  go-test02:
    container_name: go-test02
    build:
      context: ./
      dockerfile: Dockerfile
    ports:
      - "9020:8050"
  go-test03:
    container_name: go-test03
    build:
      context: ./
      dockerfile: Dockerfile
    ports:
      - "9030:8050"

6.启动docker-compose

docker-compose up -d

在这里插入图片描述
访问测试:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7. docker-compose 编排 nginx + go-test实现负载均衡

7.1 准备nginx.conf与default.conf文件 以便挂载

cd /home/docker-go-test
# 创建用于挂载nginx配置文件的目录
mkdir -p conf/conf.d
cd conf
vi nginx.conf

nginx.conf

#定义Nginx运行的用户和用户组
user  nginx;

#nginx进程数,建议设置为等于CPU总核心数
worker_processes  1;

#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log  /var/log/nginx/error.log warn;

#进程文件
pid        /var/run/nginx.pid;

#工作模式与连接数上限
events {
    #单个进程最大连接数(最大连接数=连接数*进程数)
    worker_connections  1024;
}

#设定http服务器
http {
    #文件扩展名与文件类型映射表
    include       /etc/nginx/mime.types;

    #默认文件类型
    default_type  application/octet-stream;

    #日志的格式
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    #全局访问日志
    access_log  /var/log/nginx/access.log  main;
    
     #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处
理速度,降低系统的负载。注意:如果图片显示不正常把这个改 成off。
    sendfile        on;

    #防止网络阻塞
    #tcp_nopush     on;

    #长连接超时时间,单位是秒
    keepalive_timeout  65;

    #开启gzip压缩输出
    #gzip  on;

    #负载均衡(权重轮询)
    upstream go-test {
        server go-test01:8050 weight=1;
        server go-test02:8050 weight=2;
        server go-test03:8050 weight=3;
    }


    #虚拟主机的配置
    include /etc/nginx/conf.d/*.conf;
}

cd conf.d
vi default.conf
server{
      listen 80;
      location / {
        # 反向代理
        proxy_set_header Host $http_host;
        proxy_set_header X-Forward-For $remote_addr;
        proxy_set_header  X-real-ip $remote_addr;
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
        add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
        proxy_pass  http://go-test;
      }
}

7.2 修改go-web-test.go文件

package main

import (
        "errors"
        "log"
        "net"
        "net/http"
        "strings"
)

func sayHello(w http.ResponseWriter, r *http.Request) {

        // 获取内网ip  以便区分是nginx反向代理请求是哪个go-test服务处理的
        ip, err := GetInternalIP()
        if err != nil {
                log.Fatal("GET IP Err: ", err)
        }
        w.Write([]byte("GetInternalIP: " + ip + "\n"))
        w.Write([]byte(r.Host + " : hello world"))
}

func main() {
        http.HandleFunc("/", sayHello)
        log.Println("服务启动成功 监听端口:8050")
        err := http.ListenAndServe("0.0.0.0:8050", nil)
        if err != nil {
                log.Fatal("ListenAndServe Err: ", err)
        }
}

func GetInternalIP() (string, error) {
        // 思路来自于Python版本的内网IP获取,其他版本不准确
        conn, err := net.Dial("udp", "8.8.8.8:80")
        if err != nil {
                return "", errors.New("internal IP fetch failed, detail:" + err.Error())
        }
        defer conn.Close()

        // udp 面向无连接,所以这些东西只在你本地捣鼓
        res := conn.LocalAddr().String()
        res = strings.Split(res, ":")[0]
        return res, nil
}

7.3 docker-compose 编排 nginx + go-test

docker-compose.yml
go-test01,go-test02,go-test03对宿主机开放的端口被注释,无法通过 宿主机IP:端口方式访问了
nginx开放了对宿主机的9050端口,通过nginx.conf与default.conf文件实现反向代理,负载均衡

version: '2'
services:
  nginx:
    image: nginx
    container_name: go-test-nginx
    # 挂载宿主机端口9050
    ports:
      - "9050:80"
    volumes:
      # 挂载nginx目录
      - /home/docker-go-test/www:/usr/share/nginx/html/
      # 挂载nginx日志
      - /home/docker-go-test/log:/var/log/nginx/
      # 挂载nginx配置文件
      - /home/docker-go-test/conf/nginx.conf:/etc/nginx/nginx.conf
      # 挂载虚拟主机配置文件
      - /home/docker-go-test/conf/conf.d/default.conf:/etc/nginx/conf.d/default.conf
  go-test01:
    container_name: go-test01
    build:
      # context设定上下文跟目录,以此目录指定Dockerfile
      context: ./
      dockerfile: Dockerfile
    # ports:
    #  - "9010:8050"
  go-test02:
    container_name: go-test02
    build:
      context: ./
      dockerfile: Dockerfile
    # ports:
    #   - "9020:8050"
  go-test03:
    container_name: go-test03
    build:
      context: ./
      dockerfile: Dockerfile
    # ports:
    #   - "9030:8050"

7.4 确认docker-compose创建的网络

在这里插入图片描述

# 查看docker所有网络
docker network ls
# 查看docker-compose创建的docker-go-test_default网络
docker network inspect docker-go-test_default

go-test01:172.31.0.2
go-test02:172.31.0.5
go-test03:172.31.0.3
go-test-nginx:172.31.0.4
在这里插入图片描述

7.5 访问测试

http://宿主机ip:9050/
nginx负载均衡如下图所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8. nginx 负载均衡策略

8.1 轮询(默认)

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

    upstream go-test {
        server go-test01:8050;
        server go-test02:8050;
        server go-test03:8050;
    }

8.2 权重轮询

指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的

    upstream go-test {
        server go-test01:8050 weight=1;
        server go-test02:8050 weight=2;
        server go-test03:8050 weight=3;
    }

8.3 ip_hash

每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题

    upstream go-test {
        ip_hash;
        server go-test01:8050;
        server go-test02:8050;
        server go-test03:8050;
    }

8.4 least_conn 最少连接

连接最少的;最少连接允许在某些请求需要较长时间才能完成的情况下更公平地控制应用程序实例上的负载.

    upstream go-test {
        least_conn;
        server go-test01:8050;
        server go-test02:8050;
        server go-test03:8050;
    }

每次修改负载均衡策略后 可重启go-test-nginx容器测试:

docker restart go-test-nginx
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值