Как бороться с ошибкой read ECONNRESET в Ghost

Иногда мой блог вместо страницы выдавал ошибку 500, с отображением SQL запроса, который не прошёл. select count(distinct posts.id) as aggregate from posts where (posts.status = 'published' and posts.page = false)

Анатолий Остроумов

javascript

360 Words

2019-06-16 15:22 +0300


Иногда мой блог вместо страницы выдавал ошибку 500, с отображением SQL запроса, который не прошёл. Это выглядело так:

fix_econnreset_ghost.png

Код ошибки мог меняться в замисимости от страницы, но почти всегда это был SQL запрос вроде такого

select count(distinct posts.id) as aggregate 
from posts 
where (posts.status = 'published' and posts.page = false)

Главное, что в нём всегда встречалось read ECONNRESET.

Причина неполадок состояла в том, что сервер базы данных закрывал соединение с блог платформой, так как оно, по мнению сервера, не использовалось. Данная неполадка чинится отправкой этих запросов на MariaDB сервер через консоль сервера MySQL/MariaDB:


SET GLOBAL connect_timeout=28800;
SET GLOBAL wait_timeout=28800;
SET GLOBAL interactive_timeout=28800;

Эти переменные задают критерии, используемые сервером для того, чтобы определить, какие соединения считаются неиспользуемыми, и их можно разорвать. Я поставил значение в 8 часов (28800 секунд), и разрывы соединения пропали. Подробнее о всех системных переменных базы данных MariaDB.

Обновление 1.

При перезагрузке сервера с базой данных, глобальные переменные к сожалению сбрасываются. Одно из возможных решений проблемы ошибки с разрывом соединения было описано в этом комментарии https://github.com/TryGhost/Ghost/issues/9739#issuecomment-406240883 Пользователь с ником Toub посоветовал периодически загружать главную страницу блога, чтобы платформа посылала запросы к базе данных, и соединение восстанавливалось.

При этом техническая поддержка платформы Ghost показала особенную клиентоориентированность. Z понял, что они ничем помочь не могут и не хотят, по их мнению, официальные образы докера с неправильно работающим соединением с базой данных это нормально. Поэтому, проблему я начал решать сам.


'use strict';

const async = require('async'); // tested with  version >=2.6.2
const request = require('request'); //  tested with version >=2.88.0

let i = 0;
async.doWhilst(
  function (callback) {
    request('https://blog.vodolaz095.life', function (error, response) {
      if (error) {
        return callback(error);
      }
      i += 1;
      console.log('Test %s. Status code - %s', i, response.statusCode); // eslint-disable-line
      callback(null, response.statusCode);
    });
  },
  function (statusCode) {
    return statusCode !== 200;
  },
  function (error) {
    if (error) {
      throw error;
    }
    console.log('Blog awaken!');  // eslint-disable-line
    process.exit(0);
  }
);

И поставил его в крон на запуск каждую минуту.

* * * * * cd /home/vodolaz095/ && node /home/vodolaz095/wakeBlog.js

Посмотрим, что из этого получится…

Обновление 2

Скрипт для побудки блога проработал несколько лет. Но в 2026 году я решил делать личный сайт на Hugo. Поэтому, можно считать, что проблему я решил.