网络场中的 Windows 服务(如何防止并发冲突)

发布于 2024-08-04 20:49:00 字数 588 浏览 7 评论 0原文

展望未来,当 Web Farm 将被创建时...

我们有各种 Windows 服务应用程序执行各种后台任务:发送电子邮件、缩略图/处理文件等。

在服务器场环境中,理论上我们可以安装并运行每个应用程序服务在每台机器上,但是由于基于业务对象的“先写胜”或不期望的任务重复,可能会出现冲突,例如:相同的电子邮件被发送多次。

“先写胜出”的情况可以通过解决问题或跳过该项目的代码或逻辑来克服。 (如果它是一种基本的排队机制(查询列表和进程记录),它将再次尝试)

对于任务的重复,可以在事务中执行任务以防止其他进程获取相同的资源,但是我想它们只会等待并我们需要根据再次发生的事情来处理一些登录吗?会是这样吗?

为了防止任务重复,我正在考虑构建某种机制,将“锁定标志”写入数据库,该数据库将由第一个启动的服务设置。该标志将注明日期并引用服务实例。 “拥有”该标志的服务将运行任务并定期更新此日期。在服务不拥有该标志的情况下,每个服务还将有一个超时/容差设置,它将检查容差并在需要时接管。

这听起来像是一个合理的解决方案,还是应该在该阶段采用更好的基于消息队列的解决方案(也不确定这在农场环境中如何工作?

技术:C# / ASP.NET / SQL Server

Looking ahead, to when a Web Farm will be created...

We have various windows service applications performing various back-ground tasks: sending emails, thumbnailing/processing files etc.

In a server farm environment, we could in theory install and run each service on each machine, however there may be conflicts due to business object based "first-write-win" or undesirable duplication of tasks eg: the same emails being send a number of times.

The "first-write-wins" scenario can be overcome through code or logic that resolves the issue or skips the item. (if its a basic queuing mechanism (query list and process record) it will just be tried again)

For the duplication of tasks, one could perform tasks in transactions to prevent other processses grabbing the same resources, however I guess they will just wait and we would need to handle some login based on things happening again? Would this be the case?

To prevent duplication of tasks I am thinking of maybe building some mechanism that writes a "locking flag" to the database that will be set by the first service that fires up. This flag will be dated and reference the instance of the service. The service that "owns" the flag will run the tasks and periodically update this date. There will also be a timeout/tolerance setting on each service in the situation where the service doesnt own the flag, it will check the tolerance and take over if required.

Does this sound like a resonable solution or should one go to a better message queuing based solution at that stage (also not sure how that would work in a farm environement?

Tecnologies: C# / ASP.NET / SQL Server

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

↘紸啶 2024-08-11 20:49:00

我可以想到两种机制。

  1. 如果您的所有任务都源自数据库活动,您可以创建一个新的“任务”表并在活动上设置触发器,以便插入包含任务信息的新记录。然后,您的 Windows 服务可以轮询“任务”表,并使用原子选择和删除事务来确保只有一个服务执行此操作。

  2. 您可以使用消息队列并将任务放入其中,然后让 Windows 服务轮询队列。每个排队的消息只能由单个服务出队,因此您可以确保每个任务仅完成一次。当然,您必须担心消息队列上的负载。根据您的应用程序,您可以使用 Amazon 的 Simple Queue Service 之类的东西,这将减轻您对可靠性和可扩展性的担忧。

I can think of two mechanisms.

  1. If all your tasks are derived from database activites you could create a new "tasks" table and set triggers on the activities so that a new record with the task information is inserted. Your windows services can then poll the "tasks" table and use an atomic select and delete transaction to ensure only one service does it.

  2. You could use a message queue and drop your tasks on it and then have your windows services poll the queue. Each queued message will only be able to be dequeued by a single service so you can ensure each task is only done once. Of course you then have to worry about load on your message queue. Depending on your application you could use something like Amazon's Simple Queue Service which would alleviate you having to worry about reliability and scalability.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文