Bagikan melalui


Penerapan versi di Durable Functions (Microsoft Azure Functions)

Tidak dapat dihindari bahwa fungsi akan ditambah, dihapus, dan diubah selama masa pakai aplikasi. Durable Functions memungkinkan fungsi penautan bersama dengan cara yang sebelumnya tidak mungkin, dan penautan ini memengaruhi cara Anda dapat menangani penerapan versi.

Cara menangani perubahan mencolok

Ada beberapa contoh perubahan mencolok yang harus diperhatikan. Artikel ini membahas perubahan yang paling umum. Tema utama di balik semuanya adalah bahwa orkestrasi fungsi baru dan yang ada terpengaruh oleh perubahan pada kode fungsi.

Mengubah tanda tangan fungsi aktivitas atau entitas

Perubahan tanda tangan mengacu pada perubahan nama, input, atau output fungsi. Jika perubahan semacam ini dilakukan pada fungsi aktivitas atau entitas, hal tersebut dapat memutus fungsi orkestrator yang bergantung padanya. Ini terutama berlaku untuk bahasa komputer yang aman untuk jenis. Jika Anda memperbarui fungsi orkestrator untuk mengakomodasi perubahan ini, Anda dapat memutus instans dalam penerbangan yang ada.

Sebagai contoh, misalnya kita memiliki fungsi orkestrator berikut.

[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    bool result = await context.CallActivityAsync<bool>("Foo");
    await context.CallActivityAsync("Bar", result);
}

Fungsi sederhana ini membawa hasil Foo dan meneruskannya ke Bar. Mari kita asumsikan kita perlu mengubah nilai yang dikembalikan Foo dari Boolean ke String untuk mendukung berbagai nilai hasil yang lebih luas. Hasilnya terlihat seperti ini:

[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    string result = await context.CallActivityAsync<string>("Foo");
    await context.CallActivityAsync("Bar", result);
}

Perubahan ini berfungsi dengan baik untuk semua instans baru fungsi orkestrator tetapi dapat merusak instans dalam penerbangan apa pun. Contohnya, pertimbangkan kasus di mana instans orkestrasi memanggil fungsi bernama Foo, mendapatkan kembali nilai boolean, lalu titik pemeriksaan. Jika perubahan tanda tangan disebarkan pada titik ini, instans yang berada di titik pemeriksaan akan segera gagal ketika dilanjutkan dan memutar ulang panggilan ke Foo. Kegagalan ini terjadi karena hasil dalam tabel riwayat adalah nilai Boolean tetapi kode baru mencoba mendeserialisasinya menjadi nilai String, menghasilkan perilaku yang tidak terduga atau bahkan pengecualian runtime untuk bahasa yang aman jenis.

Contoh ini hanya salah satu dari banyak cara berbeda di mana perubahan tanda tangan fungsi dapat memutus instans yang ada. Secara umum, jika orkestrator perlu mengubah cara memanggil fungsi, perubahannya cenderung bermasalah.

Mengubah logika orkestrator

Kelas lain dari masalah penerapan versi berasal dari pengubahan kode fungsi orchestrator dengan cara yang mengubah jalur eksekusi untuk instans in-flight.

Pertimbangkan fungsi orkestrator berikut:

[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    bool result = await context.CallActivityAsync<bool>("Foo");
    await context.CallActivityAsync("Bar", result);
}

Sekarang mari kita asumsikan Anda ingin membuat perubahan untuk menambahkan panggilan fungsi baru di antara dua panggilan fungsi yang ada.

[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    bool result = await context.CallActivityAsync<bool>("Foo");
    if (result)
    {
        await context.CallActivityAsync("SendNotification");
    }

    await context.CallActivityAsync("Bar", result);
}

Perubahan ini menambahkan panggilan fungsi baru ke SendNotification antara Foo dan Bar. Tidak ada perubahan tanda tangan. Masalah muncul ketika instans yang ada dilanjutkan dari panggilan ke Bilah. Selama pemutaran ulang, jika panggilan asli ke Foo dikembalikan true, maka pemutaran ulang orkestrator akan memanggil SendNotification, yang tidak dalam riwayat pelaksanaan. Runtime bahasa umum mendeteksi inkonsistensi ini dan memunculkan kesalahan orkestrasi non-deterministik karena menemukan panggilan ke SendNotification ketika seharusnya mendapatkan panggilan ke Bilah. Jenis masalah yang sama dapat terjadi saat menambahkan panggilan API ke operasi tahan lama lainnya, seperti membuat timer yang tahan lama, menunggu peristiwa eksternal, memanggil sub-oskestrasi, dll.

Strategi mitigasi

Berikut beberapa strategi untuk menghadapi tantangan penerapan versi:

  • Jangan lakukan apa-apa (tidak disarankan)
  • Menghentikan semua instans di dalam penerbangan
  • Penyebaran berdampingan

Tidak perlu melakukan apa-apa

Pendekatan naive untuk membuat versi adalah dengan tidak melakukan apa-apa dan membiarkan instans orkestrasi in-flight gagal. Bergantung pada jenis perubahan, jenis kegagalan berikut dapat terjadi.

  • Orkestrasi mungkin gagal dengan kesalahan orkestrasi non-deterministik.
  • Orchestrations mungkin terjebak tanpa batas waktu, melaporkan status Running.
  • Jika fungsi dihapus, fungsi apa pun yang mencoba memanggil fungsi tersebut mungkin gagal dengan kesalahan.
  • Jika fungsi dihapus setelah dijadwalkan untuk dijalankan, maka aplikasi mungkin mengalami kegagalan runtime tingkat rendah di mesin Durable Task Framework, yang berpotensi mengakibatkan penurunan performa yang parah.

Karena potensi kegagalan ini, strategi "tidak melakukan apa-apa" tidak dianjurkan.

Menghentikan semua instans di dalam penerbangan

Pilihan lain adalah menghentikan semua instans di dalam penerbangan. Jika Anda menggunakan Penyedia Azure Storage untuk Durable Functions, menghentikan semua instans dapat dilakukan dengan menghapus konten antrean internal antrean kontrol dan antrean workitem. Anda juga dapat menghentikan aplikasi fungsi, menghapus antrean ini, dan menghidupkan ulang aplikasi lagi. Antrean akan dibuat ulang secara otomatis setelah aplikasi dihidupkan ulang. Instans orkestrasi sebelumnya mungkin tetap berada dalam status "Berjalan" tanpa batas waktu, tetapi intans tersebut tidak akan mengacaukan log Anda dengan pesan kegagalan atau menyebabkan kerusakan pada aplikasi Anda. Pendekatan ini sangat ideal dalam pengembangan prototipe yang cepat, termasuk pengembangan lokal.

Catatan

Pendekatan ini membutuhkan akses langsung ke sumber daya penyimpanan yang mendasarinya, dan mungkin tidak sesuai untuk semua penyedia penyimpanan yang didukung oleh Durable Functions.

Penyebaran berdampingan

Cara paling sulit untuk memastikan bahwa perubahan mencolok disebarkan dengan aman adalah dengan menyebarkannya berdampingan dengan versi lama Anda. Ini dapat dilakukan menggunakan salah satu teknik berikut:

  • Sebarkan semua pembaruan sebagai fungsi yang sama sekali baru, tinggalkan fungsi yang ada apa adanya. Cara ini biasanya tidak disarankan karena kompleksitas yang terlibat dalam memperbarui pemanggil versi fungsi baru secara rekursif.
  • Sebarkan semua pembaruan sebagai aplikasi fungsi baru dengan akun penyimpanan yang berbeda.
  • Sebarkan salinan baru aplikasi fungsi dengan akun penyimpanan yang sama tetapi dengan nama hub tugasyang diperbarui. Hal ini mengakibatkan pembuatan artefak penyimpanan baru yang dapat digunakan oleh versi baru aplikasi Anda. Versi lama aplikasi Anda akan terus dijalankan menggunakan sekumpulan artefak penyimpanan sebelumnya.

Penyebaran berdampingan adalah teknik yang disarankan untuk menyebarkan versi baru aplikasi fungsi Anda.

Catatan

Panduan untuk strategi penyebaran berdampingan ini menggunakan istilah khusus Azure Storage, tetapi umumnya berlaku untuk semua Penyedia penyimpanan Durable Functions yang didukung.

Slot penyebaran

Saat melakukan penyebaran berdampingan di Azure Functions atau Azure App Service, sebaiknya Anda menyebarkan versi baru aplikasi fungsi ke Slot penyebaran baru. Slot penyebaran memungkinkan Anda menjalankan beberapa salinan aplikasi fungsi secara berdampingan hanya dengan salah satu dari mereka sebagai slot produksi aktif. Ketika Anda siap mengekspos logika orkestrasi baru ke infrastruktur yang ada, itu dapat sesederhana menukar versi baru ke slot produksi.

Catatan

Strategi ini berfungsi paling baik ketika Anda menggunakan pemicu HTTP dan webhook untuk fungsi orkestrator. Untuk pemicu non-HTTP, seperti antrean atau Pusat Aktivitas, definisi pemicu harus berasal dari pengaturan aplikasi yang diperbarui sebagai bagian dari operasi swap.

Langkah berikutnya