不考虑接入层负载均衡,只看server层。
系统选型
高并发情况下,流量通过层层负载均衡,均匀到了不同的服务器上。即使如此,集群中的单机所承受的QPS也是非常高的。如何将单机性能优化到极致?
用户购买商品可以分为3个阶段,1、生成订单2、扣减库存3、支付,保证不超卖不少卖,订单必须有效支付,还要保证系统承受极高的并发。
下单减库存
支付减库存
预扣库存
扣库存的艺术
其实有很多事无效请求。假设库存为10k,同时来了1000k的请求,有990k为无效请求。
代码演示
go+lua脚本
package remoteSpike
import "github.com/gomodule/redigo/redis"
type RemoteSpikeKeys struct {
SpikeOrderHashKey string
TotalInventoryKey string
QuantityOfOrderKey string
}
const LuaScript = `
local product_key = KEYS[1]
local product_total_key = ARGV[1]
local product_sold_key = ARGV[2]
local product_total_nums = tonumber(redis.call('HGET', product_key, product_total_key))
local product_sold_nums = tonumber(redis.call('HGET', product_key, product_sold_key))
if (product_total_nums > product_sold_nums) then
return redis.call('HINCRBY', product_key, product_sold_key, 1)
end
return 0
`
//远端统一扣库存
func (RemoteSpikeKeys *RemoteSpikeKeys) RemoteDeductionStock(conn redis.Conn) bool {
lua := redis.NewScript(1, LuaScript)
result, err := redis.Int(lua.Do(conn, RemoteSpikeKeys.SpikeOrderHashKey, RemoteSpikeKeys.TotalInventoryKey, RemoteSpikeKeys.QuantityOfOrderKey))
if err != nil {
return false
}
return result != 0
}