Canlı yeni kod dağıtımı


29

Yeni bir kodu canlı (e-ticaret) sitesinde dağıtmak için en iyi uygulama nedir?

Dizini yeniden adlandırılırken Şimdilik ben +/- 10 saniye boyunca apache durmuş public_html_newetmek public_htmlve eski public_html_old. Apache'yi yeniden başlatmadan önce bu, kısa bir zaman kaybı yaratır.

Yeni repoyu canlı dizine çekmek için Git'i kullanıyorsanız aynı soru geçerlidir. Site aktifken repoyu çekebilir miyim? Peki ya bir DB'yi kopyalamam gerekirse?

Canlı sitenin tar (yedekleme amacı) sıkıştırması sırasında değişikliklerin medya dizininde gerçekleştiğini fark ettim. Bu bana dosyaları düzenli aralıklarla değişmeye devam ettiğini gösterdi. Ve eğer bu değişiklikler Apache'nin konuşlandırma sırasında durdurulmamasına engel olabilirse.

Yanıtlar:


13

Yük dengeleyici kullanmak iyi bir fikirdir. Eğer site birkaç saniye kapalı kalma süresi için endişe edecek kadar önemliyse, hata toleransı için endişe edecek kadar önemlidir.

Bu bir yana, eğer bu bir UNIX sistemindeyse, Apache'yi yeniden adlandırma (veya sembolik bağlantı güncellemesi, vb.) Sırasında beklemeye alabilirsiniz.

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

Bu, Apache'nin yeniden adlandırma sırasında yeni istekleri kabul etmesini önleyecektir. Eğer linkleri veya başka bir yaklaşımı tercih ederseniz, aynı fikir kullanılabilir:

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

Bekleyen bağlantıların veya paketlerin işletim sisteminde sıraya gireceğini unutmayın. Çok yoğun bir site için httpd çalışan türünüze uygunsa ListenBacklog ayarını düşünün ve TCP dinleme iş listesi ile ilgili işletim sistemi ayarlarınızı kontrol edin.

DocumentRoot'u httpd.conf'ta da değiştirebilir ve zarif bir restart ( apachectl graceful) yapabilirsiniz. Buradaki dezavantaj, herhangi bir Directoryyapılandırmayı da güncellemeniz gerekeceğinden, artan hata riskidir .


Duraklatma oturumu hala sitenin çalışmasını sağlayacak mı?
nicoX

4
Apache'ye CPU zamanı vermeyi bıraktı. Apache duraklatıldığında siteye bir tarayıcıda erişmeyi denediyseniz, Apache devam edene kadar tarayıcı bağlanmayı bekleyecektir (ya da Apache zaman aşımı süresinden daha uzun süre duraklatıldıysa, tarayıcı zaman aşımına uğradı). Birisi bir dosyayı indirme sürecinde ise, Apache duraklatıldığında veri göndermeyi durdurur, çünkü herhangi bir CPU zamanı almaz. Yine, bu yalnızca Apache aktarım zaman aşımına uğrayacak kadar uzun süre durdurulursa sorunlara neden olur.
GargantuChet

5
Başka bir deyişle, Apache duraklatıldığında site yanıt vermeyecek, ancak devam edildiğinde bekleyen işlemler bitecek. Kullanıcılar "bağlantı reddedildi" almayacak ve indirmeler kopmayacak, ancak işlemler yalnızca Apache devam ettiğinde devam edecek. Bu, mevcut işlemlerin bitmesini sağlayacaktır, ancak yeni istekler yalnızca yeni içeriğiniz yerine taşındıktan sonra gerçekleştirilecektir.
GargantuChet

1
Lütfen trafik yoğunluğu yüksek herhangi bir web sitesinde bunun Apache servisinizi kolayca öldürebileceğini unutmayın. 200 rq / s, hareket ettikten sonra Apache işleminizin kilidini açtıktan hemen sonra bağlantı havuzunuzu kolayca çöpe atacak (hareket biraz zaman
alırsa

1
Yüksek trafikli bir sitede, Apache'nin yeniden başlatılmasıyla bitirilmesi gereken birçok uçuş isteği olacaktır. Bu yeni isteklerin işlenmesini hızlandıracak. Ayrıca Apache ayarlarınızın (maksimum iş parçacığı / sunucu / müşteri sayısı) makul olduğundan ve TCP birikimine göre ayarlandığından emin olmak için iyi bir argümandır. Yine de, servisi "öldürerek" kastettiğin şey hakkında kafam karıştı. Apache çok ayarlanabilir.
GargantuChet

32

En hızlı ve en kolay, gibi bir sürüm dizini kullanmaktır.

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

ve html_root'unuz olarak güncel bir sembolik bağlantı kullanın:

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

Bu teknik , dalları ve etiketleri kontrol edebileceğiniz, sembolik bağı değiştirdiği ve Apache'yi yeniden yükleyebileceğiniz gibi, revizyon kontrol sistemine (svn, git, mercurial, ...) mükemmel şekilde entegre olur . Kesintinin en alt düzeyde bu teknik kullanılarak ve onu tanır çok kolay geri alma .

Ayrıca, RPM paketleri veya yapılandırma değişikliği yönetimi (şef, kukla vb.) Altyapısı gibi daha karmaşık dağıtım sistemiyle iyi bir şekilde bütünleşir.


4
En basit çözüm her zaman en iyisidir ... :-) Tabii ki, bazı FollowSymlinks ve yapılandırmalardaki böyle apache bayraklarının gerekebileceğinden bahsetmeyi unutmayın.
peterh, Monica

@PeterHorvath'un söylediklerine özel özen gösterin. Apache, symlinked DocumentRoots ile çalışırken çok huysuz olabilir. Dikkatlice test ettiğinizden emin olun!
mhutter

@mhutter Thanks :-) Asıl sorunlu olan şey, apache'de FollowSymlinks’i etkinleştirmenin güvenlik sorunlarına neden olabileceği ...
peterh, Monica’nın

Bir sembolik linkin güncellenmesi atomik bir işlem değildir. ln -snfOrijinal sembolik bağı kapatmak gibi bir şey kullanıyor olsanız bile , temel işlem bir unlinkve symlink. Güncelleme sırasında kullanıcıların 404 alma şansı var. Bu, orijinal dizini yeniden adlandırmaktan ve yenisini yerine yeniden yerleştirmekten (dosya sistemlerini geçmediğinizi farz edersek) daha iyi bir şey değildir. Bu sorunun üstündeki onay işareti bulunan yukarıdaki cevaba bakınız.
GargantuChet

14

Dizinleri Apache'yi kapatmadan yeniden adlandırmak da işe yaramalı. Bu, pencereyi önemli ölçüde kısaltacaktır. mv public_html public_html_old && mv public_html_new public_htmlbir saniyenin kesriyle bitmelidir.

Birkaç dezavantajı, bu yaklaşımın 404pencerede gerçekleşmeyi başaran herhangi bir talebi yerine getirmesidir. Ve eğer yukarıdaki komutu bir public_html_newdizine sahip olmadan çalıştırırsanız, başarısız olur ve sizi 404her istekte bulunan bir siteyle birlikte bırakır .

Dizinler ile atomik olarak yapmak desteklemiyor. Ama semboliklerle yapabilirsin. Bunun yerine adlı bir dizin sahip public_html, adlı bir dizin var public_html.version-numberve adında bir sembolik public_htmlbu dizine işaret. Şimdi adı verilen bir dizin public_html.new-version-numberve adı verilen yeni bir sembolik bağlantı oluşturabilirsiniz public_html.new.

Sonra atomik geçiş public_html.newyapmak public_htmliçin yeniden adlandırabilirsiniz . mvBu yeniden adlandırmayı gerçekleştirmek için "çok akıllı" olduğuna dikkat edin , ancak os.renamepython veya renamesistem çağrısı yapmayı akıllı olmaya çalışmadan başka bir şey kullanarak yapılabilir .

Veri tabanıyla ne yapılması, hangi veritabanını kullandığınıza ve ne için kullandığınıza bağlıdır. Sorunuzun bu bölümüne size iyi bir cevap verebilmemiz için önce veritabanı hakkında daha fazla ayrıntı vermeniz gerekir.


1
Debian sistemimde sembolik bağlantıyı takip mvetmekten -Talıkoyan bir seçenek var. Bu atomik adlandırmak sağlayacak public_html.newüzerinde public_htmlhem yumuşak bağlantılar vardır varsayarak.
GargantuChet

11

Symlinks ve mv arkadaşınızdır, ancak yeni bir sürümü dağıtırken son kullanıcıların bir hata sayfası almaktan kaçınmanız gerekiyorsa, en az 2 arka uç sunucusunun önünde bir ters proxy veya bir yük dengeleyici bulundurmalısınız (apache) Senin durumunda).

Dağıtım sırasında, bir seferde bir arka ucu durdurmanız, yeni kodu dağıtmanız, yeniden başlatmanız ve ardından kalan arka uçları yinelemeniz yeterlidir.

Son kullanıcılar her zaman vekil tarafından iyi arka uçlara yönlendirilecektir.


4
Ben sadece seni daha önce yolladığını gördüğümde bu cevap üzerinde çalışıyordum. Dengeleyici + 2 sunucular süreci görünmez hale getiriyor ve kötü bir güncellemeden kurtarmayı kolaylaştırıyor ...
Bart Silverstrim

9

Bir üretim sisteminde düzenli olarak değişiklikler uyguluyorsanız, yapısal bir yaşam döngüsüyle ben ilgilenirim. İyi bir uygulama Capistrano http://capistranorb.com/ . Bu, yazılımı birkaç platformda ve yapılandırmada bir veya daha fazla sunucuya dağıtmak için açık kaynaklı bir çözümdür.

Magento için bir eklenti bile var: https://github.com/augustash/capistrano-ash/wiki/Magento-Example

Tek sunucu ve neredeyse kesintisiz geçişler için, sembolik bağlantılar kullanmanızı öneririz.


4

Bunu yapmak, yerel dev ortamımdan Github gibi bir çevrimiçi Git deposuna değişikliklerimi yapmak. Üretim ortamım uzak bir havuzda çalışıyor, bu yüzden tek yapmam gereken sunucuya ssh koymak ve git pullen son değişiklikleri getirmek için çalışıyor. Web sunucunuzu durdurmanıza gerek yok.

Projenizde ayarları ve / veya içeriği yerel sürümünüzden farklı olan dosyalarınız (yapılandırma dosyaları ve medya yüklemeleri gibi) varsa, ortam değişkenlerini kullanabilir ve / veya .gitignoredepo ile senkronizasyonu önlemek için bu dosyaları / dizinleri bir dosyaya ekleyebilirsiniz .


3

Benim ilk fikrim:

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

İyi bir çözüm rsync kullanmaktı. Sadece gerçekten değiştirilen dosyaları değiştirdi. Dikkat edin, yolun sonundaki eğik çizgiler yolların burada önemli olduğunu unutmayın.

Normalde apache'nin yeniden başlatılması gerekmez, java dünyası değildir. İstek üzerine her php dosyasının değişimini kontrol eder ve değişimin üzerine otomatik olarak yeniden okur (ve yeniden belirtir).

Git çekme benzer verimli, ancak komut dosyası biraz zor olsa da. Tabii ki, farklı birleşme / değişim tespit olanakları geniş yelpazesinde olanak sağlamıştır.

Bu çözüm sorunsuz bir şekilde ancak gerçekten büyük değişiklikler olmazsa - dağıtımda büyük değişiklikler varsa, kodun kısmen değiştirileceği zaman ihmal edilemez bir zaman aralığı olmadığından, bir miktar tehlike kapatılamaz ve kısmen değil.

Büyük değişiklikler varsa, önerim ilk çözümünüzdü (iki yeniden adlandırma).


İşte biraz sert ama% 100 atomik çözüm:

(1) magento'nuzun gerçekleştiği bazı dosya sisteminizi, alternatif bir montaj yapın:

mount /dev/sdXY /mnt/tmp

(2) --bindpublic_html_new ile public_html arasında bir bağlantı yapın:

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

Bu noktadan itibaren, apache yeni dağıtımınızı görecektir. 404'te herhangi bir değişiklik yapılması mümkün değildir.

(3) senkronizasyonu rsync ile fakat alternatif bağlama noktasında yapın):

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

(4) bağlama düzeneğini çıkarın

umount /path/to/public_html

Komut public_html dosyasını silecek ve public_html_new dosyasını içine yerleştirecek mi?
nicoX

@NicoX Hayır, yalnızca değişiklikleri kopyalar .
peterh Monica

@nicoX Her iki dizin yapısında da devam eder ve bir fark bulursa (yeni dosya, değiştirilmiş dosya, silinen dosya), ikinci dizini, gerektiği gibi ilkiyle eşleşecek şekilde değiştirir. Sonuçta public_html dosyasını sildiyseniz ve sonra public_html_new yerine getirildi , ancak geçici bir 404 problemi olma ihtimali yoktu.
peterh Monica

1
Hayır, bu iyi bir fikir değil. Değişikliklere bağlı olarak, kodun public_htmltutarsız bir durumda olduğu kısa bir süre olabilir ve bu şansı kullanmak istemezsiniz.
Sven

@SvW Haklısın, fikrim sadece küçük değişiklikler varsa tamamdır. Buna göre cevabımı uzattım.
peterh Monica

1

Http sunucunuz çalışmaya devam ederken , http_publicklasörün değiştirilmesi / değiştirilmesi basit mvveya ln -skomutlar veya eşdeğeri ile sağlanabilir . Arıza süresini önemli ölçüde azaltmak için bazı komut dosyaları kullanabilirsiniz, ancak işlemi otomatik hale getirirseniz komut dosyalarınızın komut kodlarını dikkatlice kontrol edin.

Bu, hiçbir kesinti elde etmek istemiyorsanız, uygulamanın da desteklemesi gerektiğini söyledi. Çoğu uygulama kalıcılık için bir veritabanı kullanır. Uygulamanızın N sürümünün, veri modelinizin N + 1 (veya tersi) ile karıştırılması, geliştirme ekibi tarafından öngörülmediği takdirde işleri bozabilir.

Tecrübelerden, yükseltme işlemlerinde böyle bir tutarlılığın sağlanması çoğu uygulama için verilmez. Arıza süresine rağmen uygun bir kapanma, tutarlılık sorunlarından kaçınmak için iyi bir yoldur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.