Triển khai mã mới trực tiếp


29

Cách thực hành tốt nhất để triển khai mã mới trên trang web trực tuyến (thương mại điện tử) là gì?

Hiện tại tôi đã dừng apache trong khoảng +/- 10 giây khi đổi tên thư mục public_html_newthành public_htmlvà cũ thành public_html_old. Điều này tạo ra một thời gian ngắn, trước khi tôi khởi động lại Apache.

Câu hỏi tương tự sẽ xảy ra nếu sử dụng Git để kéo repo mới vào thư mục trực tiếp. Tôi có thể kéo repo khi trang đang hoạt động không? Và nếu tôi cần sao chép DB thì sao?

Trong quá trình nén tar (mục đích sao lưu) của trang web trực tiếp, tôi nhận thấy rằng những thay đổi đã xảy ra trong thư mục phương tiện. Điều đó cho tôi thấy rằng các tập tin tiếp tục thay đổi theo định kỳ. Và nếu những thay đổi này có thể can thiệp nếu Apache không bị dừng trong quá trình triển khai.

Câu trả lời:


13

Sử dụng một bộ cân bằng tải là một ý tưởng tốt. Nếu trang web đủ quan trọng để lo lắng về một vài giây ngừng hoạt động, thì điều đó đủ quan trọng để lo lắng về khả năng chịu lỗi.

Ngoài ra, nếu điều này nằm trên một hệ thống UNIX, bạn có thể tạm dừng Apache trong khi đổi tên (hoặc cập nhật symlink, v.v.):

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

Điều này sẽ ngăn Apache chấp nhận các yêu cầu mới trong quá trình đổi tên. Nếu bạn thích liên kết tượng trưng hoặc một số cách tiếp cận khác, cùng một ý tưởng có thể được sử dụng:

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

Lưu ý rằng mọi kết nối hoặc gói đang chờ xử lý sẽ xếp hàng trong HĐH. Đối với một trang web cực kỳ bận rộn, hãy xem xét điều chỉnh ListenBacklog nếu phù hợp với loại nhân viên httpd của bạn và kiểm tra cài đặt hệ điều hành của bạn liên quan đến tồn đọng nghe TCP.

Bạn cũng có thể thay đổi DocumentRoot trong httpd.conf và thực hiện khởi động lại duyên dáng ( apachectl graceful). Hạn chế ở đây là tăng nguy cơ lỗi, vì bạn cũng phải cập nhật bất kỳ Directorycấu hình nào .


Phiên tạm dừng này vẫn có trang web đang chạy?
nicoX

4
Nó ngừng cung cấp thời gian CPU cho Apache. Nếu bạn đã cố truy cập trang web trong trình duyệt trong khi Apache bị tạm dừng, trình duyệt sẽ chờ kết nối cho đến khi Apache được nối lại (hoặc trình duyệt hết thời gian, nếu Apache bị tạm dừng lâu hơn thời gian chờ). Nếu ai đó đang trong quá trình tải xuống một tệp, Apache sẽ ngừng gửi dữ liệu trong khi nó bị tạm dừng, vì nó không nhận được bất kỳ thời gian CPU nào. Một lần nữa, điều này sẽ chỉ gây ra vấn đề nếu Apache bị dừng quá lâu mà hết thời gian chuyển.
GargantuChet

5
Nói cách khác, trang web sẽ không phản hồi trong khi Apache bị tạm dừng, nhưng các hoạt động đang chờ xử lý sẽ kết thúc khi được nối lại. Người dùng sẽ không nhận được "từ chối kết nối" và tải xuống sẽ không bị hỏng, nhưng các hoạt động sẽ chỉ tiếp tục khi Apache được nối lại. Điều này sẽ đảm bảo rằng các giao dịch hiện tại có thể kết thúc, nhưng các yêu cầu mới sẽ chỉ được xử lý sau khi nội dung mới của bạn được chuyển vào vị trí.
GargantuChet

1
Xin lưu ý rằng trong bất kỳ trang web có lưu lượng truy cập cao nào, điều này sẽ rất dễ dàng giết chết dịch vụ Apache của bạn. 200 rq / s sẽ rất dễ dàng làm hỏng nhóm kết nối của bạn ngay khi bạn sẽ 'mở khóa' quy trình Apache của mình sau khi di chuyển (nếu di chuyển mất một lúc)
CloudWeavers

1
Trên một trang web có lưu lượng truy cập cao, sẽ có rất nhiều yêu cầu trên chuyến bay kết thúc khi Apache được nối lại. Điều này sẽ ngăn cản việc xử lý các yêu cầu mới. Đây cũng là một lý lẽ tốt để đảm bảo các cài đặt Apache của bạn (số lượng chủ đề / máy chủ / máy khách tối đa) hợp lý và điều chỉnh tồn đọng TCP tương ứng. Mặc dù tôi bối rối về ý của bạn khi "giết" dịch vụ. Apache rất dễ điều chỉnh.
GargantuChet

32

Nhanh nhất và dễ nhất là sử dụng một thư mục phiên bản như

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

và sử dụng một liên kết tượng trưng hiện tại làm html_root của bạn:

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

Kỹ thuật này tích hợp hoàn hảo vào hệ thống kiểm soát sửa đổi (svn, git, mercurial, ...) khi bạn có thể kiểm tra các nhánh & thẻ, thay đổi liên kết tượng trưng và tải lại Apache. Thời gian chết là tối thiểu khi sử dụng kỹ thuật này và nó cho phép khôi phục rất dễ dàng .

Nó cũng tích hợp tốt với hệ thống triển khai phức tạp hơn như các gói RPM hoặc cơ sở hạ tầng quản lý thay đổi cấu hình (đầu bếp, con rối, v.v.).


4
Giải pháp đơn giản nhất luôn là tốt nhất ... :-) Tất nhiên đừng quên đề cập, có thể cần một số FollowSymlinks và các cờ apache như vậy trong các cấu hình.
peterh nói rằng phục hồi Monica

Hãy đặc biệt quan tâm đến những gì @PeterHorvath nói. Apache có thể trở nên rất cục cằn khi làm việc với DocumentRoots được liên kết. Hãy chắc chắn để kiểm tra cẩn thận!
mhutter

@mhutter Cảm ơn :-) Điều thực sự có vấn đề là việc kích hoạt FollowSymlinks trên apache có thể gây ra vấn đề bảo mật ...
peterh nói phục hồi Monica

Cập nhật một liên kết tượng trưng không phải là một hoạt động nguyên tử. Ngay cả khi sử dụng một cái gì đó như ln -snfđể chặn các liên kết ban đầu, hoạt động cơ bản là một unlinksymlink. Có một cơ hội người dùng nhận được 404 trong khi cập nhật. Điều này không tốt hơn là chỉ đổi tên thư mục gốc ra khỏi đường đi và đổi tên một thư mục mới vào vị trí (giả sử bạn không vượt qua các hệ thống tập tin). Xem câu trả lời ở trên với một dấu kiểm bên cạnh, giải quyết mối quan tâm này.
GargantuChet

14

Đổi tên các thư mục mà không tắt Apache cũng sẽ hoạt động. Điều đó sẽ rút ngắn đáng kể cửa sổ.mv public_html public_html_old && mv public_html_new public_htmlnên kết thúc trong một phần của giây.

Một vài nhược điểm là cách tiếp cận này sẽ đưa ra 404bất kỳ yêu cầu nào vẫn còn xảy ra trong cửa sổ. Và nếu bạn chạy lệnh trên mà không có public_html_newthư mục thì nó sẽ thất bại và để lại cho bạn một trang web cung cấp cho 404mỗi yêu cầu.

Làm nó nguyên tử với các thư mục không hỗ trợ. Nhưng bạn có thể làm điều đó với symlink. Thay vì có một thư mục được đặt tên public_html, hãy đặt một thư mục có tên public_html.version-numbervà một liên kết tượng trưng được gọi là public_htmltrỏ đến thư mục đó. Bây giờ bạn có thể tạo một thư mục được gọi public_html.new-version-numbervà một liên kết tượng trưng mới được gọi public_html.new.

Sau đó, bạn có thể đổi tên public_html.newđể public_htmlchuyển đổi nguyên tử. Lưu ý rằng mv"quá thông minh" để thực hiện việc đổi tên đó, nhưng nó có thể được thực hiện bằng cách sử dụng os.renametừ python hoặc bất cứ thứ gì khác sẽ gọirename hệ thống mà không cố tỏ ra thông minh.

Phải làm gì với cơ sở dữ liệu tùy thuộc vào cơ sở dữ liệu bạn đang sử dụng và bạn đang sử dụng cơ sở dữ liệu đó để làm gì. Bạn cần cung cấp nhiều chi tiết hơn về cơ sở dữ liệu trước khi chúng tôi có thể cung cấp cho bạn câu trả lời hay cho phần câu hỏi đó.


1
Trên hệ thống Debian của tôi, mvcó một -Ttùy chọn giữ cho nó không theo liên kết tượng trưng. Điều này sẽ cho phép bạn đổi tên nguyên tử public_html.newtrên public_html, giả sử cả hai đều là liên kết mềm.
GargantuChet

11

Symlinks và mv là bạn bè của bạn, tuy nhiên, nếu bạn thực sự cần tránh người dùng cuối gặp phải trang lỗi trong khi triển khai phiên bản mới, bạn nên có proxy ngược hoặc bộ cân bằng tải trước ít nhất 2 máy chủ phụ trợ (apache trong trường hợp của bạn).

Trong quá trình triển khai, bạn chỉ cần dừng một phụ trợ tại một thời điểm, triển khai mã mới, khởi động lại và sau đó lặp lại trên các phụ trợ còn lại.

Người dùng cuối sẽ luôn được proxy hướng đến các phụ trợ tốt.


4
Tôi chỉ đang làm việc với câu trả lời này khi tôi thấy bạn đã đăng nó. Máy chủ Balancer + 2 làm cho quá trình trở nên vô hình và dễ dàng phục hồi hơn từ bản nâng cấp xấu ...
Bart Silverstrim

9

Nếu bạn đang áp dụng các thay đổi thường xuyên trên một hệ thống sản xuất, tôi sẽ chăm sóc một vòng đời có cấu trúc. Một thực hành tốt là Capistrano http://capistranorb.com/ . Đây là một giải pháp nguồn mở để triển khai phần mềm trên một hoặc nhiều máy chủ trên một số nền tảng và cấu hình.

Đối với Magento thậm chí còn có một plugin: https://github.com/augustash/capistrano-ash/wiki/Magento-Example

Đối với máy chủ đơn và chuyển tiếp gần như liền mạch, tôi khuyên bạn nên sử dụng liên kết tượng trưng.


4

Cách tôi làm là cam kết những thay đổi của tôi từ môi trường nhà phát triển địa phương của tôi sang kho lưu trữ Git trực tuyến như Github. Môi trường sản xuất của tôi chạy ra một kho lưu trữ từ xa, vì vậy tất cả những gì tôi cần làm là ssh đến máy chủ và chạy git pullđể đưa ra những thay đổi mới nhất. Không cần phải dừng máy chủ web của bạn.

Nếu bạn có các tệp trong dự án có cài đặt và / hoặc nội dung khác với phiên bản cục bộ của bạn (chẳng hạn như tệp cấu hình và tải lên phương tiện), bạn có thể sử dụng các biến môi trường và / hoặc thêm các tệp / thư mục này vào .gitignoretệp để ngăn đồng bộ hóa với kho lưu trữ.


3

Ý tưởng đầu tiên của tôi là:

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

Một giải pháp tốt là sử dụng rsync. Nó chỉ thay đổi các tập tin thực sự thay đổi. Hãy coi chừng, dấu gạch chéo ở cuối ot các đường dẫn ở đây rất quan trọng.

Thông thường apache không cần khởi động lại, đó không phải là thế giới java. Nó kiểm tra sự thay đổi của mọi tệp php theo yêu cầu và tự động đọc lại (và mã hóa lại) khi thay đổi.

Git pull có hiệu quả tương tự, mặc dù kịch bản khó hơn một chút. Tất nhiên, nó cho phép một loạt các khả năng phát hiện thay đổi / hợp nhất khác nhau.

Giải pháp này sẽ chỉ liền mạch nếu không có thay đổi thực sự lớn - nếu có những thay đổi lớn trong quá trình triển khai, một chút nguy hiểm không thể được đóng lại, bởi vì có một khoảng thời gian không đáng kể, khi mã sẽ được thay đổi một phần và đặc biệt là không.

Nếu có thay đổi lớn, đề xuất của tôi là giải pháp ban đầu của bạn (hai lần đổi tên).


Đây là một chút khó khăn, nhưng giải pháp nguyên tử 100%:

(1) thực hiện thay thế một số hệ thống tập tin của bạn, nơi magento của bạn diễn ra:

mount /dev/sdXY /mnt/tmp

(2) thực hiện việc --bindgắn kết public_html_new của bạn thành public_html:

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

Từ thời điểm này, apache sẽ thấy triển khai mới của bạn. Mọi thay đổi của 404 là không thể.

(3) thực hiện quá trình tổng hợp với rsync, nhưng trên điểm gắn kết thay thế):

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

(4) loại bỏ gắn kết liên kết

umount /path/to/public_html

Lệnh sẽ xóa public_html và triển khai public_html_new vào nó chứ?
nicoX

@nicoX Không, nó sẽ chỉ sao chép các thay đổi.
peterh nói rằng phục hồi Monica

@nicoX Nó đi qua cả hai cấu trúc thư mục và nếu tìm thấy sự khác biệt (tệp mới, tệp đã sửa đổi, tệp đã xóa), nó sẽ sửa đổi thư mục thứ hai để khớp với thư mục thứ nhất, vì nó cần thiết. Kết quả nếu bạn đã xóa public_html và sau đó di chuyển public_html_new đến vị trí của nó, nhưng không có khả năng xảy ra sự cố 404 tạm thời.
peterh nói rằng phục hồi Monica

1
Không, đây không phải là một ý tưởng tốt. Tùy thuộc vào các thay đổi, bạn có thể có một khoảng thời gian ngắn mà mã ở public_htmltrạng thái không nhất quán và bạn không muốn nắm lấy cơ hội này.
Sven

@SvW Bạn nói đúng, ý tưởng của tôi chỉ ổn nếu chỉ có những thay đổi nhỏ. Tôi mở rộng câu trả lời của mình cho phù hợp.
peterh nói phục hồi Monica

1

Di chuyển / thay thế http_publicthư mục có thể đạt được bằng cách đơn giản mvhoặcln -s lệnh hoặc tương đương trong khi máy chủ http của bạn luôn chạy. Bạn có thể thực hiện một số tập lệnh để giảm đáng kể thời gian chết, nhưng hãy kiểm tra cẩn thận mã trả về của các lệnh trong tập lệnh nếu bạn tự động hóa quy trình.

Điều đó nói rằng, nếu bạn muốn đạt được không có thời gian chết, bạn áp dụng cũng phải hỗ trợ nó. Hầu hết các ứng dụng sử dụng một cơ sở dữ liệu cho sự kiên trì. Có phiên bản N của ứng dụng của bạn gây rối với phiên bản N + 1 (hoặc ngược lại) của datamodel của bạn có thể phá vỡ mọi thứ nếu không được dự kiến ​​bởi nhóm phát triển.

Từ kinh nghiệm, việc duy trì tính nhất quán như vậy thông qua các bản nâng cấp không phải là điều được đưa ra cho hầu hết các ứng dụng. Tắt máy đúng cách, mặc dù thời gian chết, là một cách tốt để tránh các vấn đề nhất quán.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.