
Hai, habrozhiteli! Jika untuk waktu yang lama tampaknya bagi Anda bahwa semua pengembangan dan penyebaran di perusahaan Anda telah melambat ke puncak - pergi ke arsitektur microservice. Ini menyediakan pengembangan berkelanjutan, pengiriman dan penyebaran aplikasi dari segala kompleksitas.
Buku ini, ditujukan untuk para pengembang dan arsitek dari perusahaan besar, menceritakan bagaimana merancang dan menulis aplikasi dalam semangat arsitektur layanan-mikro. Ini juga menjelaskan bagaimana cara memperbaiki aplikasi besar - dan monolith berubah menjadi seperangkat layanan microser.
Kami menawarkan Anda untuk membiasakan diri dengan bagian "Manajemen Transaksi dalam Arsitektur Layanan Mikro"
Hampir setiap permintaan yang diproses oleh aplikasi industri dijalankan sebagai bagian dari transaksi basis data. Pengembang aplikasi semacam itu menggunakan kerangka kerja dan perpustakaan yang menyederhanakan bekerja dengan transaksi. Beberapa alat menyediakan API keharusan untuk memulai, melakukan, dan memutar kembali transaksi secara manual. Dan kerangka kerja seperti Spring memiliki mekanisme deklaratif. Spring mendukung anotasi @Transaksional, yang secara otomatis memanggil metode dalam transaksi. Berkat ini, menulis logika bisnis transaksional menjadi sangat sederhana.
Untuk lebih tepatnya, mengelola transaksi sederhana dalam aplikasi monolitik yang mengakses satu basis data. Jika aplikasi menggunakan beberapa database dan pialang pesan, proses ini menjadi lebih sulit. Nah, dalam arsitektur microservice, transaksi mencakup beberapa layanan, yang masing-masing memiliki database sendiri. Dalam keadaan seperti itu, aplikasi harus menggunakan mekanisme transaksi yang lebih canggih. Seperti yang akan segera Anda lihat, pendekatan tradisional untuk transaksi terdistribusi tidak layak dalam aplikasi modern. Sistem berbasis microservice harus menggunakan mendongeng sebagai gantinya.
Tetapi sebelum beralih ke narasi, mari kita lihat mengapa manajemen transaksi menciptakan begitu banyak kompleksitas dalam arsitektur layanan-mikro.
4.1.1. Arsitektur microservice dan kebutuhan untuk transaksi terdistribusi
Bayangkan Anda adalah pengembang di FTGO dan bertanggung jawab untuk mengimplementasikan operasi sistem createOrder (). Seperti yang dijelaskan dalam Bab 2, operasi ini harus memastikan bahwa pelanggan dapat melakukan pemesanan, memeriksa detail pesanan, mengotorisasi kartu bank pelanggan, dan membuat catatan pesanan dalam database. Implementasi dari tindakan ini akan relatif sederhana dalam aplikasi monolitik. Semua data yang diperlukan untuk memverifikasi pesanan sudah siap dan tersedia. Selain itu, transaksi ACID dapat digunakan untuk memastikan konsistensi data. Anda cukup menentukan anotasi @Transaksional untuk metode layanan createOrder ().
Namun, melakukan operasi ini dalam arsitektur layanan mikro jauh lebih sulit. Seperti yang dapat dilihat pada gambar. 4.1, data yang diperlukan oleh operasi createOrder () tersebar di beberapa layanan. createOrder () membaca informasi dari layanan Konsumen dan memperbarui konten dari layanan Order, Kitchen, dan Accounting.
Karena setiap layanan memiliki database sendiri, Anda harus menggunakan mekanisme untuk mengoordinasikan data di antara mereka.
4.1.2. Masalah Transaksi Terdistribusi
Pendekatan tradisional untuk memastikan konsistensi data antara beberapa layanan, database, atau pialang pesan adalah penggunaan transaksi yang didistribusikan. Standar de facto untuk manajemen transaksi terdistribusi adalah X / Open XA (lihat
en.wikipedia.org/wiki/XA ). Model XA menggunakan komitmen dua fase (2PC) untuk memastikan bahwa semua perubahan transaksi disimpan atau dibatalkan. Ini membutuhkan basis data, pialang pesan, penggerak basis data, dan API perpesanan untuk mematuhi standar XA, dan mekanisme komunikasi antarproses yang mendistribusikan pengidentifikasi transaksi XA global juga diperlukan. Sebagian besar basis data relasional kompatibel dengan XA, seperti halnya beberapa broker pesan. Misalnya, aplikasi berbasis Java EE dapat melakukan transaksi terdistribusi menggunakan JTA.
Terlepas dari kesederhanaannya, transaksi yang didistribusikan memiliki sejumlah masalah. Banyak teknologi modern, termasuk basis data NoSQL seperti MongoDB dan Cassandra, tidak mendukungnya. Transaksi yang didistribusikan tidak didukung oleh beberapa broker pesan modern seperti RabbitMQ dan Apache Kafka. Jadi, jika Anda memutuskan untuk menggunakan transaksi terdistribusi, banyak alat modern tidak akan tersedia untuk Anda.
Masalah lain dengan transaksi terdistribusi adalah bahwa mereka adalah bentuk IPC sinkron, yang mengganggu ketersediaan. Agar transaksi yang didistribusikan dilakukan, semua layanan yang terlibat di dalamnya harus dapat diakses. Seperti dijelaskan dalam Bab 3, aksesibilitas sistem adalah produk dari aksesibilitas semua peserta transaksi. Jika dua layanan dengan ketersediaan 99,5% berpartisipasi dalam transaksi terdistribusi, ketersediaan keseluruhan akan menjadi 99%, yang jauh lebih sedikit. Setiap layanan tambahan menurunkan tingkat ketersediaan. Eric Brewer merumuskan teorema CAP, yang menyatakan bahwa sistem hanya dapat memiliki dua dari tiga properti berikut: konsistensi, aksesibilitas, dan resistensi partisi (en.wikipedia.org/wiki/CAP_ Theorem). Saat ini, arsitek menyukai sistem yang terjangkau, mengorbankan konsistensi.
Sekilas, transaksi yang didistribusikan mungkin tampak menarik. Dari sudut pandang pengembang, mereka memiliki model perangkat lunak yang sama dengan transaksi lokal. Tetapi karena masalah yang dijelaskan sebelumnya, teknologi ini tidak dapat digunakan dalam aplikasi modern. Bab 3 menunjukkan cara mengirim pesan sebagai bagian dari transaksi basis data tanpa menggunakan transaksi terdistribusi. Untuk memecahkan masalah yang lebih kompleks dalam memastikan konsistensi data dalam arsitektur layanan mikro, aplikasi harus menggunakan mekanisme yang berbeda berdasarkan konsep layanan asinkron yang digabungkan secara longgar. Dan di sini narasinya sangat berguna.
4.1.3. Gunakan template Storytelling untuk menjaga konsistensi data
Mendongeng adalah mekanisme yang memastikan konsistensi data dalam arsitektur layanan mikro tanpa menggunakan transaksi yang didistribusikan. Narasi dibuat untuk setiap tim sistem yang perlu memperbarui data di beberapa layanan. Ini adalah urutan transaksi lokal, yang masing-masing memperbarui data dalam satu layanan, menggunakan kerangka kerja dan pustaka yang dikenal untuk transaksi ACID yang disebutkan sebelumnya.
Templat Mendongeng
Memastikan konsistensi data antara layanan menggunakan urutan transaksi lokal yang dikoordinasikan menggunakan pesan asinkron. Lihat microservices.io/patterns/data/saga.html .
Operasi sistem memulai tahap pertama dari narasi. Penyelesaian satu transaksi lokal mengarah ke yang berikut ini. Di bagian 4.2, Anda akan melihat bagaimana koordinasi langkah-langkah ini dicapai menggunakan pesan asinkron. Keuntungan penting dari pesan asinkron adalah memastikan semua tahap narasi selesai, bahkan jika satu atau lebih peserta tidak dapat diakses.
Narasi memiliki beberapa perbedaan penting dari transaksi ACID. Pertama-tama, mereka tidak memiliki isolasi (untuk lebih lanjut tentang ini, lihat Bagian 4.3). Selain itu, karena setiap transaksi lokal menangkap perubahannya, untuk memutar kembali cerita, Anda harus menggunakan transaksi kompensasi, yang akan kita bahas nanti di bagian ini. Pertimbangkan contoh mendongeng.
Contoh Naratif: Membuat Pesanan
Dalam bab ini, kami menggunakan narasi Buat Pesanan sebagai contoh (Gbr. 4.2). Ini mengimplementasikan operasi createOrder (). Transaksi lokal pertama dipicu oleh permintaan pembuatan pesanan eksternal. Lima transaksi yang tersisa dipicu satu demi satu.
Narasi ini terdiri dari transaksi lokal berikut.
1. Layanan pemesanan. Membuat pesanan dengan status APPROVAL_PENDING.
2. Layanan Konsumen. Cek apakah pelanggan dapat memesan.
3. Layanan dapur. Periksa detail pesanan dan buat permintaan dengan status CREATE_PENDING.
4. Layanan akuntansi. Memberi otorisasi kartu bank pelanggan.
5. Layanan dapur. Mengubah status aplikasi menjadi AWAITING_ACCEPTANCE.
6. Pesanan Layanan. Mengubah status pesanan menjadi DISETUJUI.
Di Bagian 4.2, saya akan menunjukkan bagaimana layanan yang terlibat dalam cerita berinteraksi satu sama lain menggunakan pesan asinkron. Layanan menerbitkan pesan setelah menyelesaikan transaksi lokal. Ini memulai tahap narasi berikutnya dan memungkinkan tidak hanya untuk mencapai kohesi yang lemah dari para peserta, tetapi juga untuk menjamin implementasi narasi sepenuhnya. Bahkan jika penerima tidak tersedia untuk sementara waktu, broker memberikan pesan sampai dapat dikirimkan.
Narasi tampak sederhana, tetapi penggunaannya dikaitkan dengan beberapa kesulitan, terutama dengan kurangnya isolasi di antara mereka. Solusi untuk masalah ini dijelaskan pada bagian 4.3. Aspek non-sepele lainnya adalah kemunduran perubahan saat terjadi kesalahan. Mari kita lihat bagaimana ini dilakukan.
Naratif menggunakan transaksi penyeimbangan untuk mengembalikan perubahan
Transaksi ACID tradisional memiliki satu fitur hebat: logika bisnis dapat dengan mudah mengembalikan transaksi jika pelanggaran aturan bisnis terdeteksi. Itu hanya menjalankan perintah ROLLBACK, dan database membatalkan semua perubahan yang dibuat sejauh ini. Sayangnya, cerita tidak dapat diputar kembali secara otomatis, karena pada setiap tahap menangkap perubahan dalam database lokal. Ini, misalnya, berarti bahwa dalam hal terjadi kegagalan otorisasi kartu bank pada tahap keempat dari narasi Buat Pesanan, aplikasi FTGO harus secara manual membatalkan perubahan yang dibuat dalam tiga tahap sebelumnya. Anda harus menulis apa yang disebut transaksi offset.
Misalkan transaksi (n +1) dalam cerita gagal. Hal ini diperlukan untuk menetralisir konsekuensi dari transaksi sebelumnya. Pada tingkat konseptual, masing-masing tahap Ti ini memiliki transaksi kompensasi Ci sendiri, yang membatalkan efek Ti. Untuk mengkompensasi efek dari n tahap pertama, narasi harus mengeksekusi setiap transaksi Ci dalam urutan terbalik. Urutannya terlihat seperti ini: T1 ... Tn, Cn ... C1 (Gbr. 4.3). Dalam contoh ini, langkah Tn + 1 gagal, yang membutuhkan pembatalan langkah T1 ... Tn.
Narasi melakukan transaksi kompensasi dalam urutan terbalik dengan yang asli: Cn ... C1. Di sini, mekanisme eksekusi sekuensial yang sama beroperasi seperti dalam kasus Ti. Pengakhiran Ci harus memulai Ci - 1.
Ambil, misalnya, narasi dari Create Order. Mungkin gagal karena berbagai alasan.
1. Informasi yang salah tentang pelanggan, atau pelanggan tidak diizinkan untuk membuat pesanan.
2. Informasi yang salah tentang restoran, atau restoran tidak dapat menerima pesanan.
3. Ketidakmampuan untuk mengotorisasi kartu bank pelanggan.
Dalam hal terjadi kegagalan dalam transaksi lokal, mekanisme koordinasi mendongeng harus melakukan langkah-langkah kompensasi yang menolak pesanan dan mungkin pesanan. Di atas meja. 4.1 transaksi kompensasi dikumpulkan untuk setiap tahap narasi Buat Pesanan. Perlu dicatat bahwa tidak setiap tahap membutuhkan transaksi kompensasi. Ini berlaku, misalnya, untuk membaca operasi, seperti memverifikasiConsumerDetails (), atau operasi authorizeCreditCard (), semua langkah setelah itu selalu berhasil.
Di Bagian 4.3, Anda akan menemukan bahwa tiga tahap pertama dari narasi Buat Pesanan disebut transaksi yang tersedia untuk kompensasi, karena langkah-langkah berikut mereka mungkin gagal. Langkah keempat disebut transaksi balik karena langkah selanjutnya tidak pernah gagal. Dua langkah terakhir disebut transaksi berulang, karena selalu berakhir dengan sukses.
Untuk memahami bagaimana transaksi kompensasi digunakan, bayangkan situasi di mana otorisasi kartu bank pelanggan gagal. Dalam hal ini, narasi melakukan transaksi lokal berikut.
1. Layanan pemesanan. Membuat pesanan dengan status APPROVAL_PENDING.
2. Layanan Konsumen. Cek apakah pelanggan dapat memesan.
3. Layanan dapur. Periksa detail pesanan dan buat permintaan dengan status CREATE_PENDING.
4. Layanan akuntansi. Melakukan upaya yang gagal untuk mengotorisasi kartu bank pelanggan.
5. Layanan dapur. Mengubah status aplikasi menjadi CREATE_REJECTED.
6. Pesanan Layanan. Mengubah status pesanan menjadi DITOLAK.
Tahap kelima dan keenam mengkompensasi transaksi yang membatalkan pembaruan yang dibuat oleh layanan Dapur dan, dengan demikian, Memesan. Logika naratif yang terkoordinasi bertanggung jawab atas urutan transaksi langsung dan penyeimbangan. Mari kita lihat cara kerjanya.
Tentang penulis
Chris Richardson adalah pengembang, arsitek, dan penulis POJO in Action (Manning, 2006), yang menjelaskan cara membangun aplikasi Java tingkat perusahaan menggunakan kerangka kerja Spring dan Hibernate. Ia menyandang gelar kehormatan Java Champion dan JavaOne Rock Star.
Chris mengembangkan versi asli CloudFoundry.com, implementasi awal platform Java PaaS untuk Amazon EC2.
Sekarang ia dianggap sebagai pemimpin ideologis yang diakui di dunia layanan-mikro dan secara teratur berbicara di konferensi internasional. Chris menciptakan microservices.io, yang berisi pola desain microservice. Dia juga melakukan konsultasi dan pelatihan di seluruh dunia untuk organisasi yang beralih ke arsitektur layanan mikro. Chris saat ini sedang mengerjakan startup ketiga, Eventuate.io. Ini adalah platform perangkat lunak untuk mengembangkan layanan transaksional microser.
»Informasi lebih lanjut tentang buku ini dapat ditemukan di
situs web penerbit»
Isi»
KutipanKupon diskon 25% untuk penjaja -
Pola Layanan MikroSetelah pembayaran versi kertas buku, sebuah buku elektronik dikirim melalui email.