繁体   English   中英

Open Telemetry 使 Next.js 初始化极慢

[英]Open Telemetry makes Next.js initialization extremely slow

通过node -rnode --require初始化 Nextjs 时,应用程序需要 4-5 分钟才能加载。 遥测脚本会在前 5 秒内加载,因此此问题可能与 Nextjs 或节点有关。 这对比了没有节点的调用需要模块的 30 秒加载时间。

没有节点需要模块:

"dev": "env-cmd -f environments/.env.development next dev",

使用节点需要模块:

"dev": "env-cmd -f environments/.env.development node --require ./tracing.js ./node_modules/next/dist/bin/next dev",

此实现基于ross-hagan 关于 instrument-nextjs-opentelemetry 的博客

自定义服务器的替代方案

我最初使用一个完全独立的 tracing.js 脚本开始,其中包含我们的 start.js 脚本的内容,没有调用 startServer。

这将遥测 SDK 启动与服务器分开。 然后,您可以通过在启动 Next 应用程序之前使用节点 --require (-r) 加载模块来保留 Next.js 内置启动行为。

在您的 npm 中,在您的 package.json 中运行开发脚本,如下所示:

node -r tracing.js./node_modules/.bin/next dev

在让节点命令在 Dockerfile 中运行感到沮丧后,我放弃了这个,因为这是注定要用于 Google Kube.netes Engine 运行时的。 此外,还有一些关于使用 --require 标志的问题。

看看这样做是否适合您,因为 Next.js 自定义服务器会在其文档中记录一些后果!


我尝试了两个单独的tracing.js ,但未能成功减少加载时间。

开放遥测提供的tracing.js

/* tracing.js */

// Require dependencies
const opentelemetry = require("@opentelemetry/sdk-node");
const { getNodeAutoInstrumentations } = require("@opentelemetry/auto-instrumentations-node");
const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');

// For troubleshooting, set the log level to DiagLogLevel.DEBUG
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);

const sdk = new opentelemetry.NodeSDK({
  traceExporter: new opentelemetry.tracing.ConsoleSpanExporter(),
  instrumentations: [getNodeAutoInstrumentations()]
});

sdk.start()

以及为 jaeger 定制的tracing.js

const process = require('process');
const opentelemetry = require('@opentelemetry/sdk-node');
const {
  getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
const { Resource } = require('@opentelemetry/resources');
const {
  SemanticResourceAttributes,
} = require('@opentelemetry/semantic-conventions');
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');

const hostName = process.env.OTEL_TRACE_HOST || 'localhost';

const options = {
  tags: [],
  endpoint: `http://${hostName}:1234/api/traces`,
};
const traceExporter = new JaegerExporter(options);

// configure the SDK to export telemetry data to the console
// enable all auto-instrumentations from the meta package
const sdk = new opentelemetry.NodeSDK({
  resource: new Resource({
    [SemanticResourceAttributes.SERVICE_NAME]: 'my_app',
  }),
  traceExporter,
  instrumentations: [
    getNodeAutoInstrumentations({
      // Each of the auto-instrumentations
      // can have config set here or you can
      // npm install each individually and not use the auto-instruments
      '@opentelemetry/instrumentation-http': {
        ignoreIncomingPaths: [
          // Pattern match to filter endpoints
          // that you really want to stop altogether
          '/ping',

          // You can filter conditionally
          // Next.js gets a little too chatty
          // if you trace all the incoming requests
          ...(process.env.NODE_ENV !== 'production'
            ? [/^\/_next\/static.*/]
            : []),
        ],

        // This gives your request spans a more meaningful name
        // than `HTTP GET`
        requestHook: (span, request) => {
          span.setAttributes({
            name: `${request.method} ${request.url || request.path}`,
          });
        },

        // Re-assign the root span's attributes
        startIncomingSpanHook: (request) => {
          return {
            name: `${request.method} ${request.url || request.path}`,
            'request.path': request.url || request.path,
          };
        },
      },
    }),
  ],
});

// initialize the SDK and register with the OpenTelemetry API
// this enables the API to record telemetry
sdk
  .start()
  .then(() => console.log('Tracing initialized'))
  .catch((error) =>
    console.log('Error initializing tracing and starting server', error)
  );

// gracefully shut down the SDK on process exit
process.on('SIGTERM', () => {
  sdk
    .shutdown()
    .then(() => console.log('Tracing terminated'))
    .catch((error) => console.log('Error terminating tracing', error))
    .finally(() => process.exit(0));
});

另外,构建然后服务也不会加快加载时间。

检查您是否遇到此处报告的问题[@opentelemetry/instrumentation] require performance grows linearly with each instrumentation plugin 在这个问题中,有一个错误会导致仪器反复叠加在自身之上。 他们已经解决了这个问题。

另请参阅此答案

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM