目錄
1.什麼是lua
擼啊(Lua)是一門小巧的腳本語言,它的主要特點是輕量級、可擴展。主要應用場景是:遊戲開發、獨立應用腳本、Web 應用腳本。lua還有一個重要的特點是可以輕鬆嵌入到其他開發語言中。lua腳本語句比較簡單,語句風格和C語言類型,可以通過Lua在線工具進行語言試驗。 Redis 2.6.0 版本開始的,使用內置的 Lua 解釋器,可以對 Lua 腳本進行求值。
2.爲什麼是lua
介紹了這麼多究竟爲什麼要使用redis+lua實現秒殺場景呢?
因爲在秒殺場景中需要有優惠券信息列表、已成功搶券用戶表,採用redis存儲的優勢是讀取快。而Lua操作是原子性的,只要將1. 驗證用戶是不是已經成功搶券 、2.券數量減一 、3.在已成功搶券用戶表中添加當前用戶 這三個邏輯放到lua腳本中便可以保證數據的準確性,能夠合理的避免高併發下一券多發、庫存錯誤等情況。所以redis+lua二者結合可以完美實現秒殺的業務需求。
3.搶令牌的業務場景 + 代碼實現
redis+lua的配方不止適用於秒殺場景,本文實戰的場景是一個抽象的搶令牌模型,實現的語言是java+redis+lua
完整的業務是這樣滴:
樂淘商城有10個客服,後臺需要保證每次前臺請求都返回一個客服的id,且每個客服服務的客戶數量要平均。
具體實現方案:
1.每天凌晨將客服id放到reids list中
2.請求時返回第一個id,同時將此id插入到list隊尾,同時刪除此id(維護一個循環隊列)
代碼實現:
lua腳本,將腳本保存到以.lua結尾的文件中,保存到系統能加載的路徑下
--- Created by Administrator.
--- DateTime: 2020/04/20 19:46
--- 獲取隊尾第一個數據,並刪除,將刪除的數插入隊頭
local key = KEYS[1]
if (redis.call("EXISTS", key) == 0 ) then
return "defaultErrorCode"
else
local val = redis.call("RPOP", key)
redis.call("LPUSH",key,val)
return val
end
lua文件要在redisConfig中做爲資源配置
@Configuration
public class RedisConfig {
@Bean
public DefaultRedisScript<Long> redisScript() {
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/employeeAgent.lua")));
redisScript.setResultType(Long.class);
return redisScript;
}
}
java代碼需要調用RedisTemplate和DefaultRedisScript兩個對象,lua腳本是以資源文件的形式引入的。
@Autowired
private RedisTemplate redisTemplate;
@Resource
private DefaultRedisScript<Long> redisScript;
public void getEmployeeAgent() {
String redisKey = "testKey";
if(!redisTemplate.hasKey(redisKey)){
List<String> employeeInfoList = Arrays.asList("1","2","3","4","5","6","7","8","9","10");
if(EmptyUtil.isNotEmpty(employeeInfoList)){
redisTemplate.opsForList().leftPushAll(redisKey,employeeInfoList);
redisTemplate.expire(redisKey,Constant.FORTY_EIGHT, TimeUnit.HOURS);
}
}
ArrayList<String> keys = Lists.newArrayList();
keys.add(redisKey);
String result = (String)redisTemplate.execute(redisScript, keys);
}
經過測試後id是有序且平均分配。看看!用這麼少的代碼就可以實現那麼有挑戰性的需求,所以lua+redis可真是一個寶藏組合!
下次面試官再問你如何實現秒殺,大聲的告訴他擼啊!