Serverless-kehitys AWS Lambdalla · Oppitunti

Vikasietoisten palvelimettomien järjestelmien rakentaminen

Suunnitelkaa erittäin käytettäviä ja vikasietoisia palvelimettomia arkkitehtuureja hyödyntämällä funktioissanne esimerkiksi circuit breaker -katkaisijoita, uudelleenyrityksiä ja idempotenssia.

Oppitunti 2/411 vaihetta

Vikasietoisten palvelimettomien järjestelmien rakentaminen on ilmainen Serverless-kehitys AWS Lambdalla-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Serverless-kehitys AWS Lambdalla-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Serverless-kehitys AWS Lambdalla-kurssilla on yhteensä 4 oppituntia.

Vankkojen palvelimettomien järjestelmien rakentaminen

Tervetuloa! Tässä oppitunnissa perehdytte erittäin vikasietoisten ja häiriöitä kestävien palvelimettomien sovellusten suunnitteluun. Vaikka AWS hallitsee suuren osan infrastruktuurista, funktioiden on silti käsiteltävä virhetilanteet hallitusti.

Tutkimme keskeisiä arkkitehtuurimalleja, joiden avulla sovellukset pysyvät vakaina ja suorituskykyisinä myös silloin, kun jokin menee vikaan.

Hajautettujen järjestelmien todellisuus

Palvelimettomassa ympäristössä funktiot ovat usein vuorovaikutuksessa monien muiden palvelujen, kuten tietokantojen, rajapintojen ja viestijonojen, kanssa. Nämä vuorovaikutukset tapahtuvat verkon kautta, ja verkko voi olla epäluotettava.

  • Tilapäiset virheet: Lyhyet verkkohäiriöt tai palvelujen hidastumiset.
  • Riippuvuuspalvelujen ongelmat: Lambda-funktion kutsuma palvelu saattaa olla tilapäisesti poissa käytöstä.
  • Odottamattomat tiedot: Virheellinen syöte voi aiheuttaa funktion kaatumisen.

Järjestelmän vakauden kannalta on olennaista suunnitella näitä "virhetilanteita" varten.

Lambdan sisäänrakennettu uudelleenyrityslogiikka

Tietyissä kutsutyypeissä AWS Lambda yrittää suorittaa funktion automaattisesti uudelleen, jos se epäonnistuu. Tämä on tehokas sisäänrakennettu vikasietoisuusmekanismi asynkronisille kutsuille.

Jos esimerkiksi SQS-jono käynnistää Lambda-funktion ja funktio tuottaa virheen, Lambda (tai SQS) yrittää kutsua sitä uudelleen muutaman kerran. Näin tilapäiset ongelmat voidaan ohittaa ilman koodimuutoksia.

Uudelleenyritykset eivät kuitenkaan ratkaise kaikkia ongelmia: jos niitä ei käsitellä huolellisesti, ne voivat johtaa käsittelyn toistumiseen.

Toimintojen tekeminen idempotenteiksi

Uudelleenyritysten yhteydessä funktio saattaa suorittaa saman toiminnon useita kertoja. Tässä tarvitaan idempotenssia.

Idempotentti toiminto voidaan suorittaa useita kertoja ilman, että tulos muuttuu ensimmäisen suorituksen jälkeen.

  • Esimerkki: Arvon asettaminen (x = 5) on idempotenttia.
  • Vastaesimerkki: Arvon kasvattaminen (x++) EI ole idempotenttia, koska jokainen uudelleenyritys muuttaisi arvoa.

Vikasietoisissa järjestelmissä monien toimintojen tulisi olla idempotentteja.

Idempotenttien funktioiden avainasiat

Lambda-funktioiden tekeminen idempotenteiksi edellyttää usein pyynnön tilan seurantaa. Tähän kuuluu yleensä seuraavaa:

  1. Jokaiselle pyynnölle luodaan yksilöllinen idempotenssiavain (esimerkiksi pyynnön tunnisteesta tai tapahtuman lähteen tunnisteesta).
  2. Tarkistetaan ennen varsinaisen logiikan suorittamista, onko tämä avain jo käsitelty.
  3. Avainsidonnainen toiminnon tulos tai tila tallennetaan.

Näin varmistetaan, että vaikka funktiota yritettäisiin uudelleen, varsinainen sivuvaikutus tapahtuu vain kerran.

import hashlib
import json

# Imagine a database or cache for storing processed requests
# For simplicity, using a global dict here. A real app uses persistent storage.
processed_requests = {}

def is_idempotent(event_payload):
    # Create a unique key from the event payload
    # For a real app, use a proper hashing/unique ID strategy
    event_hash = hashlib.md5(json.dumps(event_payload, sort_keys=True).encode('utf-8')).hexdigest()

    if event_hash in processed_requests:
        print(f"Request with hash {event_hash} already processed.")
        return True
    
    processed_requests[event_hash] = "processing" # Mark as processing
    return False

def lambda_handler(event, context):
    if is_idempotent(event):
        return {
            'statusCode': 200,
            'body': json.dumps('Request already processed or is being processed.')
        }

    # Simulate actual work (e.g., writing to a database)
    print(f"Processing new request: {event}")
    
    # In a real scenario, update processed_requests[event_hash] = "completed"
    # after successful processing and store the result in persistent storage.
    
    return {
        'statusCode': 200,
        'body': json.dumps('Request processed successfully!')
    }

Ketjureaktiomaisten virheiden estäminen

Circuit Breaker -malli on tehokas tapa estää vikaantunutta palvelua aiheuttamasta ketjureaktiomaisia virheitä koko sovelluksessa.

Ajatellaan ulkoista rajapintaa, jonka kutsut alkavat epäonnistua. Sen jatkuva uudelleenyritys vain kuluttaa resursseja ja hidastaa funktiota. Circuit breaker havaitsee tämän ja "avaa" piirin, jolloin kutsut vikaantuneeseen palveluun keskeytetään tilapäisesti.

Näin vikaantuneelle palvelulle annetaan aikaa palautua ja sovellusta estetään kuormittumasta liikaa.

Circuit Breakerin toiminta

Circuit breakerilla on yleensä kolme tilaa:

  • Suljettu: Toiminnot etenevät normaalisti. Jos virheiden määrä ylittää raja-arvon, tila vaihtuu avoimeksi.
  • Avoin: Kaikki kutsut suojattuun palveluun epäonnistuvat välittömästi (tai palauttavat varatuloksen). Aikakatkaisun jälkeen tila vaihtuu puoliksi avoimeksi.
  • Puoliksi avoin: Rajoitettu määrä testikutsuja päästetään läpi. Jos ne onnistuvat, tila vaihtuu takaisin suljetuksi. Jos ne epäonnistuvat, tila palaa avoimeksi.

Tämä älykäs toiminta mahdollistaa itsestään palautumisen.

Yksinkertaisen Circuit Breakerin toteuttaminen

Täyden circuit breakerin toteuttaminen edellyttää tilan hallintaa (virheet, onnistumisten määrä ja viimeisimmän virheen ajankohta). Palvelimettomassa ympäristössä tämä tila voidaan tallentaa jaettuun välimuistiin (kuten ElastiCacheen) tai tietokantaan.

Vaikka circuit breakerin toteuttaminen alusta alkaen olisi yksinkertaisessa Lambdassa monimutkaista, logiikan ymmärtäminen on tärkeää. Eri kielille on saatavilla kirjastoja, tai voitte hyödyntää AWS-palveluja, kuten Step Functionsia, uudelleenyrityslogiikan orkestrointiin viiveineen.

import time

class CircuitBreaker:
    def __init__(self, failure_threshold=3, reset_timeout=5):
        self.state = "CLOSED"
        self.failure_count = 0
        self.last_failure_time = 0
        self.failure_threshold = failure_threshold
        self.reset_timeout = reset_timeout # seconds

    def call(self, func, *args, **kwargs):
        if self.state == "OPEN":
            if time.time() - self.last_failure_time > self.reset_timeout:
                self.state = "HALF-OPEN"
                # In a real app, log this state change
            else:
                raise Exception("Circuit is open, service unavailable.")
        
        try:
            result = func(*args, **kwargs)
            if self.state == "HALF-OPEN":
                self.state = "CLOSED"
                self.failure_count = 0
                # In a real app, log this state change
            return result
        except Exception as e:
            self.failure_count += 1
            self.last_failure_time = time.time()
            if self.failure_count >= self.failure_threshold:
                self.state = "OPEN"
                # In a real app, log this state change
            raise e

Aikakatkaisut estävät jumiutumisen

Toinen keskeinen vikasietoisuusmalli on aikakatkaisujen käyttäminen ulkoisissa kutsuissa. Jos Lambda-funktio kutsuu toista palvelua (esimerkiksi tietokantaa tai HTTP-rajapintaa), kutsu voi jäädä odottamaan loputtomasti, jos palvelu ei vastaa.

Aikakatkaisun määrittäminen varmistaa, ettei funktio odota ikuisesti. Se vapauttaa resursseja ja mahdollistaa uudelleenyrityslogiikan nopeamman käynnistymisen. AWS Lambdalla itsellään on määritettävä aikakatkaisu, mutta aikakatkaisut kannattaa asettaa koodissa myös yksittäisille ulkoisille pyynnöille.

Vikasietoisen suunnittelun haaste

Ajatellaan Lambda-funktiota, joka käsittelee saapuvia tilauksia. Jos funktio epäonnistuu maksun onnistuneen veloituksen jälkeen mutta ennen tilauksen tilan päivittämistä tietokantaan ja suoritetaan sitten uudelleen, mikä ongelma voisi syntyä, jos maksun veloitus EI ole idempotenttia?

Yhteenveto: vikatilanteisiin varautuminen

Olemme käsitelleet keskeisiä malleja vikasietoisten palvelimettomien sovellusten rakentamiseen:

  • Uudelleenyritykset: Lambdan sisäänrakennettu mekanismi tilapäisiä virheitä varten.
  • Idempotenssi: Varmistetaan, että toiminnot voidaan yrittää turvallisesti uudelleen ilman tahattomia sivuvaikutuksia (kuten veloitusten toistumista).
  • Circuit Breakerit: Estetään ketjureaktiomaiset virheet pysäyttämällä kutsut vikaantuviin palveluihin älykkäästi.
  • Aikakatkaisut: Suojaudutaan vastaamattomilta ulkoisilta palveluilta.

Näitä periaatteita soveltamalla voitte luoda palvelimettomia järjestelmiä, jotka käsittelevät väistämättömät virhetilanteet hallitusti.

Aloita maksutta

Opi Serverless-kehitys AWS Lambdalla tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
12
Oppitunnit
48

Usein kysytyt kysymykset

Onko oppitunti ”Vikasietoisten palvelimettomien järjestelmien rakentaminen” ilmainen?

Kyllä – oppitunnin ”Vikasietoisten palvelimettomien järjestelmien rakentaminen” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Serverless-kehitys AWS Lambdalla-kurssin, päivitä CoddyKit PROhon. Serverless-kehitys AWS Lambdalla-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Vikasietoisten palvelimettomien järjestelmien rakentaminen”?

Suunnitelkaa erittäin käytettäviä ja vikasietoisia palvelimettomia arkkitehtuureja hyödyntämällä funktioissanne esimerkiksi circuit breaker -katkaisijoita, uudelleenyrityksiä ja idempotenssia. Harjoittelet Serverless-kehitys AWS Lambdalla-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Serverless-kehitys AWS Lambdalla-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Serverless-kehitys AWS Lambdalla-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.

Kuinka kauan ”Vikasietoisten palvelimettomien järjestelmien rakentaminen”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Serverless-kehitys AWS Lambdalla-oppitunnilla?

Kyllä. Jokainen Serverless-kehitys AWS Lambdalla-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Canary- ja Blue/Green-julkaisut
  2. Vikasietoisten palvelimettomien järjestelmien rakentaminen
  3. Palvelimettomat arkkitehtuurimallit
  4. Serverless-arkkitehtuurien kustannusten optimointi
← Takaisin: Serverless-kehitys AWS Lambdalla