如何在Docker容器之间交换消息
#docker #flask #redis #express

如今,由于几乎所有应用程序都采用了容器,因此毋庸置疑,他们需要相互交流。在本文中,我们将介绍如何在容器之间轻松发送和接收消息。

我假设您的环境已经安装了Docker。接下来,我们将构建两个带有烧瓶和节点JS的应用程序,并尝试在它们之间进行通信。

让我们从使用烧瓶的Python应用开始。
创建一个称为ping-app的文件夹并创建app.py文件,将以下代码放入其中。

from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def home():
    redis.incr('pageviews')
    return 'This app has been viewed %s time(s).' % redis.get('pageviews')

@app.route('/get-redis-count')
def count():
    return redis.get('pageviews')


if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

我们可以从上面的代码中看到Redis被用作键值对数据库。在根路由上,我们正在返回一条带有计数的消息,以在屏幕上打印,同时还将redis中的pageview数量增加1。

由于此应用程序使用两个软件包,让我们提出要求。txt文件并包括以下依赖项:

flask
redis

现在创建一个名为Dockerfile的文件,并添加以下代码开始对此应用程序进行扩展:

FROM python:3.7
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD python app.py

对于下一步,我们将需要一个带有以下代码的Docker-Compose文件,以便正确执行此应用程序:创建Docker-compose.yaml文件并添加以下代码:

version: "3.9"
services:
    web:
        build:
          context: .
          dockerfile: Dockerfile
        ports:
            - "5000:5000"
        volumes:
            - .:/code
        depends_on:
            - redis
    redis:
        image: redis

在此代码中,我们可以看到我们有2个服务,1个是Web,它基本上使用我们的Docker文件运行我们已经创建的Blask应用程序,而另一个服务是Redis,它基本上是在6379端口上运行的。因此,让我们现在使用工作区终端中的以下命令运行该应用。

docker-compose up

您的redis和Web服务都将因此成为运营。
使用http://localhost:5000,让我们在浏览器上打开烧瓶应用程序。和whoohoo,结果如图所示。

Image description

现在,现在在浏览器中重新加载此应用程序,现在多次观察计数是否每次加载时都会增加。

还查看同一应用程序http://localhost:5000/get-redis-count中的另一个端点,该应用程序只需返回屏幕计数号值。

到目前为止,一切都很简单。让我们假设您有另一个希望接收pageview count的node.js应用程序。

让我们使用以下技术来制作该节点应用程序:
制作一个名为Pong-App的新文件夹作为ping-app的兄弟姐妹,然后放置一个包含以下信息的封装文件:

{
    "name": "pong-app",
    "version": "1.0.0",
    "description": "",
    "author": "Jeetendra Singh <jeetendra.apps@gmail.com>",
    "main": "app.js",
    "scripts": {
        "start": "node app.js"
    },
    "dependencies": {
        "axios": "^1.1.2",
        "express": "^4.16.1"
    }
}

之后,让创建app.js文件平行于package.json文件,带有以下代码:

const express = require('express');
const axios = require('axios');
// Constants
const PORT = 8000;
const HOST = '0.0.0.0';

// App
const app = express();
app.get('/', (req, res) => {
  res.send('Hello Node');
});

app.listen(PORT, HOST, () => {
  console.log(`Running on http://${HOST}:${PORT}`);
});

上面的代码只是小型快递应用程序的开始。你好节点,让我们首先对此应用程序进行扩展。因此,将其中包含以下信息的Dockerfile文件。

FROM node:16 
WORKDIR /usr/app
COPY package*.json ./
RUN npm install
COPY . .
CMD node app.js

让我们为此应用创建一个docker-compose.yaml文件,其中包含以下信息:

version: "3.9"
services:
    server:
        build:
          context: .
          dockerfile: Dockerfile
        ports:
            - "8000:8000"
        volumes:
            - .:/usr/app
            - /usr/app/node_modules

您现在为此应用做准备,可以使用Docker-Compose来启动一个应用程序,然后将其运行在http://localhost:8000上。在根路由上,它将输出Hello Node。

现在两个应用程序都在单独的容器中运行,这是在Node JS应用中显示Python App的pageView数量的最简单方法是访问现有烧瓶应用程序中的 /get-redis-count-count API。<
让我们在node.js中创建一个函数以使用现有烧瓶API从烧瓶应用程序检索pageview计数。

app.get("/get-data-from-ping-app",async (req,res)=>{ 
  //call flask based api
  try{
    const response= await axios.get('http://web:5000/get-redis-count')
    console.log('redis count in flask app is ',response.data)
    res.json({count:response.data})
  }catch(err){
    const error='Node App is not able to connect with flask app';
    console.log(error)
    res.send(error)
  }
})

我们正在尝试调用上述代码中烧瓶应用程序内运行的端点 /get-redis-count。< /p>

另外,如果您观察到,我们使用了Web:5000而不是Localhost:5000创建烧瓶应用程序(http://web:5000/get-redis-count)时。因此,为了使用HTTP协议访问容器中的资源,我们必须利用组合文件中定义的容器服务名称。此烧瓶应用程序的服务名称是Web,这就是为什么URL为Web:5000。

现在让S重新启动我们的节点应用程序,并测试我们是否仍然访问http://localhost:8000/get-data-from-ping-app

当前,输出消息将读取:节点应用程序无法与烧瓶应用程序连接。

但是为什么?因为两个应用程序之间没有网络,它们正在独立运行。因此,我们需要对两个应用程序进行一些更改,以在它们之间创建网络。

就在服务之前,将网络my-local-net添加到两个应用程序(ping&pong)的docker-compose.yaml文件中。

networks:
 my-local-net:
  name: my_local_net
  driver: bridge

将以下代码添加到两个Docker-Compose文件的服务部分,以将创建的网络连接到每个服务。

networks:
       - my-local-net

让我们最后一眼浏览docker-compose文件:

ping app的docker-compose.yaml文件(基于烧瓶的应用)

version: "3.9"
networks:
 my-local-net:
  name: my_local_net
  driver: bridge
services:
    web:
        build:
          context: .
          dockerfile: Dockerfile
        ports:
            - "5000:5000"
        networks:
            - my-local-net
        volumes:
            - .:/code
        depends_on:
            - redis
    redis:
        image: redis
        networks:
            - my-local-net

Pong App的Docker-compose.yaml文件(基于node.js的应用)

version: "3.9"
networks:
 my-local-net:
  name: my_local_net
  driver: bridge
services:
    server:
        build:
          context: .
          dockerfile: Dockerfile
        ports:
            - "8000:8000"
        networks:
            - my-local-net
        volumes:
            - .:/usr/app
            - /usr/app/node_modules

现在重新启动两个应用程序,然后尝试访问以下URL,以查看Node.js中的Blask App的页面浏览量:

http://localhost:8000/get-data-from-ping-app

它会以

之类的响应

{– count:x}

注意:x只是计数的替身,这将是一个整数值。

最后,由于它们都在同一网络下声明,因此在Docker容器中运行的单独应用程序可以使用Network驱动程序桥相互连接。

you can get the complete source code from our download center。此外,如果您有任何疑问,请在下面发表评论或给我发电子邮件jeetendra.apps@gmail.com