6

Tôi biết rằng với Network Load BalancingFailover Clustering chúng tôi có thể thực hiện dịch vụ thụ động có sẵn. Nhưng còn khoảng ứng dụng đang hoạt động?Làm thế nào để cung cấp các dịch vụ hoạt động cao?

Ví dụ: Một trong các ứng dụng của tôi truy xuất một số nội dung từ tài nguyên bên ngoài trong một khoảng thời gian cố định. Tôi đã tưởng tượng các trường hợp sau:

  1. Chạy trong một máy. Sự cố: nếu trường hợp này rơi, nội dung sẽ không được truy xuất
  2. Chạy nó trong mỗi máy của cụm. Sự cố: nội dung sẽ được truy lục nhiều lần
  3. Có nó trong mỗi máy của cụm, nhưng chỉ chạy nó trong một trong số chúng. Mỗi cá thể sẽ phải kiểm tra một số loại tài nguyên chung để quyết định xem lượt của nó có làm nhiệm vụ hay không.

Khi tôi đang nghĩ về giải pháp # 3 Tôi đã tự hỏi điều gì sẽ là tài nguyên chung. Tôi đã nghĩ đến việc tạo một bảng trong cơ sở dữ liệu, nơi chúng ta có thể sử dụng nó để có được một khóa toàn cầu.

Đây có phải là giải pháp tốt nhất không? Mọi người thường làm như thế nào?

Nhân tiện đây là ứng dụng C# .NET WCF chạy trên Windows Server 2008

Trả lời

4

Đối với các vấn đề như vậy, chúng đã phát minh ra hàng đợi tin nhắn. Hãy tưởng tượng trường hợp khi các ứng dụng nhóm của bạn tất cả lắng nghe một hàng đợi tin nhắn (cụm chính nó :-)). Tại một thời điểm nào đó, một cá thể có lệnh ban đầu của bạn để tải xuống tài nguyên bên ngoài của bạn. Nếu thành công, cá thể của bạn xóa thông báo và thay vào đó nó sẽ đăng một thông báo khác cho một thời gian thực hiện sau đó tương đương với 'thời gian chạy' + 'khoảng thời gian'. Nhưng trong trường hợp cá thể chết trong quá trình xử lý, đó không phải là một vấn đề. Tin nhắn được cuộn lại trong hàng đợi (sau khi hết thời gian chờ) và một số trường hợp khác có thể lấy nó. Một chút giao dịch, một chút thông điệp hàng đợi

Tôi ở bên Java EE của thế giới như vậy có thể giúp bạn với chi tiết mã hóa

+0

up-vote b/c đây là một mô hình tốt để làm theo, tuy nhiên tôi nghĩ rằng câu trả lời của bạn không hoàn toàn áp dụng cho OP vì anh ấy đang xem xét các tùy chọn sẵn có dành riêng cho NLB và phân nhóm chứ không phải doanh nghiệp. –

+0

cho một cái nhìn vào dịch vụ hàng đợi đơn giản Amazon, bạn có thể sử dụng một triển khai tương tự (hoặc thậm chí mua dịch vụ của họ). – dwery

0

Trong một số trường hợp người tìm thấy nó hữu ích để có 3 máy làm tất cả các yêu cầu, và sau đó so sánh kết quả ở cuối, để đảm bảo rằng kết quả là hoàn toàn chính xác và không có lỗi phần cứng gây ra bất kỳ vấn đề nào trong khi xử lý nó. Đây là những gì họ làm trên ví dụ máy bay.

Vào những lúc khác, bạn có thể sống với một kết quả xấu và thời gian ngừng hoạt động nhỏ để chuyển sang dịch vụ mới, nhưng chỉ muốn một dịch vụ tiếp theo được chấp nhận. Trong trường hợp đó giải pháp số 3 với một màn hình nhịp tim là một thiết lập tuyệt vời.

Lần khác, mọi người chỉ cần được thông báo bằng SMS rằng dịch vụ của họ ngừng hoạt động và ứng dụng sẽ chỉ sử dụng một số dữ liệu lỗi thời cho đến khi bạn thực hiện một số loại chuyển đổi dự phòng theo cách thủ công.

Trong trường hợp của bạn, tôi cho rằng trường hợp sau có thể hữu ích hơn cho bạn. Vì bạn không thể thực sự phụ thuộc vào dịch vụ ở đầu kia, bạn sẽ vẫn phải đưa ra một giải pháp cho việc cần làm trong trường hợp đó. Đưa lại dữ liệu lỗi thời có thể là những gì tốt cho bạn, và nó có thể không. Xin lỗi phải nói: Nó phụ thuộc.

+0

Tôi đã chắc chắn rằng giải pháp 3 là một cho tôi, những gì tôi không chắc chắn về là phương pháp đồng bộ hóa. –

+0

Câu hỏi không đề cập đến loại nội dung đang được truy xuất nhưng có thể giả định rằng nó thay đổi theo thời gian (ví dụ: báo giá cổ phiếu) và có thể không đảm bảo rằng 3 máy chủ đưa ra yêu cầu vào những thời điểm hơi khác nhau sẽ nhận được cùng một dữ liệu . –

+0

@Tuzo trong trường hợp của tôi, dữ liệu được cập nhật chỉ sau mỗi 2 phút và được tải xuống cứ mỗi 1m50s –

1

Tôi đã từng triển khai một cái gì đó tương tự bằng cách sử dụng giải pháp của bạn # 3.

Tạo bảng có tên là resource_lock, với cột (ví dụ:locking_key) sẽ chứa khóa khóa.

Sau đó, tại mỗi khoảng thời gian, tất cả các thể hiện của ứng dụng của bạn sẽ:

  1. Chạy một truy vấn như 'update resource_lock set resource_key = 1 where resource_key is null'. (bạn cũng có thể chèn id máy chủ cụ thể, dấu thời gian, v.v.)
  2. Nếu 0 hàng được cập nhật: không làm gì cả - một phiên bản ứng dụng khác đã tìm nạp tài nguyên.
  3. Nếu 1 hàng được cập nhật: tìm nạp tài nguyên và đặt locking_key quay lại null.

Có hai lợi thế với điều này:

  • Nếu một trong các máy chủ của bạn thất bại, tài nguyên sẽ vẫn được lấy bởi các máy chủ đó vẫn đang chạy.
  • Bạn để khóa cho cơ sở dữ liệu, điều này giúp bạn không tự mình thực hiện nó.
+0

nếu xảy ra lỗi trong quá trình thực hiện quy trình thì sao? –

+0

Sau đó hãy tự hỏi: có thực tế khi mong đợi rằng tài nguyên sẽ được tìm nạp thành công khi thử lại không? Nếu có: thực hiện một số loại cơ chế thử lại. Nếu không: chỉ cần bỏ qua và đợi khoảng thời gian tiếp theo. Tôi đoán nó cũng phụ thuộc vào tầm quan trọng của nó là tài nguyên được tìm nạp mỗi lần. –

+0

Tôi đã hỏi về giá trị hàng. Nếu quá trình cập nhật nó thành '1' dừng lại, giá trị có thể sẽ vẫn như vậy và sẽ không có quá trình nào tìm nạp lại tài nguyên đó nữa. –

1

Từ quan điểm đơn giản, cách nhanh nhất/dễ nhất để hoàn thành những gì bạn đang tìm kiếm sẽ là 'xoay vòng' cụm sao của bạn sao cho mọi yêu cầu, một máy được chọn (theo cụm dịch vụ quản lý hoặc một số dịch vụ như vậy) để xử lý yêu cầu. Các yêu cầu thực tế của khách hàng không trực tiếp đến máy xử lý nó; thay vào đó, chúng trỏ đến một điểm cuối duy nhất, hoạt động như một proxy để phân phối các yêu cầu đến máy dựa trên tính khả dụng và tải. Để trích dẫn liên kết được tham chiếu bên dưới,

Cân bằng tải mạng là cách để phản hồi yêu cầu. Nó thường được thực hiện nhất trong các trang trại máy chủ: các máy được định cấu hình giống nhau, trải rộng tải cho trang web hoặc có thể là trang trại Máy chủ đầu cuối. Bạn cũng có thể sử dụng nó cho một trang trại firewall (ISA), các điểm truy cập VPN, bất cứ khi nào bạn có lưu lượng TCP/IP đã tải quá nhiều cho một máy, nhưng bạn vẫn muốn nó xuất hiện như một máy đơn mục đích truy cập.

Đối với ứng dụng của bạn là "hoạt động", yêu cầu đó không ảnh hưởng đến phương trình này vì liệu 'hoạt động' hay 'thụ động', ứng dụng vẫn yêu cầu máy chủ của bạn.

Cân bằng tải thương mại tồn tại để phục vụ các yêu cầu kiểu HTTP, do đó có thể đáng để xem xét, nhưng với các tính năng cân bằng tải của W2k8, bạn có thể phục vụ tốt nhất.

Để biết thêm thông tin về cách định cấu hình trong Win2k8, hãy xem this bài viết.

this article là kỹ thuật hơn và tập trung vào việc sử dụng NLB với Exchange, nhưng các nguyên tắc vẫn nên áp dụng cho trường hợp của bạn.

see here để xem chi tiết hơn về cấu hình và thiết lập NLB.

Nếu không, bạn có thể được phục vụ tốt bằng cách tìm kiếm/đăng trên ServerFault, vì mã ứng dụng của bạn không (và không nên) nhận thức rõ ràng rằng NLB thậm chí còn tồn tại.

EDIT: đã thêm liên kết khác.

EDIT (thứ 2): OP đã sửa kết luận sai của tôi trong khái niệm 'hoạt động' so với 'thụ động'.Câu trả lời của tôi rất giống với câu trả lời ban đầu của tôi, tiết kiệm rằng dịch vụ 'hoạt động' (vì bạn đang sử dụng WCF, có thể dễ dàng là dịch vụ cửa sổ) có thể được chia thành hai phần: phần xử lý thực tế và phần quản lý. Phần quản lý sẽ chạy trên một máy chủ duy nhất, và hoạt động như một bộ cân bằng tải round-robin cho các máy chủ khác đang xử lý thực tế. Nó hơi phức tạp hơn so với kịch bản ban đầu, nhưng tôi tin rằng nó sẽ cung cấp một sự linh hoạt tốt cũng như cung cấp một sự tách biệt rõ ràng giữa xử lý và logic quản lý của bạn.

+0

Bạn không hiểu ý tôi là gì khi hoạt động. Trong kịch bản hoạt động, máy chủ của tôi sẽ không nhận được bất kỳ yêu cầu nào. Thay vào đó, họ sẽ tạo ra nó. –

+0

lời xin lỗi của tôi - Tôi sẽ cập nhật câu trả lời của mình để phản ánh rằng –

+0

cảm ơn bạn đã cập nhật –

1

Có một số yêu cầu mà bạn có thể biết nhưng chưa được mô tả trong câu hỏi làm cho câu trả lời đầy đủ thách thức. Một số câu hỏi trong số này là:

  • Nhiệm vụ có phải hoàn tất thành công không?
  • Nếu tác vụ thực hiện/không hoàn tất thành công, "ai" cần biết và loại hành động nào cần phải được thực hiện?
  • Hành vi nếu nhiệm vụ chưa hoàn thành khi thời gian đến để chạy lại tác vụ là gì? Nó có nên chạy hay không?
  • Công việc quan trọng như thế nào ở khoảng thời gian được chỉ định? Nếu khoảng thời gian là 5 phút một lần thì phải sau 5 phút hoặc có thể chạy sau 5 phút và 10 giây?

Bước đầu tiên là trả lời cách tác vụ định kỳ sẽ được lên lịch để chạy. Một tùy chọn là một tác vụ theo lịch trình của Windows nhưng đó không phải là sẵn sàng cao nhưng có thể làm việc xung quanh đó. Nếu bạn đang sử dụng SQL Server, một lựa chọn khác sẽ là sử dụng SQL Server Agent làm một bộ lập lịch vì nó sẽ chuyển đổi dự phòng thành một phần của SQL Server.

Bước tiếp theo để xác định là cách gọi ứng dụng WCF. Tùy chọn đơn giản nhất là kích hoạt một công việc để gọi dịch vụ WCF thông qua địa chỉ IP NLB. Điều này có thể được coi là không có nếu máy chủ cơ sở dữ liệu (hoặc máy chủ khác trong vùng đó) đang gọi đến vùng ứng dụng (tất nhiên luôn có các ngoại lệ như MSDTC).

Một tùy chọn khác sẽ sử dụng mô hình hàng đợi. Điều này sẽ là đáng tin cậy nhất trong hầu hết các tình huống. ví dụ. SQL Server Agent có thể thực hiện một thủ tục lưu sẵn để nhập một bản ghi trong bảng xếp hàng. Sau đó, trên mỗi máy chủ ứng dụng một dịch vụ có thể thăm dò ý kiến ​​tìm kiếm một bản ghi xếp hàng để xử lý. Truy cập vào bản ghi trong hàng đợi sẽ được tuần tự hóa bởi cơ sở dữ liệu sao cho máy chủ đầu tiên sẽ chạy công việc (và công việc đó sẽ chỉ chạy một lần).

Tùy thuộc vào câu trả lời cho câu hỏi mở trong câu trả lời này, bạn có thể phải thêm một số xử lý lỗi khác. Nếu truy xuất tài nguyên bên ngoài thường khá ngắn, bạn có thể chỉ cần giữ hồ sơ hàng đợi bị khóa với select for update và khi tác vụ được hoàn thành cập nhật trạng thái (hoặc xóa bản ghi nếu bạn muốn). Điều này sẽ chặn các trường hợp dịch vụ khác xử lý bản ghi trong khi nó đang được xử lý trên máy chủ khác và nếu xảy ra sự cố trong quá trình xử lý, giao dịch sẽ được khôi phục và một dịch vụ khác trong cụm có thể nhận bản ghi. (Mặc dù, bạn có thể tăng thời gian chờ giao dịch cho tới chừng nào bạn nghĩ mình cần.)

Nếu giữ khóa cơ sở dữ liệu trong một thời gian dài là không khả thi thì bạn có thể thay đổi logic và thêm một số giám sát vào dịch vụ. Bây giờ, khi một công việc được bắt đầu xử lý, trạng thái của nó sẽ được thay đổi từ hàng đợi để chạy và máy chủ đang xử lý bản ghi sẽ được cập nhật trên bản ghi. Một số loại bảng trạng thái dịch vụ có thể được tạo và mỗi cá thể dịch vụ sẽ cập nhật thời gian hiện tại mỗi khi chúng thăm dò ý kiến. Điều này sẽ cho phép các dịch vụ khác trong cluster xử lý lại các công việc hiển thị như đang chạy nhưng dịch vụ mà chúng được cho là đang chạy trên chưa "kiểm tra" trong một khoảng thời gian nhất định.

Cách tiếp cận này cũng có những hạn chế: nếu nhiệm vụ thực sự hoàn thành nhưng bằng cách nào đó kết nối cơ sở dữ liệu bị mất - công việc có khả năng có thể chạy lại. Tất nhiên, tôi không nghĩ rằng vấn đề có hành động cơ sở dữ liệu nguyên tử được kết hợp với các tài nguyên không giao dịch khác (ví dụ: yêu cầu web, hệ thống tệp) sẽ dễ dàng được giải quyết. Tôi giả sử bạn đang viết một tập tin hoặc một cái gì đó - nếu nội dung bên ngoài cũng được đặt vào một cơ sở dữ liệu thì một giao dịch duy nhất sẽ đảm bảo rằng mọi thứ đều nhất quán.

+0

tôi thích đề xuất của Đại lý máy chủ SQL. Tôi chắc chắn nhiều RDBMS có các tính năng tương tự. –

0

Sở thú làm cho trường hợp sử dụng tốt các khóa phân phối. Zookeeper có z-nút mà giống như thư mục với dữ liệu.

Ngay cả người quản lý Netflix cũng có nhiều công thức nấu ăn đã được thực hiện và sử dụng. Giống như: cuộc bầu cử lãnh đạo, khóa phân phối và nhiều hơn nữa.

Tôi nghĩ rằng chúng tôi có khách hàng của sở thú cho C#. Bạn chắc chắn nên thử tùy chọn này. # Option3

Các vấn đề liên quan