前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

1、发布/订阅

Redis提供了基于发布/订阅的消息机制

此种模式下,消息发布者和订阅着不能相互直接通信而是发布者客户端向指定的频道(channel)发布消息,订阅该频道的每个客户端都可以收到该消息

WX20180413-154821@2x

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

ContactAuthor