Menyebarkan kode baru secara langsung

29

Apa praktik terbaik untuk menyebarkan kode baru di situs langsung (e-commerce)?

Untuk saat ini saya telah menghentikan apache selama +/- 10 detik ketika mengganti nama direktori public_html_newmenjadi public_htmldan menjadi lama public_html_old. Ini membuat down-time pendek, sebelum saya memulai Apache lagi.

Pertanyaan yang sama berlaku jika menggunakan Git untuk menarik repo baru ke direktori langsung. Bisakah saya menarik repo saat situs aktif? Dan bagaimana kalau saya perlu menyalin DB juga?

Selama tar (tujuan pencadangan) kompresi situs langsung saya perhatikan bahwa perubahan terjadi pada direktori media. Itu menunjukkan kepada saya bahwa file terus berubah secara berkala. Dan jika perubahan ini dapat mengganggu jika Apache tidak berhenti selama penyebaran.

nicoX
sumber

Jawaban:

13

Menggunakan load balancer adalah ide yang bagus. Jika situs cukup penting untuk mengkhawatirkan downtime beberapa detik, cukup penting untuk khawatir tentang toleransi kesalahan.

Selain itu, jika ini menggunakan sistem UNIX, Anda dapat menahan Apache selama penggantian nama (atau pembaruan symlink, dll.):

killall -STOP httpd  # Pause all httpd processes
mv public_html public_html_orig
mv public_html_new public_html
killall -CONT httpd  # Resume all httpd processes

Ini akan menjaga Apache dari menerima permintaan baru selama penggantian nama. Jika Anda lebih suka symlink atau pendekatan lain, ide yang sama dapat digunakan:

killall -STOP httpd  # Pause all httpd processes
rm /var/www/html
ln -s /var/www/version/03 /var/www/html
killall -CONT httpd  # Resume all httpd processes

Perhatikan bahwa koneksi atau paket yang tertunda akan mengantri di OS. Untuk situs yang sangat sibuk, pertimbangkan untuk menyetel ListenBacklog jika sesuai dengan jenis pekerja httpd Anda, dan periksa pengaturan OS Anda yang terkait dengan backlog dengarkan TCP.

Anda juga dapat mengubah DocumentRoot di httpd.conf dan melakukan restart dengan anggun ( apachectl graceful). Kekurangannya di sini adalah meningkatnya risiko kesalahan, karena Anda harus memperbarui Directorykonfigurasi apa pun juga.

GargantuChet
sumber
Apakah sesi jeda ini masih membuat situs berjalan?
nicoX
4
Itu berhenti memberi waktu CPU ke Apache. Jika Anda mencoba mengakses situs di peramban ketika Apache dijeda, peramban akan menunggu untuk terhubung hingga Apache dilanjutkan (atau peramban waktu habis, jika Apache dijeda lebih lama dari periode waktu habis). Jika seseorang sedang dalam proses mengunduh file, Apache akan berhenti mengirim data saat dijeda, lagi karena tidak mendapatkan waktu CPU. Sekali lagi ini hanya akan menyebabkan masalah jika Apache dihentikan begitu lama sehingga transfer habis.
GargantuChet
5
Dengan kata lain, situs akan tidak responsif ketika Apache dijeda, tetapi operasi yang tertunda akan selesai ketika dilanjutkan. Pengguna tidak akan mendapatkan "koneksi ditolak", dan unduhan tidak akan putus, tetapi operasi hanya akan berlanjut ketika Apache dilanjutkan. Ini akan memastikan bahwa transaksi yang ada dapat selesai, tetapi permintaan baru hanya akan ditangani setelah konten baru Anda dipindahkan.
GargantuChet
1
Harap perhatikan bahwa di situs web lalu lintas tinggi mana pun, ini akan sangat mudah mematikan layanan Apache Anda. 200 rq / dtk akan dengan mudah membuang kumpulan koneksi Anda segera setelah Anda akan 'membuka' proses Apache Anda setelah pindah (jika perlu waktu lama)
CloudWeavers
1
Di situs dengan lalu lintas tinggi, akan ada banyak permintaan dalam penerbangan untuk diselesaikan ketika Apache dilanjutkan. Ini akan mengejutkan pemrosesan permintaan baru. Ini juga argumen yang bagus untuk memastikan pengaturan Apache Anda (jumlah maksimum utas / server / klien) masuk akal, dan menyetel backlog TCP yang sesuai. Meskipun saya bingung tentang apa yang Anda maksud dengan "membunuh" layanan. Apache sangat merdu.
GargantuChet
32

Yang tercepat dan termudah adalah dengan menggunakan direktori versi seperti

/var/www/version/01
/var/www/version/02

dan gunakan tautan simbolis saat ini sebagai html_root Anda:

/var/www/html -> /var/www/version/02

Teknik ini terintegrasi sempurna ke dalam sistem kontrol revisi (svn, git, lincah, ...) karena Anda dapat checkout cabang & tag, mengubah tautan simbolik dan memuat ulang Apache. The downtime minimal menggunakan teknik ini dan itu memungkinkan rollback sangat mudah .

Ini juga terintegrasi dengan baik dengan sistem penyebaran yang lebih kompleks seperti paket RPM, atau manajemen perubahan konfigurasi (koki, boneka, dll).

CloudWeavers
sumber
4
Solusi paling sederhana selalu yang terbaik ... :-) Tentu saja jangan lupa untuk menyebutkan, bahwa beberapa FollowSymlinks dan flag apache semacam itu di konfigurasi mungkin diperlukan.
peterh mengatakan mengembalikan Monica
Berhati-hatilah dengan apa yang dikatakan @PeterHorvath. Apache bisa menjadi sangat pemarah saat bekerja dengan DocumentRoots yang dikaitkan. Pastikan untuk menguji dengan cermat!
mhutter
@mhutter Terima kasih :-) Yang benar-benar bermasalah adalah mengaktifkan FollowSymlinks di apache dapat menyebabkan masalah keamanan ...
peterh mengatakan pulihkan Monica
Memperbarui symlink bukanlah operasi atom. Bahkan menggunakan sesuatu seperti ln -snfuntuk menghancurkan symlink asli, operasi yang mendasarinya adalah unlinkdan symlink. Ada kemungkinan pengguna mendapatkan 404 selama pembaruan. Ini tidak lebih baik dari sekadar mengganti nama direktori asli dan mengganti nama yang baru ke tempatnya (dengan asumsi Anda tidak melintasi sistem file). Lihat jawaban di atas dengan tanda centang di sebelahnya, yang membahas masalah ini.
GargantuChet
14

Mengganti nama direktori tanpa mematikan Apache seharusnya juga berfungsi. Itu akan memperpendek jendela secara signifikan. mv public_html public_html_old && mv public_html_new public_htmlharus selesai dalam sepersekian detik.

Beberapa kelemahan adalah bahwa pendekatan ini akan memberikan 404permintaan yang masih bisa terjadi selama jendela. Dan jika Anda menjalankan perintah di atas tanpa memiliki public_html_newdirektori itu akan gagal dan meninggalkan Anda dengan situs memberikan 404pada setiap permintaan.

Melakukannya secara atomis dengan direktori tidak mendukung. Tetapi Anda bisa melakukannya dengan symlink. Alih-alih memiliki direktori bernama public_html, memiliki direktori bernama public_html.version-numberdan symlink yang disebut public_htmlmenunjuk ke direktori itu. Sekarang Anda dapat membuat direktori bernama public_html.new-version-numberdan symlink baru bernama public_html.new.

Kemudian Anda dapat mengubah nama public_html.newuntuk public_htmlberalih atom. Perhatikan bahwa mv"terlalu cerdas" untuk melakukan penggantian nama itu, tetapi itu bisa dilakukan menggunakan os.renamedari python atau apa pun yang akan memanggil renamesystem call tanpa berusaha menjadi pintar.

Apa yang harus dilakukan dengan basis data tergantung pada basis data apa yang Anda gunakan, dan untuk apa Anda menggunakannya. Anda perlu memberikan lebih banyak detail tentang basis data sebelum kami dapat memberikan jawaban yang baik untuk bagian pertanyaan Anda itu.

kasperd
sumber
1
Di sistem Debian saya, mvada -Topsi yang mencegahnya mengikuti symlink. Ini akan membiarkan Anda atom mengubah nama public_html.newlebih public_html, dengan asumsi kedua adalah link lembut.
GargantuChet
11

Symlinks dan mv adalah teman Anda, namun, jika Anda benar-benar harus menghindari pengguna akhir mendapatkan halaman kesalahan saat menggunakan versi baru, Anda harus memiliki proxy terbalik atau penyeimbang beban di depan setidaknya 2 server backend (apache dalam kasus Anda).

Selama penerapan, Anda hanya perlu menghentikan satu backend pada satu waktu, menyebarkan kode baru, restart dan kemudian beralih pada backend yang tersisa.

Pengguna akhir akan selalu diarahkan ke backend yang baik oleh proxy.

Giovanni Toraldo
sumber
4
Saya baru saja mengerjakan jawaban ini ketika saya melihat Anda sudah mempostingnya. Server Balancer + 2 membuat prosesnya tidak terlihat dan lebih mudah pulih dari pembaruan yang buruk ...
Bart Silverstrim
9

Jika Anda menerapkan perubahan secara teratur pada sistem produksi, saya akan menjaga siklus hidup terstruktur. Praktik yang baik adalah Capistrano http://capistranorb.com/ . Ini adalah solusi open source untuk menyebarkan perangkat lunak pada satu atau lebih server pada beberapa platform dan konfigurasi.

Untuk Magento bahkan ada sebuah plugin: https://github.com/augustash/capistrano-ash/wiki/Magento-Example

Untuk server tunggal dan transisi yang hampir mulus, saya sarankan untuk menggunakan symlink.

Skiaddict
sumber
4

Cara saya melakukannya adalah mengkomit perubahan saya dari lingkungan dev lokal saya ke repositori Git online seperti Github. Lingkungan produksi saya menjalankan repositori jarak jauh sehingga yang perlu saya lakukan adalah ssh ke server dan jalankan git pulluntuk membawa perubahan terbaru. Tidak perlu menghentikan server web Anda.

Jika Anda memiliki file di proyek Anda yang pengaturan dan / atau kontennya berbeda dari versi lokal Anda (seperti file konfigurasi dan unggahan media), Anda dapat menggunakan variabel lingkungan dan / atau menambahkan file / direktori ini ke .gitignorefile untuk mencegah sinkronisasi dengan repositori.

harryg
sumber
3

Ide pertama saya adalah:

# deploy into public_html_new, and then:
rsync -vaH --delete public_html_new/ public_html/

Solusi yang baik adalah menggunakan rsync. Itu hanya mengubah file yang benar-benar berubah. Waspadalah, garis miring di ujung jalan di sini penting.

Biasanya apache tidak perlu restart, itu bukan dunia java. Ia memeriksa perubahan setiap file php berdasarkan permintaan, dan membaca ulang (dan mengubah token) pada perubahan secara otomatis.

Git pull sama efisiennya, meskipun sedikit lebih sulit untuk skrip. Tentu saja memungkinkan spektrum yang luas dari berbagai kemungkinan deteksi penggabungan / perubahan.

Solusi ini akan mulus hanya jika tidak ada perubahan besar - jika ada perubahan besar dalam penempatan, sedikit bahaya tidak dapat ditutup, karena tidak ada interval waktu yang dapat diabaikan, ketika kode akan diubah sebagian dan sebagian tidak.

Jika ada perubahan besar, saran saya adalah solusi awal Anda (dua ganti nama).


Berikut ini sedikit hardcore, tetapi solusi atom 100%:

(1) lakukan mount alternatif beberapa sistem file Anda, di mana magento Anda terjadi:

mount /dev/sdXY /mnt/tmp

(2) lakukan --bindmount public_html_new Anda ke public_html:

mount --bind /path/to/public_html_new /path/to/public_html

Dari titik ini, apache akan melihat penyebaran baru Anda. Perubahan 404 tidak dimungkinkan.

(3) lakukan sinkronisasi dengan rsync, tetapi pada titik mount alternatif):

rsync -vaH --delete /mnt/tmp/path/to/public_html_new/ /mnt/tmp/path/to/public_html/

(4) lepaskan bind mount

umount /path/to/public_html
peterh mengatakan mengembalikan Monica
sumber
Apakah perintah akan menghapus public_html dan menyebarkan public_html_new ke dalamnya?
nicoX
@nicoX Tidak, itu hanya akan menyalin perubahan.
peterh mengatakan mengembalikan Monica
@nicoX Ini berjalan melalui kedua struktur direktori, dan jika ia menemukan perbedaan (file baru, file yang dimodifikasi, file yang dihapus), ia memodifikasi direktori kedua agar sesuai dengan yang pertama, sesuai kebutuhan. Hasilnya jika Anda menghapus public_html dan kemudian memindahkan public_html_new ke tempatnya, tetapi tanpa kemungkinan masalah 404 sementara.
peterh mengatakan mengembalikan Monica
1
Tidak, ini bukan ide yang bagus. Bergantung pada perubahannya, Anda mungkin memiliki periode waktu singkat di mana kode public_htmlini berada dalam kondisi tidak konsisten, dan Anda tidak ingin mengambil kesempatan ini.
Sven
@ SVW Anda benar, ide saya hanya baik-baik saja jika hanya ada sedikit perubahan. Saya memperpanjang jawaban saya sesuai.
peterh mengatakan mengembalikan Monica
1

Memindahkan / mengganti http_publicfolder dapat dicapai dengan sederhana mvatau ln -sperintah atau setara saat server http Anda terus berjalan. Anda dapat melakukan beberapa skrip untuk mengurangi downtime secara signifikan, tetapi periksa dengan hati-hati kode kembalinya dari perintah Anda dalam skrip jika Anda mengotomatiskan prosesnya.

Yang mengatakan, jika Anda ingin mencapai tidak ada downtime, aplikasi Anda juga harus mendukungnya. Sebagian besar aplikasi menggunakan database untuk kegigihan. Memiliki versi N dari aplikasi Anda yang mengacaukan versi N +1 (atau kebalikan) dari model data Anda dapat merusak banyak hal jika tidak diramalkan oleh tim pengembang.

Dari pengalaman, mempertahankan konsistensi seperti itu melalui peningkatan tidak diberikan untuk sebagian besar aplikasi. Shutdown yang tepat, meskipun downtime, adalah cara yang baik untuk menghindari masalah konsistensi.

Uriel
sumber