Hacker News Digest

Тег: #fastify

Постов: 2

Show HN: PrinceJS – 19,200 req/s Bun framework in 2.8 kB (built by a 13yo) (princejs.vercel.app)

PrinceJS позиционируется как самый быстрый фреймворк для Bun, демонстрируя впечатляющую производительность в 19,200 запросов в секунду при размере всего 2.8 килобайта. Эта сверхлегкая реализация делает его идеальным выбором для высоконагруженных приложений, где важна каждая миллисекунда и каждый байт. Фреймворк сохраняет при этом простоту использования и функциональность, необходимую для разработки современных веб-приложений.

Разработчики подчеркивают, что PrinceJS достигает такой производительности благодаря минималистичному подходу и отсутствию избыточных абстракций. Несмотря на крошечный размер, фреймворк включает все необходимые функции для создания REST API и веб-приложений. Это делает его привлекательной альтернативой более крупным фреймворкам, таким как Express.js или Fastify, особенно для проектов, где критически важны скорость и эффективность.

by lilprince1218 • 17 ноября 2025 г. в 19:45 • 122 points

ОригиналHN

#bun#expressjs#fastify#rest-api#web-frameworks#performance#web-development

Комментарии (39)

  • Пользователи отмечают, что 13-летний разработчик из Нигерии создал фреймворк, который по производительности превосходит Express и Fastify, но при этом не поддерживает wildcard-роутинг и не имеет тестов.
  • Сообщество обсуждает, что примерно 20 тыс. запросов в секунду для простого эндпоинта — это не рекорд, но при этом нет никакой информации о том, какие именно фичи отсутствуют и какие баги могут быть в таком фреймворке.
  • Некоторые участники обсуждения отмечают, что фреймворк не имеет тестов и не ясен вопрос, как он будет вести себя в продакшене.
  • Участники также отмечают, что в документации фреймворка нет информации о том, какие именно фичи он поддерживает, и какие из них отсутствуют.

What Are Traces and Spans in OpenTelemetry? (oneuptime.com)

Trace — полный путь одного запроса через все сервисы.
Span — отдельный шаг в этом пути (функция, SQL, HTTP-вызов).
Root span — первый span (обычно входящий HTTP-запрос).
Child span — вложенный шаг.
Context — передаёт trace_id и текущий span по асинхронным вызовам.
Sampler — решает, записывать ли трассировку.
Exporter — отправляет spans в OneUptime, Jaeger и т.д.


Структура span

  • name — короткое имя операции
  • start/end time — длительность
  • status — OK / ERROR
  • attributes — произвольные метки (user_id, db.table)
  • events — точки во времени (exception, cache hit)
  • links — связи с другими traces

Быстрый старт в Node.js / TypeScript

npm i @opentelemetry/api @opentelemetry/sdk-node \
      @opentelemetry/auto-instrumentations-node
// tracing.ts
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';

const sdk = new NodeSDK({
  serviceName: 'my-api',
  traceExporter: new OTLPTraceExporter({ url: 'https://otlp.oneuptime.com' }),
  instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();

Ручная инструментация

import { trace } from '@opentelemetry/api';
const tracer = trace.getTracer('my-service');

async function getUser(id: string) {
  return tracer.startActiveSpan('db.users.findById', async (span) => {
    span.setAttributes({ 'db.table': 'users', 'user.id': id });
    try {
      const user = await db.users.findById(id);
      span.setStatus({ code: SpanStatusCode.OK });
      return user;
    } catch (e) {
      span.recordException(e);
      span.setStatus({ code: SpanStatusCode.ERROR, message: e.message });
      throw e;
    } finally {
      span.end();
    }
  });
}

Express/Fastify middleware

import { trace } from '@opentelemetry/api';

export function traceMiddleware(req, res, next) {
  const span = trace.getTracer('http').startSpan(`${req.method} ${req.route?.path || req.url}`);
  trace.getActiveContext().with(trace.setSpan(trace.getActiveContext(), span), () => {
    res.on('finish', () => {
      span.setAttributes({
        'http.status_code': res.statusCode,
        'http.method': req.method,
        'http.route': req.route?.path,
      });
      span.end();
    });
    next();
  });
}

Практические советы

  • Именование: verb noun (GET /users, db.users.insert).
  • Атрибуты: добавляйте user.id, order.id, region.
  • Ошибки: span.recordException(err) + span.setStatus({code: ERROR}).
  • Sampling: head-based (решение на старте) или tail-based (после завершения).
  • Антипаттерны: слишком мелкие spans, отсутствие span.end(), захардкоженные ID.

Сборка всего вместе

  1. Запустите SDK на старте приложения.
  2. Добавьте auto-instrumentations (http, express, pg, redis).
  3. Дополните ручными spans для критичных операций.
  4. Отправляйте traces в OneUptime → исследуйте flame-графы, ищите узкие места.

by ndhandala • 27 августа 2025 г. в 12:10 • 88 points

ОригиналHN

#opentelemetry#nodejs#typescript#express#fastify#jaeger#oneuptime#distributed-tracing

Комментарии (28)

  • OTEL хвалят как стандарт, но реальные реализации сильно разнятся между вендорами и часто усложняют жизнь.
  • Базовые понятия: span — это интервал работы с уникальным ID и ссылкой на родителя, trace — DAG спанов, рассказывающий историю запроса.
  • Авто-инструментация почти даром даёт данные для JVM-приложений, но вне веб-бэкендов примеров мало и приходится искать «правильный» подмножество.
  • Некоторые жалуются на объём кода и хранилище (десятки ТБ трейсов за неделю), другие считают это разовой настройкой и платой за прозрачность системы.
  • Появляются упрощающие обёртки (Logfire, otelize) и примеры интеграции, но документация по дашбордам Grafana всё ещё вызывает трудности.