Đạt được triển khai không ngừng hoạt động


40

Tôi đang cố gắng để đạt được việc triển khai thời gian chết bằng không để tôi có thể triển khai ít hơn trong giờ nghỉ và nhiều hơn trong giờ "chậm" - hoặc bất cứ lúc nào, theo lý thuyết.

Thiết lập hiện tại của tôi, có phần đơn giản hóa:

  • Máy chủ web A (Ứng dụng .NET)
  • Máy chủ web B (Ứng dụng .NET)
  • Máy chủ cơ sở dữ liệu (Máy chủ SQL)

Quy trình triển khai hiện tại của tôi:

  1. "Dừng" các trang web trên cả Máy chủ Web A và B
  2. Nâng cấp lược đồ cơ sở dữ liệu cho phiên bản của ứng dụng đang được triển khai
  3. Cập nhật máy chủ web A
  4. Cập nhật máy chủ web B
  5. Đưa mọi thứ trở lại trực tuyến

Vấn đề hiện tại

Điều này dẫn đến một lượng nhỏ thời gian chết mỗi tháng - khoảng 30 phút. Tôi làm điều này trong giờ nghỉ, vì vậy đó không phải là một vấn đề lớn - nhưng đó là điều tôi muốn tránh xa.

Ngoài ra - không có cách nào để thực sự quay trở lại. Tôi thường không tạo các tập lệnh DB rollback - chỉ nâng cấp các tập lệnh.

Tận dụng cân bằng tải

Tôi muốn có thể nâng cấp một Máy chủ Web cùng một lúc. Lấy Web Server A ra khỏi bộ cân bằng tải, nâng cấp nó, đưa nó trở lại trực tuyến, sau đó lặp lại cho Web Server B.

Vấn đề là cơ sở dữ liệu. Mỗi phiên bản phần mềm của tôi sẽ cần phải thực thi đối với một phiên bản cơ sở dữ liệu khác nhau - vì vậy tôi bị "kẹt".

Giải pháp có thể

Một giải pháp hiện tại tôi đang xem xét là áp dụng các quy tắc sau:

  • Không bao giờ xóa bảng cơ sở dữ liệu.
  • Không bao giờ xóa một cột cơ sở dữ liệu.
  • Không bao giờ đổi tên một cột cơ sở dữ liệu.
  • Không bao giờ sắp xếp lại một cột.
  • Mỗi thủ tục lưu trữ phải được phiên bản.
    • Ý nghĩa - 'spFind ALLThings' sẽ trở thành 'spFind ALLThings_2' khi nó được chỉnh sửa.
    • Sau đó, nó trở thành 'spFind ALLThings_3' khi được chỉnh sửa lại.
    • Quy tắc tương tự áp dụng cho quan điểm.

Trong khi, điều này có vẻ hơi cực đoan - tôi nghĩ nó giải quyết được vấn đề. Mỗi phiên bản của ứng dụng sẽ đánh DB theo cách không phá vỡ. Mã mong đợi một số kết quả nhất định từ các lượt xem / thủ tục được lưu trữ - và điều này giữ cho 'hợp đồng' có hiệu lực. Vấn đề là - nó chỉ thấm nước. Tôi biết tôi có thể dọn sạch các thủ tục lưu trữ cũ sau khi ứng dụng được triển khai trong một thời gian, nhưng nó chỉ cảm thấy bẩn. Ngoài ra - nó phụ thuộc vào tất cả các nhà phát triển tuân theo quy tắc này, điều này hầu hết sẽ xảy ra, nhưng tôi tưởng tượng ai đó sẽ phạm sai lầm.

Cuối cùng - Câu hỏi của tôi

  • Đây là cẩu thả hay hacky?
  • Có ai khác làm theo cách này?
  • Những người khác giải quyết vấn đề này như thế nào?

2
Kế hoạch dự phòng của bạn ở đâu? Làm thế nào để bạn kiểm tra rằng tất cả mọi thứ hoạt động và không có hồi quy?
Deer Hunter

3
Bạn không cần "không bao giờ": bạn "chỉ" cần đảm bảo rằng mỗi hai phiên bản liền kề có thể chạy đồng thời. Điều này hạn chế các đường dẫn nâng cấp của bạn, nhưng không nghiêm trọng như không bao giờ có thể thay đổi lược đồ DB đáng kể.
Joachim Sauer

Cảm ơn Joachim ... Tôi thích nói chuyện một cách tuyệt đối để ý tưởng cơ bản rõ ràng - nhưng bạn đã đúng, chúng ta có thể có chính sách tương thích ngược với các bản phát hành N, tại đó chúng ta có thể loại bỏ các đối tượng DB không cần thiết.
MattW

2
Bạn sẽ muốn có một kế hoạch rollback tại chỗ. Một ngày nào đó bạn sẽ cần nó.
Thorbjørn Ravn Andersen

1
Theo kinh nghiệm của tôi, đối với hầu hết các trang web, giải pháp khả thi của bạn còn tồi tệ hơn vấn đề mà nó giải quyết. Sự phức tạp mà nó sẽ thêm sẽ đắt hơn bạn có thể dự đoán bây giờ. Có lẽ nhiều lần hơn thời gian / nỗ lực để thực hiện thay đổi và thêm tính năng. Tôi chỉ muốn xem xét nó cho các trang web mà hoàn toàn không thể nào có thời gian chết, bao giờ hết .
MGOwen

Câu trả lời:


14

Đây là một cách tiếp cận rất thực tế để nâng cấp phần mềm dựa trên cơ sở dữ liệu. Nó được mô tả bởi Martin Fowler và Pramod Sadalage vào năm 2003 và sau đó được viết trong Tái cấu trúc cơ sở dữ liệu: Thiết kế cơ sở dữ liệu tiến hóa .

Tôi có thể hiểu ý của bạn khi bạn nói rằng nó có vẻ cẩu thả, nhưng khi được thực hiện một cách có chủ ý và đã biết trước và dành thời gian để cấu trúc lại các cấu trúc không sử dụng ra khỏi cơ sở dữ liệu và cơ sở dữ liệu khi chúng không còn được sử dụng nữa, nó mạnh hơn nhiều giải pháp đơn giản hơn dựa trên các kịch bản nâng cấp và rollback.


5

"Thời gian chết không" chỉ là một trong nhiều lý do có thể cho cách tiếp cận này. Giữ một datamodel tương thích ngược theo cách này giúp bạn giải quyết rất nhiều vấn đề khác nhau:

  • nếu bạn có nhiều gói phần mềm truy cập cơ sở dữ liệu của mình, bạn sẽ không phải kiểm tra tất cả nếu thay đổi lược đồ ảnh hưởng đến chúng (trong các tổ chức lớn hơn có nhiều nhóm viết chương trình, tất cả truy cập vào cùng một cơ sở dữ liệu, các thay đổi lược đồ có thể trở nên rất khó khăn)

  • nếu bạn phải, bạn có thể kiểm tra phiên bản cũ hơn của một trong các chương trình của mình và rất có thể nó sẽ chạy lại cơ sở dữ liệu mới hơn (miễn là bạn không mong đợi chương trình cũ xử lý chính xác bất kỳ cột nào mới hơn)

  • nhập / xuất dữ liệu lưu trữ vào phiên bản cơ sở dữ liệu hiện tại dễ dàng hơn nhiều

Đây là một quy tắc bổ sung cho danh sách của bạn

  • mỗi cột mới phải là NULLable hoặc cung cấp một giá trị mặc định có ý nghĩa

(điều này đảm bảo ngay cả các chương trình cũ hơn không biết các cột mới sẽ không phá vỡ bất cứ điều gì khi chúng tạo bản ghi mới trong cơ sở dữ liệu của bạn).

Tất nhiên, cách tiếp cận này có một nhược điểm thực sự: chất lượng datamodel của bạn có thể suy giảm theo thời gian. Và nếu bạn có toàn quyền kiểm soát tất cả các ứng dụng truy cập cơ sở dữ liệu của mình và bạn có thể cấu trúc lại tất cả các ứng dụng đó một cách dễ dàng khi, ví dụ, bạn sẽ đổi tên một cột, thì bạn có thể xem xét để cấu trúc lại mọi thứ theo cách sạch hơn.


4

Nó thay đổi từ triển khai này sang triển khai khác.

Chắc chắn, bạn không bao giờ có thể xóa một bảng hoặc một cột. Bạn không bao giờ có thể thay đổi bất cứ điều gì phá vỡ tính tương thích giao diện. Bạn luôn có thể thêm một lớp trừu tượng. Nhưng sau đó, bạn phải phiên bản trừu tượng hóa và phiên bản phiên bản.

Câu hỏi bạn cần tự hỏi mình là, liệu mỗi bản phát hành có thay đổi lược đồ theo cách không tương thích ngược không?

Nếu rất ít bản phát hành thay đổi lược đồ theo cách đó, thì vấn đề cơ sở dữ liệu bị tắt tiếng. Chỉ cần thực hiện một triển khai của các máy chủ ứng dụng.

Hai điều mà tôi đã thấy giúp ích nhiều nhất cho việc triển khai thời gian chết tối thiểu là:

  1. Phấn đấu cho khả năng tương thích ngược - ít nhất là trong một bản phát hành. Bạn sẽ không luôn đạt được nó, nhưng tôi có thể cá rằng bạn có thể đạt được 90% hoặc nhiều hơn các bản phát hành của mình, đặc biệt nếu mỗi bản phát hành nhỏ.
  2. Có một kịch bản cơ sở dữ liệu trước khi phát hành và sau phát hành. Điều này cho phép bạn xử lý việc đổi tên hoặc thay đổi giao diện bằng cách tạo đối tượng mới trước khi mã ứng dụng của bạn được triển khai, sau đó loại bỏ đối tượng cũ sau khi mã ứng dụng được triển khai. Nếu bạn thêm một cột không nullable mới, bạn có thể thêm nó dưới dạng nullable trong tập lệnh phát hành trước với một bộ kích hoạt điền vào một giá trị mặc định. Sau đó, trong bản phát hành sau của bạn, bạn có thể thả kích hoạt.

Hy vọng phần còn lại của các triển khai của bạn có thể được lưu cho các cửa sổ bảo trì.

Các ý tưởng khác có thể giúp đối phó với một số triển khai cần thời gian chết:

  • Bạn có thể xây dựng khả năng tương thích ngược vào mã của bạn? Ví dụ, có cách nào để mã của bạn có thể hỗ trợ nhiều loại tập kết quả không? Nếu bạn cần thay đổi một cột từ số nguyên thành số kép, mã ứng dụng của bạn có thể đọc nó dưới dạng chuỗi và phân tích cú pháp. Một loại hacky, nhưng nếu đó là mã tạm thời để tự mình vượt qua quá trình phát hành, nó có thể không phải là ngày tận thế.
  • Các thủ tục được lưu trữ có thể giúp cách ly mã ứng dụng của bạn khỏi các thay đổi lược đồ. Điều này chỉ có thể đi rất xa, nhưng không giúp được một chút.

2

Bạn có khả năng có thể làm điều đó như thế này cho một chút nỗ lực.

  1. Sao lưu cơ sở dữ liệu bằng cách xuất
  2. Nhập bản sao lưu nhưng đổi tên nó bằng phiên bản phát hành, ví dụ myDb_2_1
  3. Thực thi phát hành cơ sở dữ liệu trên myDB_2_1
  4. "Dừng" nhóm ứng dụng trên Máy chủ Web A hoặc đưa nó ra khỏi bộ cân bằng tải
  5. Cập nhật Máy chủ Web A, chạy thử nghiệm triển khai bài và khôi phục nếu cần
  6. Phiên làm chảy Web Server B và đưa Web Server A vào vòng lặp
  7. Nâng cấp máy chủ Web B và sau đó đặt lại vào bộ cân bằng tải

Đương nhiên, các bản cập nhật web sẽ cần các mục cấu hình mới để trỏ đến lược đồ Db mới. Điều quan trọng là nếu bạn đang phát hành mỗi tháng một lần và đó là một nhóm nhỏ có bao nhiêu thay đổi DB mà bạn thực sự làm cho nó không tương thích ngược? Nếu bạn có thể kiểm soát điều đó bằng cách kiểm tra, bạn có thể tiến hành triển khai tự động mà không mất thời gian hoặc có thể tệ nhất chỉ sau 5 phút.


1
Điều gì sẽ xảy ra nếu (khi) ứng dụng trên Máy chủ A ghi vào DB của nó sau khi bạn lưu trữ bản sao lưu, nhưng trước khi bạn dừng Máy chủ A? Luôn có một "cửa sổ dễ bị tổn thương". Những bài viết này sẽ bị mất, có thể không được chấp nhận.
sleske
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.