升级后出现 Redis 错误

你好,

通过 Web 前端升级后,我无法再访问我的网站。我没有进行任何更改,只是点击了升级按钮!错误提示表明与 Redis 的连接存在问题。我已经进行了大量搜索,但尚未找到任何帮助。production.log 为空。服务器运行在 DigitalOcean 上的 Ubuntu 系统,此前已正常运行 18 个月,除了 6 个月前因磁盘空间不足导致的问题外(当时我成功扩展了磁盘空间),没有其他错误。

磁盘空间目前正常:

Filesystem      Size  Used Avail Use% Mounted on
overlay          49G   25G   24G  52% /
tmpfs            64M     0   64M   0% /dev
tmpfs          1001M     0 1001M   0% /sys/fs/cgroup
shm             512M  8.0K  512M   1% /dev/shm
/dev/vda1        49G   25G   24G  52% /shared
tmpfs          1001M     0 1001M   0% /proc/acpi
tmpfs          1001M     0 1001M   0% /proc/scsi
tmpfs          1001M     0 1001M   0% /sys/firmware

unicorn.stdout.log 显示:

> 2020-06-03T06:29:28.352Z pid=715 tid=osk2fuo0n ERROR: Error fetching job: Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL)
> 2020-06-03T06:29:28.353Z pid=715 tid=osk2fszrb ERROR: Error fetching job: Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL)
> 2020-06-03T06:29:28.354Z pid=715 tid=osk2fsjw3 ERROR: Error fetching job: Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL)
> 2020-06-03T06:29:28.354Z pid=715 tid=osk2ftlhz ERROR: Error fetching job: Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL)
> 2020-06-03T06:29:28.355Z pid=715 tid=osk2ftr43 ERROR: Error fetching job: Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL)
> Starting up 1 supervised sidekiqs
> Loading Sidekiq in process id 725

我首先尝试手动重建应用,

随后尝试了 apt upgrade docker,并通过 reboot 重启了服务器,然后使用 ./launcher rebuild app 重新构建。

redis-cli ping 命令返回了 PONG 响应:

ss -t
State      Recv-Q Send-Q Local Address:Port                 Peer Address:Port   
ESTAB      0      0      104.248.166.162:ssh                  5.81.114.19:56270 
ESTAB      0      0      104.248.166.162:ssh                  5.81.114.19:56211 

ps -axf 显示 Redis 正在运行:

  PID TTY      STAT   TIME COMMAND
 2378 pts/1    Ss     0:00 /bin/bash --login
 2849 pts/1    R+     0:00  \_ ps -axf
    1 pts/0    Ss+    0:00 /bin/bash /sbin/boot
  627 pts/0    S+     0:00 /usr/bin/runsvdir -P /etc/service
  628 ?        Ss     0:00  \_ runsv rsyslog
  641 ?        Sl     0:00  |   \_ rsyslogd -n
  629 ?        Ss     0:00  \_ runsv cron
  640 ?        S      0:00  |   \_ cron -f
  630 ?        Ss     0:00  \_ runsv unicorn
  639 ?        S      0:00  |   \_ /bin/bash config/unicorn_launcher -E producti
  665 ?        Sl     0:09  |       \_ unicorn master -E production -c config/un
  725 ?        SNl    0:12  |       |   \_ sidekiq 6.0.7 discourse [0 of 5 busy]
  750 ?        Sl     0:20  |       |   \_ unicorn worker[0] -E production -c co
  758 ?        Sl     0:17  |       |   \_ unicorn worker[1] -E production -c co
 2848 ?        S      0:00  |       \_ sleep 1
  631 ?        Ss     0:00  \_ runsv postgres
  635 ?        S      0:00  |   \_ svlogd /var/log/postgres
  636 ?        S      0:00  |   \_ /usr/lib/postgresql/12/bin/postmaster -D /etc
  659 ?        Ss     0:00  |       \_ postgres: 12/main: checkpointer
  660 ?        Ss     0:00  |       \_ postgres: 12/main: background writer
  661 ?        Ss     0:00  |       \_ postgres: 12/main: walwriter
  662 ?        Ss     0:00  |       \_ postgres: 12/main: autovacuum launcher
  663 ?        Ss     0:00  |       \_ postgres: 12/main: stats collector
  664 ?        Ss     0:00  |       \_ postgres: 12/main: logical replication la
  691 ?        Ss     0:00  |       \_ postgres: 12/main: discourse discourse [l
 1848 ?        Ss     0:00  |       \_ postgres: 12/main: discourse discourse [l
 2633 ?        Ss     0:00  |       \_ postgres: 12/main: discourse discourse [l
 2675 ?        Ss     0:00  |       \_ postgres: 12/main: discourse discourse [l
 2840 ?        Ss     0:00  |       \_ postgres: 12/main: discourse discourse [l
  632 ?        Ss     0:00  \_ runsv nginx
  634 ?        S      0:00  |   \_ nginx: master process /usr/sbin/nginx
  654 ?        S      0:02  |       \_ nginx: worker process
  655 ?        S      0:00  |       \_ nginx: cache manager process
  633 ?        Ss     0:00  \_ runsv redis
  637 ?        S      0:00      \_ svlogd /var/log/redis
  638 ?        Sl     0:05      \_ /usr/bin/redis-server *:6379

有什么建议吗?我不是专家,真的很难找到恢复运行的方法。是否有我遗漏的简单步骤?还有其他可以检查的地方来帮助我找到问题吗?

谢谢

哦……看来你已经重启并做了所有显而易见的操作……

你能贴出你的容器配置吗(请去掉密码)?Redis 模板是否混入了其中?

docker logs app 中有没有什么值得关注的信息?

你的容器内部能否正确解析 localhost?

3 个赞

嗨,Sam,抱歉我可能不太懂,

你是指 app.yml 文件吗?

你说的 Docker 日志具体是哪些日志?我执行了 ./launcher logs app

run-parts: 正在执行 /etc/runit/1.d/00-ensure-links
run-parts: 正在执行 /etc/runit/1.d/00-fix-var-logs
run-parts: 正在执行 /etc/runit/1.d/anacron
run-parts: 正在执行 /etc/runit/1.d/cleanup-pids
清理过期的 PID 文件
run-parts: 正在执行 /etc/runit/1.d/copy-env
run-parts: 正在执行 /etc/runit/1.d/letsencrypt
[2020 年 6 月 3 日 星期三 06:34:47 UTC] 域名未更改。
[2020 年 6 月 3 日 星期三 06:34:47 UTC] 跳过,下次续期时间为:2020 年 7 月 1 日 00:35:12 UTC
[2020 年 6 月 3 日 星期三 06:34:47 UTC] 添加 '--force' 以强制续期。
[2020 年 6 月 3 日 星期三 06:34:47 UTC] 正在将密钥安装到:/shared/ssl/forum.tritalk.co.uk.key
[2020 年 6 月 3 日 星期三 06:34:47 UTC] 正在将完整链安装到:/shared/ssl/forum.tritalk.co.uk.cer
[2020 年 6 月 3 日 星期三 06:34:47 UTC] 运行重载命令:sv reload nginx
警告:nginx: 无法打开 supervise/ok:文件不存在
[2020 年 6 月 3 日 星期三 06:34:47 UTC] 重载错误:
[2020 年 6 月 3 日 星期三 06:34:48 UTC] 域名未更改。
[2020 年 6 月 3 日 星期三 06:34:48 UTC] 跳过,下次续期时间为:2020 年 7 月 9 日 00:35:12 UTC
[2020 年 6 月 3 日 星期三 06:34:48 UTC] 添加 '--force' 以强制续期。
[2020 年 6 月 3 日 星期三 06:34:48 UTC] 正在将密钥安装到:/shared/ssl/forum.tritalk.co.uk_ecc.key
[2020 年 6 月 3 日 星期三 06:34:48 UTC] 正在将完整链安装到:/shared/ssl/forum.tritalk.co.uk_ecc.cer
[2020 年 6 月 3 日 星期三 06:34:48 UTC] 运行重载命令:sv reload nginx
警告:nginx: 无法打开 supervise/ok:文件不存在
[2020 年 6 月 3 日 星期三 06:34:48 UTC] 重载错误:
runsvdir 已启动,PID 为 627
ok: 运行:redis: (pid 638) 0 秒
ok: 运行:postgres: (pid 636) 0 秒
chgrp: 无效的用户组:'syslog'
rsyslogd: imklog: 无法打开内核日志 (/proc/kmsg):操作不允许。
rsyslogd: imklog 模块激活失败 [v8.1901.0 请查看 https://www.rsyslog.com/e/2145 ]
supervisor pid: 639 unicorn pid: 665

在容器内我尝试了该命令,不确定这是否是你所指的

tritalk@TriTalk-Discourse:/var/discourse$ sudo ./launcher enter app
root@TriTalk-Discourse-app:/var/www/discourse# curl http://localhost:8080
curl: (7) 无法连接到 localhost 端口 8080:连接被拒绝
1 个赞

是的,是 app.yml,但请删除任何密码或敏感信息。

2 个赞
## 这是 Discourse 的独立 Docker 容器模板,集所有功能于一体
##
## 修改此文件后,您必须重新构建
## /var/discourse/launcher rebuild app
##
## 编辑时请*非常*小心!
## YAML 文件对空白字符或缩进错误极其敏感!
## 必要时请访问 http://www.yamllint.com/ 验证此文件

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## 如果您想添加 Lets Encrypt (https),请取消注释以下两行
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"

## 此容器应暴露哪些 TCP/IP 端口?
## 如果您希望 Discourse 与 Apache 或 nginx 等其他 Web 服务器共享端口,
## 请参阅 https://meta.discourse.org/t/17247 了解详情
expose:
  - "80:80"   # http
  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## 将 db_shared_buffers 设置为总内存的最大 25%。
## 将根据检测到的 RAM 由 bootstrap 自动设置,您也可以覆盖该值
  db_shared_buffers: "128MB"

  ## 可提高排序性能,但会增加每个连接的内存使用量
  #db_work_mem: "40MB"

  ## 此容器应使用哪个 Git 修订版本?(默认:tests-passed)
  #version: tests-passed

env:
  LANG: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## 支持多少并发 Web 请求?取决于内存和 CPU 核心数。
  ## 将根据检测到的 CPU 由 bootstrap 自动设置,您也可以覆盖该值
  UNICORN_WORKERS: 2

  ## TODO: 此 Discourse 实例将响应的域名
  ## 必填。Discourse 无法在仅使用 IP 地址的情况下工作。
  DISCOURSE_HOSTNAME: forum.xxxx.co.uk

  ## 如果您希望容器以与上述指定的相同的主机名(-h 选项)启动,请取消注释
  ## (默认值为 "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: 初始注册时将设为管理员和开发者的逗号分隔的电子邮件列表
  ## 示例:'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'admin@xxxx.co.uk'

  ## TODO: 用于验证新账户和发送通知的 SMTP 邮件服务器
  # SMTP 地址、用户名和密码是必需的
  # 警告:SMTP 密码中的字符 '#' 可能导致问题!
  DISCOURSE_SMTP_ADDRESS: in-v3.mailjet.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: xxxx
  DISCOURSE_SMTP_PASSWORD: "xxxx"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (可选,默认为 true)

  ## 如果您添加了 Lets Encrypt 模板,请取消注释以下行以获取免费 SSL 证书
  LETSENCRYPT_ACCOUNT_EMAIL: admin@xxxx.co.uk

  ## 此 Discourse 实例的 CDN 地址(配置为拉取)
  ## 请参阅 https://meta.discourse.org/t/14857 了解详情
  #DISCOURSE_CDN_URL: //discourse-cdn.example.com

## Docker 容器是无状态的;所有数据都存储在 /shared 中
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## 插件放在此处
## 请参阅 https://meta.discourse.org/t/19157 了解详情
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - mkdir -p plugins
          - git clone https://github.com/discourse/discourse-adplugin.git
          - git clone https://github.com/discourse/discourse-affiliate.git

## 构建后运行的任何自定义命令
run:
  - exec: echo "开始自定义命令"
  ## 如果您想为首次注册设置“发件人”电子邮件地址,请取消注释并修改:
  ## 收到首次注册邮件后,请重新注释该行。该行只需运行一次。
  - exec: rails r "SiteSetting.notification_email='admin@xxxx.co.uk'"
  - exec: echo "结束自定义命令"

这是个难题,你运行的是哪个版本的 Docker?docker info 返回了什么?

你说得没错!看起来像是找不到数据库,当你进入网站时,只显示一个带有标题的屏幕。

Docker 信息:-

客户端:
 调试模式:false

服务器:
 容器:2
  运行中:1
  已暂停:0
  已停止:1
 镜像:6
 服务器版本:19.03.11
 存储驱动:overlay2
  后端文件系统:extfs
  支持 d_type:true
  原生 Overlay 差异:true
 日志驱动:json-file
 Cgroup 驱动:cgroupfs
 插件:
  卷:local
  网络:bridge host ipvlan macvlan null overlay
  日志:awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm:未激活
 运行时:runc
 默认运行时:runc
 初始化二进制:docker-init
 containerd 版本:7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc 版本:dc9208a3303feef5b3839f4323d9beb36df0a9dd
 初始化版本:fec3683
 安全选项:
  apparmor
  seccomp
   配置文件:default
 内核版本:4.4.0-179-generic
 操作系统:Ubuntu 16.04.6 LTS
 OSType:linux
 架构:x86_64
 CPU 数量:1
 总内存:1.953GiB
 名称:TriTalk-Discourse
 ID:SYIS:XPWU:W2SP:NYNA:GFP7:DNVK:E7JF:553N:EGWF:OR7M:TV2E:A6ZX
 Docker 根目录:/var/lib/docker
 调试模式:false
 注册表:https://index.docker.io/v1/
 标签:
 实验性功能:false
 不安全注册表:
  127.0.0.0/8
 实时恢复已启用:false

警告:不支持交换分区限制

您可以尝试安全模式吗?

我使用了安全模式,如果进入后不禁用插件,就会失败。看来升级后某个插件出了问题。我从 yml 文件中注释掉这些插件,重新构建应用后一切正常。问题可能出在 discourse-affiliate 或 discourse-adplugin 上。我稍后会进一步调查,但至少网站已经恢复运行了。感谢大家的支持。提醒自己:以后进行初步检查时记得使用安全模式!

3 个赞

您的插件区域格式似乎不正确。这是否导致了问题?

实际上应该如下所示:

        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-adplugin.git
          - git clone https://github.com/discourse/discourse-affiliate.git

(移除 -mkdir -p plugins
希望这能解决插件相关的问题。

1 个赞

谢谢 Bhanu。我会试试看,奇怪的是,之前一直能用,今天却出了问题。也许是最新的 Docker 版本加强了某些限制。

我可能在这里弄错了。我从未在我的 yml 文件中使用过该参数,但到目前为止一切正常。

1 个赞

你好 @carlb

仅供参考,Redis 主要用于后台任务(与其配套的任务调度器 Sidekiq 一起使用);另外,就我个人经验而言,在开发环境中,我通常会在 Redis 或 Sidekiq 未运行的情况下运行 Discourse,因为我不希望这些“后台任务”在运行。

因此,即使 Redis 未运行,你的 Discourse 论坛仍应显示核心论坛、主题、用户、帖子等内容。我之所以补充这一点,是因为你的主题标题为:

Redis Error after upgrade

……然后你非常贴心地提供了论坛截图,其中显示了许多基本问题,这些问题与 Redis 本身并无直接关联。

1 个赞

谢谢你的解释。我对这些组件如何协同工作并不太了解,因为它们一直以来都能正常运行,所以我从未需要深入探究,这对我未来的工作很有帮助。我只是假设,因为我发现的所有错误都提到了无法连接到 Redis,所以这可能是根本原因。而且,通常能解决基本问题的常规方法也都失效了。

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.