Bagaimana Kami Membuat Mesin Workflow Kami

Di DIRECTUM, kami sedang mengembangkan sistem DirectumRX ECM. Elemen inti dari modul Workflow untuk sistem ECM adalah engine. Dia bertanggung jawab untuk mengubah keadaan proses instance (instance) selama siklus hidup. Sebelum Anda mulai mengembangkan modul Workflow, Anda harus memutuskan: ambil mesin yang sudah jadi atau tulis sendiri. Awalnya, kami memilih opsi pertama. Kami mengambil mesin Windows Workflow Foundation (WF), dan secara keseluruhan cocok untuk kami. Namun seiring waktu, kami menyadari bahwa kami membutuhkan mesin kami sendiri. Bagaimana ini terjadi, dan apa yang terjadi, saya akan ceritakan di bawah ini.

Mesin tua


Mengapa wf


Kembali pada tahun 2013, ketika tiba saatnya untuk mengembangkan modul Workflow untuk DirectumRX, kami memutuskan untuk mengambil mesin yang sudah jadi. Dilihat dari Windows Workflow Foundation (WF), ActiveFlow, K2.NET, WorkflowEngine.NET, cDevWorkflow, NetBpm. Beberapa tidak senang dengan nilai, ada yang mentah, beberapa, pada saat itu, belum didukung untuk waktu yang lama.
Akibatnya, pilihan jatuh pada WF. Kami kemudian secara aktif menggunakan tumpukan Microsoft (WCF, WPF) dan memutuskan bahwa W lain tidak akan menyakiti kami. Keuntungan lain adalah status kami sebagai Mitra Pengembangan Aplikasi Microsoft Gold, yang memungkinkan untuk mengembangkan produk menggunakan teknologi Microsoft. Nah, secara umum, kemampuan mesin cocok untuk kami dan mencakup hampir semua kasus kami.

Apa yang salah dengan WF?


Setelah 6 tahun menggunakan WF, kami telah mengakumulasikan sejumlah masalah, dan biaya untuk menyelesaikan masalah ini terlalu tinggi. Kami mulai berpikir untuk mengembangkan mesin kami sendiri. Saya akan memberi tahu Anda tentang beberapa di antaranya.

Diagnostik mahal dan perbaikan bug


Tahun-tahun berlalu, jumlah instalasi produk dan beban bertambah. Bug mulai muncul, diagnosis dan koreksi yang membutuhkan banyak sumber daya. Ini difasilitasi oleh alasan yang kompleks: kurangnya kompetensi, kesalahan desain ketika menanamkan mesin sebelumnya, dan fitur WF.
Kami memiliki cukup kompetensi dasar untuk dibangun di WF DirectumRX, tingkat yang sama sudah cukup untuk menangani bug sederhana. Untuk kasus yang kompleks, kompetensi menjadi kurang - analisis log, analisis keadaan contoh, dan sebagainya, sulit.
Dimungkinkan untuk mengirim seseorang ke kursus tentang WF, tetapi mereka hampir tidak diajari cara menganalisis keadaan instance dan mengaitkan perubahannya dengan log. Dan terus terang, tidak ada yang memiliki keinginan khusus untuk meningkatkan keterampilan mereka dengan teknologi yang hampir mati.
Cara lain adalah dengan merekrut seseorang dengan kompetensi yang sesuai. Tetapi menemukan satu di Izhevsk bukanlah tugas sepele, dan bukan fakta bahwa levelnya cukup untuk menyelesaikan masalah kita.
Bahkan, kita dihadapkan dengan ambang masuk yang tinggi untuk mendukung WF. Dengan satu atau lain cara, saya pikir kita akan menangani masalah ini, jika bukan karena sejumlah alasan lain.
Masalah lain adalah ketika membuat diagram proses, kami menggunakan notasi kami sendiri. Lebih visual dan lebih mudah dikembangkan. Misalnya, WF tidak memungkinkan untuk mengimplementasikan grafik penuh, Anda tidak dapat menggambar buntu, ada fitur menggambar cabang paralel. Pengembalian untuk ini adalah konversi sirkuit kami ke sirkuit WF, yang tidak begitu sederhana dan memaksakan sejumlah batasan. Ketika debugging, saya harus menganalisis keadaan sirkuit WF, karena ini, visibilitas hilang, saya harus membandingkan blok dan wajah satu sama lain untuk memahami apa langkah instance itu.
gambar

Representasi rangkaian dalam DirectumRX
gambar

Representasi rangkaian dalam WF
Juga, kami dihadapkan dengan fakta bahwa dokumentasi WF menggambarkan repositori instance dengan buruk. Seperti yang saya tulis di atas, ini diperlukan ketika menganalisis bug untuk memahami keadaan proses contoh. Selain itu, bagian dari data dienkripsi, yang juga mengganggu analisis.

Postgres sebagai DBMS


Selama bertahun-tahun sekarang, ada kecenderungan di Rusia untuk substitusi impor, dan semakin sering salah satu persyaratan untuk platform tersebut adalah dukungan sistem manajemen basis data sumber terbuka (DBMS) atau DBMS produksi dalam negeri. Paling sering itu Postgres. Di luar kotak, WF hanya mendukung MS SQL. Untuk bekerja dengan database lain, Anda bisa menggunakan penyedia pihak ketiga. Kami memilih dotConnect dari DevArt.
Sementara bebannya ringan, semuanya bekerja dengan baik. Tapi begitu kami mengendarai sistem di bawah beban, masalah muncul. WF tiba-tiba bisa berhenti dan berhenti memproses contoh (transaksi selesai), atau semua pesan masuk ke MSMQ Poisoned Queue, dll. Kami menangani semua masalah ini, tetapi menghabiskan banyak waktu untuk itu. Tidak ada jaminan bahwa yang baru tidak akan muncul, solusinya harus menghabiskan jumlah yang sama.

Peduli pada inti bersih


Setelah Microsoft mengumumkan .Net Core, kami memutuskan bahwa kami secara bertahap akan menuju untuk mencapai cross-platform untuk solusi kami. Microsoft memutuskan untuk tidak menggunakan WF, yang memblokir cara kami mentransfer modul Workflow ke .Net Core dalam bentuk yang ada. Kami menyadari bahwa ada port WF tidak resmi di .Net Core, dan di antara mereka bahkan ada dari pengembang WF, tetapi semuanya tidak 100% kompatibel. Faktor lain adalah penolakan Microsoft untuk mengembangkan .Net. mendukung .Net Core.

Mesin baru


Mengambil semua tumpukan masalah ini, opsi solusi, kompleksitas refactoring dan koreksi, menimbang semua pro dan kontra, kami memutuskan untuk beralih ke mesin baru. Kami mulai dengan menganalisis yang sudah ada.

Pilihan


Persyaratan utama saat memilih mesin adalah:
  • bekerja pada .Net Core;
  • skalabilitas
  • konversi instance proses yang ada, dengan kemampuan untuk melanjutkan eksekusi setelah konversi
  • biaya yang wajar untuk menganalisis masalah yang ada
  • bekerja dengan DBMS berbeda

Selain itu, diperlukan bahwa Kegiatan (Aktivitas) dapat mengeksekusi kode aplikasi dalam C #, dimungkinkan untuk men-debug blok, dll.
Sebagai bagian dari analisis mesin yang ada, kami melihat:
  1. Inti wf
  2. Flowwright
  3. Alur kerja K2
  4. Inti alur kerja
  5. Zeebe
  6. Mesin alur kerja
  7. Kerangka Kerja Tahan Lama
  8. Camunda
  9. Kegiatan Orleans

Setelah memberlakukan semua persyaratan pada solusi yang ditinjau dan menambahkan biaya solusi berbayar, kami menganggap bahwa mesin kami tidak terlalu mahal, sementara itu akan 100% cocok untuk permintaan kami dan akan mudah disempurnakan.

Implementasi / Arsitektur


Dalam implementasi sebelumnya, modul WF adalah layanan WCF yang terhubung dengan perpustakaan WF. Dia mampu membuat instance proses, memulai proses, menjalankan blok, termasuk logika bisnis (kode yang ditulis oleh pengembang). Semua ini di-host di aplikasi IIS.
Dalam implementasi baru, mengikuti tren arsitektur layanan mikro, kami memutuskan untuk segera membagi layanan menjadi dua: Workflow Process Service (WPS) dan Workflow Block Service (WBS), yang dapat di-host secara terpisah. Tautan lain dalam rantai ini adalah Layanan Aplikasi, yang mengimplementasikan sistem DirectumRX dan logika bisnis, dan klien bekerja dengannya.
WPS "berjalan" sesuai dengan skema, WBS memproses blok dan menjalankan logika bisnis di setiap langkah. Perintah untuk memulai proses berasal dari Server Aplikasi. Interaksi antara layanan dilakukan menggunakan RabbitMQ. Di bawah ini saya akan bercerita lebih banyak tentang mereka masing-masing.


Wps


Workflow Process Service adalah layanan microser yang bertanggung jawab untuk memulai proses dan melewati diagram proses.
Repositori layanan berisi diagram proses dengan dukungan untuk versi dan keadaan serial proses serial. Anda dapat menggunakan MS SQL dan Postgres sebagai penyimpanan.
Layanan ini dapat memproses pesan yang diterima dari layanan lain melalui RabbitMQ. Pada dasarnya, pesan adalah API layanan. Jenis pesan yang dapat diterima layanan:
  • StartProcess - membuat instance proses baru dan mulai merangkak di atasnya;
  • CompleteBlock - penyelesaian blok, setelah pesan ini, layanan memindahkan instance proses lebih jauh di sepanjang skema;
  • Tangguhkan / Lanjutkan Proses - menangguhkan eksekusi instance proses, misalnya, karena kesalahan saat memproses blok, dan melanjutkan eksekusi setelah kesalahan diperbaiki;
  • Abort / RestartProcess - hentikan eksekusi proses instance dan mulai lagi;
  • DeleteProcess - hapus instance proses.

Skema ini terdiri dari blok dan koneksi di antara mereka (wajah). Setiap wajah memiliki pengenal, yang disebut "Hasil Eksekusi". Ada 5 jenis blok:
  • StartBlock
  • Blokir
  • OrBlock;
  • AndBlock;
  • FinishBlock.

gambar

Tampilan skema WPS
Ketika sebuah pesan tiba di awal proses, layanan menciptakan sebuah instance dan mulai "berjalan" sesuai dengan skema. Kelas yang bertanggung jawab untuk "berjalan" sesuai dengan skema, kami bercanda menyebut "Stepator". Sirkuit selalu dimulai dengan StartBlock. Kemudian strider mengambil semua wajah keluar dan mengaktifkannya. Setiap blok bekerja berdasarkan prinsip blok "DAN", mis. semua wajah yang masuk harus aktif sehingga blok dapat diaktifkan. Algoritme kemudian memutuskan blok mana yang dapat diaktifkan dan mengirim pesan WBS untuk mengaktifkan blok ini. WBS memproses blok dan mengembalikan hasil WPS. Bergantung pada hasil eksekusi, strider memilih wajah yang sesuai yang keluar dari blok untuk aktivasi, dan proses berlanjut.
Selama pengembangan, kami menemukan situasi menarik terkait dengan koneksi siklik antar blok, yang menambahkan logika saat memutuskan blok mana yang akan diaktifkan / dihentikan.
Layanan bersifat otonom, mis. cukup sampaikan skema dalam format Json, tulis block handler Anda sendiri, dan Anda dapat bertukar pesan.

Wbs


Layanan Block Workflow adalah layanan yang memproses diagram blok. Layanan tahu tentang esensi logika bisnis, seperti tugas, tugas, dll. Entitas ini dapat ditambahkan ke lingkungan pengembangan DirectumRX Development Studio (DDS). Misalnya, blok kami memiliki acara untuk memulai blok. Kode untuk pengendali acara ini ditulis oleh pengembang di DDS, dan WBS mengeksekusi kode ini. Sebenarnya, ini adalah implementasi kami dari handler blok, Anda dapat menggantinya dengan Anda sendiri.
Layanan menyimpan status blok. Selain sifat dasar (Id, Negara), blok dapat berisi informasi lain yang diperlukan untuk eksekusi / penghentian / penangguhan blok.
Blok mungkin dalam keadaan:
  • Selesai - masuk ke kondisi ini setelah berhasil menyelesaikan pekerjaan di blok;
  • Tertunda - dalam keadaan menunggu ketika beberapa pekerjaan dilakukan di dalam blok, misalnya, beberapa jenis respons diperlukan dari pengguna;
  • Dibatalkan - masuk ke kondisi ini ketika proses dihentikan;
  • Ditangguhkan - masuk ke status ini saat proses berhenti saat terjadi kesalahan.

Ketika sebuah pesan tiba pada eksekusi blok, blok dieksekusi, dan WBS mengirim pesan dengan hasil eksekusi blok.

Skalabilitas


WPS dan WBS dapat digunakan dalam banyak hal. Pada satu titik waktu, hanya satu layanan WPS yang dapat memproses satu proses instance. Hal yang sama berlaku untuk blok pemrosesan - contoh proses satu dapat memproses hanya satu blok pada suatu waktu. Ini dibantu oleh kunci yang diletakkan pada proses selama pemrosesan. Jika ada beberapa pesan dalam antrian untuk memproses suatu proses / blok dalam satu proses, maka pesan tersebut ditunda selama beberapa waktu. Pada saat yang sama, setiap layanan dapat secara bersamaan melakukan pekerjaan pada beberapa proses proses.
Situasi mungkin muncul ketika beberapa pesan datang dalam satu proses demi proses untuk memproses blok (cabang paralel). Untuk mengurangi jumlah situasi ketika Anda harus menunda pesan, WBS mengambil beberapa pesan sekaligus dan mengeksekusi mereka satu demi satu, melewati pengiriman ke antrian untuk eksekusi berulang karena memblokir proses.

Konversi


Setelah transisi ke mesin baru, muncul pertanyaan, apa yang harus dilakukan dengan mesin virtual yang ada? Pilihan yang lebih disukai adalah konversi mereka, sehingga mereka terus bekerja pada mesin baru. Keuntungannya jelas: kami hanya mendukung satu mesin, masalah mendukung mesin lama hilang (lihat di atas). Tetapi ada risiko bahwa kami tidak akan dapat sepenuhnya mengetahui cara mendapatkan data yang kami butuhkan dari proses serial. Ada juga fallback: untuk memberikan contoh yang ada diselesaikan pada mesin lama, dan meluncurkan yang baru pada yang baru. Kelemahan dari opsi ini berasal dari keunggulan yang sebelumnya, ditambah sumber daya tambahan yang diperlukan untuk memutar kedua mesin.
Untuk konversi, kami perlu mengambil status proses yang lama dalam format WF dan menghasilkan status proses dan blok. Kami menulis sebuah utilitas yang mengambil keadaan serial dari instance proses dalam database, menarik darinya daftar blok aktif, hasil eksekusi untuk wajah, dan hampir mengeksekusi proses. Akibatnya, kami mendapatkan status instance pada saat konversi.
Kesulitan muncul dalam cara deserialize data contoh proses dengan benar di WF. Keadaan proses (instance) contoh WF disimpan dalam database sebagai xaml. Kami tidak dapat menemukan deskripsi yang jelas tentang struktur xaml ini, kami harus melakukan semuanya secara empiris. Mengurai data secara manual dan mengeluarkan informasi yang kami butuhkan. Sebagai bagian dari tugas ini, kami membuat pilihan lain - menggunakan alat WF untuk menghilangkan status keadaan instance dan mencoba untuk mendapatkan informasi dari objek. Tetapi karena fakta bahwa struktur benda-benda seperti itu sangat kompleks, kami meninggalkan ide ini dan memilih xaml parsing "manual".
Akibatnya, konversi berhasil, dan semua proses contoh mulai diproses oleh mesin baru.

Kesimpulan


Jadi apa yang diberikan oleh mesin Workflow? Sebenarnya, kami berhasil mengalahkan semua masalah yang disuarakan di awal artikel:
  • Mesinnya ditulis dalam .NET Core;
  • ini adalah layanan self-host independen dari IIS;
  • sebagai operasi pengujian, kami secara aktif menggunakan mesin baru dalam sistem perusahaan dan berhasil memastikan bahwa analisis bug membutuhkan waktu lebih sedikit;
  • melakukan pengujian beban pada Postgres, menurut data awal, bundel WPS + WBS mengatasi beban dari 5000 pengguna secara bersamaan tanpa masalah;
  • dan tentu saja, seperti karya menarik lainnya, ini merupakan pengalaman yang menarik.

Sebagai bonus, kami mendapat kode yang jelas dan didukung yang dapat kami sesuaikan dengan diri kami sendiri.
Biaya mesin ternyata sebanding dengan apa yang harus kami keluarkan untuk pembelian / adaptasi produk pihak ketiga. Saat ini, kami percaya bahwa keputusan untuk mengembangkan mesin Anda sendiri ternyata dapat dibenarkan.
Kami juga menunggu pengujian beban untuk lebih dari 10.000 pengguna secara bersamaan. Mungkin beberapa optimasi akan diperlukan, atau mungkin akan lepas landas? ;-)
Kami baru-baru ini merilis DirectumRX 3.2, yang termasuk Workflow baru. Mari kita lihat bagaimana mesin akan menampilkan dirinya kepada pelanggan.

Source: https://habr.com/ru/post/id468803/


All Articles