1.项目中需要在redis中存放时效的key,当失效时触发事件
2.项目启动时监听redis中0索引数据库中所有失效key
@Component
public class SocketServer {
@Autowired
private MyPubSubListener myPubSubListener;
@PostConstruct
public void init() {
logger.info("监听redis");
String[] channels = new String[1];
channels[0] = "__keyevent@0__:expired";
final RedisSubcribeClient client = new RedisSubcribeClient("statusWatch", myPubSubListener, channels);
new Thread(new Runnable() {
@Override
public void run() {
client.subscribe();
}
}).start();
}
}
3.key失效,执行程序onMessage方法,message为失效的key
我的key是{ip:1234},key是不固定值
@Component
public class MyPubSubListener extends JedisPubSub {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private RedisUtils redis;
@Override
public void onMessage(String channel, String message) {
log.info("当前频道:" + channel);
log.info("接收消息:" + message);
if(message.contains("{")&&message.contains("}")) {
try {
JSONObject obj = JSONObject.parseObject(message);
String ip = obj.getString("socket");
SocketServer.map.remove(ip);
}catch(Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
log.info("订阅频道" + channel);
}
@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
log.info("取消订阅频道" + channel);
}
/**
* 全部取消订阅
*/
@Override
public void unsubscribe() {
// TODO
}
}
4.订阅redis事件
public class RedisSubcribeClient {
private Jedis jedis;
private String[] channels;
private String name;
private JedisPubSub listener;
private static final Logger log = Logger.getLogger(RedisSubcribeClient.class);
public RedisSubcribeClient(String channel) {
this.jedis = RedisMgr.getJedis();
}
public RedisSubcribeClient(String clientName, JedisPubSub listener, String[] channels) {
if (RedisMgr.getJedis() == null) {
this.jedis = RedisMgr.getInstance().getJedis();
} else {
this.jedis = RedisMgr.getJedis();
}
this.channels = channels;
this.listener = listener;
this.name = clientName;
}
public void subscribe() {
log.info("client:" + this.name + "\t订阅频道:" + this.channels[0] + "listener:"
+ this.listener.getClass().getName());
log.info("jedis is null:" + String.valueOf(jedis == null));
jedis.subscribe(this.listener, this.channels[0]);
}
public void cancelSubscribe(String[] channels) {
log.info("取消订阅,当前client名为:" + this.name);
this.listener.unsubscribe(channels);
}
}
5.redis管理类
public class RedisMgr {
public static RedisMgr redisClientPool = getInstance();
public static JedisPool jedisPool;
private String host;
private int port;
private String auth;
private int database;
public static synchronized RedisMgr getInstance() {
if (null == redisClientPool) {
redisClientPool = new RedisMgr();
}
return redisClientPool;
}
public RedisMgr() {
if (null == jedisPool) {
init();
}
}
public String getInfo(){
StringBuilder sb = new StringBuilder();
sb.append("host:"+this.host);
sb.append("port:"+this.port);
sb.append("database:"+this.database);
sb.append("auth:"+this.auth);
return sb.toString();
}
/**
* 初始化jedis连接池
*/
private void init() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//控制一个pool可分配多少个jedis实例,通过pool.getResource()来获取;
//如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
jedisPoolConfig.setMaxTotal(500);
// 最大能够保持空闲状态的对象数
jedisPoolConfig.setMaxIdle(300);
// 超时时间
jedisPoolConfig.setMaxWaitMillis(1000);
// 在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;
jedisPoolConfig.setTestOnBorrow(true);
// 在还会给pool时,是否提前进行validate操作
jedisPoolConfig.setTestOnReturn(true);
Properties property = new Properties();
String propertyPath = this.getClass().getClassLoader().getResource("config.properties").getPath();
try {
property.load(new FileInputStream(new File(propertyPath)));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
String host = property.getProperty("redis.host");// "localhost";
int port = Integer.parseInt(property.getProperty("redis.port"));// 6379;
int database = Integer.parseInt(property.getProperty("redis.database"));// 6379;
int timeout = Integer.parseInt(property.getProperty("redis.timeout"));// 60000;
this.host = host;
this.port = port;
this.database = database;
String auth = property.getProperty("redis.password");//访问密码
this.auth = auth;
if(StringUtils.isNotBlank(auth)){
jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, auth);
}else{
jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout);
}
}
/**
* 获取Jedis实例
* 默认使用数据库0
* @return
*/
public synchronized static Jedis getJedis() {
try {
if (jedisPool != null) {
Jedis resource = jedisPool.getResource();
return resource;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取Jedis实例并指定数据库
* @param db_index 数据库索引
* @return
*/
public synchronized static Jedis getJedis(int db_index) {
try {
if (jedisPool != null) {
Jedis resource = jedisPool.getResource();
resource.select(db_index);
return resource;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}