it-swarm-vi.com

Phục vụ các tác vụ nền trên một trang web lớn

Chúng tôi đang xử lý một vấn đề thú vị trên StackOverflow.

Chúng tôi đã có một loạt các nhiệm vụ "cần phải hoàn thành sớm". Một ví dụ đang cập nhật danh sách "Câu hỏi liên quan". Những gì chúng ta đã làm trong quá khứ là cõng những nhiệm vụ đó lên tải trang của một số người dùng.

Điều này không bao giờ lý tưởng, nhưng nó không thực sự đáng chú ý. Bây giờ SO đã vượt qua mốc 1.000.000 câu hỏi, những người dùng không may mắn đó đang bắt đầu cảm thấy nó.

Giải pháp tự nhiên là thực sự đẩy các tác vụ này vào nền. Có hai cách rộng rãi để làm điều này tôi đang xem xét.

1. Trong IIS dưới dạng nhóm luồng/công việc-hàng đợi tùy chỉnh

Về cơ bản, chúng tôi tạo ra một số chủ đề (không - ThreadPool , để không can thiệp vào IIS) và cung cấp cho họ các dịch vụ mà một số bộ sưu tập chúng tôi đang đưa Funcs vào.

Các pro lớn ở đây là sự đơn giản. Chúng tôi không phải lo lắng về việc sắp xếp bất cứ điều gì, chúng tôi cũng không phải đảm bảo rằng một số dịch vụ bên ngoài đã hoạt động và đáp ứng.

Chúng tôi cũng có quyền truy cập vào tất cả các mã phổ biến của chúng tôi.

Con lừa, tốt, chúng ta không nên sử dụng chủ đề nền. Tất cả những phản đối mà tôi biết đều tập trung vào việc bỏ đói IIS (nếu bạn sử dụng ThreadPool) và các luồng bị chết ngẫu nhiên (do tái chế AppPool).

Chúng tôi đã có cơ sở hạ tầng hiện có để biến cái chết của luồng ngẫu nhiên thành một vấn đề (về cơ bản có thể phát hiện một nhiệm vụ đã bị bỏ rơi) và việc giới hạn số lượng luồng (và sử dụng các luồng không phải ThreadPool) cũng không khó.

Tôi có thiếu bất kỳ sự phản đối nào khác trong IIS xử lý chuỗi luồng/công việc-hàng đợi không?

Đã chuyển sang StackOverflow , vì nó không thực sự được giải quyết ở đây.

2. Là một dịch vụ

Hoặc một số giải pháp của bên thứ ba, hoặc một giải pháp tùy chỉnh.

Về cơ bản, chúng tôi sắp xếp một nhiệm vụ xuyên qua ranh giới quy trình cho một số dịch vụ và chỉ cần quên nó đi. Có lẽ chúng tôi đang liên kết một số mã trong hoặc bị hạn chế đối với SQL thô + chuỗi kết nối.

Chuyên nghiệp là "cách đúng đắn" để làm điều này.

Nhược điểm là chúng tôi hoặc rất hạn chế trong những gì chúng tôi có thể làm hoặc chúng tôi sẽ phải tìm ra một số hệ thống để giữ dịch vụ này đồng bộ với cơ sở mã của chúng tôi. Chúng tôi cũng cần phải kết nối tất cả các hoạt động theo dõi và đăng nhập lỗi của chúng tôi bằng cách nào đó mà chúng tôi nhận được miễn phí với tùy chọn "Trong IIS".

Có bất kỳ lợi ích hoặc vấn đề nào khác với cách tiếp cận dịch vụ không?

Tóm lại, có những vấn đề chưa được giải quyết và không thể khắc phục được khiến cho cách tiếp cận số 1 không thể thực hiện được và nếu có thì có dịch vụ bên thứ ba nào tốt mà chúng ta nên xem xét cho cách tiếp cận số 2 không?

49
Kevin Montrose

Vài tuần trước tôi đã hỏi một câu hỏi tương tự trên SO. Trong một Shell Shell, cách tiếp cận của tôi trong một thời gian bây giờ là phát triển Dịch vụ Windows. Tôi sẽ sử dụng NServiceBus (về cơ bản là MSMQ dưới vỏ bọc) để yêu cầu nguyên soái từ ứng dụng web của tôi đến dịch vụ của tôi. Tôi đã từng sử dụng WCF nhưng để giao dịch phân tán hoạt động chính xác qua WCF luôn có vẻ như là một nỗi đau ở mông. NServiceBus đã thực hiện thủ thuật này, tôi có thể cam kết dữ liệu và tạo các tác vụ trong giao dịch và không lo lắng liệu dịch vụ của mình có hoạt động hay không. Một ví dụ đơn giản, nếu tôi cần gửi email (ví dụ email đăng ký), tôi sẽ tạo tài khoản người dùng và gửi tín hiệu đến Dịch vụ Windows của tôi (để gửi email) trong giao dịch. Trình xử lý tin nhắn ở phía dịch vụ sẽ nhận tin nhắn và xử lý tương ứng.

Vì ASP .NET 4.0 và AppFoven đã được phát hành, có một số lựa chọn thay thế khả thi cho cơ chế trên. Tham khảo lại câu hỏi tôi đã đề cập ở trên, giờ đây chúng tôi đã có AppInitialize của AppFoven (qua mạng. pipe) cũng như ASP Tính năng tự khởi động của .NET 4.0 giúp phát triển Windows Services thành ứng dụng web thay thế khả thi. Tôi đã bắt đầu thực hiện điều này ngay bây giờ vì một số lý do (lớn nhất đang triển khai không còn là một nỗi đau ở mông):

  1. Bạn có thể phát triển giao diện người dùng web qua dịch vụ của mình (vì nó chạy như một ứng dụng web). Điều này cực kỳ hữu ích để xem những gì đang xảy ra trong thời gian chạy.
  2. Mô hình triển khai cho các ứng dụng web của bạn sẽ hoạt động cho ứng dụng dịch vụ của bạn.
  3. IIS cung cấp một vài tính năng gọn gàng để xử lý các lỗi ứng dụng (tương tự ở một số khía cạnh với Dịch vụ Windows).
  4. Các nhà phát triển web rất quen thuộc với việc phát triển các ứng dụng web (một cách tự nhiên), hầu hết không biết nhiều về thực tiễn tốt nhất khi phát triển Dịch vụ Windows.
  5. Nó cung cấp một số lựa chọn thay thế để hiển thị API cho các ứng dụng khác tiêu thụ.

Nếu bạn đi theo con đường này (tha thứ cho tôi vì sao chép và dán từ bài viết gốc của tôi) tôi chắc chắn sẽ xem xét việc chạy logic nền trong một ứng dụng web riêng biệt. Có nhiều lý do cho việc này:

  1. Bảo mật . Có thể có một mô hình bảo mật khác nhau cho giao diện người dùng hiển thị thông tin về các quy trình nền đang chạy. Tôi không muốn tiết lộ UI này cho bất kỳ ai khác ngoài nhóm ops. Ngoài ra, ứng dụng web có thể chạy như một người dùng khác có bộ quyền cao.
  2. Bảo trì . Thật tuyệt vời khi có thể triển khai các thay đổi cho ứng dụng lưu trữ các quy trình nền mà không ảnh hưởng đến người dùng sử dụng trang web giao diện người dùng.
  3. Hiệu suất . Việc tách ứng dụng khỏi các yêu cầu người dùng xử lý trang chính có nghĩa là các luồng nền sẽ không làm giảm khả năng của IIS để xử lý hàng đợi yêu cầu đến. Hơn nữa, ứng dụng xử lý các tác vụ nền có thể được triển khai đến một máy chủ riêng nếu cần.

Làm điều này trở lại khía cạnh đầm lầy. WCF, NServiceBus/RabbitMQ/ActiveMQ, v.v., Vanilla MSMQ, RESTful API (nghĩ rằng MVC) đều là các tùy chọn. Nếu bạn đang sử dụng Windows Workflow 4.0, bạn có thể hiển thị điểm cuối Máy chủ mà ứng dụng web của bạn có thể sử dụng.

Cách tiếp cận lưu trữ web cho các dịch vụ vẫn còn khá mới đối với tôi, chỉ có thời gian mới trả lời được liệu đó có phải là lựa chọn chính xác hay không. Cho đến nay rất tốt mặc dù. Nhân tiện, nếu bạn không muốn sử dụng AppFoven (Tôi không thể vì một số lý do kỳ lạ, Windows Server Web Edition không được hỗ trợ), khả năng Tự động khởi động được đề cập trong bài đăng của Gu hoạt động rất tốt. Tuy nhiên, tránh xa tệp applicationationhost.config, mọi thứ trong bài đăng đó đều có thể được thiết lập thông qua bảng điều khiển IIS (Trình chỉnh sửa cấu hình ở cấp máy chủ chính).

Lưu ý: Ban đầu tôi đã đăng thêm một vài liên kết trong tin nhắn này nhưng than ôi, đây là bài viết đầu tiên của tôi để trao đổi này và chỉ có một liên kết được hỗ trợ! Về cơ bản có hai người khác, để đưa họ Google "Death to Windows Services ... Long Live AppFoven!" và "tự động khởi động-asp-net-application". Xin lỗi vì điều đó.

17
Rohland

Thực sự có một cách thứ ba trong Windows để chạy các dịch vụ nền và nó rất phổ biến trong thế giới UNIX. Cách thứ ba là một công việc CRON chạy một phần cơ sở hạ tầng của bạn. Trong Windows, cái này được gọi là task scheduler và rất phổ biến để chạy mã trên cơ sở theo lịch trình. Để sử dụng điều này, bạn sẽ tạo một ứng dụng dòng lệnh được thực thi theo lịch trình được xác định trước. Ưu điểm của việc này là bạn không phải lo lắng nếu quy trình được duy trì và chạy như một dịch vụ, bởi vì nếu thất bại vì một lý do nào đó, nó sẽ chỉ khởi động vào lần tới.

Đối với việc sắp xếp các tác vụ cụ thể, bạn thực sự chỉ cần lưu trữ các tác vụ này trong một bộ lưu trữ nhị phân liên tục. Cho đến khi ứng dụng dòng lệnh chọn chúng ra khỏi bộ lưu trữ và thực thi chúng. Tôi đã thực hiện điều này trong quá khứ bằng cách sử dụng cơ sở dữ liệu Cassandra làm Nhà cung cấp trạng thái phiên để nhồi các tác vụ nền cho người dùng cụ thể trong cơ sở dữ liệu Cassandra, sau đó có dòng lệnh chọn chúng ra và thực hiện chúng cho người dùng.

Đây có thể không phải là giải pháp đầm lầy điển hình, nhưng nó hoạt động rất tốt đối với tôi và hóa ra đó là một giải pháp rất thanh lịch, bởi vì các tác vụ theo lịch trình vẫn tồn tại khi tắt máy, sự cố mạng và bất kỳ máy nào cũng có thể thực hiện tác vụ vì nó nằm ở trung tâm lưu trữ.

Quảng cáo không biết xấu hổ, nhưng đây là dự án của tôi và giải pháp tôi chỉ nêu chi tiết ngắn gọn là lý do tôi tạo dự án: http://github.com/managedfusion/fluentcassandra/

22
Nick Berardi

Ứng dụng web +

Đây là một thiết kế được thử nghiệm trong trận chiến chia tỷ lệ theo chiều ngang cùng với trang trại của bạn và đảm bảo rằng bạn đang sử dụng ngăn xếp công nghệ web bạn đã biết.

Đây là cách nó hoạt động:

  1. Tạo một bộ điều khiển/hành động trong ứng dụng web của bạn để xử lý các tác vụ nền được lên lịch. Theo quy ước, tôi thường gọi tôi là http://mydomain.com/system/cron.
  2. Để bảo mật, hành động này nên được khóa chỉ với các địa chỉ IP được xác thực trên mạng cục bộ.
  3. Trên một máy riêng biệt, cài đặt Wget và thiết lập một Tác vụ theo lịch trình để wget tìm nạp tài nguyên từ bước 1. Bạn có thể thực hiện tác vụ chạy thường xuyên như bạn muốn (tôi thường chọn trong 30 giây). Đừng quên chuyển đối số cookie thích hợp cho Wget để nó xác thực với ứng dụng web của bạn.
  4. Để dự phòng, bạn cũng có thể cài đặt wget theo lịch trình thứ hai trên máy thứ hai.

Hoan hô! Bây giờ bạn có một tuyến đường sẽ được gọi cứ sau 30 giây. Và nếu yêu cầu mất 5 phút để xử lý, sẽ không có ai quan tâm, vì đó không phải là một phần của yêu cầu trang của người dùng.

Hành động cron kết thúc trông rất đơn giản: anh ta có một danh sách các phương thức để thực hiện trên một tần số nhất định. Khi một yêu cầu đến, anh ta thấy nếu có một phương thức cần được thực thi và gọi phương thức thích hợp. Điều này có nghĩa là bạn có thể kiểm soát lịch biểu trong cơ sở dữ liệu của mình , nơi bạn có thể đã có rất nhiều dữ liệu cấu hình quan trọng khác cho trang web của mình.

Quan trọng hơn (đối với bạn), điều này có nghĩa là công việc của bạn không phải được gọi theo lịch trình cố định. Bạn có thể viết bất kỳ logic nào bạn muốn xác định khi nào thực hiện một phương thức.

Ưu và nhược điểm

  • Bạn đã rất giỏi trong việc viết mã ASP.NET MVC, vì vậy điều này cho phép bạn viết các tác vụ nền của mình trong cùng một nền tảng mà bạn viết phần còn lại của giải pháp của bạn trong.
  • Các tác vụ chạy trong cùng ngữ cảnh với ứng dụng web của bạn, vì vậy bạn có thể chia sẻ bộ đệm và sử dụng trình trợ giúp phương thức đã tồn tại.
  • Nếu bạn đã tìm nạp URI URI cân bằng tải , thì các tác vụ nền của bạn hiện cũng được cân bằng tải.
  • Triển khai đồng thời - bạn không phải lo lắng về việc đồng bộ hóa ứng dụng web của mình với logic tác vụ nền, bởi vì tất cả chúng đều nằm trong cùng một triển khai.
  • Trong nhiều năm, một vài người đã nói với tôi rằng thiết kế này là "rất khớp", nhưng khi nhấn họ không thể nói rõ tại sao đó là một điều xấu.

Lưu ý: Nếu có bất kỳ câu hỏi hoặc thắc mắc nào, vui lòng thêm nhận xét. Tôi rất vui được giải thích.

10
Portman

Tôi đã thử và sử dụng mọi cách có thể để làm điều này trong ứng dụng hiện tại của mình. Tôi bắt đầu làm điều tương tự như bạn hiện đang làm, cõng theo yêu cầu của người dùng để điền dữ liệu và sau đó lưu trữ bộ đệm. Tôi nhận ra đây cũng là một ý tưởng tồi (đặc biệt là khi bạn mở rộng quy mô cho nhiều máy chủ web, nhiều người dùng sẽ thành công hơn).

Tôi cũng đã có một công việc được lên lịch truy cập một URL trong ứng dụng ASP.NET - đây là một giải pháp hợp lý nhưng nó bắt đầu phá vỡ phút bạn mở rộng quy mô 1 máy chủ web.

Hiện tại tôi sử dụng hai phương pháp khác nhau, cả hai đều sử dụng Quartz.NET, đây là một thư viện nhỏ tuyệt vời. Đầu tiên là Quartz.NET chạy trong tiến trình với ASP.NET, nó được thiết lập trong global.asax và chạy cứ sau vài phút. Tôi sử dụng điều này để cập nhật bộ đệm ASP.NET ra khỏi băng tần, đó là lý do duy nhất nó được chạy như một phần của ASP.NET.

Thứ hai là tôi đã viết một thư viện để bọc Quartz.NET có tên là DaemonMaster - nó giúp dễ dàng thả a DLL vào một thư mục và để nó chạy trong dịch vụ Windows. Tôi thấy nó giúp tránh Một số phần khó chịu khi làm việc với Dịch vụ Windows và cũng dọn sạch một số ứng dụng Quartz.NET. Các dịch vụ chạy qua DaemonMaster có hai hương vị khác nhau, đầu tiên là các công việc cần chạy mỗi đêm hoặc mỗi lần khai thác X. các công việc khác hoạt động theo hàng đợi dựa trên dữ liệu đến từ ứng dụng ASP.NET. Ứng dụng ASP.NET loại bỏ các đối tượng JSON trên RabbitMQ và các dịch vụ thăm dò RabbitMQ sau đó xử lý dữ liệu.

Dựa trên điều này tôi sẽ khuyên bạn nên sử dụng dịch vụ Windows (và kiểm tra DaemonMaster) và nếu cần sử dụng hàng đợi như RabbitMQ để truyền dữ liệu từ ứng dụng ASP.NET sang các dịch vụ - nó đã hoạt động tốt nhất trong tất cả các giải pháp này . Nếu bạn đang tải bộ đệm thì chạy trong ASP.NET có ý nghĩa, nếu không tôi không nghĩ vậy.

7
James Avery

Tôi sẽ làm điều đó đúng cách và có một Dịch vụ Windows đang chạy theo dõi "hàng đợi". Tôi nói "xếp hàng" bởi vì lập trình w/MSMQ gần giống với việc dán các pokemon nóng bỏng vào nhãn cầu của bạn.

Tôi đã yêu sự đơn giản của Delayed :: Job trong Rails, và một cái gì đó tương tự có thể dễ dàng được thực hiện trong .NET.

Về cơ bản, bạn thêm bất kỳ loại SomethingOperation (thứ gì đó có phương thức Perform()). Sau đó, chỉ cần tuần tự hóa các tham số có liên quan, ưu tiên nó, một số loại hành vi thử lại mặc định và nhét nó vào cơ sở dữ liệu.

Dịch vụ của bạn sẽ chỉ giám sát điều này và thực hiện các công việc trong hàng đợi.

6
Ben Scheirman

Chúng tôi đã khá hài lòng với cách tiếp cận Dịch vụ/Hàng đợi Tin nhắn/Dịch vụ. Kiến trúc cơ bản là thế này.

Trang web gửi tin nhắn đến hàng đợi

bus.Send(new ProjectApproved()); // returns immediately

Dịch vụ Windows nhận và xử lý tin nhắn trong thời gian riêng của nó

public class DoesSomethingAwesome : ConsumerOf<ProjectApproved>
{
   public void Consume(ProjectApproved Message)
   {
      // Do something "offline"
   }
}

Ưu điểm là không có độ trễ cho dịch vụ front-end mà người dùng cũng được kết nối. Dịch vụ windows có thể được tắt và được nâng cấp mà không bị gián đoạn đến trang chính. Thêm vào đó là cực kỳ nhanh.

Nếu bạn không thể lưu trữ tất cả dữ liệu của mình trong tin nhắn, bạn luôn có thể lưu trữ và truy xuất dữ liệu đó sau. Tôi đề nghị sử dụng cơ chế lưu trữ tài liệu, chẳng hạn như: RavenDB hoặc MongoDB trong đó rất dễ dàng để lưu trữ các lớp của bạn mà không thay đổi.

Trang web gửi tin nhắn đến hàng đợi

// Save your object
store.Save(completeProject);

// Send a message indicating its ready to be processed
bus.Send(new ProjectApproved() { ProjectId = completeProject.Id });

Dịch vụ Windows nhận và xử lý tin nhắn trong thời gian riêng của nó

public class DoesSomethingAwesome : ConsumerOf<ProjectApproved>
{
   public void Consume(ProjectApproved Message)
   {
      // Retrieve your object back
      var completeProject = store.Get(Message.ProjectId);
   }
}

Để làm cho mọi thứ đơn giản, chúng tôi sử dụng: Rhino ESBTopshelf . Cấu hình cực kỳ đơn giản và áp dụng điều này cho một ứng dụng hiện có đã chứng tỏ mất rất ít thời gian.

4
Nathan Palmer

Tôi tò mò tại sao sự kết hợp của cả hai không phải là một lựa chọn khả thi. Ngay bây giờ bạn kích hoạt các công việc trên lượt xem trang, với một số sap không may bị kẹt chờ 10 giây để trang xuất hiện. Ít nhất đó là sự hiểu biết của tôi về phương pháp hiện tại của bạn.

Tuy nhiên, những công việc đó đang mất nhiều thời gian hơn để chạy khi trang web phát triển và bạn không muốn làm hỏng trải nghiệm người dùng trên trang web. Thậm chí không dành cho một số ít (hoặc có thể rất nhiều) người dùng xui xẻo suốt cả ngày, vì vậy bây giờ bạn đang nghĩ về việc sắp xếp công việc trong nền.

Tôi không thấy lý do tại sao một công việc nền chạy đều đặn không thể bắt chước khách truy cập. Bây giờ tôi không phải là lập trình viên Windows, nhưng trong thế giới Linux, tôi sẽ thiết lập một công việc định kỳ chạy ở một khoảng thời gian thông thường và nó sẽ có 2 dòng mã.

#!/bin/bash
wget -O /dev/null http://stackoverflow.com/specially_crafted_url

Nó kết hợp những ưu điểm của cả hai hệ thống. Nó được thực hiện trong nền. Nó không ảnh hưởng đến người dùng. Nó vẫn sử dụng chế độ xem trang để khởi động công việc. Tôi đã thấy cách tiếp cận này được sử dụng trước đây. Nó có xu hướng là trung gian giữa những cách đơn giản cũ và những cách phức tạp hơn đi xuống đường.

Cập nhật

Tôi nghĩ bạn có thể giải quyết vấn đề cân bằng tải bằng cách chạy các trình chạy công việc trên các máy chủ web. Người chạy công việc kéo một URL ra khỏi hàng đợi công việc và chạy nó như vậy:

wget -O /dev/null http://localhost/specially_crafted_url

Do tính chất của hàng đợi công việc/nhắn tin, các công việc sẽ được phân bổ đồng đều giữa những người chạy công việc, điều đó có nghĩa là Special_crafted_url cuối cùng được phân phối giữa các máy chủ web của bạn.

3
mellowsoon

Tôi nghĩ rằng con lừa với cách tiếp cận dịch vụ thuần túy là bạn có mã nằm rải rác trong dịch vụ và tránh xa ứng dụng cốt lõi.

Đây là những gì chúng tôi đã thực hiện với các công việc không nhạy cảm với thời gian lớn, giúp giữ mã cùng nhau và đơn giản hóa dịch vụ:

  1. Tạo một hàng đợi công việc (trong bộ nhớ hoặc DB, bất kỳ sự kiên trì nào là cần thiết cho các loại công việc)
  2. Tạo một dịch vụ web sẽ thực thi các công việc được xếp hàng
  3. Ứng dụng dịch vụ đơn giản đã chết gọi dịch vụ web theo một khoảng thời gian xác định, để lại tất cả những thứ phức tạp (truy xuất và thực thi công việc) cho dịch vụ web trong cơ sở mã cơ sở của bạn.

Thậm chí đơn giản hơn, chỉ cần thực hiện cuộc gọi trong ứng dụng bảng điều khiển và sử dụng Trình lập lịch tác vụ hoặc VisualCron để biến cuộc gọi thành "dịch vụ".

2
Brandon

Resque là Đẹp. Hoặc thậm chí Kthxbye nếu bạn cần được thông báo về giá trị kết quả sau khi hoàn thành.

Cả Redis/Ruby dựa tho.

Thành thật mà nói, nếu bạn đang thực hiện một cách tiếp cận dựa trên dịch vụ, nó thực sự không cần phải được tích hợp siêu với nền tảng hiện tại của bạn, điều mà tôi cảm thấy là một lợi thế. Tôi hy vọng nó có thể là một hệ thống quên và sẽ chạy (với sự giám sát của một số loại) và hoàn thành công việc. Tôi không chắc chắn nó phải được chạy trên cùng một nền tảng vì nó chỉ cập nhật/sửa đổi thông tin cơ sở dữ liệu.

Khá chắc chắn rằng bạn có thể thoát khỏi nhiều hơn với chi phí thấp hơn rất nhiều nếu bạn nuôi loại này làm việc với một thực thể riêng biệt, đặc biệt là vì có vẻ như bạn đang xử lý các vấn đề luồng. Cả ResqueKthxbye di chuyển quá trình xử lý ra các quy trình riêng biệt để cho phép HĐH xử lý đồng thời.

Phục hồi

Kthxbye

1
Lukas

Tôi thích TopShelf. Giữ sự đơn giản, nhưng vẫn thực hiện theo cách phù hợp khi chạy như một Dịch vụ Windows. Về cơ bản tạo Ứng dụng Console, thêm khoảng 15-20 dòng mã, sau đó cài đặt dưới dạng dịch vụ.

http://code.google.com.vn/p/topshelf/

1
Shane

Làm thế nào về việc có một dịch vụ Windows rất đơn giản chạy trên máy chủ web và định kỳ truy cập một URL bảo trì thực hiện các nhiệm vụ linh tinh của bạn. Có nó điều tiết bao nhiêu công việc nó làm trong bất kỳ yêu cầu nhất định.

1
Rob Sobers

Tôi sẽ nắm bắt xu hướng rõ ràng ở đây và đề nghị sử dụng mô hình trong IIS. Tôi đã sử dụng nó cho mình và nó hoạt động thực sự tốt. Thực sự không khó để thực hiện một lớp nhóm luồng tốt (trong nhiều năm qua, tôi đã mở rộng lớp nhóm luồng của mình để hỗ trợ tạo động và phá hủy các luồng, thử lại các công việc, v.v.). Ưu điểm là:

  • Không có dịch vụ bên ngoài để giám sát
  • Đơn giản thực hiện: không có quy trình xử lý chéo, không giám sát công việc nâng cao
  • Bạn vẫn còn trong quá trình IIS, vì vậy bạn có thể thực hiện tất cả các bản ghi thông thường của mình, v.v. (không cần nhiều tệp nhật ký)
  • Việc triển khai rất đơn giản (khi bạn cập nhật một dịch vụ, bạn phải dừng dịch vụ, sao chép các tệp, khởi động dịch vụ - đây là ngoài các cập nhật thông thường của bạn cho mã trang web)

Theo tôi, một giải pháp trong IIS chỉ đơn giản là "bước tiếp theo" từ việc cõng công việc lên các lượt xem trang ngẫu nhiên.

1
Dean Harding

Hàng đợi nhiệm vụ Java Tổng quan về API

Khái niệm nhiệm vụ
[.__.] Trong xử lý nền của Máy ứng dụng, một tác vụ là một mô tả đầy đủ về một đơn vị công việc nhỏ. Mô tả này bao gồm hai phần:

  • Một tải trọng dữ liệu tham số hóa nhiệm vụ.
  • Mã mà thực hiện các nhiệm vụ.

Nhiệm vụ như các móc web ngoại tuyến
[.__.] May mắn thay, Internet đã cung cấp một giải pháp như vậy, dưới dạng một yêu cầu HTTP và phản hồi của nó. Tải trọng dữ liệu là nội dung của yêu cầu HTTP, chẳng hạn như các biến của biểu mẫu web, XML, JSON hoặc dữ liệu nhị phân được mã hóa. Tham chiếu mã là chính URL; mã thực tế là bất cứ logic nào mà máy chủ thực thi trong việc chuẩn bị phản hồi.

0
antony.trupe

Tôi sẽ sử dụng dịch vụ WCF được lưu trữ trên WAS để nghe Hàng đợi MSMQ.

Chuyên nghiệp

  • Cháy và quên tin nhắn một chiều từ ứng dụng web

  • Điều chỉnh và thử lại MSMQ/WCF

  • Đảm bảo giao hàng; D

  • Quản lý thư chết

  • Quá trình đóng góp

  • Kích hoạt WAS/MSMQ

Con

  • MSMQ (nó chưa chết ... Tuy nhiên)

Các tính năng MSMQ trong WCF giúp sử dụng MSMQ thực sự tốt. Có bạn sẽ chảy máu trên cấu hình nhưng lợi ích sẽ lớn hơn sự hy sinh.

0
Adam

Tôi đã gặp phải điều này một vài lần khi phát triển các ứng dụng web. Chúng tôi đã giải quyết nó bằng cách tạo một ứng dụng bảng điều khiển windows thực hiện nhiệm vụ và tạo một tác vụ theo lịch trình chạy thường xuyên để thực hiện nhiệm vụ.

0
John Christensen

Bạn có thể chuyển sang một luồng nền (hoặc nhiều luồng nền) bằng Rx và một cái gì đó như sau:

var scheduler = new EventLoopScheduler( SchedulerThreadName );
_workToDo = new Subject<Action>();
var queueSubscription = _workToDo.ObserveOn( scheduler ).Subscribe( work => work() );
_cleanup = new CompositeDisposable( queueSubscription, scheduler );

Để sử dụng:

var work = () => { ... };
_workToDo.OnNext( work ); // Can also put on error / on complete in here

Lưu trữ tất cả những gì bên trong một lớp chỉ có một (hay còn gọi là đơn lẻ, nhưng thực hiện đúng cách - sử dụng bộ chứa IoC của bạn để xác định lối sống).

Bạn có thể kiểm soát kích thước của nhóm luồng, v.v. bằng cách viết một trình lập lịch tùy chỉnh thay vì sử dụng EventLoopScheduler (chạy một luồng duy nhất).

0
Neal

Làm tất cả

Thêm một tham số tùy chọn vào đường dẫn câu hỏi thực hiện công việc mà bạn hiện đang cõng theo yêu cầu của người dùng:

Phục vụ các tác vụ nền trên một trang web lớn

Tạo một ứng dụng bảng điều khiển chạy trên mỗi máy chủ và mở IIS nhật ký chia sẻ nhị phân và đọc nó đến cuối tệp hiện tại. Sử dụng trình quản lý tệp hoặc khoảng thời gian để đọc chuyển tiếp để thu thập các bản cập nhật như IIS xóa nhật ký.

Sử dụng thông tin này để xác định những trang nào hiện đang được xem.

Sử dụng các url trang từ nhật ký được phân tích cú pháp để gọi phiên bản "extrastuff" của url trên localhost với một đối tượng webclient.

Thêm vào một số mã để chuyển đổi tập tin vào cuối mỗi giai đoạn nhật ký hoặc khởi động lại quá trình mỗi giai đoạn nhật ký.

0
Bill

Tôi đã thực hiện loại điều này một vài lần. Trên các cửa sổ, tôi thiết lập một chương trình dòng lệnh python thực hiện một số thứ vào nhiều thời điểm khác nhau. Chương trình này cũng hiển thị giao diện xmlrpc trên một cổng. Sau đó, một công việc được lên lịch chạy mỗi phút và truy vấn các giao diện xmlrpc. Nếu chúng không hoạt động, nó sẽ cố khởi chạy chúng. Nếu không thể, nó sẽ gửi email cho tôi.

Ưu điểm là công việc chạy không phải là cron hoặc lịch trình bị ràng buộc. Tôi có một công việc xử lý chạy mỗi giây, nhưng sẽ chờ đợi lâu hơn và lâu hơn giữa khi bắt đầu một công việc mới tùy thuộc vào việc nó có công việc phải làm hay không. Ngoài ra, nó có thể được sử dụng để hành động thông minh dựa trên kết quả. Có một lỗi 500? Có một sự chậm trễ thực sự dài? Làm việc gì khác. Thông báo cho dịch vụ khác. Vân vân.

Và cùng một hệ thống hoạt động trên unix, với những sửa đổi nhỏ.

0
Christopher Mahan

Bản thân tôi không có câu trả lời cho bạn, nhưng vấn đề rung chuông - Tôi nhớ một số người ngẫu nhiên thảo luận về nó trên podcast một lần .

Spolsky: Tôi nhận thấy một trong những câu hỏi bạn đã hỏi trên blog là bạn nên xử lý các nhiệm vụ định kỳ bảo trì nói chung như thế nào?

Atwood: Vâng.

Spolsky: Đó có phải là một đặc tính công bằng? Mỗi trang web đều có một số tác vụ mà bạn không muốn thực thi tại thời điểm trang web đang tải, nhưng bạn muốn thực hiện với một số lần lặp lại.

Atwood: Ya, nhiệm vụ nền tảng của sự vật.

Spolsky: Ya, vậy bạn đã tìm ra điều gì?

Atwood: Chà, ban đầu tôi đã hỏi trên Twitter, vì tôi chỉ muốn một cái gì đó nhẹ cân. Tôi thực sự không muốn viết một dịch vụ windows. Tôi cảm thấy như đó là ra khỏi mã ban nhạc. Cộng với mã thực sự làm việc là một trang web trên thực tế, bởi vì với tôi đó là một đơn vị công việc logic trên một trang web là một trang web. Vì vậy, nó thực sự giống như chúng tôi đang gọi lại vào trang web, nó giống như một yêu cầu khác trong trang web, vì vậy tôi đã xem nó như một thứ gì đó nên giữ nguyên, và cách tiếp cận nhỏ mà chúng tôi đã đưa ra được đề xuất cho tôi trên Twitter về cơ bản là để thêm một cái gì đó vào bộ đệm của ứng dụng khi hết hạn cố định, sau đó bạn có một cuộc gọi lại để khi hết hạn, nó sẽ gọi một chức năng nhất định, sau đó bạn thêm nó vào bộ đệm với cùng thời hạn. Vì vậy, đó là một chút, có lẽ "ghetto" là từ đúng.

0
Oddthinking