В прошлом году я написал Blueprints for Up, описывая, как доступно большинство строительных блоков для создания отличного бессерверного опыта на AWS с минимальными усилиями. В этом посте рассказывается о первом альфа-выпуске Up.

Зачем сосредотачиваться на бессерверных? Во-первых, это рентабельно, поскольку вы платите по запросу только за то, что используете. Бессерверные варианты являются самовосстанавливающимися, поскольку каждый запрос изолирован и считается «не имеющим состояния». И, наконец, он легко масштабируется до бесконечности - нет компьютеров или кластеров, которыми нужно было бы управлять. Разверните свой код, и все готово.

Примерно месяц назад я решил начать работу над этим заново в apex / up и написал первое небольшое бессерверное примерное приложение tj / gh-polls для живых выступлений. Опросы пользователей SVG GitHub. Он работал хорошо и стоил менее 1 доллара в месяц для обслуживания миллионов опросов, поэтому я подумал, что продолжу проект и посмотрю, смогу ли я предложить варианты с открытым исходным кодом и коммерческие варианты.

Долгосрочная цель - предоставить своего рода «принеси свой собственный Heroku», поддерживающий множество платформ. Хотя платформа как услуга не является чем-то новым, бессерверная экосистема делает подобные программы все более тривиальными. При этом AWS и другие часто страдают с точки зрения UX из-за гибкости, которую они предоставляют. Up абстрагирует сложность, но при этом предоставляет вам решение, практически не требующее операций.

Установка

Вы можете установить Up с помощью следующей команды и просмотреть временную документацию, чтобы начать работу. Или, если вы набросаны сценариями установки, возьмите бинарный выпуск. (Имейте в виду, что этот проект все еще находится на ранней стадии.)

curl -sfL https://raw.githubusercontent.com/apex/up/master/install.sh | sh

Для обновления до последней версии в любой момент просто запустите:

up upgrade

Вы также можете установить через NPM:

npm install -g up

Функции

Какие функции предоставляет ранняя альфа-версия? Давайте взглянем! Имейте в виду, что Up не является размещенным сервисом, поэтому вам потребуется учетная запись AWS и учетные данные AWS. Если вы совсем не знакомы с AWS, вы можете подождать, пока этот процесс не будет оптимизирован.

Первый вопрос, который мне всегда задают: чем up (1) отличается от apex (1)? Apex фокусируется на развертывании функций для конвейеров и обработки событий, в то время как Up фокусируется на приложениях, API и статических сайтах, или отдельных развертываемых модулях. Apex не предоставляет вам API-шлюз, сертификаты SSL или DNS, а также не обеспечивает перезапись URL-адресов, внедрение сценариев и т. Д.

Бессерверные приложения с единой командой

Up позволяет развертывать приложения, API-интерфейсы и статические сайты с помощью одной команды. Все, что вам нужно для создания приложения, - это один файл, в случае Node.js - ./app.js прослушивание PORT, которое предоставляется Up. Обратите внимание, что если вы используете package.json, Up обнаружит и использует start и build scripts.

const http = require('http')
const { PORT = 3000 } = process.env
http.createServer((req, res) => {
  res.end('Hello World\n')
}).listen(PORT)

Дополнительные среды выполнения поддерживаются из коробки, например main.go для Golang, поэтому вы можете развернуть приложения Golang, Python, Crystal или Node.js за секунды.

package main
import (
 "fmt"
 "log"
 "net/http"
 "os"
)
func main() {
 addr := ":" + os.Getenv("PORT")
 http.HandleFunc("/", hello)
 log.Fatal(http.ListenAndServe(addr, nil))
}
func hello(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "Hello World from Go")
}

Чтобы развернуть приложение, введите up для создания необходимых ресурсов и разверните само приложение. Здесь нет дыма и зеркал, как только написано «завершено», все готово, приложение сразу становится доступным - удаленного процесса сборки нет.

Последующие развертывания будут еще быстрее, поскольку стек уже подготовлен:

Протестируйте свое приложение с up url --open, чтобы просмотреть его в браузере, up url --copy, чтобы сохранить URL-адрес в буфер обмена, или попробуйте с помощью curl:

curl `up url`
Hello World

Чтобы удалить приложение и его ресурсы, просто введите up stack delete:

Разверните в тестовой или производственной среде, например, с помощью up staging, up production и up url --open production. Обратите внимание, что кастомные домены пока недоступны, скоро будут. Позже вы также сможете продвигать релиз на другие стадии.

Обратный прокси

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

Инфраструктура как код

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

Вот пример настройки некоторых (фиктивных) записей DNS и бесплатных сертификатов SSL через AWS ACM, который использует LetsEncrypt.

{
  "name": "app",
  "dns": {
    "myapp.com": [
      {
        "name": "myapp.com",
        "type": "A",
        "ttl": 300,
        "value": ["35.161.83.243"]
      },
      {
        "name": "blog.myapp.com",
        "type": "CNAME",
        "ttl": 300,
        "value": ["34.209.172.67"]
      },
      {
        "name": "api.myapp.com",
        "type": "A",
        "ttl": 300,
        "value": ["54.187.185.18"]
      }
    ]
  },
  "certs": [
    {
      "domains": ["myapp.com", "*.myapp.com"]
    }
  ]
}

При первом развертывании приложения через up для вас создаются все необходимые разрешения, API-шлюз, лямбда-функция, сертификаты ACM, DNS-записи Route53 и другие.

Наборы изменений еще не реализованы, но вы сможете предварительно просмотреть дальнейшие изменения с помощью up stack plan и зафиксировать их с помощью up stack apply, как и с Terraform.

Ознакомьтесь с документацией по конфигурации для получения дополнительной информации.

Глобальное развертывание

Массив regions позволяет указать целевые регионы для вашего приложения. Например, если вас интересует только один регион, который вы бы использовали:

{
  "regions": ["us-west-2"]
}

Если ваши клиенты сосредоточены в Северной Америке, вы можете использовать все регионы США и CA:

{
  "regions": ["us-*", "ca-*"]
}

Наконец, вы, конечно, можете настроить таргетинг на все 14 поддерживаемых в настоящее время регионов:

{
  "regions": ["*"]
}

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

Раздача статических файлов

Up поддерживает обслуживание статических файлов прямо из коробки с поддержкой HTTP-кеша, поэтому вы можете использовать CloudFront или любой другой CDN перед своим приложением, чтобы значительно уменьшить задержку.

По умолчанию рабочий каталог обслуживается (`.`), когда type является« статическим », однако вы также можете указать static.dir:

{
  "name": "app",
  "type": "static",
  "static": {
    "dir": "public"
  }
}

Строить крючки

Перехватчики сборки позволяют определять настраиваемые действия при развертывании или выполнении других операций. Типичным примером может быть объединение приложений Node.js с помощью Webpack или Browserify, что значительно уменьшает размер файла, поскольку node_modules огромен.

{
  "name": "app",
  "hooks": {
    "build": "browserify --node server.js > app.js",
    "clean": "rm app.js"
  }
}

Внедрение скриптов и таблиц стилей

Up позволяет декларативно внедрять скрипты и стили, как встроенные, так и пути. Он даже поддерживает ряд стандартных скриптов для Google Analytics и Segment, просто скопируйте и вставьте свой ключ записи.

{
  "name": "site",
  "type": "static",
  "inject": {
    "head": [
      {
        "type": "segment",
        "value": "API_KEY"
      },
      {
        "type": "inline style",
        "file": "/css/primer.css"
      }
    ],
    "body": [
      {
        "type": "script",
        "value": "/app.js"
      }
    ]
  }
}

Переписывает и перенаправляет

Up поддерживает перенаправления и перезапись URL-адресов с помощью объекта redirects, который сопоставляет шаблоны путей с новым местоположением. Если status опущено (или 200), то это переписывание, в противном случае - перенаправление.

{
  "name": "app",
  "type": "static",
  "redirects": {
    "/blog": {
      "location": "https://blog.apex.sh/",
      "status": 301
    },
    "/docs/:section/guides/:guide": {
      "location": "/help/:section/:guide",
      "status": 302
    },
    "/store/*": {
      "location": "/shop/:splat"
    }
  }
}

Обычный вариант использования перезаписи - это SPA (одностраничные приложения), где вы хотите обслуживать файл index.html независимо от пути. Если конечно файл не существует.

{
  "name": "app",
  "type": "static",
  "redirects": {
    "/*": {
      "location": "/",
      "status": 200
    }
  }
}

Если вы хотите принудительно применить правило независимо от существующего файла, просто добавьте "force": true.

Переменные среды

Секреты будут в следующем выпуске, однако пока поддерживаются текстовые переменные среды:

{
  "name": "api",
  "environment": {
    "API_FEATURE_FOO": "1",
    "API_FEATURE_BAR": "0"
  }
}

Поддержка CORS

Поддержка CORS позволяет вам указать, какие (если есть) домены могут получить доступ к вашему API из браузера. Если вы хотите разрешить любому сайту доступ к вашему API, просто включите его:

{
  "cors": {
    "enable": true
  }
}

Вы также можете настроить доступ, например, ограничив доступ API только к вашему интерфейсу или SPA.

{
  "cors": {
    "allowed_origins": ["https://myapp.com"],
    "allowed_methods": ["HEAD", "GET", "POST", "PUT", "DELETE"],
    "allowed_headers": ["Content-Type", "Authorization"]
  }
}

логирование

По невысокой цене в 0,5 доллара за ГБ вы можете использовать журналы CloudWatch для запросов и отслеживания структурированных журналов. Up реализует собственный язык запросов, используемый для улучшения того, что предоставляет CloudWatch, специально созданный для запросов к структурированным журналам JSON.

Вы можете запросить существующие журналы:

up logs

Хвостовые живые журналы:

up logs -f

Или отфильтруйте любой из них, например, показывая только 200 запросов GET / HEAD, выполнение которых занимает более 5 миллисекунд:

up logs 'method in ("GET", "HEAD") status = 200 duration >= 5'

Язык запросов достаточно гибкий, вот еще несколько примеров из up help logs

Show logs from the past 5 minutes.
$ up logs
Show logs from the past 30 minutes.
$ up logs -s 30m
Show logs from the past 5 hours.
$ up logs -s 5h
Show live log output.
$ up logs -f
Show error logs.
$ up logs error
Show error and fatal logs.
$ up logs 'error or fatal'
Show non-info logs.
$ up logs 'not info'
Show logs with a specific message.
$ up logs 'message = "user login"'
Show 200 responses with latency above 150ms.
$ up logs 'status = 200 duration > 150'
Show 4xx and 5xx responses.
$ up logs 'status >= 400'
Show emails containing @apex.sh.
$ up logs 'user.email contains "@apex.sh"'
Show emails ending with @apex.sh.
$ up logs 'user.email = "*@apex.sh"'
Show emails starting with tj@.
$ up logs 'user.email = "tj@*"'
Show errors from /tobi and /loki
$ up logs 'error and (path = "/tobi" or path = "/loki")'
Show the same as above with 'in'
$ up logs 'error and path in ("/tobi", "/loki")'
Show logs with a more complex query.
$ up logs 'method in ("POST", "PUT") ip = "207.*" status = 200 duration >= 50'
Pipe JSON error logs to the jq tool.
$ up logs error | jq

Обратите внимание, что подразумевается ключевое слово and, хотя вы можете использовать его, если хотите.

Время холодного старта

Это свойство AWS Lambda как платформы, но время холодного запуска обычно значительно меньше 1 секунды, и в будущем я планирую предоставить возможность поддерживать их в тепле.

Проверка конфигурации

Команда up config выводит разрешенную конфигурацию вместе со значениями по умолчанию и предполагаемыми настройками времени выполнения - она ​​также служит двойной цели проверки конфигурации, поскольку любая ошибка приведет к выходу ›0.

Восстановление после сбоя

Еще одно преимущество использования Up в качестве обратного прокси-сервера - это выполнение восстановления после сбоя - перезапуск сервера после сбоя и повторная попытка запроса перед тем, как ответить клиенту с ошибкой.

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

Удобство непрерывной интеграции

Трудно назвать это функцией, но благодаря относительно небольшим и изолированным двоичным файлам Golang вы можете установить Up в CI за секунду или две.

HTTP / 2

Up поддерживает HTTP / 2 прямо из коробки через API Gateway, уменьшая задержку при обслуживании приложений и сайтов с большим количеством ресурсов. В будущем я проведу более комплексное тестирование на многих платформах, но задержка Up уже благоприятна:

Страницы ошибок

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

{
  "name": "site",
  "type": "static",
  "error_pages": {
    "variables": {
      "support_email": "[email protected]",
      "color": "#228ae6"
    }
  }
}

По умолчанию это выглядит так:

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

  • error.html - соответствует любым 4xx или 5xx
  • 5xx.html - соответствует любой ошибке 5xx
  • 4xx.html - соответствует любой ошибке 4xx
  • CODE.html - соответствует определенному коду, например 404.html.

Прочтите документацию, чтобы узнать больше о шаблонах.

Масштабирование и стоимость

Итак, вы зашли так далеко, но насколько хорошо масштабируется Up? В настоящее время целевой платформой являются API Gateway и AWS, поэтому вам не нужно вносить какие-либо изменения для масштабирования, просто разверните свой код и готово. Вы платите только за то, что действительно используете, по требованию, и ручное вмешательство не требуется для масштабирования.

AWS предлагает 1 000 000 запросов в месяц бесплатно, но вы можете использовать http://serverlesscalc.com, чтобы подключить ожидаемый трафик. В будущем Up предоставит дополнительные платформы, так что если одна станет слишком дорогой, вы сможете перейти на другую!

Будущее

На этом пока все! Может показаться, что это не так уж много, но он уже набрал более 10 000 строк кода, и я только начал разработку. Взгляните на очередь задач, чтобы понять, чего ожидать в будущем, если проект станет устойчивым.

Если вы найдете бесплатную версию полезной, пожалуйста, подумайте о пожертвовании на OpenCollective, так как я не зарабатываю деньги, работая над ней. Вскоре я буду работать над ранним доступом к версии Pro со сниженной годовой ценой для первых пользователей. Версии Pro или Enterprise также предоставляют исходный код, поэтому можно вносить внутренние исправления и настройки.

Обязательно следите за обновлениями в репозитории GitHub. Ваше здоровье!