sql >> Database teknologi >  >> NoSQL >> Redis

Spring Redis fejlhåndtag

Jeg havde selv samme problem. Jeg er ved at udvikle nogle datatjenester mod en database ved at bruge Redis som cachelageret ved hjælp af Spring Caching-annoteringer. Hvis Redis-serveren bliver utilgængelig, vil jeg gerne have, at tjenesterne fortsætter med at fungere, som om de ikke var i cache, i stedet for at give undtagelser.

Først prøvede jeg en brugerdefineret CacheErrorHandler, en mekanisme leveret af Spring. Det virkede ikke helt, fordi det kun håndterer RuntimeExceptions, og lader stadig ting som java.net.ConnectException sprænge tingene i luften.

I sidste ende var det, jeg gjorde, at udvide RedisTemplate og tilsidesætte nogle få execute()-metoder, så de logger advarsler i stedet for at udbrede undtagelser. Det virker som lidt af et hack, og jeg har måske tilsidesat for få execute()-metoder eller for mange, men det virker som en charme i alle mine testsager.

Der er dog et vigtigt operationelt aspekt ved denne tilgang. Hvis Redis-serveren bliver utilgængelig, skal du tømme den (rydde ud i indtastningerne), før du gør den tilgængelig igen. Ellers er der en chance for, at du begynder at hente cache-poster, der har forkerte data på grund af opdateringer, der er sket i mellemtiden.

Nedenfor er kilden. Brug den gerne. Jeg håber, det hjælper.

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.data.redis.serializer.RedisSerializer;


/**
 * An extension of RedisTemplate that logs exceptions instead of letting them propagate.
 * If the Redis server is unavailable, cache operations are always a "miss" and data is fetched from the database.
 */
public class LoggingRedisTemplate<K, V> extends RedisTemplate<K, V> {

    private static final Logger logger = LoggerFactory.getLogger(LoggingRedisTemplate.class);


    @Override
    public <T> T execute(final RedisCallback<T> action, final boolean exposeConnection, final boolean pipeline) {
        try {
            return super.execute(action, exposeConnection, pipeline);
        }
        catch(final Throwable t) {
            logger.warn("Error executing cache operation: {}", t.getMessage());
            return null;
        }
    }


    @Override
    public <T> T execute(final RedisScript<T> script, final List<K> keys, final Object... args) {
        try {
            return super.execute(script, keys, args);
        }
        catch(final Throwable t) {
            logger.warn("Error executing cache operation: {}", t.getMessage());
            return null;
        }
    }


    @Override
    public <T> T execute(final RedisScript<T> script, final RedisSerializer<?> argsSerializer, final RedisSerializer<T> resultSerializer, final List<K> keys, final Object... args) {
        try {
            return super.execute(script, argsSerializer, resultSerializer, keys, args);
        }
        catch(final Throwable t) {
            logger.warn("Error executing cache operation: {}", t.getMessage());
            return null;
        }
    }


    @Override
    public <T> T execute(final SessionCallback<T> session) {
        try {
            return super.execute(session);
        }
        catch(final Throwable t) {
            logger.warn("Error executing cache operation: {}", t.getMessage());
            return null;
        }
    }
}


  1. Hvad er den anbefalede måde at droppe indekser ved at bruge Mongoose?

  2. 7 måder at tjekke din MongoDB-version på

  3. Hvordan opdaterer jeg kun MongoDB-dokumentfelter, hvis de ikke eksisterer?

  4. Redis Pub-Sub eller Socket.IO's udsendelse