简体   繁体   English

Web应用程序架构:未来打样

[英]Web Application Architecture: Future Proofing

I have a web application that currently sends emails. 我有一个当前发送电子邮件的Web应用程序。 At the time my web applications sends emails (sending of emails is based on user actions - not automatic), it has to run other processes like zipping up files. 当我的Web应用程序发送电子邮件(发送电子邮件是基于用户操作 - 不是自动的)时,它必须运行其他过程,如压缩文件。

I am trying to make my application "future proof" - so when there are a large number of users I don't want the server strained, so i thought that putting the emails that need to be sent and the files that need to be zipped in a queue. 我正在努力使我的应用程序“面向未来” - 所以当有大量用户时我不希望服务器紧张,所以我认为需要发送需要发送的电子邮件和需要压缩的文件在队列中。 Put them in table and then use a cron job to check every second and execute them (x rows at a time). 将它们放在表中,然后使用cron作业检查每一秒并执行它们(一次x行)。

Is the above a good idea? 以上是个好主意吗? Or is there a better approach? 还是有更好的方法? I really need help to get this done properly to save myself headaches later on :) 我真的需要帮助才能正确完成这项工作,以便以后节省我的头痛:)

Thanks all 谢谢大家

It's a good approach, but the most important thing you can do right now is have a clear interface for queuing up the messages, and one for consuming the queue. 这是一个很好的方法,但你现在可以做的最重要的事情是有一个清晰的界面来排队消息,一个用于消耗队列。 Don't make the usage on either end hard-coded to a DB. 不要将两端的用法硬编码到DB。

Later on, if this becomes a bottleneck, you may want the mail sending to be done from a different machine which may not even have access to the DB, so this tiny investment up front will give you options later. 稍后,如果这成为瓶颈,您可能希望从另一台甚至无法访问数据库的计算机上完成邮件发送,因此这项微小的投资可以在以后为您提供选项。

One aspect you might have ignored is the zipping speed you are using, it might be in your best interest to use a lighter compression level in your zip process as that can make large improvements in zip time (easily double) which can add up to a lot when you get into the realm of multiple users. 您可能忽略的一个方面是您正在使用的压缩速度,在您的zip过程中使用较轻的压缩级别可能符合您的最佳利益,因为这可以大大改进拉链时间(轻松加倍),这可以增加到当你进入多个用户的领域时很多。

Even better if you make the zipping intelligent and use no compression when you're zipping large already compressed files (MP3, ZIP, DOCX, XLSX, JPG, GIF, etc) and using high compression when you have simple text files (TXT, XML, DOC, XLS, etc) as they will zip very quickly even with heavy compression. 如果你使用压缩文件(MP3,ZIP,DOCX,XLSX,JPG,GIF等)并且在使用简单文本文件时使用高压缩(TXT,XML ,DOC,XLS等)因为它们即使在高压缩下也会非常快速地拉链。

An important point might be that rather than having a cron job run once every second, have a always-running daemon that's automatically restarted on exit - or something like that. 重要的一点是,不要让cron作业每秒运行一次,而是让一个始终运行的守护进程在退出时自动重启 - 或类似的东西。

One reason is, just as you describe it yourself, if a lot of users request emails to be sent out and the queue builds up, one cronjob won't have time to finnish before the ext one stats, and you risk having your system flooded with processes. 一个原因是,就像你自己描述的那样,如果很多用户要求发送电子邮件并且队列建立起来,那么一个cronjob将没有时间在ext ext stats之前进行芬兰语,并且你冒着系统泛滥的风险与流程。

Is the above a good idea? 以上是个好主意吗? yes

could there be a better solution to handle millions of users down the road? 有没有更好的解决方案来处理数百万用户? possibly.. but thats not what is important. 可能......但那并不重要。 what is important is that you have build in the layer of abstraction. 重要的是你已经构建了抽象层。 If some day down the road you have crazy traffic and your cron queue isnt keeping up you can replace the functionality of that layer without changing any of the code which uses it. 如果有一天你有疯狂的流量,你的cron队列没有跟上,你可以替换该层的功能,而无需更改任何使用它的代码。

Hmm. 嗯。 I don't really like the idea of cron running something every second. 我真的不喜欢cron每秒运行一些东西的想法。 That seems like way too often. 这似乎太频繁了。 If your application really needs to be that responsive, then I think you should keep it synchronous. 如果您的应用程序确实需要响应,那么我认为您应该保持同步。 That is, keep the processing in your web application and look for other ways to keep the server strain level down. 也就是说,将处理保留在Web应用程序中,并寻找其他方法来降低服务器应变水平。

If you can wait longer between checking, then it would be better to have your cron job check the queue for 1 item at a time. 如果您可以在检查之间等待更长时间,那么让您的cron作业一次检查1个项目的队列会更好。 If there is one, process it, and then check again for the next one without exiting. 如果有,请对其进行处理,然后再次检查下一个而不退出。 If there isn't one, exit and don't try again for five minutes or so. 如果没有,退出并且不要再试五分钟左右。

However, all that being said, any decent Mail Transfer Agent (sendmail, postfix, Exchange) will have queuing built-in. 但是,所有这一切,任何像样的邮件传输代理(sendmail,postfix,Exchange)都将内置排队。 It will probably do a better job than you could of making sure delivery occurs when the unexpected happens. 它可能比确保在意外发生时确保交付时做得更好。 There's a lot to think about in processing queued e-mail. 在处理排队的电子邮件时需要考虑很多事情。 I generally prefer to hand-off outbound e-mail to an MTA as early in the process as I can. 我通常喜欢尽可能早地将出站电子邮件发送到MTA。

-- -
bmb BMB

Build in something that does distributed queuing. 构建分布式排队的东西。 When you scale the volume you can scale the different layers of your tier where a bottleneck may come up. 缩放卷时,您可以扩展层的不同层,从而可能出现瓶颈。

Is there a reason to run the cron every second? 是否有理由每秒运行一次cron? Is the volume that high? 音量那么高吗? I would say do your best to keep it an n-tier implementation because you will swap things in and out and refactor bits as they fight for your attention. 我会说尽力保持它是一个n层实现,因为你会交换进出的东西并重构位,因为它们会引起你的注意。

Try not to build anything you design for a few weeks. 尝试不要在几周内构建任何你设计的东西。 Often other scenarios will come to you then before things get locked in. 在事情被锁定之前,通常会遇到其他情况。

Good approach. 好方法。 Some refinements: 一些改进:

  1. Don't use a cron job, instead query on a timer. 不要使用cron作业,而是在计时器上查询。
  2. Include a state flag to keep multiple readers/writers sorted. 包含状态标志以保持多个读取器/写入器的排序。
  3. Reader should drain the queue - don't block until queue read is empty. 读取器应该排空队列 - 在队列读取为空之前不要阻塞。
  4. Keep it simple. 把事情简单化。 Put complexity and subtlety into the writer/reader conversation. 将复杂性和微妙性融入作家/读者对话中。

In my experience this will scale nicely. 根据我的经验,这将很好地扩展。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM