# HTTP Over the Decades: Tarina fysiikasta, latenssista ja Grudging Sopeutumisesta

<!--category-- HTTP, Networking, Web Development, Opinion -->
<datetime class="hidden">2025-12-28T18:00</datetime>

HTTP ei kehittynyt. *pakko* muuttaa fysiikalla, latenssilla ja väärinkäytöllä.

Jokainen versio on olemassa, koska edellisellä on kovat rajoitteet. Jos ymmärrät nämä rajoitukset, ymmärrät, miksi verkko toimii niin kuin se toimii - ja miksi niin monet "parhaat käytännöt" ovat itse asiassa protokollarajoituksia, joita olemme venkoilleet jo kolmekymmentä vuotta.

Olen rakentanut verkkosovelluksia vuodesta 1997 lähtien. Olen purkanut HTTP/1.0-yhteysmyrskyjä, katsellut selainten avaavan kuusi yhteyttä isäntää kohti "ominaisuutena", kironnut HTTP/2:n TCP-pääeston mobiiliverkoissa, ja lopulta nähnyt HTTP/3:n myöntävän, mitä tiesimme koko ajan: verkko on ongelma.

Tämä ei ole protokollaopetus, vaan tarina siitä, miten päädyimme tänne.

[TOC]

## HTTP/1.0: Stateless Text Over Epäluotettavat putket

### Maailma joka teki sen

HTTP/1.0 suunniteltiin vuonna 1996 maailmaa varten, jota ei enää ole. Ymmärtääksesi, miksi se toimi, sinun täytyy ymmärtää, mitä "verkko" tarkoitti vuonna 1996:

- **Soittoyhteydet** klo 28.8kbps (jos kävi tuuri)
- **Sivut olivat asiakirjoja** - teksti, ehkä muutama pieni kuva, hyperlinkit
- **Käyttäjät klikkasivat ja odottivat** - välitöntä reagointia ei odotettu
- **Palvelimet olivat kalliita** - yliopistot ja yritykset, eivät kaikki

Tässä maailmassa pullonkaula oli **kaistanleveys**50KB-sivun lataaminen kesti 15 sekuntia. Kuka välitti 200 metrin ylimääräisestä kädenpuristuksesta?

**Mihin HTTP/1.0 optimoitiin:**

- Yksinkertaisuus (todennäköisyys telnetin kanssa)
- Valtiottomuus (palvelijat eivät seuraa yhteyksiä)
- Inhimillinen luettavuus (tekstiprotokolla)
- Yksi pyyntö, yksi vastaus, yhteys suljettu

```
GET /index.html HTTP/1.0
Host: example.com

HTTP/1.0 200 OK
Content-Type: text/html

<html>...
```

Yksinkertainen, elegantti, täydellinen vuodelta 1996 ja täysin käyttökelvoton kaikkeen muuhun kuin asiakirjahakuun.

### Paine, joka mursi sen

Sitten verkko muuttui nopeasti.

Vuonna 1998 sivut eivät olleet vain asiakirjoja, vaan niissä oli tyylisivuja, JavaScript-kuvia ja useita kuvia. Yksi sivu voi tarvita 20-30 erillistä resurssia.

Jokainen vaadittu pyyntö:

1. **TCP-puristus** (1 kierros)
2. **Pyyntö lähetetty** (1 kierros)
3. **Saatu vaste**
4. **Yhteys suljettu**
5. Toista jokaisen kuvan, kirjoitustyylin, käsikirjoituksen...

20-resurssilla varustettu sivu tarkoitti 20 TCP-kädenpuristusta. 200 ms:n latenssiyhteydellä (joka on yhä yleinen), 4 sekuntia *vain kättelyä* ennen kuin mitään sisältöä siirretään.

Perusoletus HTTP/1.0:sta:

> **Aika oli halpaa.**

Vuonna 1996 se oli. Bandwidth oli pullonkaula. Vuonna 1999 kaistanleveys parani, mutta **Latenssi ei ollut** Yhtäkkiä kierroksilla oli merkitystä.

HTTP/1.0 oli suunniteltu dokumentteja varten. Netistä oli tullut sovellusalusta.

## HTTP/1.1: Paikkaamme sen

### Maailma joka teki sen

HTTP/1.1 saapui vuonna 1997, juuri kun verkko oli räjähtämässä. Dotcom-buumi oli alkamassa. Kaikki yritykset tarvitsivat nettisivut. Web-sivut olivat mutkikkaita - taulut ulkoasua varten, JavaScript vuorovaikutteisuutta varten, kuvat kaikkialla.

Painostus oli selvä: **Liitäntäpyyntö oli tapposuoritus**. Mutta täysin HTTP:n uudelleen suunnittelu ei ollut vaihtoehto. Liika infrastruktuuri oli jo kiinni siitä. Ratkaisun piti olla takaperin yhteensopiva.

**Mikä muuttui:**

- **Jatkuvat yhteydet** (`Connection: keep-alive` Oletuksena) – TCP-yhteyden uudelleenkäyttö
- **Siirretty koodaus** (stream-vastauksia tietämättä kokoa etukäteen)
- **Isäntäotsikot** (virtuaalinen isännöinti - useita sivustoja per IP, ratkaiseva jaettu hosting)
- **Väliseinät semantiikassa** (`Cache-Control`, `ETag`, ehdolliset pyynnöt)
- **Putket** (lähetä useita pyyntöjä odottamatta vastauksia)

**Mikä ei muuttunut:**

- Yhä peräkkäisiä vasteita (jopa piipulla)
- Silti tekstiotsikoita (toistetaan joka pyynnöstä)
- Vielä yksi vastaus kerrallaan yhteyttä kohden

```
GET /page.html HTTP/1.1
Host: example.com
Connection: keep-alive

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Cache-Control: max-age=3600

...
```

### Miksi se tavallaan toimi?

HTTP/1.1 ei itse asiassa ratkaissut suoritusongelmaa, vaan se vain liikutti sitä.

**Putket epäonnistuivat.** Spektrolin avulla voitiin lähettää useita pyyntöjä yhdellä yhteydellä, mutta:

- Vastaukset piti palauttaa *kunnossa* (linjan sulku)
- Yksi hidas reaktio esti kaiken sen takana
- Buggy proxies silpoi putkijohtoisia pyyntöjä
- Useimmat selaimet poistivat sen kokonaan

Sen sijaan, että protokollaa olisi korjattu, selaimet huijasivat:

- Avaa **6 rinnakkaista yhteyttä isäntää kohti** (selkärankaraja)
- Käyttö **verkkotunnuksen siristys** (`static1.example.com`, `static2.example.com`) liittymien moninkertaistaminen
- **Spriittilevyt** kuvien yhdistämiseen
- **CSS/JS-niputus** pyyntöjen vähentäminen
- **CDN-koodit** latenssin vähentäminen

Mikään näistä ei toiminut suunnitellusti, vaan koko ekosysteemi korvasi HTTP/1.1:n perustavanlaatuisen rajoituksen.

> **HTTP/1.1 skaalautuu huijaamalla, ei korjaamalla mallia.**

### Miksi se kuitenkin selviytyi?

HTTP/1.1 toimi *tarpeeksi hyvin* Viisitoista vuotta, ei siksi, että se olisi hyvä, vaan siksi, että ympäristö kompensoi:

- **Laajakaista saapui.** 20 millin kädenpuristukset 200 millin sijaan. Kipu oli siedettävää.
- **Mooren laki auttoi.** Palvelimet pystyivät käsittelemään kuusi yhteyttä selainta kohti vuoteen 2005 mennessä.
- **CDN:t peittivät ongelman.** Edge-palvelimet 20 metrin päässä 200 metrin sijaan.
- **Työpöytä hallitsi.** Langattomat yhteydet, matala latenssi, luotettavat verkot.

Olimme vain onnekkaita, että maailma salasi sen.

### Todelliset kustannukset

Nuo kuusi liittymää per isäntä eivät olleet ilmaisia:

- Jokainen yhteys tarkoitti toista TCP-kädenpuristusta
- Jokainen yhteys kilpaili kaistanleveydestä
- Palvelimien piti ylläpitää enemmän samanaikaisia yhteyksiä
- **Verkkosulku siirtyi juuri TCP:lle** - menettää yhden yhteyden paketin, että yhteys on tallella

Verkko nopeutui HTTP/1.1:n aikakaudella, mutta ei HTTP/1.1:n takia. Se nopeutui, koska:

- Verkot nopeutuivat
- Välilyönnistä tuli älykkäämpää
- CDN-koodit imeytyivät latenssiin
- Selaimet paranivat rinnakkainasettelussa

Rakensimme sovellusalustaa dokumenttien hakuprotokollalle, ja protokolla oli häviämässä.

## Epämukava totuus, jota kukaan ei myönnä

Vuoteen 2010 mennessä verkon suorituskyky oli jatkuvaa taistelua HTTP:tä itseään vastaan.

Aikakauden "parhaat käytännöt" kertovat tarinan:

- Yhdistä kaikki Javascript-tiedostot yhteen tiedostoon
- Sprite kaikki kuvat yhdessä
- Inline-kriittinen CSS
- Käytä datan URI-tietoja pyyntöjen välttämiseksi
- Verkkoalueen sirpale avaa lisää yhteyksiä
- Laita skriptit sivun alalaitaan

Jokainen näistä on täyskäännös "HTTP/1.1:lle, joka ei pysty käsittelemään monia pyyntöjä tehokkaasti".

Rakensin monia näistä pienistä työkaluista, kuten sprite-generaattoreista, CSS-kompressorista, aloimme käyttää reagointikompressiota jne.

Selaimet eivät olleet nopeampia, koska HTTP parani. **työskennellyt HTTP:n ympärillä**.

Kuusi yhteyttä per isäntä ei ole ominaisuus. Se on hakata. Verkkoalueen sirpale ei ole paras käytäntö, vaan myöntää epäonnistuneensa.

Opetin vuosia kehittäjiä niputtamaan hyödykkeitä, sprite-kuvia ja inline-kriittisiä resursseja. Mikään niistä ei ollut "hyvää arkkitehtuuria". **Protokollavaurioiden hallinta**.

"HTTP on yksinkertainen" myytti jatkui, koska monimutkaisuus oli piilotettu:

- Selainyhteyden hallinta
- CDN:n reunalogiikka
- Rakenna työkalujen tiivisteet
- Palvelinkytkentäyhdistelmä

HTTP/1.1 toimi, koska kaikki toimi *ympäri* se teki ylitöitä kompensoidakseen.

Jos olet koskaan nähnyt kaavion HTTP:stä, jossa ei näy latenssia, menetyksiä tai vikatiloja, se valehtelee sinulle. Protokolla on yksinkertainen. Todellisuus ei ole.

## HTTP/2: Korjasimme väärän kerroksen

### Maailma joka teki sen

Vuonna 2010 verkko oli jälleen muuttunut. Kaksi massiivista vuoroa muutti kaiken:

**1. Mobiili tapahtui.**
Vuonna 2007 lanseerattu iPhone. Vuonna 2012 mobiiliverkkoliikenne räjähti räjähdysmäisesti. Yhtäkkiä käyttäjät eivät olleet langallisella laajakaistayhteydellä - he olivat 3G:llä, sitten 4G:llä, vaihtelevalla latenssilla ja toistuvilla pakettitappioilla. Oletukset, jotka tekivät HTTP/1.1:stä siedettävän, olivat kaatumassa.

**2. Verkkosovellukset korvasivat verkkosivut.**
Gmail. Google Maps. Facebook. Twitter. Nämä eivät olleet dokumentteja, joissa oli linkkejä, vaan sovelluksia, jotka tarvitsivat kymmeniä tai satoja resursseja, reaaliaikaisia päivityksiä ja pikaisia vastauksia. "Kuusi yhteyttä per isäntä" -hakkeri osoitti ikänsä.

Googlella oli valtava mittakaava, suorituskykyinsinöörejä, ja HTTP/1.1:n todistamiseen käytetty data oli pullonkaula. Vuonna 2009 he aloittivat SPIDYn - kokeellisen protokollan, josta tulisi HTTP/2.

**Mikä muuttui:**

- **Binäärikehys** (ei tekstiä - tehokkaampi jäsennys)
- **Multipleksointi** (Yhdellä yhteydellä useita pyyntöjä/vastauksia)
- **Otsikkopuristus** (HPACK - ei enää toisteta samoja otsikoita)
- **Palvelimen työntö** (lähetä resursseja ennen kuin asiakas kysyy - vaikka tämä osoittautuikin vaikeaksi virittää oikein ja on nyt suurelta osin nurinkurista)
- **Yksi yhteys alkuperää kohti** (ei enää yhteyden räjähdystä)

```
┌──────────────────────────────────────────┐
│           Single TCP Connection          │
├──────────────────────────────────────────┤
│ Stream 1: GET /page.html                 │
│ Stream 3: GET /style.css                 │
│ Stream 5: GET /app.js                    │
│ Stream 7: GET /logo.png                  │
│ (all interleaved, no ordering required)  │
└──────────────────────────────────────────┘
```

Näin HTTP/1.1-putkenpidityksen olisi pitänyt olla. Virtaukset ovat itsenäisiä. Yksi hidas reaktio ei estä muita. Otsikko on tiivistetty. Protokolla vastasi lopulta sitä, miten käytämme verkkoa.

### Miksi se toimi (oikeilla verkoilla)

HTTP/2 oli **täydellinen laajakaistaverkolle**Ja vuonna 2015, kun se standardoitiin, laajakaista oli kaikkialla kehittyneessä maailmassa.

**Mikä parani:**

- Latenssi kevyessä kuormassa (yksi yhteys, ei kädenpuristuksia pyydettäessä)
- Vähemmän yhteyksiä (vähemmän palvelimen yläpuolella, vähemmän TCP-slow-start)
- Parempaa kaistanleveyden käyttöä (ei keinotekoisia liityntärajoja)
- Otsikkokompressio (toistuvat otsikot, kuten evästeet, eivät enää maksa kaistanleveyttä)
- Ei enää sekoilua/springingiä (moni pieni tiedosto on nyt kunnossa)

HTTP/2 oli käyttäjille langallisilla yhteyksillä, joilla oli alhainen pakettitappio, todellinen parannus. Vertailuarvot näyttivät hyviltä. Mittarit paranivat. Google julisti voiton.

### Paine, joka mursi sen

Mutta maailma oli jo mennyt eteenpäin. **Mobiili oli nyt suurin osa verkkoliikenteestä.**

Matkapuhelinverkoilla on perusominaisuus, jollaista laajakaistalla ei ole: **pakettitappio on vakio**.

TCP-takuut **Tilaustoimitus**Jos paketti 47 katoaa, paketit 48-100 odottavat, kunnes 47 lähetetään uudelleen - vaikka ne kuuluisivat täysin riippumattomiin HTTP/2 -virtoihin.

```
┌──────────────────────────────────────────┐
│              TCP Receive Buffer          │
├──────────────────────────────────────────┤
│ [pkt 45][pkt 46][  ?  ][pkt 48][pkt 49]  │
│                   ↑                       │
│         Waiting for packet 47             │
│                                          │
│ Stream 1 data: BLOCKED                   │
│ Stream 3 data: BLOCKED                   │
│ Stream 5 data: BLOCKED (has pkt 48-49)   │
│ Stream 7 data: BLOCKED                   │
└──────────────────────────────────────────┘
```

HTTP/2 ratkaisi kantapään tukoksen käyttökerroksessa, minkä jälkeen TCP palautti sen siirtokerrokseen.

**Yksi kadonnut paketti tukkii kaikki purot.** Puhtaalla langalla pakettihävikki on harvinaista. Matkapuhelimissa, hukassa olevilla WiFi-yhteyksillä tai ruuhkaisilla yhteyksillä pakkaushävikki on vakio. Ja koska HTTP/2 käyttää *single* yhteys (suunnitellusti), yksi kadonnut paketti nyt estää *kaikki* sen sijaan vain yksi kuudesta yhteydestä.

HTTP/2:n suorituskyky:

- **Langaton, pieni menetys**: Erinomaista
- **Liikkuva, kohtalainen tappio**: Joskus *pahempaa* kuin HTTP/1,1
- **Suuri latenssi, mikä tahansa menetys**: Katastrofaalinen

Ironista: HTTP/2 oli suunniteltu mobiilikäyttöön, mutta TCP:n takuut pahensivat mobiilissa sen korvaamaa protokollaa.

### Miksi HTTP/2 tuntui nopeammalta (siihen asti, kun sitä ei ollut)

HTTP/2:n käyttöönotto osoitti todellisia parannuksia:

- Vähemmän yhteyksiä tarkoitti nopeampaa alkukuormaa (TLS-puristus kerran, ei kuusi kertaa)
- Otsikkokompressio kevennettynä yleisellä tasolla
- Multiplexing toimi hyvin saman alkuperän omaisuuden hyväksi

Mutta hännän latenssi kertoi toisen tarinan. *mediaani* P99 paheni.

Näin tämän omin silmin: asiakas otti HTTP/2:n käyttöön CDN:ssä ja katseli mobiilia P99 latenssia *lisäys* Kojelaudat paranivat 40 prosentilla. Tukiliput tulivat mobiilikäyttäjiltä. Käytimme viikon sen selvittämiseen, että HTTP/2:n "parannus" pahensi suurimman osan liikenteestä.

Kun HTTP/2 toimii, se toimii kauniisti. Kun paketti putoaa mobiiliyhteydelle pahimmalla hetkellä, kaikki jäätyy. Käyttäjät huomaavat, että se jäätyy enemmän kuin nopeat mediaanit.

Perusongelma:

> **HTTP/2 oletti TCP:n kelpaavan.**

Laajakaistan osalta se oli. Mobiilien kohdalla se ei ollut. Kun HTTP/2 standardoitiin, mobiili oli jo voitolla. Olimme ajaneet niin pitkälle kuin TCP pystyi.

## HTTP/3: Hyvä on, siirrymme alas pinoon

### Maailma joka teki sen

Vuoteen 2015 mennessä todisteet olivat selvät: **TCP oli ongelma**.

Google oli käyttänyt QUICia kokeellisesti vuodesta 2012 lähtien. Heillä oli tiedot mobiiliverkoista, häviöllisistä WiFi-yhteyksistä ja korkeista latenssiyhteyksistä. HTTP/2 epäonnistui TCP:n kohdalla tavoilla, joita ei voitu korjata vaihtamatta kuljetuskerrosta.

Mutta TCP:tä ei voi vain "korjata". Se on toteutettu käyttöjärjestelmän ytimessä. Se on leivottu jokaiseen internetin reitittimeen, palomuuriin ja välilaatikkoon. TCP:n muuttaminen tarkoittaa, että se odottaa vuosikymmeniä koko internetin infrastruktuurin päivittämistä.

Joten Google teki jotain uhkarohkeaa: **he rakensivat UDP:n päälle uuden liikenneprotokollan**.

UDP on "mykkä" suunnittelultaan - se vain lähettää paketteja ilman takuita. Mutta juuri sitä tarvitset, jos haluat toteuttaa *omasi* Luotettavuussemantiikkaa. QUIC toteuttaa uudelleen TCP:n takuut (luotettava, tilattu toimitus), mutta tekee sen **Virtaa kohti** Yhteyden sijaan.

HTTP/3 (2022) on HTTP yli QUIC. Se on tunnustus, että meidän piti mennä alle HTTP korjata HTTP.

**Mikä muuttui:**

- **KYMMENEN UDP:hen verrattuna** (ei TCP)
- **Stream-tason tappion toipuminen** (yksi kadonnut pakkaus vain tukkii virtansa)
- **Nopeamman yhteyden asennus** (0-RTT:n uudelleenkäynnistys mahdollinen)
- **Salaus oletuksena** (TLS 1,3 rakennettu QUICiin)
- **Liitännäismuutto** (Keskeyttää IP-osoitteen muutokset)

```
┌──────────────────────────────────────────┐
│              QUIC Connection             │
├──────────────────────────────────────────┤
│ Stream 1: [pkt][pkt][pkt] ← flowing      │
│ Stream 3: [pkt][ ? ][pkt] ← waiting      │
│ Stream 5: [pkt][pkt][pkt] ← flowing      │
│ Stream 7: [pkt][pkt]      ← flowing      │
│                                          │
│ Lost packet only affects Stream 3        │
└──────────────────────────────────────────┘
```

**Mikä pysyi samana:**

- HTTP-semantiikat (GET, POST, otsikot, tilakoodit)
- Välimuistin logiikka
- REST-kuviot
- Kaikki sovelluskerroksessa

> **HTTP/3 ei muuttanut HTTP:tä, vaan se muutti sen, miten HTTP selviää todellisuudesta.**

### MIKSI KYSYMYKSIÄ

QUIC toteuttaa TCP:n luotettavuustakuut *Virtaa kohti*Tämä on avainnäkemys.

**TCP:n lupaus:** "Jokainen tavu saapuu järjestykseen."
**QUICin lupaus:** "Jokainen taputus *tässä virrassa* saapuu kuntoon."

Tämän eron vuoksi HTTP/3 ei kaadu häviöllisissä verkoissa.

Muita QUIC-ominaisuuksia, jotka korjaavat pitkäaikaisia ongelmia:

**Liitännäismuutto:**

```
Phone on WiFi → walks out of range → switches to cellular
TCP: Connection dies. Restart everything.
QUIC: Connection ID maintained. Streams continue.
```

Tämä on tärkeää, koska mobiilikäyttäjät *jatkuvasti* Vaihda verkkoja, kävele ulos talostasi, menetä WiFi, vaihda kännykkään. TCP:n myötä jokainen yhteys katkeaa. QUIC:n kanssa yhteys jatkuu.

**0-RTT:n uudelleen aloittaminen:**

```
First connection: Full handshake (1-RTT)
Returning user: Send data immediately (0-RTT)
```

**Salaus kaikkialla:**

```
TCP + TLS: Handshake, then encrypted tunnel
QUIC: Encryption is the handshake (TLS 1.3 integrated)
```

### Maailma, joka sitä tarvitsee

HTTP/3 on suunniteltu maailmaan, jossa oikeasti elämme:

- **Mobile first**: Yli puolet verkkoliikenteestä on mobiilia
- **Luotettavat verkot**: WiFi, soluverkko, ruuhkainen julkinen verkko
- **Maailmanlaajuiset käyttäjät**: Suurlatenssiyhteydet kaukaisille palvelimille
- **Yksityisyysodotukset**: Salaus on pakollista, ei vapaaehtoista

Protokolla vastaa vihdoin verkkotodellisuutta. 30 vuotta HTTP/1.0:n olettaman luotettavan langallisen yhteyden jälkeen HTTP/3 myöntää, että luotettavuus on poikkeus, ei sääntö.

### Edistymisen kustannukset

HTTP/3 ei ole ilmainen:

- **UDP on usein tukossa** Yhtiön palomuurit (varaudutaan HTTP/2:een)
- **Lisää prosessoria** QUICin käyttötilan toteutukseen (ei ytimessä, kuten TCP:ssä, vaikka tämä aukko on sulkeutumassa ytimen ohituksella ja optimoiduilla pinoilla)
- **Uudet vianetsintätyökalut** (tcpdump näyttää salatun UDP:n, ei luettavan HTTP:n)
- **Middlebox-häirintä** (Jotkut verkostot silpovat UDP:tä arvaamattomasti)

Mutta mobiilien ensimmäisille sovelluksille, epäluotettaville verkoille ja latenssiherkille palveluille HTTP/3 on ensimmäinen versio, joka vastaa sitä, miten verkostot todellisuudessa käyttäytyvät.

## Todellinen opetus kaikissa versioissa

Jokainen HTTP-versio vaihtui, koska **ympäristö muuttui nopeammin kuin protokolla**.

Versio: Aikakausi Ympäristö Oletus: Miksi se rikkoi?
|---------|-----|-------------|------------|--------------|
HTTP/1.0 1996 Dialup, dokumentit Bandwidth on pullonkaula. Sivuista tuli sovelluksia, latenssilla oli merkitystä.
HTTP/1.1 Laajakaista, verkkosovellukset Low latency kätkee tehottomuuden Mobile saapui pakettitappiolla
HTTP/2 2015-2022 Laajakaistahuippu, liikkuva nouseva TCP on tarpeeksi luotettava ja mobiili tuli hallitsevaksi, TCP epäonnistui.
HTTP/3 HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022 + HTTP 2022

Malli on selkeä:

1. Protokolla on suunniteltu nykyiseen ympäristöön
2. Ympäristömuutokset (nopeammin kuin protokollat voivat mukautua)
3. Työkierroksia kertyy (CDN:t, yhteyden hakkerointi, niputtaminen)
4. Uusi protokolla tunnustaa todellisuuden
5. Toista

Protokollaa työnnetään yhä lähemmäs verkkoa. Jokainen riittävältä vaikuttanut abstraktio kuoriutui takaisin, kun ympäristö sitä vaati.

**Muita huomioita:**

- "Stateless" on valhe, jonka kerromme itsellemme yöunille. Jokainen sessiokeksi, auth plake, ja kätkön otsikko on valtion johto, johon olemme pudonneet.
- Useimmat suoritusvoitot tulivat *treenit*CDN:t, välimuistit, yhdysjohdot, kehotus yhdistää - kaikki kompensoivat protokollan rajoituksia.
- HTTP/1.0 oli yksinkertainen. Tarvitsimme sinnikkäät yhteydet ja sitten multipleksoinnin. Sitten uusi siirto. Jokainen monimutkaisuuden kerros ratkaisi todelliset ongelmat.
- **Ajoituksella on väliä.** HTTP/2 olisi ollut täydellinen, jos se olisi saapunut vuonna 2005. Vuoteen 2015 mennessä mobiili oli jo muuttanut peliä. Protokolla ratkaisi eilisen ongelman.

## Mikä ei ole muuttunut 1,0:n jälkeen

30 vuoden protokollakehityksestä huolimatta:

**Pyynnöt epäonnistuvat edelleen.**
Verkkojako, palvelimet kaatuvat, aikakatkaisut tapahtuvat. Koodisi tarvitsee vielä uutta logiikkaa.

**Verkostot valehtelevat yhä.**
200 OK ei tarkoita, että vastaus olisi oikea. Yhteys suljettuna ei tarkoita, etteikö pyyntö olisi onnistunut. Aikalisät eivät tarkoita, etteikö palvelin olisi käsitellyt pyyntöäsi.

**Käpylät tarjoavat yhä tunkkaista dataa.**
`Cache-Control` Se on pyyntö, ei käsky. Proxies tekee mitä haluaa. CDN:n mitätöinti on parhaimmillaankin.

**Asiakkaat yrittävät yhä huonosti.**
Käyttäjä napsauttaa painiketta, mitään ei tapahdu, napsahtaa uudelleen. Nyt sinulla on kaksi pyyntöä. Impotenssilla on merkitystä.

**Kehittäjät ymmärtävät yhä väärin idempotenssin.**
PUT:n pitäisi olla idempotentti. POST on villi länsi. Useimmat API:t ymmärtävät tämän väärin.

```csharp
// This is still your problem, regardless of HTTP version
public async Task<Result> CreateOrderAsync(Order order)
{
    // What happens if this times out?
    // Did the server receive it?
    // Did it process it?
    // Will the client retry?
    // Will you create duplicate orders?
    
    // HTTP/3 doesn't save you here.
    // Idempotency keys do.
}
```

> **Jos et ymmärrä näitä, HTTP/3 ei pelasta sinua.**

## Mitä todella opin

Kun olet rakentanut web-sovelluksia kaikkien näiden protokolliversioiden päälle, tämä jäi jumiin:

**1. Protokolla ei ole luotettava kerros.**

HTTP antaa sinulle pyyntö- ja vastausselmantiikkaa. Se ei takaa toimitusta, korrektiutta tai tasan kertakäsittelyä. Se on sinun tehtäväsi.

**2. Latenssi on vihollinen, ei kaistanleveys.**

Suurin osa suoritusongelmista on pyöreitä, ei läpivientiin sidottuja. Vaatimusten vähentäminen on tärkeämpää kuin hyötykuorman keventäminen.

**3. Jokaisella "parhaalla käytännöllä" on viimeinen käyttöpäivä.**

Verkkoalueen siristys oli olennaista HTTP/1.1:lle. Se on haitallista HTTP/2:lle. CSS:n inlinointi oli fiksua. Nyt meillä on palvelimen työntö (joka myös epäonnistui) ja varhaiset vihjeet. Taktiikan muutos. Maali (vähennä viivettä) pysyy samana.

**4. Mittaus todellisissa verkoissa.**

Käyttäjäsi ovat mobiiliverkoissa, hotellin WiFissä ja kyllästetyissä kahviloissa. Testaa siellä.

**5. Tylsyillä osilla on eniten merkitystä.**

Aikakatkaisut, retries, virtapiirien katkaisut, häiriönsieto. Liitännäisten yhdistäminen. Nämä häikäisemättömät yksityiskohdat ratkaisevat, toimiiko järjestelmäsi kuormitettuna.

## Päätelmät

HTTP ei nopeutunut, koska siitä tuli älykkäämpi. **verkko oli ongelma**.

Jokainen versio oli oikea aikansa:

- **HTTP/1,0** oli täydellinen valintadokumentin hakuun
- **HTTP/1.1** oli täydellinen laajakaistaverkkosovelluksiin
- **HTTP/2** oli täydellinen matalan tappion langallisille yhteyksille
- **HTTP/3** on rakennettu mobiili-ensimmäiselle, epäluotettavalle verkkotodellisuudelle, jossa oikeasti elämme

Virheessä luultiin, että jokin niistä oli pysyviä ratkaisuja, jotka kaikki reagoivat erityisiin ympäristöpaineisiin. Ympäristön muuttuessa protokollaa oli noudatettava.

**HTTP-versiot eivät ole kuluttajamielessä päivityksiä, vaan ne on optimoitu erilaisiin vikajakeluihin.**

Ja silti, kaiken tämän jälkeen, perusasiat ovat edelleen:

- Pyynnöt epäonnistuvat
- Verkot valehtelevat
- Välilyönnillä on vaikeaa
- Impotenssilla on merkitystä

Protokolla kehittyi, mutta ongelmat eivät hävinneet.

Rakenna järjestelmiä, jotka selviävät epäonnistumisista. Testaa todellisia verkkoja. Ymmärrä, että jokainen HTTP-versio on aikakautensa muovaama vaihtokauppa, ei päivitys, joka vanhentuu aiemmasta.

Se on kolmekymmentä vuotta HTTP:tä. Se on verkko, jonka rakensimme. Toisella vuosikymmenellä HTTP/3:n oletukset näyttävät todennäköisesti samalta kuin HTTP/1.0:n oletukset nyt.

## Lisää luettavaa

- [RFC 9114: HTTP/3](https://datatracker.ietf.org/doc/html/rfc9114) - Viralliset tiedot
- [RFC 9000: QUIC](https://datatracker.ietf.org/doc/html/rfc9000) - Kuljetusprotokolla
- [HTTP/2 selitetty](https://http2-explained.haxx.se/) - Daniel Stenbergin erinomainen katsaus
- [Tehokas selainverkko](https://hpbn.co/) - Ilja Grigorikin syväsukellus (ilmainen verkossa)