2013-02-04 35 views
7

Tôi đang tìm một số đầu vào về cách mở rộng một Dịch vụ Windows hiện đang chạy tại công ty của tôi. Chúng tôi đang sử dụng .NET 4.0 (có thể và sẽ được nâng cấp lên 4.5 tại một số điểm trong tương lai) và chạy trên Windows Server 2012.Mở rộng các Dịch vụ Windows

Giới thiệu về dịch vụ
công việc của dịch vụ là để truy vấn cho các hàng mới trong một bảng ghi (Chúng tôi đang làm việc với một cơ sở dữ liệu Oracle), xử lý thông tin, tạo và/hoặc cập nhật một loạt các hàng trong 5 bảng khác (hãy gọi chúng là bảng Theo dõi), cập nhật bảng ghi và lặp lại.

Bảng ghi nhật ký có số lượng lớn XML (có thể lên tới 20 MB mỗi hàng) cần được chọn và lưu trong 5 bảng Theo dõi khác. Hàng mới được thêm vào tất cả các thời gian ở tốc độ tối đa 500.000 hàng một giờ.
Lưu lượng truy cập của bảng Theo dõi cao hơn nhiều, từ 90.000 hàng mới trong hàng nhỏ nhất đến hàng triệu hàng tiềm năng trong bảng lớn nhất, mỗi giờ. Chưa kể rằng có các hoạt động Cập nhật trên các bảng đó.

Giới thiệu về dữ liệu đang được xử lý
tôi cảm thấy chút này là rất quan trọng cho việc tìm kiếm một giải pháp dựa trên cách thức các đối tượng này được nhóm lại và xử lý. Cấu trúc dữ liệu trông như thế này:

public class Report 
{ 
    public long Id { get; set; } 
    public DateTime CreateTime { get; set; } 
    public Guid MessageId { get; set; } 
    public string XmlData { get; set; } 
} 

public class Message 
{ 
    public Guid Id { get; set; } 
} 
  • Báo cáo là dữ liệu khai thác gỗ tôi cần phải lựa chọn và quá trình
  • Đối với mỗi tin nhắn có trung bình 5 Báo cáo. Điều này có thể thay đổi từ 1 đến hàng trăm trong một số trường hợp.
  • Thư có một loạt các bộ sưu tập khác và các mối quan hệ khác, nhưng chúng không liên quan đến câu hỏi.

Ngày nay, dịch vụ Windows chúng ta có hầu như không quản lý tải trên một máy chủ 16 lõi (tôi không nhớ đầy đủ các thông số kỹ thuật, nhưng nó an toàn để nói máy này là một con quái vật). Tôi đã được giao nhiệm vụ tìm cách mở rộng quy mô và thêm nhiều máy hơn để xử lý tất cả dữ liệu này và không can thiệp vào các trường hợp khác.

Hiện tại, mỗi Tin nhắn đều nhận được Chủ đề riêng và xử lý các báo cáo có liên quan. Chúng tôi xử lý các báo cáo theo lô, được nhóm theo MessageId của họ để giảm số lượng truy vấn DB xuống mức tối thiểu khi xử lý dữ liệu.

Hạn chế

  • Ở giai đoạn này tôi được phép viết lại dịch vụ này từ đầu sử dụng bất kỳ kiến ​​trúc tôi thấy phù hợp.
  • Nếu một sự cố xảy ra, các trường hợp khác cần phải có khả năng tiếp nhận vị trí bị hỏng. Không có dữ liệu nào có thể bị mất.
  • Quá trình xử lý này cần càng gần thời gian thực càng tốt từ các báo cáo được chèn vào cơ sở dữ liệu.

Tôi đang tìm bất kỳ đầu vào hoặc tư vấn về làm thế nào để xây dựng một dự án như vậy. Tôi cho rằng các dịch vụ sẽ cần phải là không trạng thái, hoặc có cách nào để đồng bộ hóa bộ đệm cho tất cả các trường hợp bằng cách nào đó không? Tôi nên phối hợp giữa tất cả các trường hợp như thế nào và đảm bảo chúng không xử lý cùng một dữ liệu?Làm thế nào tôi có thể phân phối tải như nhau giữa chúng? Và tất nhiên, làm thế nào để xử lý một trường hợp bị rơi và không hoàn thành công việc của nó?

EDIT
Removed thông tin không liên quan

+0

Điều này * có vẻ * giống như quy trình ETL. Bạn đã xem xét việc xem xét một cái gì đó giống như SQL Server Integration Services (SSIS) và viết các gói có thể được lên lịch để chạy thường xuyên thực hiện quá trình này? –

+0

Chúng tôi sử dụng Oracle và up cao hơn không muốn nghe một từ về SQL Server, thật không may. – Artless

+0

Tôi đã suy nghĩ chỉ là một phần SSIS của nó và không phải là công cụ cơ sở dữ liệu :) Các lựa chọn thay thế sẽ là một cái gì đó giống như tích hợp dữ liệu Pentaho (http://www.pentaho.com/explore/pentaho-data-integration/) hoặc phân tích Talend etl (http://www.talend.com/solutions/etl-analytics) –

Trả lời

0

tôi giải quyết điều này bằng cách mã hóa tất cả các khả năng mở rộng này và các công cụ dự phòng một mình. Tôi sẽ giải thích những gì tôi đã làm và làm thế nào tôi đã làm nó, nên bất cứ ai bao giờ cần điều này.

Tôi đã tạo một vài quy trình trong từng trường hợp để theo dõi những người khác và biết bản ghi nào của cá thể cụ thể có thể xử lý. Khi khởi động, cá thể sẽ đăng ký trong cơ sở dữ liệu (nếu nó chưa được) trong một bảng có tên là Instances. Bảng này có các cột sau:

Id     Number 
MachineName  Varchar2 
LastActive   Timestamp 
IsMaster   Number(1) 

Sau khi đăng ký và tạo ra một hàng trong bảng này nếu của MachineName dụ không được tìm thấy, các trường hợp bắt đầu ping bảng này mỗi giây trong một thread riêng biệt, cập nhật cột LastActive của nó. Sau đó, nó chọn tất cả các hàng từ bảng này và đảm bảo rằng Master Instance (nhiều hơn về sau) vẫn còn sống - nghĩa là thời gian là LastActive là trong 10 giây cuối cùng. Nếu thể hiện chủ ngừng đáp ứng, nó sẽ giả định điều khiển và thiết lập chính nó làm chủ. Trong lần lặp tiếp theo, nó sẽ đảm bảo rằng chỉ có một master (trong trường hợp một cá thể khác đã quyết định giả định điều khiển cũng đồng thời), và nếu không nó sẽ sinh ra một cá thể với mức thấp nhất Id.

Ví dụ chính là gì?
Công việc của dịch vụ là quét bảng ghi nhật ký và xử lý dữ liệu đó để mọi người có thể lọc và đọc dễ dàng. Tôi đã không nói điều này trong câu hỏi của tôi, nhưng nó có thể có liên quan ở đây. Chúng tôi có một loạt các máy chủ ESB ghi nhiều bản ghi vào bảng ghi nhật ký cho mỗi yêu cầu và công việc của dịch vụ của tôi là theo dõi chúng trong thời gian thực gần. Vì họ đang ghi nhật ký của họ một cách không đồng bộ, tôi có thể có khả năng nhận được một số finished processing request A trước khi nhập started processing request A trong nhật ký. Vì vậy, tôi có một số mã phân loại các bản ghi đó và đảm bảo dịch vụ của tôi xử lý dữ liệu theo đúng thứ tự. Bởi vì tôi cần phải mở rộng dịch vụ này, chỉ một trường hợp có thể thực hiện logic này để tránh nhiều truy vấn DB không cần thiết và có thể là các lỗi điên rồ.
Đây là nơi mà Master Instance xuất hiện. Chỉ thực thi logic sắp xếp này và tạm thời lưu Id bản ghi nhật ký trong một bảng khác được gọi là ReportAssignment. Công việc của bảng này là để theo dõi các hồ sơ nào đã được xử lý và bởi ai. Sau khi quá trình xử lý hoàn tất, bản ghi sẽ bị xóa. Bảng trông giống như sau:

RecordId  Number 
InstanceId  Number Nullable 

Ví dụ chính sắp xếp các mục nhập nhật ký và chèn Id của chúng ở đây. Tất cả các trường hợp dịch vụ của tôi kiểm tra bảng này trong khoảng thời gian 1 giây cho các bản ghi mới không được xử lý bởi bất kỳ ai hoặc đang được xử lý bởi một trường hợp không hoạt động và rằng [record's Id] % [number of isnstances] == [index of current instance in a sorted array of all the active instances] (đã được mua trong quá trình Pinging). Truy vấn có vẻ như thế này:

SELECT * FROM ReportAssignment 
WHERE (InstanceId IS NULL OR InstanceId NOT IN (1, 2, 3)) // 1,2,3 are the active instances 
AND RecordId % 3 == 0 // 0 is the index of the current instance in the list of active instances 

Tại sao tôi cần phải làm điều này?

  • Hai trường hợp khác sẽ truy vấn RecordId % 3 == 1RecordId % 3 == 2.
  • RecordId % [instanceCount] == [indexOfCurrentInstance] đảm bảo rằng các bản ghi được phân phối đồng đều giữa tất cả các trường hợp.
  • InstanceId NOT IN (1,2,3) cho phép các trường hợp tiếp nhận hồ sơ đã được xử lý bởi một trường hợp đã gặp sự cố và không xử lý các bản ghi của các cá thể đã hoạt động khi một phiên bản mới được thêm vào.

Khi truy vấn cá thể cho các bản ghi này, nó sẽ thực thi lệnh cập nhật, tự đặt InstanceId và truy nhập bảng ghi nhật ký cho các bản ghi đó. Khi quá trình xử lý hoàn tất, nó sẽ xóa các bản ghi từ ReportAssignment.

Nhìn chung, tôi rất hài lòng với điều này. Nó quy mô độc đáo, đảm bảo rằng không có dữ liệu bị mất nếu trường hợp đi xuống, và gần như không có sự thay đổi nào đối với mã hiện có mà chúng ta có.

6

Đối với hạng mục công trình của bạn, Windows Workflow có lẽ là phương tiện nhanh nhất của bạn để cấu trúc lại dịch vụ của bạn.

Windows Workflow Foundation @ MSDN

Điều hữu ích nhất bạn sẽ nhận được ra khỏi WF là quy trình làm việc kiên trì, nơi một công việc thiết kế phù hợp có thể tiếp tục từ một điểm Persist, bất cứ điều gì nên xảy ra với các công việc từ điểm cuối cùng mà nó đã đã lưu.

Workflow Persistence @ MSDN

này bao gồm khả năng cho một công việc phải thu hồi từ quá trình khác nên bất kỳ quá trình sụp đổ khác khi xử lý công việc. Quá trình tiếp tục không cần phải ở trên cùng một máy nếu bạn sử dụng kho lưu trữ luồng công việc được chia sẻ. Lưu ý rằng tất cả các luồng công việc có thể phục hồi yêu cầu sử dụng kho lưu trữ luồng công việc.

Để phân phối công việc, bạn có một vài tùy chọn.

  1. Dịch vụ để tạo thông báo kết hợp với cân bằng tải trên máy chủ thông qua yêu cầu luồng công việc sử dụng điểm cuối WCF qua lớp WorkflowService. Lưu ý rằng bạn có thể muốn sử dụng trình soạn thảo chế độ thiết kế ở đây để xây dựng các phương thức nhập thay vì thiết lập thủ công Receive và các trình xử lý tương ứng SendReply (các bản đồ này cho các phương thức WCF). Bạn có thể sẽ gọi dịch vụ cho mọi Thư, và có lẽ cũng gọi dịch vụ cho mọi Báo cáo. Lưu ý rằng thuộc tính CanCreateInstance rất quan trọng ở đây. Mọi lời gọi được gắn với nó sẽ tạo ra một cá thể đang chạy chạy độc lập.
    ~
    WorkflowService Class (System.ServiceModel.Activities) @ MSDN
    Receive Class (System.ServiceModel.Activities) @ MSDN
    Receive.CanCreateInstance Property (System.ServiceModel.Activities) @ MSDN
    SendReply Class (System.ServiceModel.Activities) @ MSDN

  2. Sử dụng một chiếc xe buýt phục vụ có hỗ trợ Queue. Ở mức tối thiểu, bạn muốn một cái gì đó có khả năng chấp nhận đầu vào từ bất kỳ số lượng khách hàng nào và kết quả đầu ra của nó có thể được xác định duy nhất và xử lý chính xác một lần. Một số trong số đó là NServiceBus, MSMQ, RabbitMQ và ZeroMQ. Trong số các mục được đề cập ở đây, NServiceBus là độc quyền .NET sẵn sàng out-of-the-box. Trong một bối cảnh đám mây, các tùy chọn của bạn cũng bao gồm các dịch vụ nền tảng cụ thể như Azure Service Bus và Amazon SQS.
    ~
    NServiceBus
    MSMQ @ MSDN
    RabbitMQ
    ZeroMQ
    Azure Service Bus @ MSDN
    Amazon SQS @ Amazon AWS
    ~
    Lưu ý rằng các dịch vụ xe buýt chỉ là keo giữa một nhà sản xuất sẽ khởi Thông điệp và một người tiêu dùng có thể tồn tại trên bất kỳ số lượng máy để đọc từ hàng đợi. Tương tự, bạn có thể sử dụng tính năng này để tạo báo cáo. Người tiêu dùng của bạn sẽ tạo ra các thể hiện dòng công việc mà sau đó có thể sử dụng sự tồn tại của luồng công việc.

  3. Windows AppFabric có thể được sử dụng để lưu trữ luồng công việc, cho phép bạn sử dụng nhiều kỹ thuật áp dụng cho cân bằng tải IIS để phân phối tác phẩm của bạn. Cá nhân tôi không có kinh nghiệm với nó, vì vậy không có nhiều tôi có thể nói cho nó khác hơn là nó có hỗ trợ giám sát tốt out-of-the-box.
    ~
    How to: Host a Workflow Service with Windows App Fabric @ MSDN
+0

Cảm ơn! Tôi sẽ phải làm một số đọc và thử nghiệm, và xem những gì công ty của tôi sẵn sàng làm. – Artless

+1

Đưa ra nhận xét của bạn về nhận xét giải pháp báo cáo về câu hỏi của bạn, tôi nên cảnh báo bạn rằng cửa hàng lưu trữ lâu bền với WF dựa trên MS SQL Server, có thể là một giao dịch cho công ty của bạn. Nó có thể là giá trị nhìn thấy nếu bạn có thể nhận được MSDE làm việc như một cửa hàng kiên trì để tránh phải thiết lập một trường hợp MSSQL. – meklarian

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