简体   繁体   English

Java 并发计数器架构设计

[英]Java concurrent counter architecture design

Having the following business case:具有以下业务案例:

Email promotional campaign says that first 1_000_000 users pressing the link will receive a Bonus. Email 促销活动说,前 1_000_000 名用户点击链接将获得奖金。 Users are going to see either the Bonus or "Sorry" message immediately during visiting web page.用户在访问 web 页面时将立即看到奖励或“抱歉”消息。

Question: how to design this solution?问题:如何设计这个解决方案?

  • Option 1: Monolith.选项 1:单体。 AtomicInteger.原子整数。 Can the CAS issue take place here? CAS问题可以在这里发生吗? Or 1_000_000 is not that amount that cause an issue in this case?或者 1_000_000 不是在这种情况下导致问题的那个数量? What is the number which can "do" that?可以“做到”的数字是多少?
  • Option 2: Monolith.选项 2:单体。 sync should work here with no issues?同步应该在这里没有问题吗?
  • Option 3: Microservices.选项 3:微服务。 Redis INCR method. Redis INCR 方法。 Is there are any options for microservices architecture?微服务架构有什么选择吗? Is there a way to use MySql for this purpose?有没有办法为此目的使用 MySql ?
  1. Plain Old Java: Use in-memory synchronization using java lock semantics. Plain Old Java:使用 java 锁定语义使用内存同步。 You are correct about using AtomicInteger.您对使用 AtomicInteger 是正确的。 However, this can only work if you have only one application instance running.但是,这只有在您只运行一个应用程序实例时才有效。

  2. With MySql: There is a feature called select for update that helps you achieve what you are looking for.使用 MySql:有一个名为select for update功能可帮助您实现所需的功能。 Whenever someone clicks on the link, you do select for update in MySql to see if the bonus is still available.每当有人单击该链接时,您都会执行select for update ,以查看奖金是否仍然可用。 If it is, you do update in DB in the same transaction.如果是,您确实在同一事务中更新数据库。 Meanwhile, all other parallel reads and writes will be blocked.同时,所有其他并行读取和写入都将被阻止。 Hence you get end-to-end fully atomic operation.因此,您可以获得端到端的完全原子操作。

  3. Redis won't work because even if INCR is atomic, the whole flow of reading the value from Redis, performing the business logic, and updating the value in Redis won't be atomic. Redis 不起作用,因为即使INCR是原子的,从 Redis 读取值、执行业务逻辑和更新 ZE111446745A1825B862F8727AE63BCE4 中的值的整个流程都不会是原子的。 Eg Say the user count in Redis was 999_999 and 2 users concurrently click on the link.例如,假设 Redis 中的用户数为999_999 ,并且有 2 个用户同时点击链接。 The application checks the count and it's under the threshold of 1_000_000 which means, both users are eligible for a discount and you end up giving a discount to both.应用程序检查计数并且它低于1_000_000的阈值,这意味着,两个用户都有资格获得折扣,而您最终给两个用户都打了折扣。

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

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