Začínáme s Reliable Services v Javě

Tento článek vysvětluje základy služby Azure Service Fabric Reliable Services a provede vás vytvořením a nasazením jednoduché aplikace Reliable Service napsané v Javě.

Na této stránce najdete školicí video, které ukazuje, jak vytvořit bezstavovou spolehlivou službu:

Instalace a nastavení

Než začnete, ujistěte se, že máte na počítači nastavené vývojové prostředí Service Fabric. Pokud ho potřebujete nastavit, přejděte na stránku Začínáme na Macu nebo Začínáme s Linuxem.

Základní koncepty

Abyste mohli začít používat Reliable Services, stačí porozumět několika základním konceptům:

  • Typ služby: Toto je implementace vaší služby. Je definována třídou, kterou napíšete, a StatelessService veškerým dalším kódem nebo závislostmi použitými v této třídě spolu s názvem a číslem verze.
  • Pojmenovaná instance služby: Pokud chcete službu spustit, vytvoříte pojmenované instance vašeho typu služby, podobně jako vytváříte instance objektů typu třídy. Instance služby jsou ve skutečnosti instance objektů vaší třídy služby, kterou píšete.
  • Hostitel služby: Pojmenované instance služby, které vytvoříte, musí běžet v hostiteli. Hostitel služby je jen proces, ve kterém můžou běžet instance vaší služby.
  • Registrace služby: Registrace spojuje všechno dohromady. Typ služby musí být zaregistrovaný v modulu runtime Service Fabric v hostiteli služby, aby služba Service Fabric mohla vytvářet instance, které se mají spustit.

Vytvoření bezstavové služby

Začněte vytvořením aplikace Service Fabric. Sada Service Fabric SDK pro Linux obsahuje generátor Yeoman, který poskytuje generování uživatelského rozhraní pro aplikaci Service Fabric s bezstavovou službou. Začněte spuštěním následujícího příkazu Yeoman:

$ yo azuresfjava

Postupujte podle pokynů k vytvoření spolehlivé bezstavové služby. Pro účely tohoto kurzu pojmenujte aplikaci HelloWorldApplication a službu HelloWorld. Výsledek zahrnuje adresáře pro HelloWorldApplication a HelloWorld.

HelloWorldApplication/
├── build.gradle
├── HelloWorld
│   ├── build.gradle
│   └── src
│       └── statelessservice
│           ├── HelloWorldServiceHost.java
│           └── HelloWorldService.java
├── HelloWorldApplication
│   ├── ApplicationManifest.xml
│   └── HelloWorldPkg
│       ├── Code
│       │   ├── entryPoint.sh
│       │   └── _readme.txt
│       ├── Config
│       │   └── _readme.txt
│       ├── Data
│       │   └── _readme.txt
│       └── ServiceManifest.xml
├── install.sh
├── settings.gradle
└── uninstall.sh

Registrace služby

Typy služeb musí být zaregistrované v modulu runtime Service Fabric. Typ služby je definován ve ServiceManifest.xml třídě a služby, která implementuje StatelessService. Registrace služby se provádí v hlavním vstupním bodě procesu. V tomto příkladu je HelloWorldServiceHost.javahlavním vstupním bodem procesu :

public static void main(String[] args) throws Exception {
    try {
        ServiceRuntime.registerStatelessServiceAsync("HelloWorldType", (context) -> new HelloWorldService(), Duration.ofSeconds(10));
        logger.log(Level.INFO, "Registered stateless service type HelloWorldType.");
        Thread.sleep(Long.MAX_VALUE);
    }
    catch (Exception ex) {
        logger.log(Level.SEVERE, "Exception in registration:", ex);
        throw ex;
    }
}

Implementace služby

Otevřete HelloWorldApplication/HelloWorld/src/statelessservice/HelloWorldService.java. Tato třída definuje typ služby a může spustit libovolný kód. Rozhraní API služby poskytuje dva vstupní body pro váš kód:

  • Metoda otevřeného vstupního bodu s názvem runAsync(), kde můžete začít spouštět všechny úlohy, včetně dlouhotrvajících výpočetních úloh.
@Override
protected CompletableFuture<?> runAsync(CancellationToken cancellationToken) {
    ...
}
  • Vstupní bod komunikace, kam můžete připojit svůj komunikační zásobník podle svého výběru. Tady můžete začít přijímat žádosti od uživatelů a dalších služeb.
@Override
protected List<ServiceInstanceListener> createServiceInstanceListeners() {
    ...
}

Tento kurz se zaměřuje na metodu vstupního runAsync() bodu. Tady můžete okamžitě začít spouštět svůj kód.

RunAsync

Platforma volá tuto metodu, když je instance služby umístěna a připravena ke spuštění. U bezstavové služby to znamená při otevření instance služby. Token zrušení se poskytuje ke koordinaci, když je potřeba zavřít instanci služby. V Service Fabric může k tomuto cyklu otevření/zavření instance služby dojít mnohokrát za celou dobu životnosti služby jako celku. K tomu může dojít z různých důvodů, mezi které patří:

  • Systém přesune instance služby pro vyrovnávání prostředků.
  • V kódu dochází k chybám.
  • Aplikace nebo systém se upgraduje.
  • U základního hardwaru dochází k výpadku.

Tuto orchestraci spravuje Service Fabric, aby byla vaše služba vysoce dostupná a správně vyvážená.

runAsync() by nemělo blokovat synchronně. Vaše implementace runAsync by měla vrátit CompletableFuture, aby modul runtime mohl pokračovat. Pokud vaše úloha potřebuje implementovat dlouhotrvající úlohu, která by měla být provedena v rámci CompletableFuture.

Zrušení

Zrušení úlohy je spolupráce, která se orchestruje pomocí poskytnutého tokenu zrušení. Systém počká, než úkol skončí (úspěšným dokončením, zrušením nebo chybou), než se přesune. Je důležité dodržovat token zrušení, dokončit jakoukoli práci a co nejrychleji ukončit runAsync() , když systém požádá o zrušení. Následující příklad ukazuje, jak zpracovat událost zrušení:

@Override
protected CompletableFuture<?> runAsync(CancellationToken cancellationToken) {

    // TODO: Replace the following sample code with your own logic
    // or remove this runAsync override if it's not needed in your service.

    return CompletableFuture.runAsync(() -> {
        long iterations = 0;
        while(true)
        {
        cancellationToken.throwIfCancellationRequested();
        logger.log(Level.INFO, "Working-{0}", ++iterations);

        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex){}
        }
    });
}

V tomto příkladu bezstavové služby je počet uložený v místní proměnné. Protože se ale jedná o bezstavovou službu, uložená hodnota existuje pouze pro aktuální životní cyklus její instance služby. Když se služba přesune nebo restartuje, hodnota se ztratí.

Vytvoření stavové služby

Service Fabric zavádí nový druh služby, který je stavový. Stavová služba může spolehlivě udržovat stav v samotné službě, a to společně s kódem, který ji používá. Service Fabric zpřístupnil stav s vysokou dostupností, aniž by bylo nutné uchovávat stav v externím úložišti.

Pokud chcete převést hodnotu čítače z bezstavové na vysoce dostupnou a trvalou, i když se služba přesune nebo restartuje, potřebujete stavovou službu.

Spuštěním yo azuresfjava:AddService příkazu můžete do stejného adresáře jako aplikace HelloWorld přidat novou službu. Zvolte pro svoji architekturu spolehlivou stavovou službu a pojmenujte ji HelloWorldStateful.

Vaše aplikace by teď měla mít dvě služby: bezstavovou službu HelloWorld a stavovou službu HelloWorldStateful.

Stavová služba má stejné vstupní body jako bezstavová služba. Hlavním rozdílem je dostupnost poskytovatele stavu, který dokáže spolehlivě ukládat stav. Service Fabric se dodává s implementací poskytovatele stavu s názvem Reliable Collections, která umožňuje vytvářet replikované datové struktury prostřednictvím správce stavu Reliable State Manager. Stavová spolehlivá služba ve výchozím nastavení používá tohoto poskytovatele stavu.

Otevřete HelloWorldStateful.java v HelloWorldStateful –> src, která obsahuje následující metodu RunAsync:

@Override
protected CompletableFuture<?> runAsync(CancellationToken cancellationToken) {
    Transaction tx = stateManager.createTransaction();
    return this.stateManager.<String, Long>getOrAddReliableHashMapAsync("myHashMap").thenCompose((map) -> {
        return map.computeAsync(tx, "counter", (k, v) -> {
            if (v == null)
                return 1L;
            else
                return ++v;
            }, Duration.ofSeconds(4), cancellationToken)
                .thenCompose((r) -> tx.commitAsync())
                .whenComplete((r, e) -> {
            try {
                tx.close();
            } catch (Exception e) {
                logger.log(Level.SEVERE, e.getMessage());
            }
        });
    });
}

RunAsync

RunAsync() funguje podobně ve stavových a bezstavových službách. Ve stavové službě však platforma před spuštěním RunAsync()provede další práci vaším jménem. Tato práce může zahrnovat zajištění, že správce stavu reliable a spolehlivé kolekce jsou připravené k použití.

Reliable Collections a Reliable State Manager

ReliableHashMap<String,Long> map = this.stateManager.<String, Long>getOrAddReliableHashMapAsync("myHashMap")

ReliableHashMap je implementace slovníku, kterou můžete použít ke spolehlivému uložení stavu ve službě. Pomocí Service Fabric a Reliable HashMaps můžete ukládat data přímo do služby bez nutnosti externího trvalého úložiště. Díky spolehlivým hashmapám jsou vaše data vysoce dostupná. Service Fabric toho dosáhne tím, že za vás vytvoří a spravuje více replik vaší služby. Poskytuje také rozhraní API, které abstrahuje složitost správy těchto replik a jejich přechodů stavu.

Reliable Collections může ukládat libovolný typ Javy, včetně vašich vlastních typů, s několika upozorněními:

  • Service Fabric zajišťuje vysokou dostupnost vašeho stavu replikací stavu mezi uzly a spolehlivá mapa hash ukládá vaše data na místní disk v každé replice. To znamená, že vše, co je uloženo v Reliable HashMaps, musí být serializovatelné.

  • Objekty jsou replikovány pro zajištění vysoké dostupnosti při potvrzení transakcí na Reliable HashMaps. Objekty uložené v Reliable HashMaps se ve vaší službě uchovávají v místní paměti. To znamená, že máte místní odkaz na objekt.

    Je důležité, abyste nezmutoval místní instance těchto objektů bez provedení operace aktualizace spolehlivé kolekce v transakci. Je to proto, že změny místních instancí objektů nebudou replikovány automaticky. Musíte objekt znovu vložit zpět do slovníku nebo použít některou z metod aktualizace ve slovníku.

Reliable State Manager za vás spravuje spolehlivé hashmapy. Správce spolehlivého stavu můžete kdykoli a na libovolném místě ve vaší službě požádat o spolehlivou kolekci podle názvu. Správce spolehlivého stavu zajistí, že dostanete zpět referenci. Nedoporučujeme ukládat odkazy na spolehlivé instance kolekcí do proměnných nebo vlastností členů třídy. Je třeba věnovat zvláštní pozornost tomu, aby byl odkaz nastaven na instanci po celou dobu životního cyklu služby. Správce spolehlivého stavu zpracovává tuto práci za vás a je optimalizovaný pro opakované návštěvy.

Transakční a asynchronní operace

return map.computeAsync(tx, "counter", (k, v) -> {
    if (v == null)
        return 1L;
    else
        return ++v;
    }, Duration.ofSeconds(4), cancellationToken)
        .thenCompose((r) -> tx.commitAsync())
        .whenComplete((r, e) -> {
    try {
        tx.close();
    } catch (Exception e) {
        logger.log(Level.SEVERE, e.getMessage());
    }
});

Operace na Reliable HashMaps jsou asynchronní. Důvodem je to, že operace zápisu se spolehlivými kolekcemi provádějí vstupně-výstupní operace za účelem replikace a uchování dat na disk.

Spolehlivé operace HashMap jsou transakční, takže můžete udržovat konzistentní stav napříč několika spolehlivými objekty HashMap a operacemi. Můžete například získat pracovní položku z jednoho spolehlivého slovníku, provést operaci s ní a uložit výsledek do jiné spolehlivé hashmapy, to vše v rámci jedné transakce. Jedná se o atomické operace a zaručuje, že buď bude celá operace úspěšná, nebo se vrátí zpět. Pokud dojde k chybě po zrušení zařazení položky, ale před uložením výsledku, vrátí se celá transakce zpět a položka zůstane ve frontě pro zpracování.

Sestavení aplikace

Generování uživatelského rozhraní Yeoman zahrnuje skript gradle pro sestavení aplikace a skripty Bash pro nasazení a odebrání aplikace. Pokud chcete aplikaci spustit, nejprve ji sestavte pomocí gradle:

$ gradle

Tím se vytvoří balíček aplikace Service Fabric, který je možné nasadit pomocí rozhraní příkazového řádku Service Fabric.

Nasazení aplikace

Jakmile je aplikace sestavená, můžete ji nasadit do místního clusteru.

  1. Připojte se k místnímu clusteru služby Service Fabric.

    sfctl cluster select --endpoint http://localhost:19080
    
  2. Spuštěním instalačního skriptu, který je součástí šablony, zkopírujte balíček aplikace do úložiště imagí clusteru, zaregistrujte typ aplikace a vytvořte její instanci.

    ./install.sh
    

Nasazení sestavené aplikace je stejné jako u všech ostatních aplikací Service Fabric. Podrobné pokyny najdete v dokumentaci s popisem správy aplikace Service Fabric pomocí Service Fabric CLI.

Parametry těchto příkazů najdete v generovaných manifestech uvnitř balíčku aplikace.

Jakmile je aplikace nasazená, otevřete prohlížeč a přejděte k nástroji Service Fabric Explorer na adrese http://localhost:19080/Explorer. Pak rozbalte uzel Aplikace a všimněte si, že už obsahuje položku pro váš typ aplikace a další položku pro první instanci tohoto typu.

Důležité

Pokud chcete nasadit aplikaci do zabezpečeného clusteru s Linuxem v Azure, musíte nakonfigurovat certifikát pro ověření aplikace pomocí modulu runtime Service Fabric. Tím umožníte službám Reliable Services komunikovat s podkladovými rozhraními API modulu runtime Service Fabric. Další informace najdete v tématu Konfigurace aplikace Reliable Services pro spuštění v clusterech s Linuxem.

Další kroky