Transaksi di seluruh layanan mikro REST?

195

Katakanlah kita memiliki microservices Pengguna, Wallet REST, dan gateway API yang merekatkan semuanya. Ketika Bob mendaftar di situs web kami, gateway API kami perlu membuat pengguna melalui layanan pengguna mikro dan dompet melalui layanan mikro Dompet.

Sekarang, inilah beberapa skenario di mana segala sesuatunya bisa salah:

  • Pembuatan Bob pengguna gagal: tidak apa-apa, kami hanya mengembalikan pesan kesalahan ke Bob. Kami menggunakan transaksi SQL sehingga tidak ada yang melihat Bob di sistem. Semuanya baik :)

  • Pengguna Bob dibuat tetapi sebelum Dompet kami dapat dibuat, API gateway kami mengalami kerusakan. Kami sekarang memiliki Pengguna tanpa dompet (data tidak konsisten).

  • Pengguna Bob dibuat dan saat kami membuat Wallet, koneksi HTTP turun. Penciptaan dompet mungkin telah berhasil atau mungkin tidak.

Solusi apa yang tersedia untuk mencegah terjadinya ketidakkonsistenan data seperti ini? Apakah ada pola yang memungkinkan transaksi untuk menjangkau beberapa permintaan REST? Saya telah membaca halaman Wikipedia tentang komitmen dua fase yang sepertinya menyentuh masalah ini, tetapi saya tidak yakin bagaimana menerapkannya dalam praktik. Transaksi Terdistribusi Atom ini : makalah desain yang tenang juga tampak menarik walaupun saya belum membacanya.

Atau, saya tahu REST mungkin tidak cocok untuk kasus penggunaan ini. Apakah mungkin cara yang tepat untuk menangani situasi ini untuk menghentikan REST sepenuhnya dan menggunakan protokol komunikasi yang berbeda seperti sistem antrian pesan? Atau haruskah saya menegakkan konsistensi dalam kode aplikasi saya (misalnya, dengan memiliki pekerjaan latar belakang yang mendeteksi ketidakkonsistenan dan memperbaikinya atau dengan memiliki atribut "status" pada model Pengguna saya dengan nilai "menciptakan", "menciptakan", dll.)?

Olivier Lalonde
sumber
3
Tautan menarik: news.ycombinator.com/item?id=7995130
Olivier Lalonde
3
Jika pengguna tidak masuk akal tanpa dompet, mengapa harus membuat microservice terpisah untuk itu? Mungkin ada sesuatu yang tidak beres dengan arsitektur di tempat pertama? Mengapa Anda memerlukan gateway API generik, btw? Apakah ada alasan khusus untuk itu?
Vladislav Rastrusny
4
@VladislavRastrusny itu adalah contoh fiksi, tetapi Anda bisa menganggap layanan dompet ditangani oleh Stripe misalnya.
Olivier Lalonde
Anda dapat menggunakan manajer proses untuk melacak transaksi (pola manajer proses) atau meminta setiap layanan mikro tahu cara memicu rollback (pola manajer saga) atau melakukan semacam komit dua fase ( blog.aspiresys.com/software-product-engineering / producteering / ... )
andrew pate
@VladislavRastrusny "Jika pengguna tidak masuk akal tanpa dompet, mengapa membuat microservice terpisah untuk itu" - misalnya, selain dari kenyataan Pengguna tidak dapat ada tanpa Dompet mereka tidak memiliki kode yang sama. Jadi dua tim akan mengembangkan dan menggunakan layanan microser Pengguna dan Dompet secara mandiri. Bukankah itu inti dari melakukan layanan microser sejak awal?
Nik

Jawaban:

148

Apa yang tidak masuk akal:

  • transaksi terdistribusi dengan layanan REST . Layanan REST menurut definisi adalah tanpa kewarganegaraan, sehingga mereka tidak boleh menjadi peserta dalam batas transaksional yang mencakup lebih dari satu layanan. Skenario kasus penggunaan pendaftaran pengguna Anda masuk akal, tetapi desain dengan layanan Microsoft REST untuk membuat data Pengguna dan Dompet tidak baik.

Apa yang akan membuat Anda sakit kepala:

  • EJB dengan transaksi terdistribusi . Ini adalah salah satu hal yang bekerja secara teori tetapi tidak dalam praktiknya. Saat ini saya sedang mencoba untuk membuat transaksi transaksi terdistribusi untuk EJB jarak jauh di seluruh JBoss EAP 6.3 instance. Kami telah berbicara dengan dukungan RedHat selama berminggu-minggu, dan itu belum berfungsi.
  • Solusi komit dua fase secara umum . Saya pikir protokol 2PC adalah algoritma yang hebat (bertahun-tahun yang lalu saya mengimplementasikannya dalam C dengan RPC). Ini membutuhkan mekanisme pemulihan gagal yang komprehensif, dengan percobaan ulang, repositori negara, dll. Semua kerumitan disembunyikan dalam kerangka kerja transaksi (mis .: JBoss Arjuna). Namun, 2PC bukan bukti gagal. Ada beberapa situasi yang tidak bisa diselesaikan transaksi. Maka Anda perlu mengidentifikasi dan memperbaiki ketidakkonsistenan basis data secara manual. Ini mungkin terjadi sekali dalam sejuta transaksi jika Anda beruntung, tetapi itu bisa terjadi sekali dalam setiap 100 transaksi tergantung pada platform dan skenario Anda.
  • Sagas (Kompensasi transaksi) . Ada overhead implementasi untuk menciptakan operasi kompensasi, dan mekanisme koordinasi untuk mengaktifkan kompensasi pada akhirnya. Tetapi kompensasi juga bukan bukti gagal. Anda mungkin masih berakhir dengan ketidakkonsistenan (= sakit kepala).

Apa yang mungkin merupakan alternatif terbaik:

  • Konsistensi akhirnya . Baik transaksi yang didistribusikan seperti ACID maupun transaksi kompensasi tidak terbukti gagal, dan keduanya dapat menyebabkan inkonsistensi. Konsistensi akhirnya seringkali lebih baik daripada "ketidakkonsistenan sesekali". Ada berbagai solusi desain, seperti:
    • Anda dapat membuat solusi yang lebih kuat menggunakan komunikasi asinkron. Dalam skenario Anda, ketika Bob mendaftar, gateway API dapat mengirim pesan ke antrian Pengguna Baru, dan segera membalas pengguna yang mengatakan "Anda akan menerima email untuk mengonfirmasi pembuatan akun." Layanan konsumen antrian dapat memproses pesan, melakukan perubahan basis data dalam satu transaksi, dan mengirim email ke Bob untuk memberi tahu pembuatan akun.
    • Layanan microservice membuat catatan pengguna dan catatan dompet di database yang sama . Dalam hal ini, toko dompet dalam layanan Microsoft pengguna adalah replika dari toko dompet utama yang hanya dapat dilihat oleh layanan dompet mikro. Ada mekanisme sinkronisasi data yang berbasis pemicu atau tendangan secara berkala untuk mengirim perubahan data (misalnya, dompet baru) dari replika ke master, dan sebaliknya.

Tetapi bagaimana jika Anda membutuhkan respons sinkron?

  • Merombak layanan microser . Jika solusi dengan antrian tidak berfungsi karena konsumen layanan memerlukan respons segera, maka saya lebih suka mengubah fungsi Pengguna dan Dompet untuk ditempatkan di layanan yang sama (atau setidaknya di VM yang sama untuk menghindari transaksi terdistribusi ). Ya, ini selangkah lebih jauh dari layanan microser dan lebih dekat ke monolith, tetapi akan menyelamatkan Anda dari sakit kepala.
Paulo Merson
sumber
4
Konsistensi akhirnya berhasil untuk saya. Dalam hal ini, antrian "Pengguna Baru" harus tersedia tinggi dan tangguh.
Ram Bavireddi
@RamBavireddi do Kafka atau RabbitMQ mendukung antrian tangguh?
v.oddou
@ v.oddou Ya, benar.
Ram Bavireddi
2
@PauloMerson Saya tidak yakin tentang perbedaan antara Anda. Mengkompensasi transaksi hingga akhirnya konsisten. Bagaimana jika, dalam konsistensi akhirnya, pembuatan dompet gagal?
balsick
2
@balsick Salah satu tantangan pengaturan konsistensi akhirnya adalah meningkatnya kompleksitas desain. Pemeriksaan konsistensi dan peristiwa koreksi seringkali diperlukan. Desain solusi bervariasi. Dalam jawabannya, saya menyarankan situasi di mana catatan Dompet dibuat dalam database saat memproses pesan yang dikirim melalui pialang pesan. Dalam hal ini, kami dapat menetapkan Saluran Surat Mati, yaitu, jika memproses pesan itu menghasilkan kesalahan, kami dapat mengirim pesan ke antrian surat mati dan memberi tahu tim yang bertanggung jawab atas "Dompet".
Paulo Merson
66

Ini adalah pertanyaan klasik yang saya tanyakan saat wawancara baru-baru ini. Bagaimana cara memanggil beberapa layanan web dan masih mempertahankan beberapa jenis penanganan kesalahan di tengah tugas. Saat ini, dalam komputasi kinerja tinggi, kami menghindari komitmen dua fase. Saya membaca makalah bertahun-tahun yang lalu tentang apa yang disebut "model Starbuck" untuk transaksi: Pikirkan tentang proses pemesanan, pembayaran, persiapan dan penerimaan kopi yang Anda pesan di Starbuck ... Saya terlalu menyederhanakan berbagai hal tetapi model dua fase komit akan sarankan bahwa seluruh proses akan menjadi transaksi pembungkus tunggal untuk semua langkah yang terlibat sampai Anda menerima kopi Anda. Namun, dengan model ini, semua karyawan akan menunggu dan berhenti bekerja sampai Anda mendapatkan kopi Anda. Anda melihat gambarnya?

Sebagai gantinya, "model Starbuck" lebih produktif dengan mengikuti model "usaha terbaik" dan mengkompensasi kesalahan dalam proses. Pertama, mereka memastikan bahwa Anda membayar! Lalu, ada antrian pesan dengan pesanan Anda terlampir pada cangkir. Jika ada yang salah dalam proses, seperti Anda tidak mendapatkan kopi Anda, bukan itu yang Anda pesan, dll, kami masuk ke dalam proses kompensasi dan kami memastikan Anda mendapatkan apa yang Anda inginkan atau mengembalikan uang Anda, Ini adalah model yang paling efisien untuk peningkatan produktivitas.

Terkadang, starbuck membuang-buang kopi tetapi proses keseluruhannya efisien. Ada trik lain untuk dipikirkan ketika Anda membangun layanan web Anda seperti mendesainnya sedemikian rupa sehingga mereka dapat dipanggil berapa kali dan masih memberikan hasil akhir yang sama. Jadi, rekomendasi saya adalah:

  • Jangan terlalu baik ketika mendefinisikan layanan web Anda (saya tidak yakin tentang hype layanan mikro yang terjadi hari ini: terlalu banyak risiko terlalu jauh);

  • Async meningkatkan kinerja jadi lebih suka menjadi async, kirim pemberitahuan melalui email kapan pun memungkinkan.

  • Bangun layanan yang lebih cerdas untuk menjadikannya "dapat diingat" beberapa kali, diproses dengan uid atau taskid yang akan mengikuti urutan bottom-top hingga akhir, memvalidasi aturan bisnis di setiap langkah;

  • Gunakan antrian pesan (JMS atau yang lain) dan alihkan ke prosesor penanganan kesalahan yang akan menerapkan operasi ke "kembalikan" dengan menerapkan operasi yang berlawanan, omong-omong, bekerja dengan urutan async akan memerlukan semacam antrian untuk memvalidasi keadaan proses saat ini, jadi pertimbangkan itu;

  • Dalam upaya terakhir, (karena mungkin tidak sering terjadi), masukkan ke dalam antrian untuk pemrosesan kesalahan secara manual.

Mari kita kembali dengan masalah awal yang diposting. Buat akun dan buat dompet dan pastikan semuanya sudah selesai.

Katakanlah layanan web dipanggil untuk mengatur seluruh operasi.

Kode semu layanan web akan terlihat seperti ini:

  1. Panggil layanan pembuatan akun mikro, berikan informasi dan id tugas unik 1.1 Layanan pembuatan akun akan terlebih dahulu memeriksa apakah akun itu sudah dibuat. Id tugas dikaitkan dengan catatan akun. Layanan microsoft mendeteksi bahwa akun tidak ada sehingga membuatnya dan menyimpan id tugas. CATATAN: layanan ini dapat dipanggil 2000 kali, ia akan selalu melakukan hasil yang sama. Layanan menjawab dengan "tanda terima yang berisi informasi minimal untuk melakukan operasi pembatalan jika diperlukan".

  2. Panggil pembuatan Dompet, berikan ID akun dan id tugas. Katakanlah suatu kondisi tidak valid dan pembuatan dompet tidak dapat dilakukan. Panggilan kembali dengan kesalahan tetapi tidak ada yang dibuat.

  3. Orkestra diberitahu tentang kesalahan tersebut. Ia tahu ia harus membatalkan pembuatan Akun tetapi tidak akan melakukannya sendiri. Ia akan meminta layanan dompet untuk melakukannya dengan mengirimkan "tanda terima minimal yang dibatalkan" yang diterima pada akhir langkah 1.

  4. Layanan Akun membaca tanda terima undo dan tahu cara membatalkan operasi; tanda terima yang dibatalkan bahkan dapat menyertakan informasi tentang layanan microsoft lain yang dapat disebut sebagai bagian dari pekerjaan tersebut. Dalam situasi ini, tanda terima yang dibatalkan dapat berisi ID Akun dan mungkin beberapa informasi tambahan yang diperlukan untuk melakukan operasi yang berlawanan. Dalam kasus kami, untuk mempermudah, katakanlah cukup hapus akun menggunakan id akunnya.

  5. Sekarang, katakanlah layanan web tidak pernah menerima keberhasilan atau kegagalan (dalam hal ini) bahwa pembatalan pembuatan Akun dilakukan. Itu hanya akan memanggil layanan membatalkan Akun lagi. Dan layanan ini seharusnya tidak pernah gagal karena tujuannya adalah agar akun tidak ada lagi. Jadi ia memeriksa apakah ada dan melihat tidak ada yang bisa dilakukan untuk membatalkannya. Jadi kembalinya operasi itu sukses.

  6. Layanan web kembali ke pengguna bahwa akun tidak dapat dibuat.

Ini adalah contoh sinkron. Kami bisa mengelolanya dengan cara yang berbeda dan memasukkan kasus ke antrian pesan yang ditargetkan ke help desk jika kami tidak ingin sistem menyelesaikan kesalahan ". Saya telah melihat ini dilakukan di perusahaan di mana tidak cukup kait dapat diberikan ke sistem ujung belakang untuk memperbaiki situasi. Meja bantuan menerima pesan yang berisi apa yang dilakukan dengan sukses dan memiliki informasi yang cukup untuk memperbaiki hal-hal seperti tanda terima undo kami dapat digunakan dengan cara yang sepenuhnya otomatis.

Saya telah melakukan pencarian dan situs web microsoft memiliki deskripsi pola untuk pendekatan ini. Ini disebut pola transaksi kompensasi:

Mengkompensasi pola transaksi

pengguna8098437
sumber
2
Apakah Anda pikir Anda dapat memperluas jawaban ini untuk memberikan saran yang lebih spesifik kepada OP. Seperti berdiri, jawaban ini agak kabur dan sulit dimengerti. Walaupun saya mengerti bagaimana kopi disajikan di Starbucks, tidak jelas bagi saya aspek apa dari sistem ini yang harus ditiru dalam layanan REST.
jwg
Saya telah menambahkan contoh terkait dengan kasus yang awalnya disediakan di pos asli.
user8098437
2
Baru saja menambahkan tautan ke pola transaksi kompensasi seperti yang dijelaskan oleh Microsoft.
user8098437
3
Bagi saya, ini adalah jawaban terbaik. Sangat sederhana
Oscar Nevarez
1
Perhatikan bahwa transaksi kompensasi mungkin tidak mungkin dilakukan dalam skenario kompleks tertentu (seperti yang disorot dengan cemerlang dalam dokumen microsoft). Dalam contoh ini, bayangkan sebelum pembuatan dompet gagal, seseorang dapat membaca detail tentang akun terkait dengan melakukan panggilan GET pada layanan Akun, yang idealnya tidak ada di tempat pertama sejak pembuatan akun gagal. Ini dapat menyebabkan inkonsistensi data. Masalah isolasi ini terkenal dalam pola SAGAS.
Anmol Singh Jaggi
32

Semua sistem terdistribusi memiliki masalah dengan konsistensi transaksional. Cara terbaik untuk melakukan ini adalah seperti yang Anda katakan, memiliki komitmen dua fase. Buat dompet dan pengguna dibuat dalam status tertunda. Setelah dibuat, buat panggilan terpisah untuk mengaktifkan pengguna.

Panggilan terakhir ini harus diulang dengan aman (jika koneksi Anda turun).

Ini akan mengharuskan bahwa panggilan terakhir tahu tentang kedua tabel (sehingga dapat dilakukan dalam satu transaksi JDBC).

Atau, Anda mungkin ingin memikirkan mengapa Anda begitu khawatir tentang pengguna tanpa dompet. Apakah Anda yakin ini akan menimbulkan masalah? Jika demikian, mungkin memiliki mereka sebagai panggilan istirahat terpisah adalah ide yang buruk. Jika seorang pengguna tidak boleh ada tanpa dompet, maka Anda mungkin harus menambahkan dompet ke pengguna (dalam panggilan POST asli untuk membuat pengguna).

Rob Conklin
sumber
Terima kasih untuk sarannya. Layanan Pengguna / Dompet adalah fiksi, hanya untuk menggambarkan intinya. Tetapi saya setuju bahwa saya harus merancang sistem untuk menghindari kebutuhan transaksi sebanyak mungkin.
Olivier Lalonde
7
Saya setuju dengan sudut pandang kedua. Sepertinya, apa yang microservice Anda, yang membuat pengguna, juga harus membuat dompet, karena operasi ini merupakan unit kerja atom. Anda juga dapat membaca ini eaipatterns.com/docs/IEEE_Software_Design_2PC.pdf
Sattar Imamov
2
Ini sebenarnya ide yang bagus . Membatalkan adalah sakit kepala. Tetapi menciptakan sesuatu dalam kondisi tertunda jauh lebih tidak invasif. Semua pemeriksaan telah dilakukan, tetapi belum ada yang pasti dibuat. Sekarang kita hanya perlu mengaktifkan komponen yang dibuat. Kita bahkan dapat melakukannya tanpa transaksi.
Timo
10

IMHO salah satu aspek kunci dari arsitektur layanan microsoft adalah bahwa transaksi terbatas pada layanan microser individual (Prinsip tanggung jawab tunggal).

Dalam contoh saat ini, pembuatan Pengguna akan menjadi transaksi sendiri. Pembuatan pengguna akan mendorong acara USER_CREATED ke dalam antrian acara. Layanan Wallet akan berlangganan acara USER_CREATED dan melakukan pembuatan Wallet.

mithrandir
sumber
1
Dengan asumsi kami ingin menghindari setiap dan semua 2PC, dan dengan asumsi bahwa layanan Pengguna menulis ke dalam basis data, maka kami tidak dapat mendorong pesan ke dalam antrian acara oleh Pengguna untuk menjadi transaksi, yang berarti mungkin tidak pernah membuatnya menjadi layanan Dompet.
Roman Kharkovski
@RomanKharkovski Memang poin penting. Salah satu cara untuk mengatasinya mungkin dengan memulai transaksi, menyelamatkan Pengguna, menerbitkan acara (bukan bagian dari transaksi), dan kemudian melakukan transaksi. (Kasus terburuk, sangat tidak mungkin, komit gagal, dan mereka yang merespons acara tidak akan dapat menemukan pengguna.)
Timo
1
Kemudian simpan acara ke dalam basis data serta entitas. Minta pekerjaan terjadwal untuk memproses acara yang disimpan dan mengirimkannya ke pialang pesan. stackoverflow.com/a/52216427/4587961
Yan Khonski
7

Jika dompet saya hanyalah kumpulan catatan lain dalam basis data sql yang sama dengan pengguna, maka saya mungkin akan menempatkan kode pembuatan pengguna dan dompet di layanan yang sama dan mengatasinya dengan menggunakan fasilitas transaksi basis data normal.

Kedengarannya bagi saya Anda bertanya tentang apa yang terjadi ketika kode pembuatan dompet mengharuskan Anda menyentuh sistem atau sistem lain? Id mengatakan itu semua tergantung pada seberapa kompleks dan atau berisiko proses pembuatannya.

Jika itu hanya masalah menyentuh datastore lain yang dapat diandalkan (katakanlah yang tidak dapat berpartisipasi dalam transaksi sql Anda), maka tergantung pada parameter sistem secara keseluruhan, saya mungkin bersedia mengambil risiko dengan peluang kecil yang semakin menghilang bahwa penulisan kedua tidak akan terjadi. Saya mungkin tidak melakukan apa pun, tetapi mengajukan pengecualian dan menangani data yang tidak konsisten melalui transaksi kompensasi atau bahkan beberapa metode ad-hoc. Seperti yang selalu saya katakan kepada pengembang saya: "jika hal semacam ini terjadi di aplikasi, itu tidak akan luput dari perhatian".

Seiring meningkatnya kompleksitas dan risiko pembuatan dompet, Anda harus mengambil langkah-langkah untuk memperbaiki risiko yang terlibat. Katakanlah beberapa langkah mengharuskan memanggil beberapa mitra apis.

Pada titik ini Anda dapat memperkenalkan antrian pesan bersama dengan gagasan tentang pengguna yang dibangun sebagian dan / atau dompet.

Strategi yang sederhana dan efektif untuk memastikan entitas Anda pada akhirnya akan dibangun dengan benar adalah memiliki pekerjaan coba lagi sampai mereka berhasil, tetapi banyak tergantung pada kasus penggunaan untuk aplikasi Anda.

Saya juga akan berpikir panjang dan keras tentang mengapa saya memiliki langkah yang cenderung gagal dalam proses penyediaan saya.

Robert Moskal
sumber
4

Satu Solusi sederhana adalah Anda membuat pengguna menggunakan Layanan Pengguna dan menggunakan bus perpesanan tempat layanan pengguna memancarkan acara-acaranya, dan Layanan Wallet mendaftar pada bus perpesanan, mendengarkan acara yang Dibuat Pengguna dan membuat Dompet untuk Pengguna. Sementara itu, jika pengguna menggunakan Wallet UI untuk melihat Dompetnya, periksa apakah pengguna baru saja dibuat dan tunjukkan pembuatan dompet Anda sedang berlangsung, silakan periksa beberapa saat lagi

techagrammer
sumber
3

Solusi apa yang tersedia untuk mencegah terjadinya ketidakkonsistenan data seperti ini?

Secara tradisional, manajer transaksi terdistribusi digunakan. Beberapa tahun yang lalu di dunia Java EE Anda mungkin telah membuat layanan ini sebagai EJB yang digunakan untuk node yang berbeda dan gateway API Anda akan membuat panggilan jarak jauh ke EJB tersebut. Server aplikasi (jika dikonfigurasi dengan benar) secara otomatis memastikan, menggunakan dua fase komit, bahwa transaksi dilakukan atau dibatalkan pada setiap node, sehingga konsistensi dijamin. Tetapi itu mengharuskan semua layanan dikerahkan pada jenis server aplikasi yang sama (sehingga mereka kompatibel) dan pada kenyataannya hanya pernah bekerja dengan layanan yang dikerahkan oleh satu perusahaan.

Apakah ada pola yang memungkinkan transaksi untuk menjangkau beberapa permintaan REST?

Untuk SOAP (ok, bukan REST), ada spesifikasi WS-AT tetapi tidak ada layanan yang pernah saya integrasikan yang mendukungnya. Untuk REST, JBoss memiliki sesuatu dalam pipeline . Kalau tidak, "pola" adalah untuk menemukan produk yang dapat Anda pasang ke arsitektur Anda, atau membangun solusi Anda sendiri (tidak disarankan).

Saya telah menerbitkan produk semacam itu untuk Java EE: https://github.com/maxant/genericconnector

Menurut kertas yang Anda referensi, ada juga pola Coba-Batalkan / Konfirmasi dan Produk terkait dari Atomikos.

Mesin BPEL menangani konsistensi antara layanan yang disebarkan dari jarak jauh menggunakan kompensasi.

Atau, saya tahu REST mungkin tidak cocok untuk kasus penggunaan ini. Apakah mungkin cara yang tepat untuk menangani situasi ini untuk menghentikan REST sepenuhnya dan menggunakan protokol komunikasi yang berbeda seperti sistem antrian pesan?

Ada banyak cara untuk "mengikat" sumber daya non-transaksional ke dalam suatu transaksi:

  • Seperti yang Anda sarankan, Anda bisa menggunakan antrian pesan transaksional, tetapi akan asinkron, jadi jika Anda bergantung pada responsnya, pesan itu menjadi berantakan.
  • Anda bisa menulis fakta bahwa Anda perlu memanggil layanan back-end ke dalam database Anda, dan kemudian memanggil layanan back-end menggunakan batch. Sekali lagi, async, jadi bisa berantakan.
  • Anda bisa menggunakan mesin proses bisnis sebagai gateway API Anda untuk mengatur layanan Microsoft back end.
  • Anda bisa menggunakan EJB jarak jauh, seperti yang disebutkan di awal, karena itu mendukung transaksi terdistribusi di luar kotak.

Atau haruskah saya menegakkan konsistensi dalam kode aplikasi saya (misalnya, dengan memiliki pekerjaan latar belakang yang mendeteksi ketidakkonsistenan dan memperbaikinya atau dengan memiliki atribut "status" pada model Pengguna saya dengan nilai "menciptakan", "menciptakan", dll.)?

Bermain sebagai pendukung setan: mengapa membangun sesuatu seperti itu, ketika ada produk yang melakukannya untuk Anda (lihat di atas), dan mungkin melakukannya lebih baik daripada yang Anda bisa, karena mereka dicoba dan diuji?

Ant Kutschera
sumber
2

Secara pribadi saya suka ide Layanan Mikro, modul didefinisikan oleh kasus penggunaan, tetapi sebagai pertanyaan Anda menyebutkan, mereka memiliki masalah adaptasi untuk bisnis klasik seperti bank, asuransi, telekomunikasi, dll ...

Transaksi terdistribusi, seperti yang banyak disebutkan, bukanlah pilihan yang baik, orang-orang sekarang pergi lebih untuk sistem yang pada akhirnya konsisten tetapi saya tidak yakin ini akan bekerja untuk bank, asuransi, dll ....

Saya menulis blog tentang solusi yang saya usulkan, mungkin ini dapat membantu Anda ....

https://mehmetsalgar.wordpress.com/2016/11/05/micro-services-fan-out-transaction-problems-and-solutions-with-spring-bootjboss-and-netflix-eureka/

posthumecaver
sumber
0

Konsistensi akhirnya adalah kuncinya di sini.

  • Salah satu layanan dipilih untuk menjadi penangan utama acara.
  • Layanan ini akan menangani acara asli dengan komit tunggal.
  • Penangan utama akan bertanggung jawab untuk mengkomunikasikan secara tidak langsung efek sekunder ke layanan lain.
  • Penangan utama akan melakukan pengaturan panggilan layanan lainnya.

Komandan bertanggung jawab atas transaksi yang didistribusikan dan mengambil kendali. Ia tahu instruksi yang akan dieksekusi dan akan mengoordinasikan mengeksekusi mereka. Dalam kebanyakan skenario hanya akan ada dua instruksi, tetapi dapat menangani banyak instruksi.

Komandan bertanggung jawab untuk menjamin pelaksanaan semua instruksi, dan itu berarti pensiun. Ketika komandan mencoba untuk melakukan pembaruan jarak jauh dan tidak mendapat respons, ia tidak perlu mencoba lagi. Dengan cara ini sistem dapat dikonfigurasi agar lebih rentan terhadap kegagalan dan menyembuhkan dirinya sendiri.

Karena kami telah mencoba ulang, kami memiliki idempotensi. Idempotence adalah hak milik untuk dapat melakukan sesuatu dua kali sedemikian rupa sehingga hasil akhirnya sama seperti jika dilakukan sekali saja. Kita perlu idempotensi di layanan jarak jauh atau sumber data sehingga, dalam kasus di mana ia menerima instruksi lebih dari sekali, ia hanya memprosesnya sekali.

Konsistensi akhirnya Ini memecahkan sebagian besar tantangan transaksi terdistribusi, namun kami perlu mempertimbangkan beberapa poin di sini. Setiap transaksi yang gagal akan diikuti oleh percobaan ulang, jumlah percobaan ulang tergantung pada konteksnya.

Konsistensi adalah akhirnya yaitu, ketika sistem berada di luar kondisi yang konsisten selama coba lagi, misalnya jika pelanggan telah memesan buku, dan melakukan pembayaran dan kemudian memperbarui jumlah stok. Jika operasi pembaruan stok gagal dan dengan asumsi bahwa itu adalah stok terakhir yang tersedia, buku akan tetap tersedia sampai operasi coba lagi untuk pembaruan stok berhasil. Setelah coba lagi berhasil, sistem Anda akan konsisten.

Viyaan Jhiingade
sumber
-2

Mengapa tidak menggunakan platform API Management (APIM) yang mendukung scripting / pemrograman? Jadi, Anda akan dapat membangun layanan komposit di APIM tanpa mengganggu layanan mikro. Saya telah merancang menggunakan APIGEE untuk tujuan ini.

sra
sumber