Subscribe to publish a simple implementation redis

Applicable scene

  1. Business Process encountered a large number of asynchronous operations, and business is not very complicated
  2. Less demanding robust business model
  3. Do not ask for immediate scene

Introduce the principle of

redis official website Documentation: https://redis.io/topics/notifications#configuration

Integrated spring subscriptions to the publication: https://docs.spring.io/spring-data/redis/docs/1.7.1.RELEASE/reference/html/#redis:pubsub:subscribe

 

Related demo

Business release .java

 //         asynchronous notification message 
        String expiredEmail RedisConstants.REDIS_EXPIRE_Email_Send.getExpired = () + UUID; 
        ValueOperations <the Serializable, Object> = Operations redisTemplate3.opsForValue ();
 // Since org.springframework.data.redis.core.StringRedisTemplate use, so value must be a String 
        operations.set (expiredEmail, "1", email_expire_time, TimeUnit.SECONDS);

 

EmailSyncEventListener.java

package com.redis.listeners;


import com.carapi.services.order.FxjTCarInvoiceOrderService;
import com.common.constant.RedisConstants;
import com.exception.ErrorException;
import com.model.fxjTCarInvoiceOrder.FxjTCarInvoiceOrder;
import com.model.fxjTCarOrderList.FxjTCarOrderList;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 邮件发送
 */
public class EmailSyncEventListener extends KeyExpirationEventMessageListener {
    private static final Logger log = LoggerFactory.getLogger(EmailSyncEventListener.class);
  //可以使用自动注入,或者xml配置
    public EmailSyncEventListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Autowired
    private FxjTCarInvoiceOrderService tCarInvoiceOrderService;
//    @Autowired
//    public EmailSyncEventListener(RedisMessageListenerContainer listenerContainer) {
//        super(listenerContainer);
//    }
    @Override
    public void onMessage(Message message, byte[] pattern) {

            String channel = new String(message.getChannel(), StandardCharsets.UTF_8);
            //过期的key
            String key = new String(message.getBody(),StandardCharsets.UTF_8);
            if(StringUtils.isNotEmpty(key) && key.indexOf(RedisConstants.REDIS_EXPIRE_Email_Send.getExpired()) != -1){
                System.out.println(key);
                key = key.substring(key.indexOf(RedisConstants.REDIS_EXPIRE_Email_Send.getExpired())+RedisConstants.REDIS_EXPIRE_Email_Send.getExpired().length());
                log.info(key);
                try {

                    InvoiceOrder = tCarInvoiceOrderService.selectByPrimaryKey FxjTCarInvoiceOrder (Key); {}, key = {}", new String (pattern), channel, key);
            }
                    IF (invoiceOrder = null!) { 

                       tCarInvoiceOrderService.resendEmail (invoiceOrder.getEmail (), invoiceOrder.getInvoiceReqSerialNo ()); 
                   } 
                } the catch (ErrorException E) { 
                    log.info ( "Mail sent asynchronously failed the verification fails"); 
                } the catch (Exception E) { 
                    log.info ( "asynchronous failure sending mail"); 
                    e.printStackTrace (); 
                } 
                log.info ( "asynchronous transmit mailing successfully"); 
                log.info ( "expired Redis Key: pattern = {}, } = {Channel, Key = {} ", new new String (pattern), Channel, Key); 
    } 
}

  

spring-cache.xml

    <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
        <property name="connectionFactory" ref="jedisConnFactory"></property>
        <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
        </property>
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
        </property>
        <property name="hashKeySerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
        </property>
        <property name="hashValueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
        </property>
        <property name="stringSerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>
    </bean>




    <bean id="jedisConnFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="${redis.host}" />
        <property name="port" value="${redis.port}" />
        <property name="password" value="${redis.password}" />
        <property name="database" value="2" />
        <property name="timeout" value="${redis.timeout}" />
        <property name="poolConfig" ref="jedisPoolConfig" />
        <property name="usePool" value="true" />
    </bean>

    <!--去掉redis client的CONFIG-->
    <util:constant static-field="org.springframework.session.data.redis.config.ConfigureRedisAction.NO_OP"/>

    <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <property name="maxInactiveIntervalInSeconds" value="3600" />
    </bean>




    <!-- 将监听实现类注册到spring容器中 -->
    <bean id="emailSyncEventListener" class="com.redis.listeners.EmailSyncEventListener">
        <constructor-arg ref="redisMessageListenerContainer"></constructor-arg>
    </bean>

 

 

Emerging issues

  1. After the user's session is stored in redis, redis load imbalance, there has been the key 0 ttl to remove lingering longer

Redis does not guarantee the survival time (TTL) becomes the key 0 will immediately be deleted: If the program does not have access to this key expired, or with the survival time of a lot of the key, then key in the survival time becomes 0, until the key it really is deleted middle, there may be a more significant time interval.

Therefore, Redis is generated when time expired notice to expire key is deleted, but not when survival time is 0 keys. If Redis is configured correctly and reasonable load, the delay will not exceed more than 1s.

RedisExpiredQuartz.java

Package com.redis.quart; 

Import com.common.constant.RedisConstants;
 Import com.redis.listeners.EmailSyncEventListener;
 Import org.slf4j.Logger;
 Import org.slf4j.LoggerFactory;
 Import org.springframework.data.redis.core. RedisTemplate; 

Import javax.annotation.Resource;
 Import java.util.Set; 

/ ** 
 * Redis does not guarantee the survival time (TTL) becomes the key 0 will immediately be deleted: 
 * If the program does not have access to this key expired, or with there are key survival time of a lot of words, 
 * then the survival time key becomes 0, 
 * until the middle of this key really is deleted, there may be a more significant time interval. 
 * 
 * SO plus timer 
 * / 
public  class RedisExpiredQuartz {
     Private  static final Logger log = LoggerFactory.getLogger(EmailSyncEventListener.class);
    @Resource
    private RedisTemplate redisTemplate3;

    public synchronized  void onRedisExpiredQuartz(){
        log.trace("------------------------------------------");
        for (RedisConstants value : RedisConstants.values()) {
            Set keys = redisTemplate3.keys(value.getExpired() + "*");
            log.debug("业务需要正常通知的keys:{}",keys);
        }
    }
}

RedisConstants.java

com.common.constant Package Penalty for; 

public enum RedisConstants { 
    / ** 
     * monthly card expired cancel key prefix 
     * / 
    REDIS_EXPIRE_Sub_Card ( "redisExpiredSubCard_"), 
    / ** 
     * delay mailing key prefix 
     * / 
    REDIS_EXPIRE_Email_Send ( "redisExpiredEmail_Send_"), 
    ; 

    expired The String Private; 

    RedisConstants (expired The String) { 
        this.expired = expired The; 
    } 

    public String getExpired () { 
        return expired The; 
    } 

    public void setExpired (expired The String) { 
        this.expired = expired The; 
    } 

    // get the object enum
    public static RedisConstants get(String  expired) {
        for (RedisConstants item : values()) {
            if (expired == item.getExpired()) {
                return item;
            }
        }
        return null;
    }
}

  

Guess you like

Origin www.cnblogs.com/dmeck/p/11498964.html