Päiväkirjan hakemistoDockup / kenttämuistio
Note / unexpected-egress-charges

Odottamattomat egress-maksut: mistä kaistanleveyslaskut syntyvät

Odottamattomat egress-maksut johtuvat yleensä neljästä tavasta: median tarjoamisesta sovelluksesta, puuttuvista välimuistiotsakkeista, turhan runsaista API-kutsuista ja alueiden välisestä liikenteestä. Selvitä syy ja pienennä laskua vaihtamatta palveluntarjoajaa.

Lasku saapuu, ja se on neljä kertaa suurempi kuin odotit. Compute-rivi vastaa suunnilleen budjettiasi. Poikkeama löytyy egress-riviltä – infrastruktuuristasi lähtevistä tavuista – etkä välttämättä ole koskaan tullut ajatelleeksi koko asiaa.

Odottamattomat egress-maksut ovat sovellusten hostauksen yleisin laskutusyllätys, ja syy on rakenteellinen: kehityssilmukkasi ei mittaa tavuja missään vaiheessa. Kannettava tietokoneesi ei veloita niistä. Staging-ympäristössä ei ole käyttäjiä. Kaistanleveys tulee näkyviin ensimmäisen kerran laskulla, ja siinä vaiheessa olet jo vienyt tuotantoon tavan, joka aiheutti kulut.

Tässä ovat todelliset lähteet yleisyysjärjestyksessä.

1. Median tarjoaminen sovelluksesta

Tämä ylittää muut syyt selvästi, ja lähes aina kyse on vahingosta.

Lisäät videon /public-hakemistoon demoa varten. Se toimii, joten video jää sinne. Nyt jokainen sivulataus streamaa tiedoston ulos containeristasi. Yksi 40 Mt:n video sivulla, jolla käy tuhat vierailijaa kuukaudessa, tarkoittaa 40 gigatavua – tiedostosta, jota pidit vain väliaikaisena sisältönä.

Sama pätee tuotekuviin, PDF-tiedostoihin, käyttäjien latauksiin ja fonttitiedostoihin. Kun lisäät ne, mikään niistä ei tunnu infrastruktuuripäätökseltä.

Ratkaisu ei ole monimutkainen: staattinen media kuuluu object storageen CDN:n taakse, ei sovelluksesi tiedostojärjestelmään. Sovelluksesi pitäisi tarjota HTML:ää ja JSONia. Heti kun se tarjoilee jokaiselle vierailijalle 4 Mt:n hero-kuvaa, se tekee CDN:n työtä ilman mitään CDN:n kustannustehokkuudesta.

2. Cache-otsakkeiden puuttuminen

Jos vastauksissasi ei ole cache-otsakkeita, jokainen vierailija lataa jokaisen assetin jokaisella sivulatauksella. Uudelleen palaavat vierailijat lataavat kaiken taas. Crawler lataa samat tiedostot kymmeniä kertoja päivässä.

# Fingerprinted build assets never change — cache them for a year
Cache-Control: public, max-age=31536000, immutable

# HTML changes — revalidate but allow a short window
Cache-Control: public, max-age=0, must-revalidate

# Anything user-specific
Cache-Control: private, no-store

Tämä on yksi rivimuutos jokaista vastausluokkaa kohden, ja se poistaa usein suurimman osan kaistanleveyslaskusta, koska poistuva liikenne on pelkkää toistoa.

3. API:t, jotka palauttavat enemmän kuin asiakas käyttää

Jos list endpoint palauttaa täydet objektit, vaikka käyttöliittymä näyttää niistä kolme kenttää, jokainen pyyntö lähettää erotuksen – ikuisesti. Tämä ei näy profilingissa, koska pyyntö on nopea – se on vain suuri.

Tarkista kiireisimmistä endpointeistasi kaksi asiaa:

  • Onko compression käytössä? Content-Encoding: gzip tai br pienentää JSONin kokoa tyypillisesti 70–80 %. Kyse on yhdestä middleware-rivistä, joka puuttuu usein.
  • Lähetätkö kenttiä, joita kukaan ei lue? Koko rivin serialisointi, koska ORM tekee siitä helppoa, on useimpien codebasejen oletustoimintaa.

Polling-client pahentaa molempia sen mukaan, kuinka monta kertaa minuutissa se suorittaa kyselyn.

4. Alueiden ja palveluiden välinen liikenne

Jos sovelluksesi on yhdellä alueella ja tietokantasi toisella, jokainen kyselytulos ylittää maksullisen rajan. Tämä on helppo tehdä vahingossa: luot ensin tietokannan, valitset alueen sen kummemmin ajattelematta ja sijoitat sovelluksen viikkoja myöhemmin muualle.

Myös omien palveluidesi välinen liikenne voi olla egress-liikennettä, jos se poistuu private networkista ja palaa takaisin julkisen hostnamen kautta. Kun kaksi saman workspacen palvelua keskustelee keskenään julkisten URL-osoitteidensa kautta, maksat kahdesti keskustelusta, jonka ei olisi koskaan tarvinnut poistua verkosta.

Dockupissa tämä nimenomainen virhe on vaikea tehdä, koska palvelut löytävät toisensa sisäisillä nimillä. Palvelu tavoittaa main-db.internal:5432-osoitteessa olevan tietokannan ja toisen palvelun sen <slug>.internal-aliaksen kautta – workspace-verkon sisällä pysyvä liikenne ei koskaan osu julkiseen listeneriin. Siksi tietokannalla ei myöskään oletusarvoisesti ole julkista hostnamea: liikennettä ei voi vahingossa reitittää sen kautta.

Selvitä lähde arvailun sijaan

Arvailemalla, mikä näistä neljästä on syynä, hukkaat yhden laskutuskauden. Mittaa sen sijaan:

Lue access log tavujen, älä pyyntömäärien perusteella. Järjestä tärkeimmät vastaukset niiden lähettämien tavujen kokonaismäärän, ei pyyntömäärän mukaan. Eniten dataa lähettävä endpoint on harvoin useimmin kutsuttu.

Tarkista suurimmat staattiset assetit. Jos sovelluksestasi tarjotaan jotain yli megatavun kokoista, siirrä juuri se ensimmäisenä.

# What is the service actually doing right now
dockup metrics my-project/my-api --json

# And what is it logging
dockup logs my-project/my-api -n 1000

Tarkkaile crawlereita. Huonosti käyttäytyvä botti, joka hakee suuria tiedostoja toistuvasti, voi aiheuttaa suurimman osan sivuston kuukauden egress-liikenteestä, vaikka ihmisliikennettä olisi vähän. robots.txt ja noindex preview-ympäristöissä ovat edullisia keinoja.

Ympäristöt, joita kukaan ei laske mukaan

Kaksi tapaa synnyttää egress-liikennettä, jota kukaan ei huomioi mielessään:

Preview-ympäristöt. Pull requestia kohden luotava preview-ympäristö on aidosti hyödyllinen, mutta kasvattaa jalanjälkeä huomaamatta. Viisi avointa PR:ää tarkoittaa viittä kopiota stackistasi, ja jokaisella on oma liikenteensä – usein samoilta crawlereilta, koska preview-URL-osoitteet indeksoidaan, ellet estä sitä.

Pitkäikäinen staging. Kahdeksan kuukautta käynnissä ollut staging-ympäristö, jossa kukaan ei käy, lataa edelleen imageja, joutuu edelleen crawlerien käsittelemäksi ja suorittaa edelleen cron-ajonsa.

Kumpikaan ei ole syy lopettaa niiden käyttöä. Molemmat ovat syy rajoittaa niitä: vanhenevat preview-ympäristöt PR:n sulkeutuessa ja merkitse ne noindex-arvolla, jotta hakukoneet lopettavat niiden lataamisen puolestasi.

dockup noindex my-project/my-api --on

Miltä hyvä laskutus näyttää

Sinun pitäisi pystyä vastaamaan kolmeen kysymykseen ennen laskun saapumista:

  1. Mikä on tällä hetkellä käynnissä? Myös ne asiat, jotka unohdit.
  2. Mitä kukin niistä kulutti? Erittele compute ja transfer sen sijaan, että näyttäisit vain yhden luvun.
  3. Mitä tapahtuu, jos kulutus kasvaa nopeasti? Palvelut pysäyttävä raja on ikävä. Raja, jota ei ole olemassa, on pahempi.

Dockup mittaa infrastruktuurin erillään planista, joten plan-maksu ei peitä käyttötietoja – ja Pro-planin 20 dollarin credit vähennetään käytöstä eikä maksusta annettavana alennuksena. Olennaista on, että näet, kumpi on kumpi.

Lyhyt versio

Siirrä media object storageen. Aseta cache-otsakkeet. Ota compression käyttöön. Pidä palvelut ja niiden tietokannat samalla alueella ja anna niiden keskustella private networkin kautta julkisen internetin sijaan. Vanhennuta preview-ympäristöt ja pidä ne poissa hakutuloksista.

Nämä viisi tapaa ratkaisevat lähes kaikki yllättävät kaistanleveyslaskut, eikä yksikään niistä edellytä hostauspaikan vaihtamista.

Usein kysytyt kysymykset

Mitä egress tarkoittaa? Infrastruktuuristasi internetiin lähtevää dataa. Käyttäjille lähetettyjä vastauksia, ladattuja tiedostoja ja API-payloadia. Saapuva liikenne on yleensä ilmaista, lähtevä yleensä ei.

Miksi egress-laskuni on suurempi kuin compute-laskuni? Lähes aina siksi, että sovellus tarjoaa tiedostoja, joiden paikka olisi CDN:ssä. Yksi suuri asset suositulla sivulla maksaa enemmän kuin viikkojen requestien käsittely.

Pienentääkö CDN sitä oikeasti? Kyllä, kun se cachettaa sisällön. Origin tarjoaa tiedoston kerran jokaista edgeä kohden yhden kerran jokaista vierailijaa kohden, ja CDN:n gigatavukohtainen hinta on yleensä murto-osa application platformin hinnasta.

Maksavatko preview-ympäristöt yhtä paljon kuin tuotanto? Ne maksavat kulutuksensa mukaan, mikä on usein odotettua enemmän, koska jokainen niistä on täysi kopio ja preview-URL-osoitteita crawlataan, ellet estä sitä.