de TJ Holowaychuk

Up – implementați aplicații fără server în câteva secunde

UP implementati aplicatii fara server in cateva secunde

Anul trecut am scris Planuri pentru Up, descriind modul în care sunt disponibile cele mai multe blocuri pentru a crea o experiență excelentă fără server pe AWS cu un efort minim. Această postare vorbește despre lansarea inițială alfa a Sus.

De ce să ne concentrăm pe serverless? Pentru început este rentabil, deoarece plătiți la cerere, doar pentru ceea ce utilizați. Opțiunile fără server se auto-vindecă, deoarece fiecare cerere este izolată și considerată „apatridă”. Și, în cele din urmă, se dezvoltă la infinit cu ușurință – nu există mașini sau clustere de gestionat. Implementați codul și ați terminat.

În urmă cu aproximativ o lună, am decis să încep să lucrez la asta la vârf / sus, și a scris prima mică aplicație fără server tj / gh-polls pentru sondaje SVG GitHub live. A funcționat bine și costă mai puțin de 1 USD / lună pentru a servi milioane de sondaje, așa că m-am gândit să merg mai departe cu proiectul și să văd dacă pot oferi variante open-source și comerciale.

Obiectivul pe termen lung este de a oferi un „Adu-ți propriul Heroku”, sprijinind multe platforme. În timp ce Platform-as-a-Service nu este nimic nou, ecosistemul fără server face acest tip de program din ce în ce mai banal. Acestea fiind spuse, AWS și alții suferă adesea din punct de vedere al UX datorită flexibilității pe care o oferă. Up abstractizează complexitatea, oferindu-vă totuși o soluție practic fără operațiuni.

Instalare

Puteți instala Up cu următoarea comandă și puteți vizualiza documentare temporară pentru a incepe. Sau dacă sunteți schițat de scripturile de instalare, luați un eliberare binară. (Rețineți că acest proiect este încă devreme.)

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

Pentru a trece la ultima versiune în orice moment, rulați:

up upgrade

De asemenea, puteți instala prin NPM:

npm install -g up

Caracteristici

Ce caracteristici oferă alfa timpuriu? Hai să aruncăm o privire! Rețineți că Up nu este un serviciu găzduit, deci veți avea nevoie de un cont AWS și Acreditări AWS. Dacă nu sunteți deloc familiarizați cu AWS, vă recomandăm să rețineți până la simplificarea acestui proces.

Prima întrebare pe care o primesc întotdeauna este: în ce diferă up (1) de vârf (1)? Apex se concentrează pe implementarea funcțiilor, pentru conducte și procesarea evenimentelor, în timp ce Up se concentrează pe aplicații, API-uri și site-uri statice, adică unități unice implementabile. Apex nu furnizează API Gateway, certificate SSL sau DNS pentru dvs. și nici nu furnizează rescrierea URL-ului, injectarea de scripturi și așa mai departe.

Aplicații fără server cu comandă simplă

Up vă permite să implementați aplicații, API-uri și site-uri statice cu o singură comandă. Pentru a crea o aplicație tot ce aveți nevoie este un singur fișier, în cazul Node.js, un ./app.js ascultând mai departe PORT care este furnizat de Up. Rețineți că, dacă utilizați un package.json Sus va detecta și utiliza start și build scripturi.

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

Adiţional runtimes sunt acceptate din cutie, cum ar fi main.go pentru Golang, astfel încât să puteți implementa aplicațiile Golang, Python, Crystal sau Node.js în câteva secunde.

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")}

Pentru a implementa tipul de aplicație up pentru a crea resursele necesare și a implementa aplicația în sine. Nu există fum și oglinzi aici, după ce ați terminat, ați terminat, aplicația este disponibilă imediat – nu există un proces de construire la distanță.

1611313209 678 UP implementati aplicatii fara server in cateva secunde

Implementările ulterioare vor fi și mai rapide, deoarece stiva este deja aprovizionată:

1611313210 314 UP implementati aplicatii fara server in cateva secunde

Testați-vă aplicația cu up url --open pentru a-l vizualiza în browser, up url --copy pentru a salva adresa URL în clipboard sau pentru a încerca cu curl:

curl `up url`Hello World

Pentru a șterge aplicația și resursele sale, tastați up stack delete:

1611313210 745 UP implementati aplicatii fara server in cateva secunde

Implementați în mediile de producție sau de producție folosind up staging sau up production , și up url --open production de exemplu. Rețineți că domeniile personalizate nu sunt încă disponibile, vor fi în curând. Mai târziu veți putea „promova” o lansare în alte etape.

Proxy invers

O caracteristică care face Up unic este că nu doar îți implementează codul, ci plasează un proxy invers Golang în fața aplicației tale. Aceasta oferă multe caracteristici, cum ar fi rescrierea adreselor URL, redirecționarea, injectarea de scripturi și multe altele, pe care le vom analiza în continuare în postare.

Infrastructura ca cod

Up urmează cele mai bune practici moderne în ceea ce privește configurația, deoarece toate modificările aduse infrastructurii pot fi previzualizate înainte de aplicare, iar utilizarea politicilor IAM poate restricționa accesul dezvoltatorilor pentru a preveni accidentele. Un avantaj secundar este că vă ajută să vă autodocumentați și infrastructura.

Iată un exemplu de configurare a unor înregistrări DNS (fictive) și certificate SSL gratuite prin AWS ACM care utilizează 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"]    }  ]}

Când implementați aplicația pentru prima dată prin up toate permisiunile necesare, API Gateway, funcția Lambda, certificatele ACM, înregistrările DNS Route53 și altele sunt create pentru dvs.

ChangeSets nu sunt încă implementate, dar veți putea previzualiza modificările ulterioare cu up stack plan și comite-le cu up stack apply, la fel cum ai face cu Terraform.

Verificați documentație de configurare pentru mai multe informatii.

Implementări globale

regions matricea vă permite să specificați regiunile țintă pentru aplicația dvs. De exemplu, dacă sunteți interesat doar de o singură regiune, ați folosi:

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

Dacă clienții dvs. sunt concentrați în America de Nord, vă recomandăm să utilizați toate regiunile SUA și CA:

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

În cele din urmă, desigur, puteți viza toate cele 14 regiuni acceptate în prezent:

{  "regions": ["*"]}

Asistența multi-regiune este încă o lucrare în curs, deoarece sunt necesare câteva caracteristici AWS noi pentru a lega lucrurile.

Servirea fișierului static

Up acceptă difuzarea fișierelor statice din cutie, cu suport cache HTTP, astfel încât să puteți utiliza CloudFront sau orice alt CDN în fața aplicației dvs. pentru a reduce dramatic latența.

În mod implicit, directorul de lucru este servit (`.`) când type este „static”, totuși puteți furniza un static.dir de asemenea:

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

Construiește cârlige

Cârligele de construcție vă permit să definiți acțiuni personalizate atunci când implementați sau efectuați alte operațiuni. Un exemplu obișnuit ar fi gruparea aplicațiilor Node.js utilizând Webpack sau Browserify, reducând considerabil dimensiunea fișierului, deoarece node_modules este imens.

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

Injecție de script și foaie de stil

Sus vă permite să injectați scripturi și stiluri, fie în linie, fie căi într-o manieră declarativă. Suportă chiar și o serie de scripturi „conservate” pentru Google Analytics și Segment, doar copiați și inserați cheia de scriere.

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

Rescrie și redirecționează

Up acceptă redirecționările și rescrierea adreselor URL prin intermediul redirects obiect, care mapează modele de cale către o nouă locație. Dacă status este omis (sau 200), atunci este o rescriere, altfel este o redirecționare.

{  "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"    }  }}

Un caz de utilizare obișnuit pentru rescrieri este pentru SPA-uri (aplicații cu o singură pagină), unde doriți să difuzați fișierul `index.html` indiferent de cale. Cu excepția cazului în care fișierul există.

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

Dacă doriți să forțați regula indiferent de un fișier existent, trebuie doar să adăugați "force": true .

Variabile de mediu

Secretele vor fi în următoarea versiune, cu toate acestea, deocamdată sunt acceptate variabilele de mediu cu text simplu:

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

Suport CORS

CORS asistența vă permite să specificați ce domenii (dacă există) pot accesa API-ul dvs. din browser. Dacă doriți să permiteți oricărui site să vă acceseze API-ul, activați-l:

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

De asemenea, puteți personaliza accesul, de exemplu, restricționând accesul API doar la front-end sau SPA.

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

Logare

Pentru prețul scăzut de 0,5 USD / GB, puteți utiliza jurnale CloudWatch pentru interogarea și restrângerea jurnalelor structurate. Up implementează un obicei limbajul interogării folosit pentru a îmbunătăți ceea ce oferă CloudWatch, conceput special pentru interogarea jurnalelor JSON structurate.

1611313211 552 UP implementati aplicatii fara server in cateva secunde

Puteți interoga jurnalele existente:

up logs

Jurnalele live din coadă:

up logs -f

Sau filtrați pe oricare dintre ele, de exemplu, afișând doar 200 de cereri GET / HEAD care durează mai mult de 5 milisecunde pentru a fi finalizate:

up logs 'method in ("GET", "HEAD") status = 200 duration >= 5'
1611313211 2 UP implementati aplicatii fara server in cateva secunde

Limbajul de interogare este destul de flexibil, iată câteva exemple din 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 [email protected]$ up logs 'user.email = "[email protected]*"'
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

Rețineți că and cuvântul cheie este implicit, deși îl puteți folosi dacă preferați.

Vremuri de pornire reci

Aceasta este o proprietate a AWS Lambda ca platformă, dar orele de pornire la rece sunt de obicei mult sub 1 secundă și, în viitor, intenționez să ofer o opțiune pentru a le menține calde.

Validare config

up config command emite configurația rezolvată, completată cu setările implicite și setările de rulare deduse – servește, de asemenea, scopului dublu de validare a configurației, deoarece orice eroare va avea ca rezultat ieșirea> 0.

Recuperarea accidentelor

Un alt avantaj al utilizării Up ca un proxy invers este efectuarea recuperării blocării – repornirea serverului în caz de blocare și reîncercarea cererii înainte de a răspunde clientului cu o eroare.

De exemplu, să presupunem că aplicația dvs. Node.js se blochează cu o excepție neprinsă din cauza unei probleme intermitente a bazei de date, Up poate reîncerca această cerere înainte de a răspunde vreodată clientului. Mai târziu, acest comportament va fi mai personalizabil.

Integrare continuă prietenoasă

Este greu să numim această caracteristică, dar datorită binarelor relativ mici și izolate ale lui Golang, puteți instala Up într-un CI într-o secundă sau două.

HTTP / 2

Up acceptă HTTP / 2 din cutie prin API Gateway, reducând latența pentru servirea aplicațiilor și a site-urilor cu multe active. Voi face teste mai cuprinzătoare împotriva multor platforme în viitor, dar latența lui Up este deja favorabilă:

UP implementati aplicatii fara server in cateva secunde

Pagini de eroare

Up oferă o pagină de eroare implicită cu care puteți personaliza error_pages dacă doriți să furnizați un e-mail de asistență sau să modificați culoarea.

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

În mod implicit, arată astfel:

1611313212 257 UP implementati aplicatii fara server in cateva secunde

Dacă doriți să furnizați șabloane personalizate, puteți crea unul sau mai multe dintre următoarele fișiere. Cel mai specific fișier are prioritate.

  • error.html – Se potrivește cu orice 4xx sau 5xx
  • 5xx.html – Se potrivește cu orice eroare 5xx
  • 4xx.html – Se potrivește cu orice eroare 4xx
  • CODE.html – Se potrivește cu un anumit cod, cum ar fi 404.html

Verificați documente pentru a citi mai multe despre șablonare.

Scalare și cost

Deci ați ajuns până aici, dar cât de bine se ridică Up? În prezent, API Gateway și AWS sunt platforma țintă, deci nu vi se cere să efectuați modificări pentru a scala, doar implementați codul și gata. Plătiți doar pentru ceea ce utilizați efectiv, la cerere și nu este necesară nicio intervenție manuală pentru scalare.

AWS oferă 1.000.000 de solicitări pe lună gratuit, dar le puteți utiliza http://serverlesscalc.com pentru a vă conecta la traficul așteptat. În viitor, Up va oferi platforme suplimentare, astfel încât, dacă una devine costisitoare, puteți migra la alta!

Viitorul

Asta este tot pentru acum! S-ar putea să nu arate prea mult, dar deja are peste 10.000 de linii de cod și tocmai am început dezvoltarea. Aruncați o privire la coada de probleme pentru o scurtă privire la ce să vă așteptați în viitor, presupunând că proiectul va deveni sustenabil.

Dacă vi se pare utilă versiunea gratuită, vă rugăm să luați în considerare donarea pe OpenCollective, deoarece nu câștig niciun ban lucrând la asta. Voi lucra la acces anticipat la versiunea Pro în curând, cu un preț anual redus pentru cei care adoptă mai devreme. Fie edițiile Pro, fie Enterprise vor furniza și sursa, astfel încât să se poată face remedieri rapide și personalizări.

Asigurați-vă că urmați Repo GitHub pentru actualizări. Noroc!