การปรับใช้โค้ดใหม่แบบสด


29

แนวปฏิบัติที่เหมาะสมที่สุดในการปรับใช้รหัสใหม่ในไซต์สด (อีคอมเมิร์ซ) คืออะไร

สำหรับตอนนี้ผมได้หยุด Apache สำหรับ +/- 10 วินาทีเมื่อมีการเปลี่ยนชื่อไดเรกทอรีpublic_html_newไปและเก่าpublic_html public_html_oldสิ่งนี้สร้างช่วงเวลาสั้น ๆ ก่อนที่ฉันจะเริ่ม Apache อีกครั้ง

คำถามเดียวกันจะเกิดขึ้นหากใช้ Git เพื่อดึง repo ใหม่ไปยังไดเรกทอรีสด ฉันสามารถดึง repo ขณะที่ไซต์นั้นทำงานอยู่ได้หรือไม่? แล้วถ้าฉันต้องการคัดลอกฐานข้อมูลด้วยล่ะ

ในระหว่างการบีบอัด tar (สำรองข้อมูล) ของเว็บไซต์ถ่ายทอดสดฉันสังเกตว่าการเปลี่ยนแปลงเกิดขึ้นในไดเรกทอรีสื่อ ที่ระบุให้ฉันว่าไฟล์ยังคงมีการเปลี่ยนแปลงเป็นระยะ และหากการเปลี่ยนแปลงเหล่านี้สามารถรบกวนหาก Apache ไม่หยุดในระหว่างการปรับใช้

คำตอบ:


13

การใช้ load balancer เป็นความคิดที่ดี หากไซต์มีความสำคัญพอที่จะต้องกังวลเกี่ยวกับการหยุดทำงานไม่กี่วินาทีก็เป็นสิ่งสำคัญที่จะต้องกังวลเกี่ยวกับการยอมรับข้อบกพร่อง

นอกเหนือจากนั้นหากนี่เป็นระบบ UNIX คุณสามารถพัก Apache ไว้ระหว่างการเปลี่ยนชื่อ (หรือการอัพเดต symlink เป็นต้น):

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

สิ่งนี้จะป้องกันไม่ให้ Apache ยอมรับคำขอใหม่ในระหว่างการเปลี่ยนชื่อ หากคุณชอบ symlink หรือวิธีการอื่นคุณสามารถใช้แนวคิดเดียวกันนี้ได้:

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

โปรดทราบว่าการเชื่อมต่อหรือแพ็กเก็ตใด ๆ ที่ค้างอยู่จะเข้าคิวในระบบปฏิบัติการ สำหรับไซต์ที่ยุ่งมากให้ปรับจูน ListenBacklog ถ้าเหมาะสมกับประเภท httpd ของผู้ปฏิบัติงานของคุณและตรวจสอบการตั้งค่าระบบปฏิบัติการของคุณที่เกี่ยวข้องกับ TCP Listen backlog

คุณสามารถเปลี่ยน DocumentRoot ใน httpd.conf และทำการรีสตาร์ทอย่างนุ่มนวล ( apachectl graceful) ข้อเสียเปรียบที่นี่คือความเสี่ยงที่เพิ่มขึ้นของข้อผิดพลาดเนื่องจากคุณจะต้องอัปเดตDirectoryการกำหนดค่าใด ๆเช่นกัน


เซสชั่นหยุดชั่วคราวจะยังคงมีเว็บไซต์ทำงานอยู่หรือไม่
nicoX

4
มันหยุดให้เวลา CPU กับ Apache หากคุณพยายามเข้าถึงไซต์ในเบราว์เซอร์ขณะที่ Apache หยุดทำงานเบราว์เซอร์จะรอการเชื่อมต่อจนกว่า Apache จะกลับมาทำงานต่อ (หรือเบราว์เซอร์หมดเวลาหาก Apache หยุดทำงานนานกว่าระยะหมดเวลา) หากมีใครบางคนกำลังดาวน์โหลดไฟล์ Apache จะหยุดส่งข้อมูลในขณะที่หยุดชั่วคราวเนื่องจากไม่ได้รับเวลา CPU อีกครั้งนี่จะทำให้เกิดปัญหาหาก Apache หยุดทำงานนานจนการถ่ายโอนหมดเวลา
GargantuChet

5
อีกวิธีหนึ่งไซต์จะไม่ตอบสนองขณะที่ Apache หยุดทำงานชั่วคราว แต่การดำเนินการที่รอดำเนินการจะเสร็จสิ้นเมื่อดำเนินการต่อ ผู้ใช้จะไม่ได้รับ "การเชื่อมต่อถูกปฏิเสธ" และการดาวน์โหลดจะไม่หยุดลง แต่การดำเนินการจะดำเนินการต่อเมื่อ Apache กลับมาทำงานต่อ สิ่งนี้จะช่วยให้มั่นใจว่าการทำธุรกรรมที่มีอยู่สามารถเสร็จสิ้นได้ แต่คำขอใหม่จะได้รับการจัดการหลังจากเนื้อหาใหม่ของคุณถูกย้ายเข้าที่
GargantuChet

1
โปรดทราบว่าในเว็บไซต์ที่มีปริมาณการใช้งานสูงสิ่งนี้จะทำให้บริการ Apache ของคุณฆ่าได้ง่ายมาก 200 rq / s จะทำให้การเชื่อมต่อของคุณง่ายขึ้นมากทันทีที่คุณ 'ปลดล็อก' กระบวนการ Apache ของคุณหลังจากการย้าย (ถ้าการย้ายใช้เวลาสักครู่)
CloudWeavers

1
ในเว็บไซต์ที่มีการเข้าชมสูงจะมีคำขอในเที่ยวบินจำนวนมากที่ต้องทำให้เสร็จเมื่อ Apache กลับมาทำงานอีกครั้ง นี่จะทำให้การประมวลผลคำขอใหม่ซวนเซ นอกจากนี้ยังเป็นข้อโต้แย้งที่ดีสำหรับการตรวจสอบว่าการตั้งค่า Apache ของคุณ (จำนวนเธรด / เซิร์ฟเวอร์ / ไคลเอนต์สูงสุด) เหมาะสมและปรับ backlog TCP ตามนั้น แม้ว่าฉันสับสนเกี่ยวกับสิ่งที่คุณหมายถึงโดย "ฆ่า" บริการ Apache สามารถปรับได้มาก
GargantuChet

32

เร็วที่สุดและง่ายที่สุดคือการใช้ไดเรกทอรีรุ่นเช่น

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

และใช้ลิงก์สัญลักษณ์ปัจจุบันเป็น html_root ของคุณ:

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

เทคนิคนี้รวมกันอย่างสมบูรณ์ในระบบควบคุมการแก้ไข (svn, git, mercurial, ... ) ในขณะที่คุณสามารถชำระเงินสาขาและแท็กเปลี่ยนลิงก์สัญลักษณ์และโหลด Apache อีกครั้ง หยุดทำงานมีน้อยใช้เทคนิคนี้และจะช่วยให้ย้อนกลับง่ายมาก

นอกจากนี้ยังรวมเข้ากับระบบการปรับใช้ที่ซับซ้อนมากขึ้นเช่นแพ็คเกจ RPM หรือโครงสร้างการจัดการการเปลี่ยนแปลงการกำหนดค่า (เชฟหุ่นเชิด ฯลฯ )


4
วิธีแก้ปัญหาที่ง่ายที่สุดนั้นดีที่สุดเสมอ ... :-) แน่นอนว่าอย่าลืมที่จะพูดถึงว่าอาจต้องใช้ FollowSymlinks และอาปาเช่แฟล็กในการกำหนดค่าบางอย่าง
peterh กล่าวคืนสถานะโมนิก้า

ใช้ความระมัดระวังเป็นพิเศษในสิ่งที่ @ PeterHorvath พูด Apache สามารถทำงานไม่พอใจเมื่อทำงานกับ DocumentRoots แบบ symlinked อย่าลืมทดสอบอย่างระมัดระวัง!
mhutter

@mhutter ขอบคุณ :-) สิ่งที่เป็นปัญหาจริงๆคือการเปิดใช้งาน FollowSymlinks บน apache อาจทำให้เกิดปัญหาด้านความปลอดภัย ...
peterh พูดว่าคืนสถานะโมนิก้า

การอัปเดต symlink ไม่ใช่การทำงานของอะตอม แม้จะใช้สิ่งที่ต้องการln -snfที่จะทุบ symlink เดิมการดำเนินงานพื้นฐานเป็นและunlink symlinkมีโอกาสที่ผู้ใช้จะได้รับ 404 ระหว่างการอัพเดท สิ่งนี้ไม่ได้ดีไปกว่าการเปลี่ยนชื่อไดเรกทอรีต้นฉบับใหม่และเปลี่ยนชื่อไดเรกทอรีใหม่ให้เข้าที่ (สมมติว่าคุณไม่ได้ข้ามระบบไฟล์) ดูคำตอบข้างต้นพร้อมเครื่องหมายถูกซึ่งอยู่ข้างข้อกังวลนี้
GargantuChet

14

การเปลี่ยนชื่อไดเรกทอรีโดยไม่ต้องปิด Apache ควรทำงานได้เช่นกัน นั่นจะทำให้หน้าต่างสั้นลงอย่างมาก mv public_html public_html_old && mv public_html_new public_htmlควรเสร็จในเสี้ยววินาที

ข้อเสียสองประการคือวิธีการนี้จะให้การ404ร้องขอใด ๆ ที่ยังคงเกิดขึ้นระหว่างหน้าต่าง และถ้าคุณเรียกใช้คำสั่งข้างต้นโดยไม่ต้องมีpublic_html_newไดเรกทอรีมันจะล้มเหลวและทำให้คุณมีเว็บไซต์ที่ให้404ทุกคำขอ

การทำแบบไดเร็กตอรี่กับไดเรกทอรีไม่ได้รับการสนับสนุน แต่คุณสามารถทำได้ด้วย symlinks แทนที่จะมีชื่อไดเรกทอรีpublic_htmlให้มีชื่อไดเรกทอรีpublic_html.version-numberและ symlink เรียกว่าpublic_htmlชี้ไปที่ไดเรกทอรีนั้น ตอนนี้คุณสามารถสร้างไดเรกทอรีที่เรียกว่าpublic_html.new-version-numberและ symlink public_html.newใหม่ที่เรียกว่า

จากนั้นคุณสามารถเปลี่ยนชื่อpublic_html.newเพื่อpublic_htmlที่จะเปลี่ยนอะตอม โปรดสังเกตว่าmv"ฉลาดเกินไป" เพื่อทำการเปลี่ยนชื่อนั้น แต่สามารถทำได้โดยใช้os.renameจากไพ ธ อนหรือสิ่งอื่นใดที่จะเรียกการเรียกของrenameระบบโดยไม่ต้องพยายามฉลาด

จะทำอย่างไรกับฐานข้อมูลขึ้นอยู่กับฐานข้อมูลที่คุณใช้และสิ่งที่คุณใช้สำหรับ คุณต้องให้รายละเอียดเพิ่มเติมเกี่ยวกับฐานข้อมูลก่อนที่เราจะสามารถให้คำตอบที่ดีแก่คำถามของคุณ


1
บนระบบ Debian ของฉันmvมี-Tตัวเลือกที่ป้องกันไม่ให้ติดตาม symlink นี้จะช่วยให้คุณสามารถเปลี่ยนชื่ออะตอมpublic_html.newมากกว่าpublic_htmlสมมติว่ามีการเชื่อมโยงทั้งนุ่ม
GargantuChet

11

Symlinks และ mv เป็นเพื่อนของคุณ แต่ถ้าคุณต้องการหลีกเลี่ยงผู้ใช้ปลายทางที่ได้รับหน้าข้อผิดพลาดในขณะที่ปรับใช้เวอร์ชันใหม่คุณควรมี reverse-proxy หรือ load-balancer หน้าเซิร์ฟเวอร์ backend อย่างน้อย 2 ตัว (apache ในกรณีของคุณ)

ในระหว่างการปรับใช้คุณเพียงแค่ต้องหยุดแบ็กเอนด์ครั้งละหนึ่งครั้งปรับใช้โค้ดใหม่รีสตาร์ทและจากนั้นทำซ้ำกับแบ็กเอนด์ที่เหลือ

ผู้ใช้จะถูกนำไปที่แบ็กเอนด์ที่ดีเสมอ


4
ฉันแค่ทำงานกับคำตอบนี้เมื่อฉันเห็นคุณโพสต์แล้ว เซิร์ฟเวอร์ Balancer + 2 ทำให้กระบวนการมองไม่เห็นและกู้คืนได้ง่ายขึ้นจากการอัปเกรดที่ไม่ดี ...
Bart Silverstrim

9

หากคุณใช้การเปลี่ยนแปลงเป็นประจำในระบบการผลิตฉันจะดูแลวงจรชีวิตที่มีโครงสร้าง การปฏิบัติที่ดีคือ Capistrano http://capistranorb.com/ นี่เป็นโซลูชันโอเพ่นซอร์สสำหรับการปรับใช้ซอฟต์แวร์บนเซิร์ฟเวอร์หนึ่งเซิร์ฟเวอร์ขึ้นไปบนแพลตฟอร์มและการกำหนดค่าต่างๆ

สำหรับ Magento ยังมีปลั๊กอิน: https://github.com/augustash/capistrano-ash/wiki/Magento-Example

สำหรับเซิร์ฟเวอร์เดียวและช่วงการเปลี่ยนภาพแทบไม่มีรอยต่อผมแนะนำให้ใช้ symlink


4

วิธีที่ฉันทำคือทำการคอมมิชชันการเปลี่ยนแปลงของฉันจากสภาพแวดล้อม dev ท้องถิ่นของฉันไปยังที่เก็บ Git ออนไลน์เช่น Github สภาพแวดล้อมการใช้งานจริงของฉันหมดลงในที่เก็บระยะไกลดังนั้นสิ่งที่ฉันต้องทำก็คือ ssh ไปที่เซิร์ฟเวอร์และเรียกใช้git pullเพื่อลดการเปลี่ยนแปลงล่าสุด ไม่จำเป็นต้องหยุดเว็บเซิร์ฟเวอร์ของคุณ

หากคุณมีไฟล์ในโครงการที่มีการตั้งค่าและ / หรือเนื้อหาแตกต่างจากเวอร์ชันในระบบ (เช่นไฟล์การกำหนดค่าและการอัปโหลดสื่อ) คุณสามารถใช้ตัวแปรสภาพแวดล้อมและ / หรือเพิ่มไฟล์ / ไดเรกทอรีเหล่านี้ลงใน.gitignoreไฟล์เพื่อป้องกันการซิงค์กับที่เก็บ


3

ความคิดแรกของฉันคือ:

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

ทางออกที่ดีคือการใช้ rsync มันเปลี่ยนเฉพาะไฟล์ที่เปลี่ยนแปลงจริงๆ ระวังเครื่องหมายทับที่ท้ายเส้นทางนั้นสำคัญมาก

อาปาเชปกติไม่จำเป็นต้องรีสตาร์ทมันไม่ใช่โลกของจาวา มันจะตรวจสอบการเปลี่ยนแปลงของไฟล์ php ทุกไฟล์ที่มีการร้องขอและอ่าน (และโทเค็นซ้ำอีกครั้ง) เมื่อมีการเปลี่ยนแปลงโดยอัตโนมัติ

การดึง Git นั้นมีประสิทธิภาพคล้ายกันถึงแม้ว่ามันจะยากขึ้นเล็กน้อยในการเขียนสคริปต์ แน่นอนว่ามันช่วยให้สามารถตรวจจับการรวม / เปลี่ยนแปลงการตรวจจับได้อย่างหลากหลาย

วิธีการแก้ปัญหานี้จะทำงานอย่างราบรื่นหากไม่มีการเปลี่ยนแปลงที่สำคัญ - หากมีการเปลี่ยนแปลงครั้งใหญ่ในการปรับใช้อันตรายเล็กน้อยไม่สามารถปิดได้เพราะไม่มีช่วงเวลาที่ไม่สำคัญเมื่อรหัสจะถูกเปลี่ยนบางส่วน และโดยเฉพาะอย่างยิ่งไม่ได้

หากมีการเปลี่ยนแปลงใหญ่ข้อเสนอแนะของฉันคือโซลูชันเริ่มต้นของคุณ (เปลี่ยนชื่อสองครั้ง)


นี่คือฮาร์ดคอร์เล็กน้อย แต่วิธีแก้ปัญหาอะตอม 100%:

(1) ทำการติดตั้งระบบไฟล์บางส่วนของคุณโดยที่วีโอไอพีของคุณเกิดขึ้น:

mount /dev/sdXY /mnt/tmp

(2) --bindติดตั้ง public_html_new ไปที่ public_html ของคุณ:

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

จากจุดนี้ Apache จะเห็นการปรับใช้ใหม่ของคุณ การเปลี่ยนแปลงใด ๆ ของ 404 เป็นไปไม่ได้

(3) ทำการซิงโครไนซ์กับ rsync แต่บนจุดเมานต์สำรอง):

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

(4) ลบการผูกติด

umount /path/to/public_html

คำสั่งจะลบ public_html และปรับใช้ public_html_new ใหม่หรือไม่
nicoX

@nicoX ไม่มันจะคัดลอกเฉพาะการเปลี่ยนแปลง
เตอร์กล่าวคืนสถานะโมนิก้า

@nicoX มันผ่านทั้งโครงสร้างไดเรกทอรีและหากพบความแตกต่าง (ไฟล์ใหม่, ไฟล์ที่แก้ไข, ไฟล์ที่ถูกลบ) มันจะแก้ไขไดเรกทอรีที่สองให้ตรงกับไดเรกทอรีแรกตามที่จำเป็น ผลลัพธ์ถ้าคุณลบ public_html แล้วย้าย public_html_new ไปยังที่ของมันแต่ไม่มีปัญหาที่อาจเกิดขึ้นชั่วคราว 404
peterh กล่าวคืนสถานะโมนิก้า

1
ไม่นี่ไม่ใช่ความคิดที่ดี ขึ้นอยู่กับการเปลี่ยนแปลงคุณอาจมีช่วงเวลาสั้น ๆ ที่รหัสในpublic_htmlอยู่ในสถานะที่ไม่สอดคล้องกันและคุณไม่ต้องการใช้โอกาสนี้
สเวน

@SvW คุณพูดถูกความคิดของฉันก็โอเคถ้ามีการเปลี่ยนแปลงเพียงเล็กน้อยเท่านั้น ฉันขยายคำตอบของฉันตาม
peterh กล่าวคืนสถานะโมนิก้า

1

การย้าย / การเปลี่ยนhttp_publicโฟลเดอร์สามารถทำได้ง่าย ๆmvหรือln -sคำสั่งหรือสิ่งที่เทียบเท่าในขณะที่เซิร์ฟเวอร์ HTTP ของคุณยังทำงานต่อไป คุณสามารถทำสคริปต์บางอย่างเพื่อลดการหยุดทำงานอย่างมีนัยสำคัญ แต่ตรวจสอบรหัสส่งคืนของคำสั่งของคุณอย่างรอบคอบในสคริปต์ถ้าคุณทำให้กระบวนการอัตโนมัติ

ที่กล่าวว่าหากคุณต้องการที่จะประสบความสำเร็จไม่หยุดทำงานคุณต้องสนับสนุนแอปพลิเคชันด้วย แอปพลิเคชั่นส่วนใหญ่ใช้ฐานข้อมูลเพื่อความคงทน การมีเวอร์ชัน N ของแอปพลิเคชันของคุณยุ่งกับรุ่น N + 1 (หรือด้านหลัง) ของดาต้าโมเดลของคุณอาจทำลายสิ่งต่าง ๆ หากไม่เห็นโดยทีมพัฒนา

จากประสบการณ์การรักษาความสอดคล้องเช่นนี้ผ่านการอัปเกรดไม่ได้ถูกกำหนดไว้สำหรับแอปพลิเคชันส่วนใหญ่ การปิดระบบที่เหมาะสมแม้จะเป็นการหยุดทำงานเป็นวิธีที่ดีในการหลีกเลี่ยงปัญหาที่สอดคล้องกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.