php - PHP中的高额付款处理架构

标签 php mysql architecture payment credit-card

想象一个本地Groupon克隆。现在想象一下一个吸引10万正常访客的交易,因为访问者试图并行购买MySQL数据库,交易超过了最大购买限额。
我正在寻找高负荷网站的支付处理的最佳实践,这将处理有限数量产品的支付并行。
目前,最简单的选择似乎是在客户试图在第三方支付处理器页面上购买交易时锁定/解锁交易。
有什么想法吗?

最佳答案

我一直和你在一起,直到你开始谈论第三方支付处理页面。将用户发送到第三方网站时,很难控制他们的体验,因为你不知道他们在那里做什么,如果他们被跟踪,他们要花多长时间完成交易,如果他们完成交易,等等。
如果在本地处理付款不是一个选择,那就不一定是一个问题——它只是提出了一个问题,你必须如何实际考虑处理你的交易。
所以,如果是我,现在不考虑第三方-我们会暂时搁置这件事。显然,我会确保我的MySQL数据库有足够的弹性,不会崩溃,因为这会给协调事务带来很大的问题。但是,事情发生了,所以你需要一个后援。
我的建议是使用一个缓存系统来跟踪产品和当前可用的产品。Memcache可以很好的解决这个问题,因为它只是一个很容易抓取的记录。你不必点击数据库就可以获得产品的信息(可用性),如果它坏了,你的用户/应用程序就不会更聪明了,因为你可以直接从Memcache获取关于你的产品的信息(不需要mysql)。
这就产生了一个存储付款记录的问题(当数据库关闭时)。当你收钱的时候,你显然需要数据库中的交易信息,如果你的数据库坏了,那就是个问题。Memcache并不是一个很好的解决方案,因为你受限于你的值的大小,你必须知道你关心的每一个键。除此之外,Memcache没有set或set操作,因此您不能附加到一个值,而不必担心会触动某些数据。
所以,让我们添加一个不同的技术,Redis。
事务问题的解决方案是在MySQL服务器不可用的情况下将它们写入redis(或者如果您真的想同时写入这两个服务器,但实际上不需要这样做)。然后有一个后台进程,它知道如何从redis获取事务细节,并在恢复联机时将它们写入MySQL表。Redis对崩溃非常有弹性,并且能够以巨大的容量运行。它还具有set操作,因此您可以轻松地将数据附加到set,而无需担心读/改/写操作期间的竞争条件。
因此,您可以将所有事务存储在一个redis密钥中,作为一个单独的集合(如果您愿意,可以将它们存储为json字符串,这非常简单),然后当您的DB崩溃时,您可以从redis获取数据,并在数据恢复联机时将其写入MySQL。
为了保持简单,如果你打算使用redis来存储事务,你也可以使用它来存储你的产品缓存,而不是memcache——保持堆栈简单。
这样可以避免在MySQL崩溃时访问数据库以获取产品详细信息,还可以跟踪(可能)丢失的事务。但它并没有处理这样的问题:在MySQL关闭时,当新的事务出现时跟踪产品库存,并确保您不会过度销售产品。
为了处理这种情况,在保存事务时,可以减少可用产品的数量(将其保持为一个固定数字,这样就不会在页面加载时不断地重新计算它)。这会立即告诉你产品是否超卖。但是,这样做并不能保护“产品在购物车中”的时间。一旦用户将产品放入购物车(这是你允许的,因为你说你有库存),你就有一个问题,那就是在他们结账前确保产品不会卖完。
此问题的解决方案也可以作为第三方事务问题的解决方案。因此,您对产品使用缓存机制,对事务使用回退机制。你现在应该做的是,当用户试图购买一个产品时(要么把它放在购物车里,要么被发送到第三方处理器),为他们创建一个“产品预订”。为每一项创建一个redis条目可能是最简单的。让产品预定有一个有效期,比如5到10分钟,如果你愿意的话甚至15分钟。每次你在你的网站上看到一个用户,刷新超时以确保他们不会耗尽时间(显然,如果你愿意的话,你可以在这里面加入更多的逻辑)。当一个事务完成并从挂起更改为付费时,您将创建您的事务记录(mysql或redis,取决于数据库可用性),减少可用数量,并删除您的预订记录。
然后,除了未过期的预订信息外,您还可以使用可用数量信息来确定可供销售的数量。如果这个数字降到零,那么你实际上已经卖完了;但是如果你的某个用户没有转换它,就会释放出他们没有购买的库存,允许你清洗并重复这个过程,直到你实际上卖完为止。
对于一个相当健壮的系统,这是一个相当长的解释,如果你遇到MySQL服务器崩溃,redis崩溃的情况,你会有点崩溃;所以在这里对这两个系统进行故障转移是有意义的(这是完全可行和可能的)。它应该使结帐/库存管理过程变得相当稳定。
希望有帮助。

关于php - PHP中的高额付款处理架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10702310/

相关文章:

MySQL 按父/子和名称排序

Java 将 XML 解码为动态对象

java - 是否有一种可接受的方法来保持这些层/依赖关系分离?

php - "raw HTTP header"是什么? "HTTP header"和 "raw HTTP header"有什么区别?

javascript - 谷歌图表增加y轴宽度增加

php - 另一组眼睛 : Column count doesn't match value count at row 1

c# - ANSI C 作为 C# 项目的核心?这可能吗?

php - 带有图像的列表中的动态下拉选项

mysql - 连接表并追加列

php - PHP 和 MySQL 中的 unicode 字符问题