gpt4 book ai didi

php - 为什么 Docker Compose 重启可能会越来越多地渲染容器输出?

转载 作者:IT老高 更新时间:2023-10-28 21:37:06 32 4
gpt4 key购买 nike

我正在编写一个基于 Docker Compose 的 Web 应用程序,它有许多后台系统——一个 HTTP API、一个 HTTP 代理和一个队列。一切都在 PHP 5.6 或 7.0 的 Alpine 容器中。

我最初在 API 容器内的 Supervisor 中设置了队列,效果很好。然而,Supervisor/Python 使容器比它们应该的要胖得多(80M 而不是 25M),所以我将队列移到了它自己的容器中。它会存活约 5 分钟并退出以重新启动,而我在 Supervisor 中使用自动重启系统,因此我已切换到 Docker Compose 中的重启系统。我使用的是 Compose YAML 格式的第 2 版。

当队列启动时,它会向标准输出呈现一条简单的消息:

queue_instance     | Starting queue watcher (path=/remote/queue, proxying to proximate-proxy:8081)

当我最初执行 docker-compose up 时,这很好。但是,每次重新启动时,我都会收到三个这样的消息,然后是五个,依此类推,没有限制。如果我执行 docker ps 则表明只有一个队列在运行:

halfer@machine:~/proximate-app$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a9c94558769d proximate-app "/tmp/container-st..." 2 hours ago Up 2 hours 0.0.0.0:8084->8084/tcp app_instance
7e48d6aec459 proximate-api "sh /tmp/bin/web-s..." 2 hours ago Up 2 hours 0.0.0.0:8080->8080/tcp api_instance
86c564becadf proximate-queue "sh /var/app/bin/c..." 2 hours ago Up About a minute queue_instance
20c2145f80e4 proximate-proxy "sh /var/proxy/con..." 2 hours ago Up 2 hours 0.0.0.0:8081->8081/tcp proxy_instance

这是我的 Compose 文件:

version: '2'
services:

proximate-app:
container_name: "app_instance"
image: proximate-app
ports:
- "8084:8084"
links:
- proximate-api

# @todo Remove external ports once everything is happy
proximate-api:
container_name: "api_instance"
image: proximate-api
ports:
- "8080:8080"
links:
- proximate-proxy
- proximate-queue
volumes:
- proximate-volume:/remote/cache
- proximate-q-volume:/remote/queue
# Use time and TZ from the host, could alternatively use env vars and set it
# manually in the container, see https://wiki.alpinelinux.org/wiki/Setting_the_timezone
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
# Should perhaps pass this as a var to docker-compose so as not to hardwire it,
# but it is fine for now
environment:
- PHP_TIMEZONE=Europe/London

proximate-queue:
container_name: "queue_instance"
image: proximate-queue
restart: always
links:
- proximate-proxy
volumes:
- proximate-volume:/remote/cache
- proximate-q-volume:/remote/queue
environment:
- PROXY_ADDRESS=proximate-proxy:8081

# @todo Remove external ports once everything is happy
proximate-proxy:
container_name: "proxy_instance"
image: proximate-proxy
ports:
- "8081:8081"
volumes:
- proximate-volume:/remote/cache
environment:
- PROXY_LOG_PATH=/remote/cache/proxy.log

volumes:
proximate-volume:
proximate-q-volume:

相关的容器是proximate-queue

我很确定我的容器本身不会造成这种奇怪现象。我的 Dockerfile 这样输入:

ENTRYPOINT ["sh", "/var/app/bin/container-start.sh"]

这只是调用一个启动脚本:

#!/bin/sh

php \
/var/app/bin/queue.php \
--queue-path /remote/queue \
--proxy-address ${PROXY_ADDRESS}

运行队列进程:

#!/usr/bin/env php
<?php

use Proximate\Service\File;
use Proximate\Service\SiteFetcher as SiteFetcherService;
use Proximate\Queue\Read as QueueReader;

$root = realpath(__DIR__ . '/..');
require_once $root . '/vendor/autoload.php';

$actions = getopt('p:q:', ['proxy-address:', 'queue-path:']);

$queuePath = isset($actions['queue-path']) ? $actions['queue-path'] : (isset($actions['q']) ? $actions['q'] : null);
$proxyAddress = isset($actions['proxy-address']) ? $actions['proxy-address'] : (isset($actions['p']) ? $actions['p'] : null);

if (!$queuePath || !$proxyAddress)
{
$command = __FILE__;
die(
sprintf("Syntax: %s --proxy-address <proxy:port> --queue-path <queue-path>\n", $command)
);
}

if (!file_exists($queuePath))
{
die(
sprintf("Error: the supplied queue path `%s` does not exist\n", $queuePath)
);
}

echo sprintf(
"Starting queue watcher (path=%s, proxying to %s)\n",
$queuePath,
$proxyAddress
);

$queue = new QueueReader($queuePath, new File());
$queue->
setFetcher(new SiteFetcherService($proxyAddress))->
process();

如您所见,echo sprintf() 是宣布启动的内容,在我这边没有什么比循环更能做到这一点了。这可能是 Docker Compose 中的错误吗?我在 Ubuntu 14.04 上使用 docker-compose 版本 1.9.0, build 2585387

作为引用,Docker Compose 标准输出如下所示(队列中重复的行可见):

halfer@machine:~/proximate-app$ docker-compose up
Creating network "proximateapp_default" with the default driver
Creating proxy_instance
Creating queue_instance
Creating api_instance
Creating app_instance
Attaching to proxy_instance, queue_instance, api_instance, app_instance
proxy_instance | Teeing proxy logs also to /remote/cache/proxy.log
proxy_instance | [2017-05-10 09:18:42] stdout.INFO: Setting up queue at `/remote/cache/data` [] []
proxy_instance | [2017-05-10 09:18:42] stdout.INFO: Starting proxy listener on 172.18.0.2:8081 [] []
queue_instance | Starting queue watcher (path=/remote/queue, proxying to proximate-proxy:8081)
api_instance | PHP 7.0.16 Development Server started at Wed May 10 10:19:00 2017
app_instance | PHP 5.6.29 Development Server started at Wed May 10 09:19:10 2017
app_instance | PHP 5.6.29 Development Server started at Wed May 10 09:19:10 2017
queue_instance exited with code 0
queue_instance | Starting queue watcher (path=/remote/queue, proxying to proximate-proxy:8081)
queue_instance | Starting queue watcher (path=/remote/queue, proxying to proximate-proxy:8081)
queue_instance | Starting queue watcher (path=/remote/queue, proxying to proximate-proxy:8081)
queue_instance exited with code 0
queue_instance | Starting queue watcher (path=/remote/queue, proxying to proximate-proxy:8081)
queue_instance | Starting queue watcher (path=/remote/queue, proxying to proximate-proxy:8081)
queue_instance | Starting queue watcher (path=/remote/queue, proxying to proximate-proxy:8081)
queue_instance | Starting queue watcher (path=/remote/queue, proxying to proximate-proxy:8081)
queue_instance | Starting queue watcher (path=/remote/queue, proxying to proximate-proxy:8081)

我可以尝试的一件事是让应用程序进入休眠状态并且什么都不做,以证明某些奇怪的退出处理程序或某些东西不会造成严重破坏。但是,我希望它会做同样的事情。

更新

我已将队列替换为打印时间信息然后休眠 20 秒的脚本。这是我得到的:

halfer@machine:~/proximate-app$ docker-compose up
Creating network "proximateapp_default" with the default driver
Creating proxy_instance
Creating queue_instance
Creating api_instance
Creating app_instance
Attaching to proxy_instance, queue_instance, api_instance, app_instance
proxy_instance | Teeing proxy logs also to /remote/cache/proxy.log
proxy_instance | [2017-05-10 11:51:17] stdout.INFO: Setting up queue at `/remote/cache/data` [] []
proxy_instance | [2017-05-10 11:51:17] stdout.INFO: Starting proxy listener on 172.18.0.2:8081 [] []
queue_instance | Hello everyone! Time=Wed, 10 May 2017 11:51:27 +0000. Microtime=1494417087.107185
api_instance | PHP 7.0.16 Development Server started at Wed May 10 12:51:37 2017
app_instance | PHP 5.6.29 Development Server started at Wed May 10 11:51:46 2017
app_instance | PHP 5.6.29 Development Server started at Wed May 10 11:51:46 2017
queue_instance exited with code 0
queue_instance | Hello everyone! Time=Wed, 10 May 2017 11:51:27 +0000. Microtime=1494417087.107185
queue_instance | Hello everyone! Time=Wed, 10 May 2017 11:51:55 +0000. Microtime=1494417115.178871
queue_instance | Hello everyone! Time=Wed, 10 May 2017 11:52:22 +0000. Microtime=1494417142.409513
queue_instance exited with code 0
queue_instance | Hello everyone! Time=Wed, 10 May 2017 11:51:27 +0000. Microtime=1494417087.107185
queue_instance | Hello everyone! Time=Wed, 10 May 2017 11:51:55 +0000. Microtime=1494417115.178871
queue_instance | Hello everyone! Time=Wed, 10 May 2017 11:52:22 +0000. Microtime=1494417142.409513
queue_instance | Hello everyone! Time=Wed, 10 May 2017 11:52:49 +0000. Microtime=1494417169.612523
queue_instance | Hello everyone! Time=Wed, 10 May 2017 11:53:17 +0000. Microtime=1494417197.826749

这似乎表明:

  • 仅每隔一次重新启动报告一次重新启动
  • 我的任务将需要 20 秒,但 Compose 会非常缓慢地重新启动它们(接近每 30 秒)。这并没有让我太困扰,但可能是一个有用的观察
  • 在重复行的地方,它们实际上是旧的重启报告。

发生了什么事?

最佳答案

我总结了我们的发现。

累积输出是由于容器在每次退出时都没有被移除。因此,docker-compose 再次启动它,向您显示来自再次启动的同一容器的 docker logs -f。这按预期工作。

我没有找到一种方法让 docker-compose 在重新启动之前删除容器 inside 相同的 docker-compose up

我喜欢你的基于队列的架构,但我认为如果你使用一个长生命周期的容器而不是一个启动/退出/启动/退出的容器会更好......你可以通过一个简单的当真;做./queue-app-blabla.php;睡20;在 shell 脚本中完成

Anyone that need to reproduce this, can use the following docker-compose.yml

version: "2"

services:
ui:
image: ubuntu
command: tail -f /dev/null
links:
- queue
queue:
image: ubuntu
command: sh -c "date; echo Sleeping...; sleep 20; echo exit."
restart: always

输出:

queue_1  | Mon May 15 04:32:12 UTC 2017
queue_1 | Sleeping...
queue_1 | exit.
docker_queue_1 exited with code 0
queue_1 | Mon May 15 04:32:12 UTC 2017
queue_1 | Sleeping...
queue_1 | exit.
queue_1 | Mon May 15 04:32:33 UTC 2017
queue_1 | Sleeping...
queue_1 | exit.
queue_1 | Mon May 15 04:32:54 UTC 2017
queue_1 | Sleeping...
queue_1 | exit.
docker_queue_1 exited with code 0
queue_1 | Mon May 15 04:32:12 UTC 2017
queue_1 | Sleeping...
queue_1 | exit.
queue_1 | Mon May 15 04:32:33 UTC 2017
queue_1 | Sleeping...
queue_1 | exit.
queue_1 | Mon May 15 04:32:54 UTC 2017
queue_1 | Sleeping...
queue_1 | exit.
queue_1 | Mon May 15 04:33:17 UTC 2017
queue_1 | Sleeping...
queue_1 | exit.
queue_1 | Mon May 15 04:33:38 UTC 2017
queue_1 | Sleeping...
queue_1 | exit.

我提出的解决方案:

version: "2"

services:
ui:
image: ubuntu
command: tail -f /dev/null
links:
- queue
queue:
image: ubuntu
command: sh -c "while true; do date; echo Sleeping...; sleep 20; echo loop.; done"
restart: always

输出:

Attaching to docker_queue_1, docker_ui_1
queue_1 | Mon May 15 04:36:16 UTC 2017
queue_1 | Sleeping...
queue_1 | loop.
queue_1 | Mon May 15 04:36:36 UTC 2017
queue_1 | Sleeping...
queue_1 | loop.
queue_1 | Mon May 15 04:36:56 UTC 2017
queue_1 | Sleeping...
queue_1 | loop.
queue_1 | Mon May 15 04:37:16 UTC 2017
queue_1 | Sleeping...

IMO,最好看到容器启动和工作,而不是摆动启动/退出容器。 Docker 对具有这种行为的容器进行了特殊处理,请参阅 docker docs . “在每次重新启动之前添加一个不断增加的延迟(之前延迟的两倍,从 100 毫秒开始),以防止服务器泛滥。”(但它不适用于您的情况,因为您的容器正在运行 > 10 秒。


编辑:

检查可能的错误并退出。这可能很有用:

#!/bin/bash

PERIOD=10 # seconds

while true; do
echo Starting process...

date # the process
STATUS=$?

if [ $STATUS -ne 0 ]; then
echo "Error found. Exiting" >&2
exit $STATUS
fi

echo End process. Sleeping ${PERIOD}s
sleep $PERIOD
done

输出:

▶ ./script.sh
Starting process...
Mon May 15 11:43:06 ART 2017
End process. Sleeping 10s
Starting process...
Mon May 15 11:43:16 ART 2017
End process. Sleeping 10s
Starting process...
Mon May 15 11:43:26 ART 2017
End process. Sleeping 10s
Starting process...
Mon May 15 11:43:36 ART 2017
End process. Sleeping 10s
Starting process...
Mon May 15 11:43:46 ART 2017
End process. Sleeping 10s

关于php - 为什么 Docker Compose 重启可能会越来越多地渲染容器输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43890667/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com