Redis发布订阅和地理位置定位存储
前言
Github:https://github.com/HealerJean
1、发布/订阅
Redis提供了基于发布/订阅的消息机制
此种模式下,消息发布者和订阅着不能相互直接通信,而是发布者客户端向指定的频道(channel)发布消息,订阅该频道的每个客户端都可以收到该消息
1.1、发布消息
发布客户端发布消息
`publish channel message`
下面在频道channel:student
发布了一条消息,返回值为订阅者个数,此时没有订阅者,返回为0
127.0.0.1:6379> publish channel:student "teacher coming"
(integer) 0
127.0.0.1:6379>
1.2、订阅消息
1、当订阅的通道的时候,会进入订阅状态,一直等待消息接收,只能接收命令为
subscribe
,psubscribe
,unsubscribe
,punsubscribe
2、新开启的订阅,无法接收以前的消息,因为redis不会对之前的消息进行持久化
`subscribe channel`
订阅客户端
127.0.0.1:6379> subscribe channel:student
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel:student"
3) (integer) 1
…… 这里在等待接收下次
这个时候,发布客户端发布一条消息,
127.0.0.1:6379> publish channel:student "gime start"
(integer) 1
127.0.0.1:6379>
订阅客户端如下
127.0.0.1:6379> subscribe channel:student
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel:student"
3) (integer) 1
1) "message"
2) "channel:student"
3) "gime start"
1.3、取消订阅
unsubscribe channel:student
1.4、按照匹配模式订阅和取消订阅
匹配订阅 psubscribe hello*
匹配取消 punsubscribe hello*
1.5、查询订阅
1.5.1、查看活跃的频道
所谓活跃的频道是指至少有一个频道被订阅,如果没有的被定义则返回0
pubsub channels [partten]
6379> pubsub channels
1) "channel:student"
127.0.0.1:6379>
没有客户端订阅频道
127.0.0.1:6379> pubsub channels
(empty list or set)
1.5.2、查看频道订阅数
127.0.0.1:6379> pubsub numsub channel:student
1) "channel:student"
2) (integer) 1
127.0.0.1:6379>
1.5.3、查看按照模式的订阅数
127.0.0.1:6379>pubsub numpat
(integer) 1
1.6、使用场景
聊天教、公告牌
1.7、代码实现
1.7.1、redis配置文件
<!--配置监听队列-->
<bean id="requestMessageListener" class="com.hlj.redis.listener.RequestMessageListener"/>
<redis:listener-container>
<redis:listener ref="requestMessageListener" topic="request" />
</redis:listener-container>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:redis="http://www.springframework.org/schema/redis"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/redis http://www.springframework.org/schema/redis/spring-redis.xsd">
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" >
<property name="maxTotal" value="${hlj.redis.max-total}"/>
<property name="maxIdle" value="${hlj.redis.max-idle}"/>
<property name="maxWaitMillis" value="${hlj.redis.pool.max-wait}"/>
</bean>
<bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
<property name="password" value="${hlj.redis.password}"/>
<property name="hostName" value="${hlj.redis.host-name}"/>
<property name="port" value="${hlj.redis.port}"/>
<property name="usePool" value="true"/>
<property name="poolConfig" ref="jedisPoolConfig"/>
</bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" scope="prototype">
<property name="connectionFactory" ref="redisConnectionFactory"/>
<property name="keySerializer">
<bean class="com.hlj.redis.cacheSerializer.CustomStringRedisSerializer"/>
</property>
<property name="valueSerializer">
<bean class="com.hlj.redis.cacheSerializer.CustomJSONStringRedisSerializer"/>
</property>
</bean>
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" scope="prototype">
<property name="connectionFactory" ref="redisConnectionFactory"/>
</bean>
<!--配置监听队列-->
<bean id="requestMessageListener" class="com.hlj.redis.listener.RequestMessageListener"/>
<redis:listener-container>
<redis:listener ref="requestMessageListener" topic="request" />
</redis:listener-container>
</beans>
1.7.2、配置监听消息
package com.hlj.redis.listener;
import com.hlj.redis.cacheSerializer.CustomJSONStringRedisSerializer;
import com.hlj.redis.cacheSerializer.CustomStringRedisSerializer;
import com.hlj.redis.listener.data.ConvertBean;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
/**
* 通过监听redistemplate进行发送消息
*/
public class RequestMessageListener implements MessageListener {
private CustomStringRedisSerializer stringRedisSerializer = new CustomStringRedisSerializer();
private CustomJSONStringRedisSerializer jsonStringRedisSerializer = new CustomJSONStringRedisSerializer();
@Override
public void onMessage(Message message, byte[] bytes) {
System.out.println("message监听");
ConvertBean convertBean = (ConvertBean) jsonStringRedisSerializer.deserialize(message.getBody());
// System.out.println(convertBean.toString());
}
}
1.7.3、测试
package com.hlj.redis.listener.controller;
import com.hlj.redis.listener.data.ConvertBean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
@RequestMapping("redis/listener")
@Controller
public class ListenerController {
private RedisTemplate redisTemplate;
@GetMapping("test")
@ResponseBody
public void lockRedis(){
ConvertBean convertBean = new ConvertBean();
convertBean.setContent("content");
convertBean.setToUid("uuid");
redisTemplate.convertAndSend("request",convertBean);
}
}
2、GEO (地理信息定位)
支持存储地理位置信息来实现比如地理位置,摇一摇等依赖于地理位置信息的孤男寡女,对于实现这些功能的开发者来说绝对是一个福音
2.1、增加地理位置信息
添加背景的地理位置信息
`geoadd key 经度 纬度 城市`
返回结果表示成功的个数,如果已经存在则返回0 ,
127.0.0.1:6379> geoadd cities:location 116.28 39.55 beijing
(integer) 1
127.0.0.1:6379> geoadd cities:location 116.28 39.550 beijing
(integer) 0
127.0.0.1:6379>
同时添加多个地理位置信息
127.0.0.1:6379> geoadd cities:location 116.28 39 beijing 11.78 44.5 shanghai
(integer) 1
127.0.0.1:6379>
2.2、获取地理位置信息
127.0.0.1:6379> geopos cities:location beijing
1) 1) "116.28000229597091675"
2) "38.99999918434559731"
127.0.0.1:6379>
2.3、获取两个地理位置之间的距离
geodist key city1 city2 [unit] m米 km千米 mi英里 ft 尺
127.0.0.1:6379> geodist cities:location beijing shanghai
"8053178.4504"
127.0.0.1:6379>
2.4、获取指定位置范围内的地理信息位置集合
redis> georadiusbymember cities:location beijing 60000km
1) "Agrigento"
2) "Palermo
2.5、删除地理信息
这里需要知道的是这里存放的数据类型为zset
127.0.0.1:6379> type cities:location
zset
127.0.0.1:6379>
删除
zrem cities:location beijing