优雅关闭节点应用程序
#教程 #typescript #node #docker

本文将主要是为Dockerized节点应用程序编写的,但是最后阶段绝对可以用于任何节点应用程序,因为它使拆卸过程变得更好,更有信息。

入门

首先是安装初始服务,我个人一直在使用yelp中的dumb-init

ENTRYPOINT [ "dumb-init", "node", "app.js" ]

这样,您将适当地注入环境中的所有信号(SIGINTSIGTERMSIGHUP等),以便您可以自己处理它们。这很有用,因为没有它们,该过程就会消失,所有连接都被终止,这可能会使连接的服务悬挂,数据正确性问题和可怕的用户体验,因为它们只是被踢了。

这是一个简单的设置,类似于我用来更优雅地处理这些设置:

import cors from 'cors';
import express, {
    Express, Request, Response,
} from 'express';
import helmet from 'helmet';
import { createServer } from 'http';

/**
 * Main Express src class.
 *
 * Create a new instance and then run with await instance.start().
 */
class Server {
    app: Express;

    config: Config;

    token?: string | null;

    constructor() {
        // Get and set environment variables
        this.app = express();
        this.config = getConfig();
    }


    // eslint-disable-next-line class-methods-use-this
    teardown() {
        disconnectFromDatabase()
          .then( () => console.log( 'Disconnected from Mongo servers.' ) )
          .catch(
            ( e: Error ) => {
              console.error( `Received error ${e.message} when disconnecting from Mongo.` );
            },
          );
    }

    async start() {
        this.app.use( express.urlencoded( { extended: true, limit: this.config.fileSizeLimit } ) );
        this.app.use( express.json( { strict: false, limit: this.config.fileSizeLimit } ) );
        this.app.use( express.text() );
        this.app.use( helmet() );
        this.app.use( cors() );
        this.app.use( limiter );

        const server = createServer( this.app ).listen( this.config.port, () => {
            console.log(
                `🚀 Server ready at ${this.config.host}`,
            );
        } );
        server.timeout = this.config.express.timeout;

        process.on( 'SIGINT', () => {
            console.log( 'Received SIGINT, shutting down...' );
            this.teardown();
            server.close();
        } );
        process.on( 'SIGTERM', () => {
            console.log( 'Received SIGTERM, shutting down...' );
            this.teardown();
            server.close();
        } );
        process.on( 'SIGHUP', () => {
            console.log( 'Received SIGHUP, shutting down...' );
            this.teardown();
            server.close();
        } );
    }
}

const server = new Server();

server.start()
    .then( () => console.log( 'Running...' ) )
    .catch( ( err: Error | string ) => {
        console.error( err );
    } );

本质上就是这样。我没有包含一些方法,但是如果您连接到数据库或AMQP服务或其他服务,则可以正确关闭这些连接以确保在强制停止之前确保任何读取/写入/推/应用程序。


Simon Infanger的标题Unsplash