การอัปเดตเว็บแอปโดยไม่ต้องหยุดทำงาน


31

มันเป็นแอพ PHP ฉันจะลดเวลาหยุดทำงานในขณะที่อัพเดทฐานข้อมูลทั้งหมดได้อย่างไร

คำตอบ:


44

สิ่งที่เราทำโดยทั่วไปในที่ทำงานคือ:

  • ก่อนที่เราจะอัพเดทรูทเอกสารของเซิร์ฟเวอร์คือ:
    • ใน /www/app-2009-09-01
    • แต่เข้าถึงได้ผ่านลิงก์สัญลักษณ์ที่เรียกว่า /www/application
  • เราใส่ฐานรหัสใหม่ทั้งหมดลงไป /www/app-2009-09-08
  • เมื่อฐานรหัสทั้งหมดอยู่ที่นั่น:
    • เราลบลิงก์สัญลักษณ์เก่าออก
    • เราสร้างลิงก์สัญลักษณ์ใหม่ที่ยังคงเรียกใช้/www/applicationแต่ชี้ไปที่แหล่งใหม่:/www/app-2009-09-08
  • เราโหลด apache ใหม่เพื่อบังคับให้มีการแก้ไขเพื่อนำมาพิจารณา

กระบวนการทั้งหมดนี้ทำผ่านสคริปต์อัตโนมัติ (สิ่งเดียวที่ไม่อัตโนมัติคือเราเปิดใช้เมื่อจำเป็น) หมายความว่า:

  • ทุกอย่างดำเนินไปอย่างรวดเร็ว (โดยเฉพาะการเปลี่ยนลิงค์สัญลักษณ์ซึ่งเป็นส่วนสำคัญ)
  • ไม่มีความเสี่ยงในการทำผิดพลาด: สคริปต์ได้รับการทดสอบอย่างดีและทำงานได้เป็นเดือน / ปี


ข้อดีอีกอย่างของการเชื่อมโยงสัญลักษณ์ก่อนหน้านี้ก็คือมันเป็นเรื่องง่ายมากที่จะ "ย้อนกลับ" การอัปเดตถ้าเราสังเกตเห็นข้อผิดพลาดที่ร้ายแรงหลังจากวางเวอร์ชั่นใหม่ของแหล่งที่มาเป็นการผลิต: เราเพียงแค่เปลี่ยนลิงค์สัญลักษณ์กลับ

แน่นอนว่านี่ไม่ได้ป้องกันคุณจากการทดสอบเวอร์ชันใหม่บนเซิร์ฟเวอร์ staging ของคุณก่อนที่จะนำไปผลิต - แต่ใครจะรู้ ... บางครั้งมีข้อผิดพลาดที่ใหญ่มาก ๆ ที่ไม่มีใครสามารถมองเห็นได้ในขณะที่ การทดสอบ :-(
ตัวอย่างเช่นเนื่องจากไม่มีการทดสอบโหลดทำเป็นประจำในเครื่องจัดเตรียม
(ฉันเคยเห็นสิ่ง "ย้อนกลับ" ใช้บางอย่างเช่น 4 หรือ 5 ครั้งใน 3 ปี - ทุกครั้ง บันทึกวัน - และเว็บไซต์ ^^)


นี่คือตัวอย่างสั้น ๆ : สมมติว่าฉันมี VirtualHost นี้ในการกำหนดค่า Apache ของฉัน:

<VirtualHost *>
        ServerName example.com
        DocumentRoot /www/application
        <Directory /www/application>
            # Whatever you might need here (this example is copy-pasted from a test server and test application ^^ )
            Options Indexes FollowSymLinks MultiViews +SymLinksIfOwnerMatch
            AllowOverride All
            php_value   error_reporting 6135
            php_value short_open_tag  on
        </Directory>
</VirtualHost>

สวย "มาตรฐาน" ... สิ่งเดียวที่/www/applicationไม่ใช่ไดเรกทอรีจริง: มันเป็นเพียงลิงค์สัญลักษณ์ไปยังรุ่นปัจจุบันของแหล่งที่มา
ซึ่งหมายความว่าเมื่อคุณใส่แหล่งข้อมูลลงในเซิร์ฟเวอร์ แต่ยังไม่ได้เปลี่ยนคุณจะมีสิ่งนี้:

root@shark:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root   19 2009-09-08 22:08 application -> /www/app-2009-09-01

ขอให้สังเกตว่า symlinc ชี้ไปที่ "เวอร์ชั่นเก่า"

ตอนนี้อัปโหลดเวอร์ชันใหม่ทั้งหมดไปยังเซิร์ฟเวอร์แล้วให้สลับ:

root@shark:/www
# rm /www/application
root@shark:/www
# ln -s /www/app-2009-09-08 /www/application

และตอนนี้/www/applicationจุดที่เป็นเวอร์ชั่นใหม่ของแหล่งที่มา:

root@shark:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root   19 2009-09-08 22:09 application -> /www/app-2009-09-08

และเราต้องรีสตาร์ท Apache:

root@shark:/www
# /etc/init.d/apache2 restart
 * Restarting web server apache2

สามขั้นตอน " ลบลิงค์สร้างลิงค์ใหม่เริ่ม Apache ใหม่ " ควรทำอย่างรวดเร็ว เช่นโดยสคริปต์อัตโนมัติและไม่ใช่โดยมนุษย์

ใช้วิธีนี้:

  • คุณสามารถใช้เวลามากเท่าที่คุณต้องการอัปโหลดเวอร์ชันใหม่ของแหล่งที่มา: apache จะไม่ใช้งานตราบใดที่ยังไม่มีการเปลี่ยนแปลง
  • เมื่อทุกอย่างเรียบร้อยเพียงสลับ symlink: มันจะเปลี่ยนเร็วกว่าการเปลี่ยนแม้แต่ 1 หรือ 2 ไฟล์ ... ซึ่งหมายความว่าแทบจะไม่มีการหยุดทำงาน :-)

และถ้าใช้ opcode-cache อย่าง APC กับตัวเลือก stat ที่ 0 นั่นอาจหมายถึงความเสี่ยงต่อการหยุดทำงานน้อยลง


แน่นอนว่าเป็นรุ่น "ง่าย" - หากคุณมีไฟล์ที่อัปโหลดบางไฟล์คุณจะต้องใช้ symlink อื่นที่อื่นหรือ VirtualHost อื่นหรืออะไรก็ตาม ...


หวังว่านี่จะชัดเจนมากขึ้น :-)


มันเป็นประเภทของการแลกเปลี่ยนเซิร์ฟเวอร์ด้วย :-)
Wim Ten Brink

mod_rewrite เพื่อจัดการลิงค์สัญลักษณ์?

@GAMBOOKa: ไม่: เพียงแค่เรื่องของ DocumentRoot ของ Apache (หรือ VirtualHost DocumentRoot) ซึ่งเป็น / www / application ;; เช่นลิงก์สัญลักษณ์ - ไม่ว่าจุดใดที่ชี้ไป

2
คำตอบที่ยอดเยี่ยม อีกหนึ่งเคล็ดลับ: คุณสามารถสร้างลิงก์สัญลักษณ์ได้โดยไม่ต้องยกเลิกการเชื่อมโยง ตามที่ยกมา: "สามขั้นตอน ... ควรทำอย่างรวดเร็วเช่นโดยสคริปต์อัตโนมัติและไม่ใช่โดยมนุษย์" คำสั่ง mv เป็นการดำเนินการแบบอะตอมมิกดังนั้นคุณสามารถสร้าง symlink เช่น 'ln -s / www / app-2011-01-28 / www / application-temp' จากนั้นทำ 'mv -T / www / application-temp / www / แอพลิเคชัน'

1
มีบางสิ่งที่ไม่ครอบคลุมโดยวิธี symlink วิธีการของคุณทำงานกับ Apache + mod_php แต่อาจล้มเหลวใน lighttpd + fastcgi ในเว็บไซต์ที่มีปริมาณการใช้งานสูงคำขอจะได้รับการแลกเปลี่ยนลิงค์ซึ่งการพึ่งพาโค้ด php จะล้มเหลวเมื่อมีเวอร์ชันผสม
Dennis C

2

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


1

ตั้งค่าเซิร์ฟเวอร์ที่สองด้วย codebase ที่อัปเดตแล้วเปลี่ยนให้เร็วที่สุด :-)

หากเป็นไปไม่ได้ตรวจสอบให้แน่ใจว่า codebase ของคุณแบ่งออกเป็นหลายส่วนเล็ก ๆ จากนั้นการหยุดทำงานจะถูก จำกัด เพียงหนึ่งส่วนย่อยในเวลานั้น บล็อคโค้ดขนาดเล็กนั้นง่ายต่อการเปลี่ยนและส่วนใหญ่จะทำงานต่อไปโดยไม่มีปัญหา ลองทำสิ่งนี้ในสภาพแวดล้อมการทดสอบก่อน!


เนื่องจากแอปไม่ได้รับการทดสอบด้วยโมดูลแยกส่วนมันอาจส่งผลให้เกิดสถานการณ์ที่ไม่คาดคิด

ซึ่งหมายความว่าสิ่งนี้จะอยู่ในรายการสิ่งที่ต้องทำของคุณสำหรับหลังจากการอัพเดตนี้ :-) ทำให้เป็นมอดุลาร์มากขึ้นและคุณสามารถอัปเดตต่อโมดูล
Wim ten Brink

1
นั่นคือในรายการสิ่งที่ต้องทำ แต่เป็นเป้าหมายระยะยาว เราเพิ่งเริ่มต้นเล็กดังนั้นองค์กรภายในทีม dev จะใช้เวลาสักครู่ = D

1

ก่อนอื่นฉันมักจะใช้และชอบวิธีการที่คล้ายกับการตอบสนองของ Pascal MARTIN

อีกวิธีที่ฉันชอบคือใช้ SCM ของฉันเพื่อส่งรหัสใหม่ กระบวนการที่แน่นอนขึ้นอยู่กับประเภทของ SCM ของคุณ (git vs svn vs ... ) หากคุณกำลังใช้ svn ฉันต้องการสร้างสาขา "ออนไลน์" หรือ "การผลิต" ที่ฉันชำระเงินเป็นรูทเอกสารบนเซิร์ฟเวอร์ จากนั้นเมื่อใดก็ตามที่ฉันต้องการที่จะผลักดันรหัสใหม่จากสาขาอื่น / แท็ก / ลำตัวฉันเพียงแค่ยอมรับรหัสใหม่ในสาขา "ออนไลน์" และเรียกใช้การปรับปรุง svn ในรากของเอกสาร การทำเช่นนี้ช่วยให้สามารถย้อนกลับได้ง่ายมากเนื่องจากมีบันทึกการแก้ไขที่สมบูรณ์ของสิ่งที่ขึ้น / ลงไปยังเซิร์ฟเวอร์และใครเป็นผู้ทำและเมื่อใด นอกจากนี้คุณยังสามารถเรียกใช้สาขา "ออนไลน์" ได้อย่างง่ายดายบนกล่องทดสอบช่วยให้คุณสามารถตรวจสอบแอปที่คุณกำลังจะผลักดัน

กระบวนการนี้คล้ายกับคอมไพล์และรูปแบบอื่น ๆ ของ SCM ซึ่งเพิ่งได้รับการปรับเปลี่ยนให้เป็นธรรมชาติมากขึ้นสำหรับรูปแบบกระบวนการทำงานของพวกเขา

ต้องการดึง / สำรวจความคิดเห็นแทนที่จะทำการอัปเดตหรือไม่ เพียงแค่มีงาน cron หรืออื่น ๆ กลไกที่ชาญฉลาดทำงานเรียกใช้การปรับปรุง svn โดยอัตโนมัติ

พิเศษ:คุณสามารถใช้กระบวนการนี้เพื่อสำรองไฟล์ที่แอปพลิเคชันของคุณเขียนลงดิสก์ได้ เพียงแค่มีงาน cron หรือกลไกอื่น ๆ ที่เรียกใช้ svn กระทำ ตอนนี้ไฟล์ที่แอปพลิเคชันของคุณสร้างขึ้นจะถูกสำรองไว้ใน SCM ของคุณบันทึกการแก้ไขและอื่น ๆ (เช่นหากผู้ใช้อัปเดตไฟล์บนดิสก์ แต่ต้องการให้คุณย้อนกลับ


0

ฉันใช้วิธีการที่คล้ายคลึงกับของ Pascal MARTIN ด้วย แต่แทนที่จะอัปโหลดแอพของฉันหลายเวอร์ชันไปยังเซิร์ฟเวอร์ที่ใช้งานจริงฉันเก็บ "บิลด์" ไว้หลังไฟร์วอลล์ของฉันแต่ละอันในไดเรกทอรีแยกต่างหากด้วยหมายเลขบิลด์และวันที่ เมื่อฉันต้องการอัปโหลดเวอร์ชันใหม่ฉันใช้สคริปต์ง่ายๆที่มี "rsync -avh --delay-updates" การตั้งค่าสถานะ "ล่าช้า = การอัปเดต" จะอัปโหลดทุกอย่าง (แตกต่างกัน) ไปยังโฟลเดอร์ชั่วคราวจนกว่าจะมีการอัปเดตทั้งหมดจากนั้นย้ายทุกอย่างพร้อมกันในตอนท้ายของการถ่ายโอนไปยังเส้นทางที่เหมาะสมของพวกเขา รัฐครึ่งเก่าใหม่ มันมีผลเช่นเดียวกับวิธีการข้างต้นยกเว้นฉันเก็บแอปหนึ่งเวอร์ชันไว้ในไซต์ที่ใช้งานจริงเท่านั้น (ควรมีไฟล์สำคัญที่เปลือยเปล่าเท่านั้นบนเซิร์ฟเวอร์ที่ใช้งานจริง IMO)

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