RoundRobinService.java 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package com.ydtech.modules.ttqf.xxx;
  2. import org.springframework.data.redis.core.RedisCallback;
  3. import org.springframework.data.redis.core.RedisTemplate;
  4. import org.springframework.data.redis.core.ValueOperations;
  5. import org.springframework.data.redis.core.script.DefaultRedisScript;
  6. import org.springframework.stereotype.Service;
  7. import java.util.Arrays;
  8. import java.util.Collections;
  9. import java.util.List;
  10. @Service
  11. public class RoundRobinService {
  12. private final RedisTemplate<String, String> redisTemplate;
  13. public static final String LIST_KEY = "DEFAULT:WITHDRAWAL:id";
  14. private static final String INDEX_KEY = "DEFAULT:WITHDRAWAL:index";
  15. public RoundRobinService(RedisTemplate<String, String> redisTemplate) {
  16. this.redisTemplate = redisTemplate;
  17. }
  18. private static final String LUA_SCRIPT =
  19. "local indexKey = KEYS[2] " +
  20. "local listKey = KEYS[1] " +
  21. "local currentIndex = tonumber(redis.call('GET', indexKey) or 0) " +
  22. "local listSize = redis.call('LLEN', listKey) " +
  23. "if listSize == 0 then return nil end " +
  24. "local value = redis.call('LINDEX', listKey, currentIndex) " +
  25. "local nextIndex = (currentIndex + 1) % listSize " +
  26. "redis.call('SET', indexKey, nextIndex) " +
  27. "return value";
  28. public String getNextWithLua() {
  29. DefaultRedisScript<String> script = new DefaultRedisScript<>(LUA_SCRIPT, String.class);
  30. return redisTemplate.execute(script, Arrays.asList(LIST_KEY, INDEX_KEY));
  31. }
  32. // 添加成员(动态扩展)
  33. public void batchAdd(List<String> values) {
  34. Long l = redisTemplate.opsForList().rightPushAll(LIST_KEY, values);
  35. System.out.println("添加成功,当前队列长度为:" + l);
  36. }
  37. public boolean remove(String value) {
  38. String script =
  39. "local list = redis.call('LRANGE', KEYS[1], 0, -1) " +
  40. "local new_list = {} " +
  41. "for i, v in ipairs(list) do " +
  42. " if v ~= ARGV[1] then " +
  43. " table.insert(new_list, v) " +
  44. " end " +
  45. "end " +
  46. "redis.call('DEL', KEYS[1]) " +
  47. "redis.call('RPUSH', KEYS[1], unpack(new_list)) " +
  48. "return #new_list";
  49. Long result = redisTemplate.execute(
  50. new DefaultRedisScript<>(script, Long.class),
  51. Collections.singletonList(LIST_KEY),
  52. value
  53. );
  54. return result != null && result > 0;
  55. }
  56. /**
  57. * 添加字符串到集合
  58. */
  59. public void addString(String item) {
  60. redisTemplate.opsForList().rightPush(LIST_KEY, item);
  61. }
  62. }