Mulai menggunakan Reliable Service di Java

Artikel ini menjelaskan dasar-dasar Azure Service Fabric Reliable Services dan memandu Anda membuat dan menerapkan aplikasi Reliable Service sederhana yang teritulis di Java.

Periksa halaman ini untuk video pelatihan yang menunjukkan cara membuat layanan Andal tanpa status:

Penginstalan dan Penyetelan

Sebelum memulai, pastikan Anda memiliki lingkungan pengembangan Service Fabric yang disiapkan di mesin Anda. Jika Anda perlu mengaturnya, buka memulai di Mac atau mulai di Linux.

Konsep dasar

Untuk memulai dengan Reliable Services, Anda hanya perlu memahami beberapa konsep dasar:

  • Jenis layanan: Ini adalah implementasi layanan Anda. Ini ditentukan oleh kelas yang Anda tulis yang meluas StatelessService dan kode lain atau dependensi yang digunakan di dalamnya, bersama dengan nama dan nomor versi.
  • Instans layanan bernama: Untuk menjalankan layanan Anda, Anda membuat instans bernama jenis layanan Anda, sama seperti Anda membuat instans objek dari jenis kelas. Instans layanan sebenarnya adalah instantiansi objek dari kelas layanan Anda yang Anda tulis.
  • Host layanan: Instans layanan bernama yang Anda buat perlu dijalankan di dalam host. Host layanan hanyalah proses di mana instans layanan Anda dapat berjalan.
  • Pendaftaran layanan: Pendaftaran menyatukan semuanya. Jenis layanan harus didaftarkan dengan runtime Service Fabric di host layanan untuk memungkinkan Service Fabric membuat instans untuk dijalankan.

Membuat layanan stateless

Mulailah dengan membuat aplikasi Service Fabric. SDK Service Fabric untuk Linux mencakup generator Yeoman untuk menyediakan perancah untuk aplikasi Service Fabric dengan layanan stateless. Mulailah dengan menjalankan perintah Yeoman berikut:

$ yo azuresfjava

Ikuti instruksi untuk membuat Reliable Stateless Service. Untuk tutorial ini, beri nama aplikasi "HelloWorldApplication" dan layanan "HelloWorld". Hasilnya termasuk direktori untuk HelloWorldApplication dan 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

Registrasi layanan

Jenis layanan harus terdaftar dengan runtime Service Fabric. Jenis layanan ditentukan dalam ServiceManifest.xml dan kelas layanan Anda yang mengimplementasikan StatelessService. Pendaftaran layanan dilakukan di titik entri utama proses. Dalam contoh ini, titik entri utama proses adalahHelloWorldServiceHost.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;
    }
}

Terapkan layanan

Buka HelloWorldApplication/HelloWorld/src/statelessservice/HelloWorldService.java. Kelas ini menentukan jenis layanan, dan dapat menjalankan kode apa pun. API layanan menyediakan dua titik entri untuk kode Anda:

  • Metode titik entri terbuka, yaitu runAsync(), di mana Anda dapat mulai menjalankan beban kerja apa pun, termasuk beban kerja komputasi yang berjalan lama.
@Override
protected CompletableFuture<?> runAsync(CancellationToken cancellationToken) {
    ...
}
  • Titik entri komunikasi di mana Anda dapat memasang tumpukan komunikasi pilihan Anda. Di sinilah Anda dapat mulai menerima permintaan dari pengguna dan layanan lainnya.
@Override
protected List<ServiceInstanceListener> createServiceInstanceListeners() {
    ...
}

Tutorial ini berfokus pada runAsync() metode titik entri. Di sinilah Anda dapat segera mulai menjalankan kode Anda.

RunAsync

Platform menyebut metode ini ketika instans layanan ditempatkan dan siap untuk dieksekusi. Untuk layanan stateless, itu berarti ketika instans layanan dibuka. Token pembatalan disediakan untuk dikoordinasikan saat instans layanan Anda perlu ditutup. Dalam Service Fabric, siklus buka/tutup instans layanan ini dapat terjadi berkali-kali selama masa pakai layanan secara keseluruhan. Ini dapat terjadi karena berbagai alasan, termasuk:

  • Sistem memindahkan instans layanan Anda untuk penyeimbangan sumber daya.
  • Kesalahan terjadi dalam kode Anda.
  • Aplikasi atau sistem ditingkatkan.
  • Perangkat keras yang mendasarinya mengalami pemadaman.

Orkestrasi ini dikelola oleh Service Fabric agar layanan Anda selalu tersedia dan seimbang dengan baik.

runAsync() Tidak boleh memblokir secara serentak. Implementasi runAsync Anda harus mengembalikan CompletableFuture untuk memungkinkan runtime berlanjut. Jika beban kerja Anda perlu menerapkan tugas jangka panjang yang harus dilakukan di dalam CompletableFuture.

Pembatalan

Pembatalan beban kerja Anda adalah upaya kooperatif yang diorkestrasi oleh token pembatalan yang disediakan. Sistem menunggu tugas Anda selesai (dengan penyelesaian yang berhasil, pembatalan, atau kesalahan) sebelum dilanjutkan. Penting untuk memenuhi token pembatalan, menyelesaikan pekerjaan apa pun, dan keluar runAsync() secepat mungkin ketika sistem meminta pembatalan. Contoh berikut menunjukkan cara menangani acara pembatalan:

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

Dalam contoh layanan stateless ini, hitungan disimpan dalam variabel lokal. Tetapi karena ini adalah layanan stateless, nilai yang disimpan hanya ada untuk siklus hidup instans layanannya saat ini. Saat layanan bergerak atau dimulai ulang, nilai akan hilang.

Membuat layanan stateful

Service Fabric memperkenalkan jenis layanan baru yaitu stateful. Layanan stateful dapat mempertahankan status dengan andal dalam layanan itu sendiri, berlokasi bersama dengan kode yang menggunakannya. Status dibuat sangat tersedia oleh Service Fabric tanpa perlu mempertahankan status ke penyimpanan eksternal.

Untuk mengonversi nilai penghitung dari stateless ke sangat tersedia dan persisten, bahkan ketika layanan bergerak atau dimulai ulang, Anda memerlukan layanan stateful.

Dalam direktori yang sama dengan aplikasi HelloWorld, Anda dapat menambahkan layanan baru dengan menjalankan yo azuresfjava:AddService perintah. Pilih "Reliable Stateful Service" untuk kerangka kerja Anda dan beri nama layanan "HelloWorldStateful".

Aplikasi Anda sekarang harus memiliki dua layanan: HelloWorld layanan stateless dan HelloWorldStateful layanan stateful.

Layanan stateful memiliki titik entri yang sama dengan layanan stateless. Perbedaan utamanya adalah ketersediaan penyedia status yang dapat menyimpan status dengan andal. Service Fabric hadir dengan implementasi penyedia status yang disebut Reliable Collections, yang memungkinkan Anda membuat struktur data yang direplikasi melalui Reliable State Manager. Reliable Service yang stateful menggunakan penyedia status ini secara default.

Buka HelloWorldStateful.java di HelloWorldStateful -> src, yang berisi metode RunAsync berikut:

@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() beroperasi dengan cara yang sama dalam layanan stateful dan stateless. Namun, dalam layanan stateful, platform melakukan pekerjaan tambahan atas nama Anda sebelum dijalankan RunAsync(). Pekerjaan ini dapat mencakup pemastian bahwa Reliable State Manager dan Reliable Collections siap digunakan.

Reliable Collections dan Reliable State Manager

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

ReliableHashMap adalah implementasi kamus yang dapat Anda gunakan untuk menyimpan status dalam layanan dengan andal. Dengan Service Fabric dan Reliable HashMap, Anda dapat menyimpan data langsung di layanan Anda tanpa perlu penyimpanan persisten eksternal. Rliable HashMaps membuat data Anda sangat tersedia. Service Fabric menyelesaikan ini dengan membuat dan mengelola beberapa replika layanan Anda untuk Anda. Ini juga menyediakan API yang mengabstraksi kompleksitas pengelolaan replika tersebut dan transisi statusnya.

Reliable Collections dapat menyimpan jenis Java apa pun, termasuk jenis kustom Anda, dengan beberapa peringatan:

  • Service Fabric membuat status Anda sangat tersedia dengan mereplikasi status di seluruh node, dan Reliable HashMap menyimpan data Anda ke disk lokal pada setiap replika. Ini berarti bahwa segala sesuatu yang disimpan dalam Reliable HashMaps harus dapat diserialisasikan.

  • Objek direplikasi untuk ketersediaan tinggi saat Anda melakukan transaksi pada Reliable HashMap. Objek yang disimpan dalam Reliable HashMap disimpan dalam memori lokal dalam layanan Anda. Ini berarti Bahwa Anda memiliki referensi lokal untuk objek.

    Penting bagi Anda untuk tidak mengubah instans lokal objek tersebut tanpa melakukan operasi pembaruan pada pengumpulan yang dapat diandalkan dalam transaksi. Ini karena perubahan pada instansi lokal objek tidak akan direplikasi secara otomatis. Anda harus memasukkan kembali objek ke dalam kamus atau menggunakan salah satu metode pembaruan pada kamus.

Reliable State Manager mengelola Reliable HashMaps untuk Anda. Anda dapat meminta Reliable State Manager untuk koleksi yang andal berdasarkan nama kapan saja dan di mana saja dalam layanan Anda. Reliable State Manager memastikan bahwa Anda mendapatkan referensi kembali. Kami tidak menyarankan Anda menyimpan referensi ke instans koleksi yang andal di variabel atau properti anggota kelas. Perawatan khusus harus dilakukan untuk memastikan bahwa referensi diatur ke instans setiap saat dalam siklus hidup layanan. Reliable State Manager menangani pekerjaan ini untuk Anda, dan dioptimalkan untuk kunjungan berulang.

Operasi transaksional dan asinkron

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

Operasi pada Reliable HashMaps bersifat asinkron. Ini karena operasi tulis dengan Reliable Collections melakukan operasi I / O untuk mereplikasi dan menyimpan data ke disk.

Operasi Reliable HashMap bersifat transaksional, sehingga Anda dapat menjaga konsistensi status di beberapa operasi dan Reliable HashMap. Misalnya, Anda mungkin mendapatkan item pekerjaan dari satu Reliable Dictionary, melakukan operasi padanya, dan menyimpan hasilnya di Reliable HashMap lainnya, semuanya dalam satu transaksi. Ini diperlakukan sebagai operasi atomik, dan ini menjamin bahwa seluruh operasi akan berhasil atau seluruh operasi akan digulirkan kembali. Jika terjadi kesalahan setelah Anda dequeue item tetapi sebelum Anda menyimpan hasilnya, seluruh transaksi akan digulirkan kembali dan item tetap dalam antrean untuk diproses.

Membangun aplikasi

Perancah Yeoman mencakup skrip gradle untuk membangun aplikasi dan skrip bash untuk menyebarkan dan menghapus aplikasi. Untuk menjalankan aplikasi, pertama-tama buat aplikasi dengan gradle:

$ gradle

Ini menghasilkan paket aplikasi Service Fabric yang dapat disebarkan menggunakan Service Fabric CLI.

Sebarkan aplikasi

Setelah aplikasi dibangun, Anda dapat menyebarkannya ke klaster lokal.

  1. Sambungkan ke klaster Service Fabric lokal.

    sfctl cluster select --endpoint http://localhost:19080
    
  2. Jalankan skrip instal yang disediakan di templat untuk menyalin paket aplikasi ke penyimpanan klaster gambar, daftarkan jenis aplikasi, dan buat instans aplikasi.

    ./install.sh
    

Menyebarkan aplikasi yang dibangun sama dengan aplikasi Service Fabric lainnya. Lihat dokumentasi tentang mengelola aplikasi Service Fabric dengan Service Fabric CLI untuk petunjuk terperinci.

Parameter untuk perintah ini dapat ditemukan dalam manifes yang dihasilkan di dalam paket aplikasi.

Setelah aplikasi disebarkan, buka browser dan navigasi ke Service Fabric Explorer di http://localhost:19080/Explorer. Kemudian, perluas node Aplikasi dan perhatikan bahwa sekarang ada entri untuk jenis aplikasi Anda dan entri lain untuk instans pertama dari jenis itu.

Penting

Untuk menyebarkan aplikasi ke klaster Linux yang aman di Azure, Anda perlu mengonfigurasi sertifikat untuk memvalidasi aplikasi Anda dengan runtime Service Fabric. Dengan melakukannya, layanan Reliable Service Anda dapat berkomunikasi dengan API runtime Service Fabric yang mendasarinya. Untuk mempelajari lebih lanjut, lihat Mengonfigurasi aplikasi Reliable Services untuk dijalankan di klaster Linux.

Langkah berikutnya