docker golang 主进程与 python 子进程通信的最佳实践
Best practice on docker golang main process communicate with python subprocess
我知道使用docker的最佳实践是在每个容器中只有一个主进程并且只有一个CMD
行运行ning.
我的情况是我有一个 Golang
微服务,功能是在 python 子流程中实现的。目前主进程只接受 API 调用然后调用 exec
中的 python
子进程并读取 STDOUT
和 STDERR
.
我想优化架构,例如 运行 python 仅在 docker 内的本地主机上作为服务(Flask)。然后我的主要 Golang
进程可以使用 restful http
调用与 python 进程进行通信。
但这会让 2 个服务 运行ning 在同一个 docker 中并且它不是主进程和子进程。这实际上会很糟糕吗,知道吗?
感谢所有帮助。
通常当你有多个服务时,最好的做法是不要将它们部署在一个容器中,建议你将它们部署在多个容器中。
您可以使用docker-compose来帮助您:
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.
对于您的场景,请举一个最简单的例子作为下一个。
文件夹结构:
.
├── 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)
}
go/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
,最后得到 flask
.
产生的内容 Hey, we have Flask in a Docker container!
我知道使用docker的最佳实践是在每个容器中只有一个主进程并且只有一个CMD
行运行ning.
我的情况是我有一个 Golang
微服务,功能是在 python 子流程中实现的。目前主进程只接受 API 调用然后调用 exec
中的 python
子进程并读取 STDOUT
和 STDERR
.
我想优化架构,例如 运行 python 仅在 docker 内的本地主机上作为服务(Flask)。然后我的主要 Golang
进程可以使用 restful http
调用与 python 进程进行通信。
但这会让 2 个服务 运行ning 在同一个 docker 中并且它不是主进程和子进程。这实际上会很糟糕吗,知道吗?
感谢所有帮助。
通常当你有多个服务时,最好的做法是不要将它们部署在一个容器中,建议你将它们部署在多个容器中。
您可以使用docker-compose来帮助您:
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.
对于您的场景,请举一个最简单的例子作为下一个。
文件夹结构:
.
├── 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)
}
go/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
,最后得到 flask
.
Hey, we have Flask in a Docker container!