Latar Belakang
Saya bekerja di tim yang ingin menerapkan penerapan zero-downtime. Kami berencana menggunakan strategi penyebaran biru / hijau untuk mencapai ini. Salah satu hal yang saya sadari dalam melakukan penelitian adalah betapa rumitnya membuat perubahan database. Operasi sederhana seperti mengganti nama kolom dapat memakan waktu 3 siklus rilis penuh hingga selesai!
Tampaknya bagi saya bahwa dengan peluncuran penuh dari perubahan, ambil beberapa siklus rilis memperkenalkan banyak potensi kesalahan manusia. Dalam artikel tertaut itu menunjukkan bahwa perubahan kode diperlukan untuk 2 rilis dan migrasi database diperlukan untuk 3 rilis.
Apa yang saya cari
Saat ini, jika kita ingin mengingat untuk melakukan sesuatu, kita dapat membuat tiket dalam sistem manajemen masalah kita, yang menciptakan kekacauan dan juga mungkin akan dipindahkan ke sprint atau backlog oleh manajemen; atau kita dapat membuat komentar TODO, yang mungkin akan dilupakan sepenuhnya.
Apa yang saya cari adalah cara agar komentar TODO dapat memiliki tenggat waktu untuk menentangnya, dan sistem Integrasi Berkelanjutan kami (saat ini yang belum diputuskan yang akan kami gunakan) akan menolak pembangunan jika tenggat waktu ini kedaluwarsa.
Misalnya, jika kami mengganti nama kolom, kami dapat membuat migrasi awal untuknya, dan kemudian dua komentar TODO untuk memastikan bahwa dua migrasi lainnya dibuat:
// TODO by v55: Create migration to move constraints to new column, remove references to old column in app
// TODO by v56: Create migration to drop old column
Ini tampaknya cukup sederhana untuk diterapkan, tetapi saya ingin tahu apakah sesuatu seperti ini sudah ada, karena saya tidak ingin menemukan kembali roda.
Pikiran tambahan
Saya merasa mungkin saya menderita masalah XY di sini, mengingat bahwa penyebaran bergulir dan penyebaran biru / hijau dianggap sebagai praktik terbaik, rasanya aneh bahwa saya tidak dapat menemukan solusi untuk membuat pembaruan basis data tidak begitu menyakitkan. Jika Anda pikir saya melihat ke hal yang salah sepenuhnya, tolong beri tahu saya dalam komentar! Yang mengatakan, contoh database yang saya berikan hanyalah satu contoh, dan saya pikir komentar TODO dengan tanggal jatuh tempo akan berguna dalam situasi lain juga, jadi bahkan jika saya mendekati situasi spesifik ini semua salah, saya benar-benar ingin menjawab pertanyaan saya pertanyaan sebenarnya juga. Terima kasih!
EDIT: Saya hanya memikirkan situasi lain di mana ini bisa membantu. Jika Anda menggunakan Fitur Toggles untuk menghidupkan bagian-bagian aplikasi Anda ketika mereka sudah siap, Anda harus berhati-hati untuk membersihkannya, jika tidak, Anda akan berakhir dengan Toggle Debt . Komentar dengan tenggat waktu bisa menjadi cara yang baik untuk mengingat ini.
sumber
TODO <Bug#>:
untuk melacak solusi untuk masalah dengan komponen lainnya. Ketika bug dihapus pada salah satu komponen itu, Anda dapat dengan mudah menemukan & mengatasi solusi yang relevan. Itu tidak menggantikan pelacak masalah, itu membuatnya lebih mudah untuk dipelihara.Jawaban:
Pertanyaan ini sebenarnya adalah dua pertanyaan dalam satu.
Komentar Todo
Dari semua cara untuk melacak item tindakan, ini adalah yang terburuk. Komentar TODO baik selama bekerja aktif atau sebagai cara saran kepada pengelola, "ini adalah sesuatu yang mungkin dapat ditingkatkan di masa depan". Tetapi jika Anda mengandalkan komentar TODO untuk menyelesaikan pekerjaan, Anda pasti akan gagal.
Apa yang harus dilakukan tentang hal itu
Komentar TODO pada dasarnya adalah utang teknis, sehingga harus ditangani seperti utang teknis lainnya. Baik mengatasinya segera, jika Anda punya waktu, atau meletakkannya di tumpukan sehingga mereka dapat dilacak dan diprioritaskan.
Secara umum, dan ini sepenuhnya pendapat dan terbuka untuk diperdebatkan, komentar TODO dapat dianggap sebagai bau kode. Jika komentar TODO membuatnya sejauh diperiksa ke dalam kontrol versi, Anda harus bertanya pada diri sendiri, apakah Anda benar-benar akan menindaklanjutinya sekarang? Jika tidak, tidak apa-apa. Jujur saja dengan diri Anda sendiri dan taruh di backlog.
Bagaimana Anda mengelola simpanan ini bermuara pada proses bisnis, politik perusahaan, dan mungkin beberapa otonomi pribadi. Tetapi Anda masih membutuhkan backlog yang dilacak dan diprioritaskan untuk memastikan hal itu terjadi.
Perubahan basis data
Ya, perubahan basis data rumit dengan kebijakan zero-downtime. Beberapa trik untuk membuatnya tidak terlalu menyakitkan:
Proses pasca penyebaran
Buat proses pasca-penyebaran yang berjalan sebagai bagian dari rilis yang sama. Bagaimanapun Anda ingin itu berhasil. Pada sistem terakhir yang saya kerjakan, saya merancang penyebaran 4 fase:
Idenya adalah bahwa sedapat mungkin, kami akan menempatkan sebanyak mungkin perubahan database ke dalam preapp.
Postapp dicadangkan untuk kasus-kasus yang tidak biasa di mana kami perlu membuat perubahan skema yang tidak kompatibel. Dalam kasus tersebut, preapp akan membuat cukup banyak perubahan untuk membuat kode aplikasi baru yang kompatibel (mungkin membuat tampilan sementara untuk kompatibilitas), dan postapp akan membersihkan artefak sementara semacam itu.
Fase jendela perawatan dicadangkan untuk perubahan yang benar-benar membutuhkan waktu henti atau di mana risiko atau biaya penyebaran langsung tidak sepadan. Misalnya, skrip yang mengubah sejumlah besar data mungkin perlu mengunci seluruh tabel.
Sebarkan sesering mungkin
Jika Anda menggunakan rilis baru cukup sering, Anda dapat mencapai titik di mana membawa perubahan di 2 atau 3 rilis itu sepele. Siklus rilis yang panjang memperkuat biaya perubahan basis data.
sumber
Jangan gunakan TODO. Anda sudah memiliki daftar TODO di proyek Anda. Ini disebut pelacak masalah.
Saya pikir masalah sebenarnya ada di kalimat ini:
Jika pelacak masalah Anda membuat banyak kekacauan, temukan cara untuk memperbaikinya. Mungkin jenis masalah khusus / tag yang melibatkan upacara kurang. Mungkin sub-isu. Mungkin kurang upacara sama sekali. Kami tidak bisa mengatakannya. Tetapi jika pelacak masalah Anda menghasilkan begitu banyak pekerjaan, sehingga orang lebih suka merumuskan pertanyaan yang rumit di forum publik daripada hanya menambahkan masalah itu, ada sesuatu yang salah.
Jika manajemen Anda terlalu menunda bagian terakhir tugas, Anda memiliki dua opsi:
bicarakan dengan manajemen Anda mengapa ini adalah ide yang buruk.
menanganinya sebagai satu tugas. Ini mungkin solusi standar emas. Di dunia yang sempurna, Anda harus dapat membuat tiga perubahan yang dibutuhkan di setiap langkah. Terapkan satu ke cabang master, biarkan ia membangun dan menggunakan. Sementara itu terapkan yang kedua ke cabang master, biarkan ia membangun dan menyebarkan dan seterusnya sehingga semuanya terjadi dalam sprint yang sama, dan jika tidak, itu tidak dilakukan. Mungkin bahkan sesuatu otomatis masuk akal di mana Anda secara logis melakukan satu penyebaran, tetapi sebenarnya dibagi menjadi 3.
sumber
// TODO(#12345): Frobnicate the sprocket before passing it along
, asalkan bug # 12345 adalah nomor masalah "nyata" dan masalah tersebut diberikan kepada seseorang. Ini membuat sumber lebih mudah dibaca dengan mengklarifikasi: "Tidak, langkah frobnicate tidak bersembunyi di salah satu metode pembantu, itu hanya tidak diterapkan. Lihat bug # 12345 untuk lebih banyak konteks." Idealnya, Anda akan memiliki linter harian melindas basis kode mencari nomor masalah yang ditutup atau tidak valid, tentu saja.Apa yang Anda minta bisa dilakukan jika Anda bersedia melakukan pekerjaan dan menindaklanjutinya.
grep
//TODO by v55
ketika saatnya untuk menggunakan v55. Deploy build menjalankan skrip yang melakukan itu sebagai tes integrasi.Anda dapat mengikat 55 ke dalam pelacakan versi Anda atau hanya meminta untuk itu.
Ini menjadi menarik jika Anda ingin memeriksa // TODO oleh v54 ketika melakukan 55. Daripada mencari basis kode 55 kali hanya mencari // TODO oleh. Kemudian saring hasil itu untuk 1 hingga 55. Sekarang 56 tidak akan memicu kegagalan.
Anda mungkin berpikir "oh kami tidak akan membutuhkannya. Kami akan memperbaikinya setiap saat selama kami memiliki cek". Tidak, tidak kamu tidak akan.
sumber
Kami memiliki masalah yang sangat mirip di tim kami. Untuk mengatasi ini kami menulis pemeriksaan analisis statis yang menangani TODO ini dengan memeriksa masalah JIRA atau Masalah Git yang mereka rujuk. Bangunan kami gagal ketika Masalah yang ditentukan bergerak melewati kolom "Dalam Pengembangan".
Oleh karena itu kita dapat dengan nyaman memiliki TODO tanpa khawatir mereka akan dilupakan.
Saya membuat implementasi open-source untuk ini, di Jawa. Ya, penafian adalah bahwa saya menulis ini, tetapi seperti yang saya katakan itu sepenuhnya bersumber terbuka dan berlisensi.
Alat ini disebut Westie dan contoh pemeriksa masalah Jira ada di README.md. Lihat juga GitIssueAnalyser.
Untuk mencegah mempromosikan diri jika Anda memiliki pertanyaan lebih lanjut, kirimkan saya pesan. Jika Anda memutuskan untuk menggunakannya dan memiliki saran, silakan ajukan masalah apa pun di github.
sumber
Jangan Lakukan. Lakukan sekarang.
TLDR: Tulis (dan uji) skrip DB Anda sekarang, bukan nanti; hanya kode mereka sehingga eksekusi mereka bergantung pada versi DB.
Contoh
Sebagai contoh, mari kita bayangkan bahwa Anda ingin mengubah nama kolom dari
SSN
menjadiTaxID
, persyaratan umum saat menjadi internasional.Untuk mewujudkannya, mungkin Anda akan sementara memiliki kolom
TaxID
dan aSSN
. Dan sementara mendukung kedua versi, Anda akan memiliki pemicu untuk memperbarui satu dari yang lain. Tetapi Anda tidak ingin menyimpan pemicu itu untuk waktu yang tidak terbatas, jadi nanti, ketika kompatibilitas mundur tidak diperlukan lagi, Anda ingin pemicu itu dihapus (danSSN
kolomnya jatuh). Kami akan mengkodekan semua itu di depan tanpa perlu item ToDo.Dalam contoh kami, kami akan menggunakan build 102 (yang memiliki kolom baru) sambil mempertahankan kompatibilitas dengan build 101 (yang tidak).
Inilah langkah-langkahnya.
1. Siapkan tabel versi
Tambahkan satu tabel yang disebut
Configuration
dengan dua kolom,Name
danValue
.Tambahkan baris dengan
Name
"TargetVersion" dan setelValue
ke versi bangunan baru yang akan digunakan.Tambahkan baris dengan
Name
"CompatibleWith" dan setelValue
ke nomor versi minimum yang penyebarannya harus kompatibel.Periksa dan perbarui baris ini sebelum setiap penempatan.
2. Ubah skrip penerapan
Tambahkan skrip yang membuat kolom baru
TaxID
, berdampingan denganSSN
, dan mengisinya dariSSN
kolom. Lampirkan kode ini dalamIf
pernyataan yang memeriksa TargetVersion; jika versi target terlalu rendah (artinyaTaxID
belum diperlukan), lewati.Tambahkan skrip yang membuat pemicu yang mengisi
TaxID
saat memasukkan atau memperbaruiSSN
dan sebaliknya. Lampirkan kode ini dalamIf
pernyataan yang memeriksa versi target dan versi yang kompatibel; lewati jika TargetVersion terlalu rendah (TaxID
tidak diperlukan) atau jika versi CompatibleWith terlalu tinggi (SSN
bidang tidak diperlukan).Tambahkan skrip untuk menghapus
SSN
kolom. Lampirkan dalamIf
pernyataan yang menghapus kolom hanya jika versi CompatibleWith cukup tinggi (SSN
tidak diperlukan lagi).3. Pengujian
Pastikan untuk menguji penyebaran Anda dengan kombinasi nomor versi Biru / Hijau yang ingin Anda dukung dalam produksi. Anda dapat menguji segera setelah kode siap, dengan memanipulasi
Configuration
tabel di lingkungan QA Anda.4. Di playbook penerapan Anda
Tambahkan langkah untuk seorang insinyur untuk memperbarui versi CompatibleWith dan baris TargetVersion. Jika Anda menggunakan Blue, atur TargetVersion ke nomor versi Blue dan versi CompatibleWith ke nomor versi Green; balikkan jika Anda menggunakan Green.
Perangkap
Tidak masalah untuk skrip penerapan Anda untuk referensi dan bergantung pada nomor versi yang dimiliki dalam tabel DB itu. BUKAN kode runtime.
Jika Anda mulai menulis kode runtime untuk memeriksa nomor versi, Anda memperkenalkan tingkat kerumitan baru dalam aplikasi Anda yang berpotensi menjadi masalah pemeliharaan yang besar. Setiap jalur eksekusi runtime harus diuji; jika Anda membawa kondisi-kondisi ini ke depan, QA harus mengumpulkan matriks rasa sakit untuk memvalidasinya dengan setiap rilis. Saran saya adalah menjaga kondisi seperti ini di skrip penerapan saja.
Hasil dari semua ini
Pada akhirnya, Anda harus dapat menulis semua kode di muka (dan mengujinya juga) tanpa takut akan mengeksekusi terlalu dini. Juga, kode akan membersihkan pemicu kompatibilitas mundur ketika saatnya tiba tanpa Anda perlu khawatir tentang hal itu lebih lanjut.
Dengan cara ini Anda dapat menulis dan menguji semua kode di muka, ketika Anda memikirkannya, dan Anda tidak perlu berurusan dengan komentar ToDo yang berantakan itu.
sumber
Anda mendapatkan banyak pushback pada ide TODO Anda, tetapi saya pribadi tidak melihat masalah dengan itu. Pada akhirnya, cara terbaik (dan termudah) untuk memastikan migrasi masuk ke produksi adalah dengan gagal tes unit jika tidak. Ini benar-benar akan membawa Anda kurang dari satu menit untuk mematikan fungsi migrasi kosong yang melempar pengecualian jika versinya 55 atau lebih (atau apa pun persyaratannya).
Kemudian jika Anda mencoba untuk melepaskannya, Anda akan berakhir dengan tes gagal, dan seseorang harus mengubah pengecualian itu menjadi kode migrasi yang sebenarnya.
sumber
Tidak seorang pun tampaknya berfokus pada akar keluhannya yang merupakan fakta bahwa perubahan basis data dapat mengambil terlalu banyak siklus rilis. Dia ingin melanjutkan dengan jadwal penyebaran biru / hijau dan solusinya seharusnya sudah ada di sana tetapi kecuali saya kehilangan sesuatu uraiannya tampaknya menunjukkan bahwa hanya ada satu database yang dibagi oleh kedua sistem. Bukan sistem Biru / Hijau sejati jika itu yang terjadi. Karena tampaknya database adalah tiang panjang di tenda, maka harus digandakan juga sehingga tidak peduli berapa lama atau berapa banyak siklus rilis yang diperlukan untuk mengimplementasikan perubahan database pada sistem offline, mereka tidak ditayangkan sampai selesai dan sepenuhnya diuji. Dalam skrip sistem offline sementara dapat menjaga database offline sepenuhnya diperbarui setiap hari.
sumber