
Semakin cepat proses pengembangan, semakin cepat perusahaan teknologi berkembang.
Sayangnya, aplikasi modern bekerja melawan kita - sistem kita harus diperbarui secara real time dan pada saat yang sama tidak mengganggu siapa pun dan tidak mengarah ke downtime dan interupsi. Penempatan dalam sistem seperti itu menjadi tugas yang sulit dan membutuhkan jaringan pengiriman kontinu yang kompleks bahkan dalam tim kecil.
Pipa-pipa ini biasanya memiliki aplikasi yang sempit, bekerja lambat dan tidak dapat diandalkan. Pengembang pertama-tama harus membuatnya secara manual, dan kemudian mengelolanya, dan perusahaan sering kali mempekerjakan seluruh tim DevOps untuk ini.
Kecepatan pengembangan tergantung pada kecepatan pipa-pipa ini. Untuk tim-tim terbaik, penempatan membutuhkan waktu 5-10 menit, tetapi biasanya itu membutuhkan waktu lebih lama, dan untuk satu penempatan dibutuhkan beberapa jam.
Dalam Gelap, dibutuhkan 50 ms. Lima puluh Milidetik Dark adalah solusi lengkap dengan bahasa pemrograman, editor dan infrastruktur yang dirancang khusus untuk pengiriman terus-menerus, dan semua aspek Dark, termasuk bahasa itu sendiri, dibangun dengan tampilan penyebaran instan yang aman.
Mengapa konveyor kontinu sangat lambat?
Katakanlah kita memiliki aplikasi web Python dan kita telah membuat pipa pengiriman kontinu yang indah dan modern. Untuk pengembang yang sibuk dengan proyek ini setiap hari, menggunakan satu perubahan kecil akan terlihat seperti ini:
Membuat perubahan
- Membuat cabang baru di git
- Membuat Perubahan Di Balik Sakelar Fungsi
- Pengujian unit untuk memverifikasi perubahan dengan dan tanpa sakelar fungsi
Permintaan kolam renang
- Berkomit berkomitmen
- Posting perubahan ke repositori jarak jauh di github
- Permintaan kolam renang
- CI dibangun secara otomatis di latar belakang
- Ulasan kode
- Beberapa ulasan lagi, jika perlu
- Gabungkan perubahan dengan git wizard.
CI berjalan pada wizard
- Mengatur dependensi frontend melalui npm
- Membangun dan mengoptimalkan sumber daya HTML + CSS + JS
- Jalankan di ujung depan unit dan tes fungsi
- Instal dependensi Python dari PyPI
- Jalankan di backend unit dan tes fungsional
- Pengujian integrasi di kedua ujungnya
- Kirim sumber daya frontend ke CDN
- Membangun wadah untuk program Python
- Mengirim wadah ke registri
- Manifes pembaruan Kubernetes
Mengganti kode lama dengan yang baru
- Kubernetes meluncurkan banyak contoh wadah baru
- Kubernetes sedang menunggu mesin virtual mulai beroperasi
- Kubernetes menambahkan instance ke penyeimbang beban HTTP
- Kubernet menunggu contoh lama berhenti digunakan
- Kubernetes menghentikan instance lama
- Kubernetes mengulangi operasi ini hingga instance baru menggantikan semua yang lama
Nyalakan sakelar fungsi baru
- Kode baru hanya disertakan untuk saya sendiri, untuk memastikan semuanya baik-baik saja
- Kode baru disertakan untuk 10% pengguna, metrik operasional dan bisnis dilacak
- Kode baru disertakan untuk 50% pengguna, metrik operasional dan bisnis dilacak
- Kode baru disertakan untuk 100% pengguna, metrik operasional dan bisnis dilacak
- Akhirnya, Anda mengulangi seluruh prosedur untuk menghapus kode lama dan beralih
Prosesnya tergantung pada alat, bahasa, dan penggunaan arsitektur berorientasi layanan, tetapi secara umum, terlihat seperti ini. Saya tidak menyebutkan penyebaran migrasi database karena ini membutuhkan perencanaan yang cermat, tetapi di bawah ini saya akan menjelaskan bagaimana Dark menangani hal ini.
Ada banyak komponen di sini, dan banyak dari mereka dapat dengan mudah memperlambat, crash, menyebabkan persaingan sementara atau menjatuhkan sistem kerja.
Dan karena pipa-pipa ini hampir selalu dibuat untuk acara khusus, sulit untuk mengandalkannya. Banyak orang memiliki hari-hari ketika kode tidak dapat digunakan, karena ada masalah di Dockerfile, salah satu dari puluhan layanan macet atau spesialis yang tepat berlibur.
Lebih buruk lagi, banyak dari langkah-langkah ini tidak melakukan apa pun. Kami membutuhkannya sebelum ketika kami menggunakan kode segera untuk pengguna, tetapi sekarang kami memiliki saklar untuk kode baru, dan proses ini dibagi. Akibatnya, langkah di mana kode digunakan (yang lama digantikan oleh yang baru) kini menjadi risiko tambahan.
Tentu saja, ini adalah pipa yang sangat bijaksana. Tim yang menciptakannya membutuhkan waktu dan uang untuk menyebar dengan cepat. Biasanya penyebaran pipa jauh lebih lambat dan lebih tidak dapat diandalkan.
Menerapkan Pengiriman Berkelanjutan dalam Gelap
Pengiriman berkelanjutan sangat penting untuk Gelap sehingga kami menetapkan waktu tepat waktu dalam waktu kurang dari sedetik. Kami melewati semua langkah pipa untuk menghapus semua yang tidak perlu, dan membawa sisanya ke pikiran. Inilah cara kami menghapus langkah-langkahnya.
Jessie Frazelle menciptakan kata baru deployless di konferensi Future of Software Development di Reykjavik
Kami segera memutuskan bahwa Dark akan didasarkan pada konsep "deployless" (terima kasih kepada Jesse Frazel untuk neologisme). Deployless berarti bahwa kode apa pun langsung disebarkan dan siap digunakan dalam produksi. Tentu saja, kami tidak akan melewatkan kode yang salah atau tidak lengkap (saya akan menjelaskan prinsip-prinsip keselamatan di bawah).
Di demo Dark, kami sering ditanya bagaimana kami berhasil mempercepat penyebaran. Pertanyaan aneh. Orang-orang mungkin berpikir bahwa kita telah menemukan semacam teknologi supertech yang membandingkan kode, mengkompilasinya, mengemasnya ke dalam wadah, meluncurkan mesin virtual, meluncurkan sebuah wadah pada yang dingin dan semua hal semacam itu - dan semua ini dalam 50 ms. Ini hampir tidak mungkin. Tetapi kami telah menciptakan mesin penyebaran khusus, yang tidak membutuhkan semua ini.
Dark meluncurkan penerjemah di awan. Misalkan Anda menulis kode dalam fungsi atau penangan untuk HTTP atau acara. Kami mengirim diff ke pohon sintaksis abstrak (implementasi kode yang digunakan secara internal oleh editor dan server kami) ke server kami, dan kemudian jalankan kode ini ketika permintaan diterima. Jadi penyebarannya terlihat seperti catatan sederhana dalam database - instan dan elementer. Penyebaran sangat cepat karena termasuk minimum.
Di masa depan, kami berencana untuk membuat kompiler infrastruktur dari Dark, yang akan membuat dan menjalankan infrastruktur yang ideal untuk kinerja tinggi dan keandalan aplikasi. Penempatan instan, tentu saja, tidak ke mana-mana.
Penempatan yang aman
Editor Terstruktur
Kode dalam Gelap ditulis dalam editor Gelap. Editor terstruktur tidak membuat kesalahan sintaksis. Faktanya, Dark bahkan tidak memiliki analisa. Saat Anda mengetik, kami bekerja secara langsung dengan Pohon Sintaksis Abstrak (AST) seperti Paredit , Sketsa-n-Sketsa , Tahu , Pangkas, dan MPS .
Setiap kode yang tidak lengkap dalam Dark memiliki semantik eksekusi yang valid, seperti halnya lubang yang diketik di Hazel . Misalnya, jika Anda mengubah panggilan fungsi, kami menyimpan fungsi yang lama hingga yang baru dapat digunakan.
Setiap program di Dark memiliki artinya sendiri, sehingga kode yang tidak lengkap tidak mengganggu pekerjaan yang sudah selesai.
Mode pengeditan
Anda menulis kode dalam Gelap dalam dua kasus. Pertama: Anda menulis kode baru dan satu-satunya pengguna. Misalnya, itu ada di REPL, dan pengguna lain tidak akan pernah mendapatkan akses ke sana, atau itu adalah rute HTTP baru yang tidak Anda rujuk ke mana pun. Anda dapat bekerja di sini tanpa tindakan pencegahan, dan sekarang Anda hampir bekerja di lingkungan pengembangan.
Situasi kedua: kode sudah digunakan. Jika lalu lintas melewati kode (fungsi, penangan acara, database, tipe), harus diperhatikan. Untuk melakukan ini, kami memblokir semua kode yang digunakan dan memerlukan penggunaan alat yang lebih terstruktur untuk mengeditnya. Saya akan berbicara tentang alat struktural di bawah ini: sakelar fungsi untuk HTTP dan pengendali acara, platform migrasi yang kuat untuk basis data, dan metode kontrol versi baru untuk fungsi dan tipe.
Sakelar fungsi
Salah satu cara untuk menghilangkan kompleksitas ekstra dalam Dark adalah dengan memperbaiki beberapa masalah dengan satu solusi. Sakelar fungsi melakukan banyak tugas berbeda: mengganti lingkungan pengembangan lokal, cabang git, menyebarkan kode, dan, tentu saja, pelepasan kode baru yang lambat dan terkontrol secara tradisional.
Penciptaan dan penyebaran saklar fungsi dilakukan di editor kami dalam satu operasi. Ini menciptakan ruang kosong untuk kode baru dan menyediakan kontrol akses untuk kode lama dan baru, serta tombol dan perintah untuk transisi bertahap ke kode baru atau pengecualiannya.
Sakelar fungsi dibuat dalam bahasa Gelap, dan bahkan sakelar tidak lengkap menjalankan tugasnya - jika kondisi di sakelar tidak terpenuhi, kode lama yang diblokir akan dieksekusi.
Lingkungan pengembangan
Sakelar fungsi menggantikan lingkungan pengembangan lokal. Hari ini, sulit bagi tim untuk memastikan bahwa semua orang menggunakan versi alat dan pustaka yang sama (pembuat kode, linter, manajer paket, kompiler, preprosesor, alat pengujian, dll.) Dengan Dark, Anda tidak perlu menginstal dependensi secara lokal, mengontrol instalasi Docker lokal, atau mengambil langkah-langkah lain untuk memastikan setidaknya persamaan kesamaan antara lingkungan pengembangan dan produksi. Mengingat bahwa kesetaraan seperti itu masih mustahil , kami bahkan tidak akan berpura-pura bahwa kami berjuang untuk itu.
Alih-alih menciptakan lingkungan lokal yang dikloning, sakelar dalam Gelap membuat kotak pasir baru dalam produksi yang menggantikan lingkungan pengembangan. Di masa depan, kami juga berencana untuk membuat kotak pasir untuk bagian lain dari aplikasi (misalnya, klon basis data instan), meskipun untuk saat ini sepertinya tidak begitu penting.
Cabang dan Penempatan
Sekarang ada beberapa cara untuk memasukkan kode baru ke dalam sistem: cabang git, fase penyebaran, dan sakelar fungsi. Mereka memecahkan satu masalah di berbagai bagian alur kerja: git - pada tahap sebelum penyebaran, penempatan - pada saat transisi dari kode lama ke kode baru, dan fungsi beralih - untuk pelepasan terkontrol kode baru.
Cara yang paling efektif adalah sakelar fungsi (pada saat yang sama termudah untuk dipahami dan digunakan). Dengan mereka, Anda dapat sepenuhnya meninggalkan dua metode lainnya. Sangat berguna untuk menghapus penyebaran - jika kita menggunakan sakelar fungsi untuk memasukkan kode, langkah memindahkan server ke kode baru hanya menciptakan risiko yang tidak perlu.
Git sulit digunakan, terutama untuk pemula, dan itu benar-benar membatasi, tetapi memiliki cabang yang nyaman. Kami telah merapikan banyak kekurangan git. Dark diedit secara real time dan memberikan kemampuan untuk bekerja bersama dalam gaya Google Documents, sehingga Anda tidak harus mengirim kode dan Anda dapat lebih jarang melakukan relokasi dan penggabungan.
Sakelar fitur mendukung penyebaran aman. Bersama dengan penerapan instan, mereka memungkinkan Anda untuk dengan cepat menguji konsep dalam fragmen kecil dengan risiko rendah, alih-alih menerapkan satu perubahan besar yang dapat menurunkan sistem.
Versi
Untuk mengubah fungsi dan jenis, kami menggunakan versi. Jika Anda ingin mengubah suatu fungsi, Dark membuat versi baru dari fungsi ini. Kemudian Anda dapat menjalankan versi ini menggunakan sakelar di HTTP atau pengendali event. (Jika ini adalah fungsi yang jauh di dalam grafik panggilan, versi baru dari setiap fungsi dibuat di sepanjang jalan. Mungkin sepertinya terlalu banyak, tetapi fungsi tidak mengganggu jika Anda tidak menggunakannya, sehingga Anda bahkan tidak akan menyadarinya.)
Untuk alasan yang sama, kami adalah jenis versi. Kami berbicara tentang sistem tipe kami secara rinci di posting sebelumnya .
Dengan mengversi fungsi dan tipe, Anda dapat membuat perubahan pada aplikasi secara bertahap. Anda dapat memverifikasi bahwa masing-masing pawang bekerja dengan versi baru, Anda tidak perlu segera melakukan semua perubahan pada aplikasi (tetapi kami memiliki alat untuk melakukan ini dengan cepat jika Anda mau).
Ini jauh lebih aman daripada sepenuhnya menerapkan semuanya sekaligus, seperti sekarang.
Versi paket baru dan perpustakaan standar
Ketika Anda memperbarui paket dalam Dark, kami tidak segera mengganti penggunaan setiap fungsi atau ketik di seluruh basis kode. Ini tidak aman. Kode terus menggunakan versi yang sama yang digunakannya, dan Anda memperbarui penggunaan fungsi dan tipe ke versi baru untuk setiap kasus menggunakan saklar.

Tangkapan layar bagian dari proses otomatis dalam Dark yang menampilkan dua versi fungsi Dict :: get. Dict :: get_v0 mengembalikan tipe Any (yang kami tolak), dan Dict :: get_v1 kembali ketik Opsi.
Kami sering menyediakan fitur baru di perpustakaan standar dan mengecualikan versi yang lebih lama. Pengguna dengan versi lama dalam kode akan mempertahankan akses ke sana, tetapi pengguna baru tidak akan bisa mendapatkannya. Kami akan menyediakan alat untuk mentransfer pengguna dari versi lama ke yang baru dalam 1 langkah, dan sekali lagi menggunakan sakelar fungsi.
Dark juga memberikan peluang unik: begitu kami mengeksekusi kode kerja Anda, kami dapat menguji sendiri versi baru, membandingkan output untuk permintaan baru dan lama untuk memberi tahu Anda tentang perubahan tersebut. Akibatnya, pembaruan paket, yang sering dilakukan secara membabi buta (atau membutuhkan pengujian keamanan yang ketat), menimbulkan risiko yang jauh lebih sedikit dan dapat terjadi secara otomatis.
Versi Gelap Baru
Transisi dari Python 2 ke Python 3 telah berlangsung lebih dari satu dekade dan masih menjadi masalah. Setelah kami membuat Gelap untuk pengiriman berkelanjutan, perubahan bahasa ini perlu dipertimbangkan.
Saat kami membuat perubahan kecil pada bahasa, kami membuat versi baru Dark. Kode lama tetap di versi lama Dark, dan kode baru digunakan di versi baru. Untuk beralih ke versi Dark yang baru, Anda dapat menggunakan sakelar atau versi fungsi.
Ini sangat berguna mengingat Gelap telah muncul baru-baru ini. Banyak perubahan pada bahasa atau perpustakaan mungkin gagal. Versi bertahap bahasa memungkinkan kita membuat pembaruan kecil, yaitu, kita tidak bisa terburu-buru dan menunda banyak keputusan tentang bahasa sampai kita memiliki lebih banyak pengguna, dan karenanya lebih banyak informasi.
Migrasi basis data
Ada rumus standar untuk migrasi basis data yang aman:
- Tulis ulang kode untuk mendukung format baru dan lama
- Konversi semua data ke format baru
- Hapus akses data lama
Akibatnya, migrasi basis data tertunda dan membutuhkan banyak sumber daya. Dan kami mengumpulkan skema yang sudah ketinggalan zaman, karena bahkan tugas sederhana, seperti memperbaiki nama tabel atau kolom, tidak sepadan dengan usaha.
Dark memiliki platform migrasi basis data yang efektif yang (kami harap) akan menyederhanakan prosesnya sehingga Anda tidak akan lagi takut padanya. Semua data menyimpan dalam Dark (pasangan nilai kunci atau tabel hash persisten) bertipe. Untuk memigrasi gudang data, Anda cukup menetapkannya sebagai tipe baru dan fungsi rollback dan rollback untuk mengonversi nilai di antara kedua jenis.
Akses ke gudang data dalam Dark melalui nama variabel berversi. Misalnya, penyimpanan data Pengguna pada awalnya akan disebut Users-v0. Ketika versi baru dengan tipe berbeda dibuat, namanya berubah menjadi Users-v1. Jika data disimpan melalui Users-v0, dan Anda mengaksesnya melalui Users-v1, fungsi roll-over diterapkan. Jika data disimpan melalui Users-v1, dan Anda mengaksesnya melalui Users-v0, fungsi rollback digunakan.

Layar migrasi basis data dengan nama bidang untuk basis data lama, ekspresi rollback dan rollback, dan instruksi untuk mengaktifkan migrasi.
Gunakan sakelar fungsi untuk merutekan panggilan ke Users-v0 ke Users-v1. Anda dapat melakukan ini satu penangan HTTP sekaligus untuk mengurangi risiko, dan sakelar juga bekerja untuk pengguna individu sehingga Anda dapat memverifikasi bahwa semuanya berfungsi seperti yang diharapkan. Ketika Users-v0 tidak tersisa, Dark mengubah semua data yang tersisa di latar belakang dari format lama ke yang baru. Anda bahkan tidak akan menyadarinya.
Pengujian
Gelap adalah bahasa pemrograman fungsional dengan pengetikan statis dan nilai yang tidak dapat diubah, oleh karena itu, permukaan pengujiannya secara signifikan lebih kecil dibandingkan dengan bahasa berorientasi objek dengan pengetikan dinamis. Tetapi Anda masih perlu menguji.
Dalam Gelap, editor secara otomatis menjalankan tes unit di latar belakang untuk kode yang dapat diedit dan secara default menjalankan tes ini untuk semua sakelar fungsi. Di masa mendatang, kami ingin menggunakan tipe statis untuk secara otomatis menghapus kode untuk menemukan bug.
Selain itu, Dark menjalankan infrastruktur Anda dalam produksi, dan ini membuka kemungkinan baru. Kami secara otomatis menyimpan permintaan HTTP di infrastruktur Gelap (untuk saat ini kami menyimpan semua permintaan, tetapi kemudian kami ingin beralih ke pengambilan). Kami menguji kode baru pada mereka dan melakukan tes unit, dan jika Anda mau, Anda dapat dengan mudah mengkonversi pertanyaan menarik menjadi tes unit.
Apa yang kita singkirkan
Karena kami tidak memiliki penyebaran, tetapi ada sakelar fungsi, sekitar 60% dari pipa penempatan tetap ke laut. Kami tidak memerlukan permintaan git cabang atau kumpulan, membangun sumber daya backend dan wadah, mengirim sumber daya dan kontainer untuk registrasi atau langkah-langkah penyebaran di Kubernetes.

Perbandingan pipa pengiriman kontinu standar (kiri) dan pasokan berkelanjutan Dark (kanan). Dalam Gelap, pengiriman terdiri dari 6 langkah dan satu siklus, sedangkan versi tradisional mencakup 35 langkah dan 3 siklus.
Dalam Gelap, hanya ada 6 langkah dan 1 siklus dalam penyebaran (langkah yang diulang beberapa kali), sedangkan pipa pasokan kontinu modern terdiri dari 35 langkah dan 3 siklus. Dalam Gelap, tes berjalan secara otomatis, dan Anda bahkan tidak melihatnya; dependensi diinstal secara otomatis; apapun yang berhubungan dengan git atau github tidak lagi dibutuhkan; Tidak perlu mengumpulkan, menguji, dan mengirim wadah Docker; Penempatan Kubernetes tidak lagi diperlukan.
Bahkan langkah-langkah yang tersisa dalam Gelap menjadi lebih mudah. Karena sakelar fungsi dapat dikontrol dalam satu tindakan, Anda tidak harus melewati seluruh pipa penempatan untuk kedua kalinya untuk menghapus kode lama.
Kami menyederhanakan pengiriman kode sebanyak mungkin, mengurangi waktu dan risiko pengiriman berkelanjutan. Kami juga sangat menyederhanakan pembaruan paket, migrasi basis data, pengujian, kontrol versi, instalasi dependensi, kesetaraan antara lingkungan pengembangan dan produksi, dan peningkatan versi bahasa yang cepat dan aman.
Saya menjawab pertanyaan tentang ini di HackerNews .
Untuk mempelajari lebih lanjut tentang perangkat Gelap, baca artikel Gelap , ikuti kami di Twitter (atau saya ), atau mendaftar untuk versi beta dan menerima pemberitahuan dari posting berikut . Jika Anda datang ke StrangeLoop pada bulan September, datanglah ke peluncuran kami .