您好,登錄后才能下訂單哦!
二話不說,直接上貨.多多交流哈,謝謝各路大神.
.
重點(diǎn)就是下面這段:
Object object = redisTemplate.execute(redisUpdateOrderScript,
//這里有key 要像官網(wǎng)說的那樣加個(gè)"{}",不然就報(bào)錯(cuò)了,這里3個(gè)key都要前綴一致
Arrays.asList(hkey, amountKey, key),
//值無要求
amount.longValueExact(),price.doubleValue(),price.doubleValue());
我自己的理解是,執(zhí)行腳本和執(zhí)行hget 是一樣的,只是lua腳本內(nèi)容由Redis執(zhí)行,但發(fā)送命令的要求是一樣的.所以上面3個(gè)key 都得加一樣的前綴.
.
.
.
業(yè)務(wù)邏輯是這樣子的:
把20檔盤口放到Redis里面
1.用有序集合(sorted set)進(jìn)行自動(dòng)價(jià)格排序
ZADD key 0.0354 "0.0354"
2.然后再根據(jù)價(jià)格到hash里去取值,取的val 就是這個(gè)價(jià)格的下單量
HGET key 0.0354
java 代碼
加盤口
public void addOrderForLua(BeforeMatchDTO model) {
//緩存失效
redisService.remove(RedisService.getPositionKey(model.getContract()));
BigDecimal price = model.getPrice();
BigDecimal amount = model.getAmount().multiply(PRECISION_DOUBLE);
String key = RedisKeyGen.getContractPositionZsetKey(model.getContract(), model.getDirection());
log.info("getContractPositionZsetKey:{}",key);
String hkey = RedisKeyGen.getContractPositionHashKey(model.getContract(), model.getDirection());
log.info("getContractPositionHashKey:{}",hkey);
String amountKey = RedisKeyGen.getContractPositionAmountKey(model.getContract(),price.stripTrailingZeros().toPlainString());
log.info("getContractPositionAmountKey:{}",amountKey);
log.info("addOrderForLua contract:{}, value:{}", model.getContract(), amount.longValueExact());
Object object = redisTemplate.execute(redisUpdateOrderScript, Arrays.asList(hkey, amountKey, key), amount.longValueExact(),price.doubleValue(),price.doubleValue());
log.info("addOrderForLua" + object);
}
減盤口
public void subOrderForLua(String contract,BigDecimal price,BigDecimal amount,int direction) {
//緩存失效
redisService.remove(RedisService.getPositionKey(contract));
String key = RedisKeyGen.getContractPositionZsetKey(contract, direction);
log.info("getContractPositionZsetKey:{}",key);
String hkey = RedisKeyGen.getContractPositionHashKey(contract, direction);
log.info("getContractPositionHashKey:{}",hkey);
String amountKey = RedisKeyGen.getContractPositionAmountKey(contract,price.stripTrailingZeros().toPlainString());
log.info("getContractPositionAmountKey:{}",amountKey);
log.info("subOrderForLua contract:{}, value:{}", contract, amount.doubleValue());
BigDecimal amountTag = amount.multiply(PRECISION_DOUBLE).negate(); //轉(zhuǎn)成負(fù)數(shù)
Object nowAmount = redisService.hmGet(hkey, price.toPlainString());
log.info("subOrderForLua nowAmount:{},direction:{}", nowAmount, direction);
Object object = redisTemplate.execute(redisUpdateOrderScript, Arrays.asList(hkey, amountKey, key), amountTag.longValueExact(),price.doubleValue(),price.doubleValue());
log.info("subOrderForLua" + object);
}
查詢(重點(diǎn)看取值的地方,轉(zhuǎn)換請(qǐng)忽略)
public List<QuotationOrderRsgResp> query(String contract,int direction) {
List<QuotationOrderRsgResp> result = new ArrayList<>();
String key = RedisKeyGen.getContractPositionZsetKey(contract, direction);
log.info("getContractPositionZsetKey:{}",key);
String hkey = RedisKeyGen.getContractPositionHashKey(contract, direction);
log.info("getContractPositionHashKey:{}",hkey);
Set<Object> objectSet = null;
//賣從低到高
if(QuotationConstants.DIRECTION_SELL == direction) {
objectSet = redisService.rangeByIndex(key, 0, 19);
} else {
//買從高到低
objectSet = redisService.reverseRangeByIndex(key, 0, 19);
}
if (objectSet != null && objectSet.size() > 0) {
Integer [] digits = convertService.getContractDigitsForInt(contract);
for (Object obj : objectSet) {
log.info("query class:{},val:{}",obj.getClass(),JSON.toJSONString(obj));
BigDecimal price = new BigDecimal(obj.toString());
String amountKey = RedisKeyGen.getContractPositionAmountKey(contract,price.stripTrailingZeros().toPlainString());
Object object = redisService.hmGet(hkey, amountKey);
log.info("getContractPositionAmountKey hmGet key:{},val:{}",amountKey,object);
BigDecimal valTemp = getBigDecimal(object);
if(valTemp.compareTo(BigDecimal.ZERO) == 0) continue;
BigDecimal val = valTemp.divide(PRECISION_DOUBLE);
QuotationOrderRsgResp resp = new QuotationOrderRsgResp();
resp.setContract(contract);
resp.setDirection(direction);
resp.setPrice(convertService.setScale(price, digits[0]));
resp.setVolume(convertService.setScale(val,digits[1]));
resp.setTotal(convertService.setScale(price.multiply(val),add(digits[0] ,digits[1])));
result.add(resp);
}
} else {
log.info("query redis is null! contract:{},direction:{}", contract, direction);
}
return result;
}
key 生成
public static final String getContractPositionZsetKey(String contract,int direction){
return "{POSITION:"+contract+"}.POSITION-ORDER-" + contract + "-" + direction;
}
public static final String getContractPositionHashKey(String contract,int direction){
return "{POSITION:"+contract+"}.POSITION-ORDER-VAL-" + contract + "-" + direction;
}
public static final String getContractPositionAmountKey(String contract,String amount){
return "{POSITION:"+contract+"}." + amount;
}
lua 腳本
local val1 = '"'
local valAmount = redis.call('hget',KEYS[1],KEYS[2])
if not valAmount then
redis.pcall('hset',KEYS[1],KEYS[2],ARGV[1])
if tonumber(ARGV[1]) > 0 then
local val2 = val1 .. ARGV[3] .. val1
return redis.pcall('ZADD', KEYS[3], tonumber(ARGV[2]), val2)
else
return 1
end
else
local tagAmount = tonumber(valAmount) + ARGV[1]
redis.pcall('hset',KEYS[1],KEYS[2],tagAmount)
local val2 = val1 .. ARGV[3] .. val1
local zset = redis.pcall('ZRANK', KEYS[3], val2)
if tagAmount <= 0 then
if not zset then
return 1
else
return redis.pcall('ZREMRANGEBYSCORE', KEYS[3], tonumber(ARGV[2]), tonumber(ARGV[2]))
end
else
if not zset then
local val2 = val1 .. ARGV[3] .. val1
return redis.pcall('ZADD', KEYS[3], tonumber(ARGV[2]), val2)
else
return 1
end
end
end
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。