Как подключить Cloudflare

Оптимизация рабочих, которая уменьшает ваш счет

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

Задний план

Рабочие часто используются для реализации HTTP-прокси, где JavaScript используется для перезаписи HTTP-запроса перед его отправкой на исходный сервер, а затем для перезаписи ответа перед его отправкой обратно клиенту. Вы можете реализовать любой вид перезаписи в Worker, включая переписывание заголовков и тела.

Многие рабочие, однако, на самом деле не изменяют тело ответа, а вместо этого просто пропускают байты от источника к клиенту. В этом случае код приложения Worker завершил выполнение, как только были отправлены заголовки ответа, прежде чем байты тела прошли. Исторически сложилось так, что Worker, тем не менее, считался «используемым» до тех пор, пока тело ответа полностью не завершило потоковую передачу.

В целях выставления счетов в рамках модели ценообразования Workers Unbound мы взимаем плату за длительность памяти (гигабайты в секундах) за время, в течение которого используется Worker.

Перемена

15–16 декабря мы изменили способ обработки запросов, которые проходят через ответ, без изменения содержимого. Это изменение означает, что мы можем пометить код приложения как «ожидающий», как только будут возвращены заголовки ответа.

Поскольку никакой дальнейший код приложения не будет выполняться от имени запроса, системе не нужно хранить состояние запроса в памяти — ей нужно только отслеживать низкоуровневые собственные сокеты и прокачивать байты. Так что теперь, в течение этого времени, Worker будет считаться бездействующим и даже может быть вытеснен до завершения потока (хотя это маловероятно, если поток не длится очень долго).

Визуально это выглядит примерно так:

Оптимизация рабочих, которая уменьшает ваш счет

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

Это изменение совершенно незаметно для приложения. Для любого внешнего наблюдателя все ведет себя так же, как и раньше. Но поскольку система теперь считает, что Worker бездействует во время потоковой передачи ответов, время потоковой передачи ответов больше не будет оплачиваться. Итак, если вы увидели снижение счета, вот почему!

Но это еще не все!

Это изменение также относится к нескольким другим часто используемым сценариям, а именно к проксированию Websocket, чтению из кеша и потоковой передаче из KV.

Веб-сокеты: как только Worker организовал прокси через WebSocket, пока он не обрабатывает отдельные сообщения в вашем коде Worker, Worker не остается в использовании во время проксирования. Изменение применяется к обычным рабочим объектам без сохранения состояния, но не к устойчивым объектам, которые обычно не используются для проксирования.

export default {
  async fetch(request: Request) {
    //Do anything before
    const upgradeHeader = request.headers.get('Upgrade')
    if (upgradeHeader || upgradeHeader === 'websocket') {
      return await fetch(request)
    }
    //Or with other requests
  }
}

Чтение из кэша: Если вы возвращаете ответ от cache.match вызов, Worker считается бездействующим, как только возвращаются заголовки ответа.

export default {
  async fetch(request: Request) {
    let response = await caches.default.match('https://example.com')
    if (response) {
      return response
    }
    // get/create response and put into cache
  }
}

Трансляция из КВ: И последнее, когда стримишь с КВ. Это немного сложнее сделать правильно, потому что часто люди получают значение из KV в виде строки или объекта JSON, а затем создают ответ с этим значением. Но если вы извлекаете значение в виде потока, как это сделано в приведенном ниже примере, вы можете создать ответ с помощью ReadableStream.

interface Env {
  MY_KV_NAME: KVNamespace
}

export default {
  async fetch(request: Request, env: Env) {
    const readableStream = await env.MY_KV_NAME.get('hello_world.pdf', { type: 'stream' })
    if (readableStream) {
      return new Response(readableStream, { headers: { 'content-type': 'application/pdf' } })
    }
  },
}

Заинтересованы в работниках на свободе?

Если вы уже используете Unbound, ваш счет уже будет автоматически снят.

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

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

Что такое Cloudflare