【问题标题】:Best practice on docker golang main process communicate with python subprocessdocker golang主进程与python子进程通信的最佳实践
【发布时间】:2022-01-03 08:40:40
【问题描述】:

我知道使用 docker 的最佳实践是每个容器中只有一个主进程,并且只有一个 CMD 行运行。

我的情况是我有一个Golang 微服务,并且该功能是在 python 子进程中实现的。目前主进程只接受API调用然后调用exec中的python子进程并读取STDOUTSTDERR

我想优化架构,例如仅在 docker 内的 localhost 上运行 python 作为服务(Flask)。那么我的主Golang进程就可以使用restfulhttp调用与python进程通信了。

但这会让 2 个服务在同一个 docker 中运行,它不是一个主进程和一个子进程。这实际上会很糟糕,知道吗?

感谢所有帮助。

【问题讨论】:

  • 当你说优化时,你是什么意思?针对内存、性能进行优化?.. 您到底想优化什么,您不喜欢当前解决方案的什么?是否需要两种语言?
  • 嗨@jabbson,当我提到“优化”时,主要是关于性能。由于依赖库,业务逻辑只能在python中实现,主要的golang微服务是公司必须使用的。
  • 好吧,如果出于商业原因需要使用两种语言,那么您无能为力,对吧?不过说实话,听起来还是有点奇怪。你不能从 Go 调用的 python 子进程调用是什么?它必须在同一个容器中吗?它可以是运行 python 烧瓶应用程序的单独容器吗?那么你的 Go 应用程序会像一个 API 网关,而 Python 容器会实现一个具体的后端逻辑吗?这是你追求的东西吗?
  • 其实公司只支持我们使用 Golang 作为后端语言和相关的内部框架。但是开源的解决方案都是python

标签: docker go flask docker-compose interprocess


【解决方案1】:

通常当您有多个服务时,最好不要将它们部署在一个容器中,建议您将它们部署在多个容器中。

您可以使用docker-compose 来帮助您:

Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。使用 Compose,您可以使用 YAML 文件来配置应用程序的服务。然后,使用一个命令,您就可以从您的配置中创建并启动所有服务。

对于你的场景,给你一个最小的例子。

文件夹结构:

.
├── docker-compose.yaml
├── flask
│   ├── app.py
│   └── Dockerfile
└── go
    ├── app.go
    └── Dockerfile

docker-compose.yaml:

version: '3'
services:
  flask_service:
    build: flask

  go_service:
    build: go
    ports:
    - "9500:9500"
    depends_on:
    - flask_service

go/app.go:

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
        url := "http://flask_service:9600"
        ret, err := http.Get(url)
        if err != nil {
                panic(err)
        }
        defer ret.Body.Close()

        body, err := ioutil.ReadAll(ret.Body)
        if err != nil {
                panic(err)
        }
        fmt.Fprintf(w, string(body))
}

func main() {
        http.HandleFunc("/", handler)
        http.ListenAndServe(":9500", nil)
}

去/Dockerfile:

FROM golang:latest as build

WORKDIR /go/app
COPY ./app.go .
RUN go mod init app; go mod tidy; go build

CMD ["/go/app/app"]

flask/app.py:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hey, we have Flask in a Docker container!'

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=9600)

flask/Dockerfile:

FROM python:alpine3.7

WORKDIR /app

RUN pip install flask

COPY . /app

ENTRYPOINT [ "python" ]
CMD [ "app.py" ]

执行:

$ docker-compose up
Creating network "20211203_default" with the default driver
Creating 20211203_flask_service_1 ... done
Creating 20211203_go_service_1    ... done
Attaching to 20211203_flask_service_1, 20211203_go_service_1

验证:

$ curl http://10.192.244.21:9500
Hey, we have Flask in a Docker container!

你可以看到我们访问了9500端口,它将请求路由到golang container,然后golang container会通过api调用flask service container,最终得到Hey, we have Flask in a Docker container!产生的内容flask .

【讨论】:

  • 非常感谢您的详细解释!也许这是我应该申请在同一虚拟机中部署这两种服务的最佳实践。
猜你喜欢
  • 2019-06-08
  • 1970-01-01
  • 1970-01-01
  • 2012-07-07
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多