Говоря об обработке ошибок во внешнем интерфейсе

Node.js база данных внешний интерфейс CDN

Как найти причину ошибки, когда пользователь отзывает белый экран открытой страницы? Как убедиться, что в определенном ежедневном выпуске нет ошибок? Насколько важно в это время отлавливать и сообщать об ошибках в выполнении кода.

Поскольку обнаружение ошибок и сообщение об ошибках — неотъемлемая часть ежедневной разработки, как вы их отлавливаете? мощныйtry...catch


try{

throw new Error()

} catch(e) {

// handle error

}

Кажется, как просто захват ошибок, но следующие сценарии не могут быть захвачены


try {

setTimeout(() => {

throw new Error('error')

})

} catch (e) {

// handle error

}

Вы обнаружите, что ошибка в приведенном выше примере не может быть перехвачена обычным образом.Кажется, что перехват ошибки не так прост, **try...catch** можно сделать, конечно, вы также можете обернуть слой **try ... поймать**, чтобы справиться.

В браузере **window.onerror** для обнаружения ваших ошибок


window.onerror = function (msg, url, row, col, error) {

console.log('error');

console.log({

msg, url, row, col, error

})

};

После обнаружения ошибки вы можете сообщить об ошибке.Метод сообщения очень прост.Вы можете создать простой **img** и указать адрес сообщения через **src**.Конечно, чтобы не отправлять слишком много запросы на отчетность, вы можете Отчет объединен, и отчет объединен. Данные могут периодически передаваться на сервер.

Но когда вы посмотрите на информацию, сообщаемую об ошибке, вы обнаружите некоторые такие ошибки **Ошибка скрипта**

Из-за политики браузера в отношении одного и того же источника **ошибка скрипта** выдается при ошибках с разными доменными именами. Как решить эту проблему? Тем более сейчас в основном ресурсы js будут размещаться на cdn.

решение

1: Все ресурсы размещаются под одним доменным именем. Но это также будет иметь проблему, заключающуюся в невозможности использования преимуществ cdn.

2. Добавьте поддержку междоменных ресурсов, добавьте поддержку междоменных запросов для основного домена в cdn и добавьте атрибут **crossorigin** в тег скрипта.

В использованииPromiseпроцесс, если у вас нетcatch, то вы можете поймать ошибку следующим образом

window.addEventListener("unhandledrejection", function(err, promise) { 
    // handle error here, for example log   
});

Как ловить ошибки в NodeJs

Перехват ошибок в NodeJ важен, потому что неправильное обращение с ним может привести к лавине непригодных сервисов. Конечно не только умеете ловить ошибки, но и умеете избегать тех или иных ошибок.

  • Когда вы пишете функцию, вы, возможно, думали, что когда возникает ошибка при выполнении функции, я должен выбросить ее напрямую.throwили используйтеcallbackилиevent emitterИли это какой-то другой способ распространения ошибки?

  • Должен ли я проверить, является ли параметр правильным типом, не так ли?null

  • Что делать, если параметры не совпадают? выдать ошибку или пройтиcallbackКак насчет ошибок распределения другими способами?

  • Что, если будет сохранено достаточно ошибок, чтобы восстановить сцену ошибки?

  • Что делать, если вы хотите поймать некоторые ошибки исключения?try...catchещеdomain

Ошибка операции VS ошибка кодирования

1. Ошибка операции

Операции ошибки часто встречаются во время выполнения, а не из-за ошибок кода, но могут быть связаны с вашей системой, не хватающей памятью или не хватает ручек файлов, или нет сети и т. Д.

2. Ошибка кодирования

Легче понять, если кодировка неверна, это может бытьundefinedНо она вызывается как функция, либо возвращает неверный тип данных, либо утечки памяти и т.д.

Обработка операционных ошибок

  • Вы можете зарегистрировать ошибку, а затем ничего не делать

  • Вы также можете повторить попытку, например, потому что соединение с базой данных не удалось, но количество попыток должно быть ограничено.

  • Вы также можете указать интерфейс, а затем повторить попытку позже.

  • Возможно, вы также можете обработать это напрямую.Например, если путь не существует, создайте путь

Обработка ошибок кодирования

С плохой кодировкой нелегко справиться, потому что она вызвана ошибками кодирования. Хороший способ - перезапустить процесс, потому что

  • Вы не уверены, повлияет ли ошибка, вызванная ошибкой кодирования, на другие запросы.Например, ошибка установления соединения с базой данных не может быть успешной из-за ошибки кодирования, тогда другие ошибки сделают другие запросы недоступными.

  • Возможно, операция ввода-вывода выполняется до того, как будет выброшена ошибка, поэтому дескриптор ввода-вывода не может быть закрыт, что будет занимать память в течение длительного времени, что в итоге может привести к исчерпанию памяти и недоступности всей службы.

  • Два пункта, упомянутых выше, на самом деле не решают проблему вообще.Вы должны сделать тест перед выходом в сеть и контролировать его после выхода в сеть.При возникновении подобной ошибки вы должны следить за сигнализацией, обращать внимание и решать проблему.

Как распространять ошибки

  • В синхронной функции непосредственноthrowошибка

  • Для некоторых асинхронных функций ошибка может быть передана черезcallbackбросать

  • async/awaitможно использовать напрямуюtry..catchпоймать ошибки

  • EventEmitterбросатьerrorмероприятие

Эксплуатация и обслуживание NodeJ

Для приложения NodeJs трудно обеспечить стабильную работу только на уровне кода, но также и на уровне эксплуатации и обслуживания.

Мультипроцесс для управления вашим приложением

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

может относиться кTSWДизайн многопроцессорный. Мастер отвечает за управление воркером.Рабочий и мастер поддерживают мониторинг сердцебиения.В случае потери они будут немедленно перезапущены.

domain
process.on('uncaughtException', function(err) {
    console.error('Error caught in uncaughtException event:', err);
});
process.on('unhandleRejection', function(err) {
  // TODO
})

При перехвате исключений в nodejs выше можно сказать, что это очень жестоко. Но когда исключение перехвачено в это время, вы потеряли контекст в это время, и можно сказать, что контекст здесь является запросом. Если в веб-службе происходит какая-то аномалия, все еще есть надежда, что некоторый восходящий контент может быть возвращен для улучшения взаимодействия с пользователем. Например, рендеринг на стороне сервера или изоморфизм, даже если он не работает, вы можете вернуть статический html и принять решение для понижения версии, но контекст в это время будет потерян. Выхода нет.

function domainMiddleware(options) {
    return async function (ctx, next) {
        const request = ctx.request;
        const d = process.domain || domain.create();
        d.request = request;
        let errHandler = (err) => {
            ctx.set('Content-Type', 'text/html; charset=UTF-8');
            ctx.body = options.staticHtml;
        };
        d.on('error', errHandler);
        d.add(ctx.request);
        d.add(ctx.response);
        try {
            await next();
        } catch(e) {
            errHandler(e)
        }
    }

Выше приведено простое промежуточное программное обеспечение домена koa2, использующее мониторинг домена.errorСобытие, объекты запроса и ответа каждого запроса будут запускаться при возникновении ошибки.errorСобытия, когда возникает ошибка, могут ухудшаться в зависимости от контекста.

Как избежать утечек памяти

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

  • Не блокируйте выполнение цикла событий, особенно больших циклов или операций синхронизации ввода-вывода.

    for ( var i = 0; i < 10000000; i++ ) {
        var user       = {};
        user.name  = 'outmem';
        user.pass  = '123456';
        user.email = 'outmem[@outmem](/user/outmem).com';
    }
    

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

    годный к употреблениюsetTimeoutВыполнение операции в следующем цикле, сокращение длинных циклов и синхронизация сопротивления ввода-вывода процессу Блокировка выполнения следующего цикла также снизит производительность приложения.

  • Частные переменные и методы модуля всегда находятся в памяти.

var leakArray = [];   
exports.leak = function () {  
  leakArray.push("leak" + Math.random());  
};

Когда в узле требуется модуль, в конце формируется синглтон, то есть пока функция вызывается, память функции будет увеличиваться, а замыкание не будет переработано.leakМетод является приватным, и этот метод всегда будет существовать в памяти. Каждый запрос будет вызывать этот метод, после чего память на какое-то время взорвется.

Подобные сценарии довольно распространены

// main.js
function Main() {
  this.greeting = 'hello world';
}
module.exports = Main;
var a = require('./main.js')();
var b = require('./main.js')();
a.greeting = 'hello a';
console.log(a.greeting); // hello a
console.log(b.greeting); // hello a

require является синглтоном, Когда каждый запрос выполняется на сервере, операция является синглтоном, так что переменные или атрибуты, сгенерированные каждым выполнением, всегда будут висеть на этом объекте, не могут быть переработаны и занимают много памяти.

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

var a = new require('./main.js');
// TODO

Иногда трудно избежать некоторых проблем, которые могут вызвать утечку памяти, вы можете использоватьvmКаждый вызов выполняется в среде песочницы, и вызов возвращается, когда он израсходован.

  • Последнее, что нужно сделать, это избегать циклических ссылок, которые также приведут к неперерабатываемым ресурсам.