Java'da Reliable Services'ı kullanmaya başlama

Bu makalede Azure Service Fabric Reliable Services'in temelleri açıklanır ve Java ile yazılmış basit bir Güvenilir Hizmet uygulaması oluşturma ve dağıtma adımları açıklanmaktadır.

Durum bilgisi olmayan bir Reliable hizmeti oluşturmayı gösteren eğitim videosu için bu sayfayı gözden geçirin:

Yükleme ve kurulum

Başlamadan önce makinenizde Service Fabric geliştirme ortamının ayarlandığından emin olun. Bunu ayarlamanız gerekiyorsa Mac'i kullanmaya başlama veya Linux'ta çalışmaya başlama bölümüne gidin.

Temel kavramlar

Reliable Services'ı kullanmaya başlamak için yalnızca birkaç temel kavramı anlamanız gerekir:

  • Hizmet türü: Bu, hizmet uygulamanızdır. Bir ad ve sürüm numarasıyla birlikte, genişleten StatelessService yazdığınız sınıf ve burada kullanılan diğer kod veya bağımlılıklar tarafından tanımlanır.
  • Adlandırılmış hizmet örneği: Hizmetinizi çalıştırmak için, bir sınıf türünün nesne örneklerini oluşturduğunuz gibi hizmet türünüzün adlandırılmış örneklerini oluşturursunuz. Hizmet örnekleri aslında yazdığınız hizmet sınıfınızın nesne örneklemeleridir.
  • Hizmet konağı: Oluşturduğunuz adlandırılmış hizmet örneklerinin bir konak içinde çalıştırılması gerekir. Hizmet ana bilgisayarı yalnızca hizmetinizin örneklerinin çalışabileceği bir işlemdir.
  • Hizmet kaydı: Kayıt her şeyi bir araya getirir. Service Fabric'in çalıştırılacak örneklerini oluşturmasına izin vermek için hizmet türünün bir hizmet konağındaki Service Fabric çalışma zamanına kaydedilmesi gerekir.

Durum bilgisi olmayan hizmet oluşturma

Bir Service Fabric uygulaması oluşturarak başlayın. Linux için Service Fabric SDK'sı, durum bilgisi olmayan bir hizmetle service Fabric uygulaması için yapı iskelesi sağlayan bir Yeoman oluşturucu içerir. Aşağıdaki Yeoman komutunu çalıştırarak başlayın:

$ yo azuresfjava

Güvenilir Durum Bilgisi Olmayan Hizmet oluşturmak için yönergeleri izleyin. Bu öğretici için uygulamayı "HelloWorldApplication" ve hizmetini "HelloWorld" olarak adlandırın. Sonuç, ve HelloWorlddizinlerini HelloWorldApplication içerir.

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

Hizmet kaydı

Hizmet türleri Service Fabric çalışma zamanına kaydedilmelidir. Hizmet türü, ve uygulayan StatelessServicehizmet sınıfınızda tanımlanırServiceManifest.xml. Hizmet kaydı işlem ana giriş noktasında gerçekleştirilir. Bu örnekte işlem ana giriş noktası şöyledir HelloWorldServiceHost.java:

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;
    }
}

Hizmeti uygulama

HelloWorldApplication/HelloWorld/src/statelessservice/HelloWorldService.java dosyasını açın. Bu sınıf hizmet türünü tanımlar ve herhangi bir kodu çalıştırabilir. Hizmet API'si kodunuz için iki giriş noktası sağlar:

  • uzun süre çalışan işlem iş yükleri de dahil olmak üzere tüm iş yüklerini yürütmeye başlayabileceğiniz adlı runAsync()açık uçlu bir giriş noktası yöntemi.
@Override
protected CompletableFuture<?> runAsync(CancellationToken cancellationToken) {
    ...
}
  • İstediğiniz iletişim yığınını takabileceğiniz bir iletişim giriş noktası. Burada kullanıcılardan ve diğer hizmetlerden istek almaya başlayabilirsiniz.
@Override
protected List<ServiceInstanceListener> createServiceInstanceListeners() {
    ...
}

Bu öğretici giriş noktası yöntemine runAsync() odaklanır. Kodunuzu hemen çalıştırmaya buradan başlayabilirsiniz.

RunAsync

Bir hizmet örneği yerleştirildiğinde ve yürütülmeye hazır olduğunda platform bu yöntemi çağırır. Durum bilgisi olmayan bir hizmet için bu, hizmet örneğinin ne zaman açıldığı anlamına gelir. Hizmet örneğinizin kapatılması gerektiğinde koordine etmek için bir iptal belirteci sağlanır. Service Fabric'te, bir hizmet örneğinin bu açma/kapatma döngüsü, bir bütün olarak hizmetin ömrü boyunca birçok kez gerçekleşebilir. Bu, aşağıdakiler gibi çeşitli nedenlerle oluşabilir:

  • Sistem, kaynak dengeleme için hizmet örneklerinizi taşır.
  • Hata kodunuzda oluşur.
  • Uygulama veya sistem yükseltilir.
  • Temel alınan donanımda kesinti yaşanıyor.

Bu düzenleme, hizmetinizi yüksek oranda kullanılabilir ve dengeli tutmak için Service Fabric tarafından yönetilir.

runAsync() zaman uyumlu olarak engellememelidir. runAsync uygulamanız çalışma zamanının devam etmesi için bir CompletableFuture döndürmelidir. İş yükünüzün CompletableFuture içinde yapılması gereken uzun süre çalışan bir görev uygulaması gerekiyorsa.

İptal

İş yükünüzün iptali, sağlanan iptal belirteci tarafından düzenlenmiş işbirliğine dayalı bir çabadır. Sistem, devam etmeden önce görevinizin bitmesini bekler (başarıyla tamamlanarak, iptal ederek veya hatayla). sistem iptal isteğinde bulunurken iptal belirtecini yerine getirmek, tüm işleri bitirmek ve mümkün olan en kısa sürede çıkmak runAsync() önemlidir. Aşağıdaki örnek, bir iptal olayının nasıl işlendiğini gösterir:

@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){}
        }
    });
}

Bu durum bilgisi olmayan hizmet örneğinde, sayı bir yerel değişkende depolanır. Ancak bu durum bilgisi olmayan bir hizmet olduğundan depolanan değer yalnızca hizmet örneğinin geçerli yaşam döngüsü için mevcuttur. Hizmet hareket ettiğinde veya yeniden başlatıldığında değer kaybolur.

Durum bilgisi olan bir hizmet oluşturma

Service Fabric durum bilgisi olan yeni bir hizmet türü getirir. Durum bilgisi olan bir hizmet, hizmeti kullanan kodla birlikte bulunan hizmetin içinde durumu güvenilir bir şekilde koruyabilir. Durum, durumu bir dış depoda kalıcı hale getirmek zorunda kalmadan Service Fabric tarafından yüksek oranda kullanılabilir hale getirilir.

Hizmet taşınsa veya yeniden başlatıldığında bile bir sayaç değerini durum bilgisi olmayandan yüksek oranda kullanılabilir ve kalıcı hale getirmek için durum bilgisi olan bir hizmete ihtiyacınız vardır.

HelloWorld uygulamasıyla aynı dizinde komutunu çalıştırarak yo azuresfjava:AddService yeni bir hizmet ekleyebilirsiniz. Çerçeveniz için "Güvenilir Durum Bilgisi Olan Hizmet"i seçin ve hizmeti "HelloWorldStateful" olarak adlandırın.

Uygulamanızın artık iki hizmeti olmalıdır: durum bilgisi olmayan Hizmet HelloWorld ve durum bilgisi olan HelloWorldStateful hizmeti.

Durum bilgisi olan bir hizmet, durum bilgisi olmayan bir hizmetle aynı giriş noktalarına sahiptir. Temel fark, durumu güvenilir bir şekilde depolayan bir durum sağlayıcısının kullanılabilirliğidir. Service Fabric, Reliable State Manager aracılığıyla çoğaltılmış veri yapıları oluşturmanıza olanak tanıyan Reliable Collections adlı bir durum sağlayıcısı uygulamasıyla birlikte gelir. Durum bilgisi olan bir Güvenilir Hizmet bu durum sağlayıcısını varsayılan olarak kullanır.

HelloWorldStateful.java dosyasını, aşağıdaki RunAsync yöntemini içeren HelloWorldStateful -> src dosyasında açın:

@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() durum bilgisi olan ve durum bilgisi olmayan hizmetlerde benzer şekilde çalışır. Ancak durum bilgisi olan bir hizmette, platform yürütülmeden RunAsync()önce sizin yerinize ek işler gerçekleştirir. Bu çalışma, Reliable State Manager ve Reliable Collections'ın kullanıma hazır olduğundan emin olunmasını içerebilir.

Reliable Collections ve Reliable State Manager

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

ReliableHashMap , hizmette durumu güvenilir bir şekilde depolamak için kullanabileceğiniz bir sözlük uygulamasıdır. Service Fabric ve Reliable HashMaps ile dış kalıcı depoya gerek kalmadan verileri doğrudan hizmetinizde depolayabilirsiniz. Güvenilir HashMap'ler verilerinizi yüksek oranda kullanılabilir hale getirir. Service Fabric bunu sizin için hizmetinizin birden çok çoğaltmasını oluşturup yöneterek gerçekleştirir. Ayrıca, bu çoğaltmaları ve durum geçişlerini yönetmenin karmaşıklıklarını soyutlayan bir API sağlar.

Güvenilir Koleksiyonlar, özel türleriniz de dahil olmak üzere herhangi bir Java türünü birkaç uyarıyla depolayabilir:

  • Service Fabric, durumunuzu düğümler arasında çoğaltarak yüksek oranda kullanılabilir hale getirir ve Reliable HashMap verilerinizi her çoğaltmadaki yerel diske depolar. Bu, Reliable HashMap'lerde depolanan her şeyin seri hale getirilebilir olması gerektiği anlamına gelir.

  • Reliable HashMap'lerde işlem gerçekleştirdiğinizde nesneler yüksek kullanılabilirlik için çoğaltılır. Reliable HashMap'lerde depolanan nesneler hizmetinizdeki yerel bellekte tutulur. Bu, nesneye yerel bir başvurunuz olduğu anlamına gelir.

    Bir işlemdeki güvenilir koleksiyonda bir güncelleştirme işlemi gerçekleştirmeden bu nesnelerin yerel örneklerini sessize almamanız önemlidir. Bunun nedeni, nesnelerin yerel örneklerinde yapılan değişikliklerin otomatik olarak çoğaltılmamasıdır. Nesneyi sözlüğe yeniden eklemelisiniz veya sözlükte güncelleştirme yöntemlerinden birini kullanmalısınız.

Reliable State Manager, Reliable HashMap'leri sizin için yönetir. Reliable State Manager'dan istediğiniz zaman ve hizmetinizdeki herhangi bir yerde ada göre güvenilir bir koleksiyon isteyebilirsiniz. Reliable State Manager, bir başvuruyu geri almanızı sağlar. Sınıf üyesi değişkenlerinde veya özelliklerinde güvenilir koleksiyon örneklerine başvuruları kaydetmenizi önermeyiz. Başvurunun hizmet yaşam döngüsünde her zaman bir örneğe ayarlandığından emin olmak için özel özen gösterilmelidir. Reliable State Manager bu işi sizin için işler ve tekrar ziyaretler için en iyi duruma getirilmiştir.

İşlemsel ve zaman uyumsuz işlemler

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());
    }
});

Reliable HashMap'lerdeki işlemler zaman uyumsuz olur. Bunun nedeni, Reliable Collections ile yazma işlemlerinin verileri diske çoğaltmak ve kalıcı hale getirmek için G/Ç işlemleri gerçekleştirmesidir.

Güvenilir HashMap işlemleri işlemseldir, böylece birden çok Reliable HashMap ve işlemde durum tutarlılığı sağlayabilirsiniz. Örneğin, bir Güvenilir Sözlükten bir iş öğesi alabilir, üzerinde bir işlem gerçekleştirebilir ve sonucu tek bir işlem içinde başka bir Reliable HashMap'e kaydedebilirsiniz. Bu bir atomik işlem olarak kabul edilir ve işlemin tamamının başarılı olacağını veya tüm işlemin geri döndürüleceğini garanti eder. Öğeyi sıraladıktan sonra ancak sonucu kaydetmeden önce bir hata oluşursa, işlemin tamamı geri alınır ve öğe işlenmek üzere kuyrukta kalır.

Uygulama oluşturma

Yeoman yapı iskelesi, uygulamayı derlemek için bir gradle betiği ve uygulamayı dağıtmak ve kaldırmak için bash betikleri içerir. Uygulamayı çalıştırmak için önce uygulamayı gradle ile derleyin:

$ gradle

Bu, Service Fabric CLI kullanılarak dağıtılabilir bir Service Fabric uygulama paketi oluşturur.

Uygulamayı dağıtma

Uygulama oluşturulduktan sonra uygulamayı yerel kümeye dağıtabilirsiniz.

  1. Yerel Service Fabric kümesine bağlanın.

    sfctl cluster select --endpoint http://localhost:19080
    
  2. Uygulama paketini kümenin görüntü deposuna kopyalamak, uygulama türünü kaydetmek ve uygulamanın bir örneğini oluşturmak için şablonda verilen yükleme betiğini çalıştırın.

    ./install.sh
    

Oluşturulan uygulamayı dağıtma işlemi, diğer tüm Service Fabric uygulamalarında olduğu gibidir. Ayrıntılı yönergeler için Service Fabric uygulamasını Service Fabric CLI ile yönetme ile ilgili belgelere bakın.

Bu komutların parametreleri, uygulama paketi içinde oluşturulmuş bildirimlerde bulunabilir.

Uygulama dağıtıldığında bir tarayıcı açın ve http://localhost:19080/Explorer konumundaki Service Fabric Explorer'a gidin. Ardından, Uygulamalar düğümünü genişletin ve geçerli olarak uygulamanızın türü için bir giriş ve bu türün ilk örneği için başka bir giriş olduğuna dikkat edin.

Önemli

Uygulamayı Azure'da güvenli bir Linux kümesine dağıtmak için, uygulamanızı Service Fabric çalışma zamanıyla doğrulayacak bir sertifika yapılandırmanız gerekir. Bunun yapılması, Reliable Services hizmetlerinizin temel alınan Service Fabric çalışma zamanı API'leriyle iletişim kurmasını sağlar. Daha fazla bilgi edinmek için bkz . Reliable Services uygulamasını Linux kümelerinde çalışacak şekilde yapılandırma.

Sonraki adımlar