Redis — это база данных nosql, которая очень часто используется при разработке Java. Данные хранятся в памяти в виде пар ключ-значение. Общие сценарии использования Redis включают кеширование, распределенные блокировки, последовательности с автоматическим приращением и т. д. Способ использования Redis аналогичен тому, как мы используем базы данных. Сначала нам нужно установить сервер Redis на нашем локальном компьютере или сервере Java. клиент интегрируется в программу, а затем операции добавления, удаления, изменения и запроса Redis выполняются через клиент. Для Redis по-прежнему существует множество типов Java-клиентов, наиболее распространенными из них являются jedis, redission, салат и т. д., поэтому при интеграции мы можем выбрать прямую интеграцию этих собственных клиентов. Но более распространенный способ в SpringBoot — интеграция Spring-Data-Redis, проекта, предоставляемого Spring специально для работы с Redis. Он инкапсулирует общие операции Redis и в основном инкапсулирует два клиента jedis и салат. Это эквивалентно добавлению поверх них слоя фасада.
В этой статье мы сосредоточимся на внедрении SpringBoot для использования общих операций в Redis путем интеграции Spring-Data-Redis.
Поскольку проблем с совместимостью нет, мы разрабатываем непосредственно ветку Feature/MybatisPlus.
Добавьте необходимые зависимости для Redis:
<!-- Интеграция зависимостей Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Завершить pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lsqingfeng.springboot</groupId>
<artifactId>springboot-learning</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
<!-- mybatis-plus необходимые зависимости -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
<!-- Горячий старт разработки -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- MySQL-соединение -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Интеграция зависимостей Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</project>
Здесь мы непосредственно представляем Spring-boot-starter-data-redis, стартер, уже предоставленный самим SpringBoot. Мы можем щелкнуть мышью, чтобы увидеть, какие зависимости включены в этот стартер:
Можно обнаружить, что он содержит два основных пакета: Spring-data-Redis и Lettuce-Core. Вот почему наш Spring-boot-starter-data-redis по умолчанию использует клиент салата.
Что, если мы хотим использовать клиент jedis? Вам просто нужно исключить зависимость от салата, а затем ввести соответствующие зависимости от джедиса.
Так почему же нам нужно вводить только разные зависимости, чтобы Spring-data-redis мог свободно переключать клиентов? На самом деле это включает в себя принцип автоматической настройки SpringBoot. Мы можем дать вам краткое объяснение.
Одной из основных причин, по которой платформа SpringBoot может легко интегрировать другие технологии с помощью различных стартеров, является функция автоматической настройки самой SpringBoot. Так называемая автоматическая конфигурация означает, что SpringBoot сам предварительно установил классы интеграции некоторых распространенных фреймворков. Затем используйте аннотации условного определения, аналогичные ConditionOn, чтобы определить, есть ли в вашем проекте соответствующие классы (или конфигурации), а затем инициализируйте соответствующие конфигурации.
Предустановленные классы автоматической настройки SpringBoot находятся в пакете Spring-boot-autoconfigure. Пока мы создаем проект SpringBoot, этот пакет будет представлен.
В этом пакете есть класс RedisAutoConfiguration, который, как следует из названия, представляет собой автоматическую настройку Redis. В этом классе будут представлены два класса конфигурации LettuceConnectionConfiguration и JedisConnectionConfiguration, соответствующие двум клиентам Lettuce и Jedis соответственно.
Оба класса используют аннотацию ConditionOn, чтобы определить, следует ли загружать.
джедаи следующие;
Поскольку наш проект автоматически вводит салатное ядро без введения зависимостей, связанных с jedis, класс LettuceConnectionConfiguration будет загружен, если суждение истинно, но суждение Jedis неверно, поэтому он не будет загружен. Затем вступает в силу конфигурация салата, поэтому по умолчанию мы используем клиент салата.
Затем нам нужно настроить пароль учетной записи и другую информацию, необходимую для подключения к Redis. Здесь каждый должен заранее установить Redis, чтобы наша локальная программа могла подключиться к нашему Redis. Если вы не знаете, как установить Redis, вы можете обратиться к статье: [Установка redis6.0.5 в системе Linux] https://blog.csdn.net/lsqingfeng/article/details/107359076
Общая конфигурация выглядит следующим образом: Настройте информацию о соединении Redis в файле конфигурации application.yml.
spring:
redis:
host: localhost
port: 6379
password: 123456
database: 0
Если есть другие конфигурации вместе взятые:
server:
port: 19191
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot_learning?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
username: root
password: root
redis:
host: localhost
port: 6379
password: 123456
database: 0
lettuce:
pool:
max-idle: 16
max-active: 32
min-idle: 8
devtools:
restart:
enable: true
third:
weather:
url: http://www.baidu.com
port: 8080
username: test
cities:
- Пекин
- Шанхай
- Гуанчжоу
list[0]: aaa
list[1]: bbb
list[2]: ccc
Таким образом, мы можем управлять Redis непосредственно в проекте. Если вы используете кластер, используйте следующую конфигурацию:
spring:
redis:
password: 123456
cluster:
nodes: 10.255.144.115:7001,10.255.144.115:7002,10.255.144.115:7003,10.255.144.115:7004,10.255.144.115:7005,10.255.144.115:7006
max-redirects: 3
Но иногда нам нужно настроить пул соединений для нашего клиента Redis. Как и при подключении к MySQL, мы также настроим пул соединений. Цель — улучшить управление подключениями к данным, повысить эффективность доступа и обеспечить разумное использование ресурсов. Итак, как нам настроить пул соединений? Каждый должен обратить на это внимание. Во многих онлайн-статьях представленные методы могут быть не особенно точными, поскольку версия слишком низкая. Например, многие используют для настройки Spring.redis.pool, что неверно (не знаю, настроена ли так старая версия, но в Springboot-starter-data-redis такой способ написания неправильный). Первый — это файл конфигурации. Поскольку мы используем клиент салата, при настройке добавьте салат и пул в файл Spring.redis для настройки следующим образом:
spring:
redis:
host: 10.255.144.111
port: 6379
password: 123456
database: 0
lettuce:
pool:
max-idle: 16
max-active: 32
min-idle: 8
Если вы используете jedis, замените салат на jedis (обратите внимание, что зависимости также необходимо заменить).
Но просто добавив это в файл конфигурации, пул соединений не вступит в силу. Здесь каждый должен обратить внимание. Многие студенты добавляют этот параграф в файл конфигурации и думают, что пул соединений настроен. На самом деле это не так. Самый важный шаг — импорт зависимости. Если нет, настройте. это так. Это тоже бесполезно.
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
После этого пул соединений вступит в силу. Мы можем провести сравнение. Вы можете убедиться в этом, наблюдая за значением объекта RedisTemplate до и после импорта пакета.
Перед импортом:
После импорта:
Информация о нашем пуле соединений будет иметь ценность только после присоединения к компании, что также подтверждает наш вывод, сделанный выше.
Для получения конкретной информации о конфигурации мы можем просмотреть исходный код. Класс RedisProperties используется в исходном коде для получения параметров конфигурации Redis.
После того, как наша работа по настройке будет готова, мы сможем использовать Redis в проекте. Если мы это сделаем, мы сможем использовать класс RedisTemplate, предоставленный нам в Spring-data-Redis. Давайте сначала рассмотрим простой пример, вставив пару ключ-значение (значение — строка).
package com.lsqingfeng.springboot.controller;
import com.lsqingfeng.springboot.base.Result;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @className: RedisController
* @description:
* @author: sh.Liu
* @date: 2022-03-08 14:28
*/
@RestController
@RequestMapping("redis")
public class RedisController {
private final RedisTemplate redisTemplate;
public RedisController(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
@GetMapping("save")
public Result save(String key, String value){
redisTemplate.opsForValue().set(key, value);
return Result.success();
}
}
Мы успешно управляли сервером Redis через RedisTemplate в предыдущем коде. Например, чтобы установить строку, мы можем использовать:
redisTemplate.opsForValue().set(key, value);
Чтобы поместить пару ключ-значение типа String. Redis может поддерживать пять форматов данных: строка, список, хэш, набор и zset. Общие операции этих пяти форматов данных инкапсулированы в класс RedisTemplate. Для работы со строковым типом используйте opsForValue, для работы со списком — используйте listOps, для работы с набором — используйте setOps и т. д. Мы можем узнать об общих функциях, просмотрев исходный код класса RedisTemplate.
Все эти функции находятся в этом классе, что не очень удобно использовать. Обычно мы инкапсулируем класс инструмента отдельно, чтобы абстрагировать некоторые часто используемые методы. При работе действуйте непосредственно через класс инструмента.
package com.lsqingfeng.springboot.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* @className: RedisUtil
* @description:
* @author: sh.Liu
* @date: 2022-03-09 14:07
*/
@Component
public class RedisUtil {
@Autowired
private RedisTemplate redisTemplate;
/**
* дать назначенное key Срок действия добавленного значения
*
* @param key
* @param time
* @return
*/
public boolean expire(String key, long time) {
return redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
/**
* Согласно ключевому Получить срок годности
*
* @param key
* @return
*/
public long getTime(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* Согласно ключевому Получить срок годности
*
* @param key
* @return
*/
public boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* Удалить указанный ключ срок годности
*
* @param key
* @return
*/
public boolean persist(String key) {
return redisTemplate.boundValueOps(key).persist();
}
//- - - - - - - - - - - - - - - - - - - - - Тип строки - - - - - - - - - - - - - - - - - - - -
/**
* Согласно ключевому Получатьценить
*
* @param key ключ
* @return ценить
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* Поместить ценить в кэш
*
* @param key ключ
* @param value ценить
* @return настоящий успех false неудача
*/
public void set(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* Поместить ценить в кэш并设置时间
*
* @param key ключ
* @param value ценить
* @param time время (секунды) -1 означает неограниченный
* @return настоящий успех false неудача
*/
public void set(String key, String value, long time) {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
redisTemplate.opsForValue().set(key, value);
}
}
/**
* Добавлять партиями key (Повторный выбор будет перезаписан)
*
* @param keyAndValue
*/
public void batchSet(Map<String, String> keyAndValue) {
redisTemplate.opsForValue().multiSet(keyAndValue);
}
/**
* Добавлять партиями key-value Только в ключне Добавлять только тогда, когда существует
* map середина Пока существует один ключ, ни один не будет добавлен.
*
* @param keyAndValue
*/
public void batchSetIfAbsent(Map<String, String> keyAndValue) {
redisTemplate.opsForValue().multiSetIfAbsent(keyAndValue);
}
/**
* одному key-value изценить выполнять операции сложения и вычитания,
* Если key не существует Ключ будет создан. И назначить ценить number
* если key существует, но value Не длинное целое число , сообщит об ошибке
*
* @param key
* @param number
*/
public Long increment(String key, long number) {
return redisTemplate.opsForValue().increment(key, number);
}
/**
* одному key-value изценить выполнять операции сложения и вычитания,
* Если key не существует Ключ будет создан. И назначить ценить number
* если key существует, но value нет чистые числа , сообщит об ошибке
*
* @param key
* @param number
*/
public Double increment(String key, double number) {
return redisTemplate.opsForValue().increment(key, number);
}
//- - - - - - - - - - - - - - - - - - - - - тип установки - - - - - - - - - - - - - - - - - - - -
/**
* Поместить данные в установленный кеш
*
* @param key ключ
* @return
*/
public void sSet(String key, String value) {
redisTemplate.opsForSet().add(key, value);
}
/**
* Получатьпеременнаясерединаизценить
*
* @param key ключ
* @return
*/
public Set<Object> members(String key) {
return redisTemplate.opsForSet().members(key);
}
/**
* Случайным образом получить указанное количество элементов из переменной середина
*
* @param key ключ
* @param count ценить
* @return
*/
public void randomMembers(String key, long count) {
redisTemplate.opsForSet().randomMembers(key, count);
}
/**
* Случайным образом получить элементы переменной середина
*
* @param key ключ
* @return
*/
public Object randomMember(String key) {
return redisTemplate.opsForSet().randomMember(key);
}
/**
* Вытолкните элемент переменной середина
*
* @param key ключ
* @return
*/
public Object pop(String key) {
return redisTemplate.opsForSet().pop("setValue");
}
/**
* Получатьпеременнаясерединаценитьиз长度
*
* @param key ключ
* @return
*/
public long size(String key) {
return redisTemplate.opsForSet().size(key);
}
/**
* Запрос из наборасередина на основе значения, существует ли оно
*
* @param key ключ
* @param value ценить
* @return true существовать falseне существует
*/
public boolean sHasKey(String key, Object value) {
return redisTemplate.opsForSet().isMember(key, value);
}
/**
* Проверяет, находится ли данный элемент в переменной середина.
*
* @param key ключ
* @param obj элемент объекта
* @return
*/
public boolean isMember(String key, Object obj) {
return redisTemplate.opsForSet().isMember(key, obj);
}
/**
* 转移переменнаяизэлементценить До сих поризпеременная。
*
* @param key ключ
* @param value элемент объекта
* @param destKey элемент объекта
* @return
*/
public boolean move(String key, String value, String destKey) {
return redisTemplate.opsForSet().move(key, value, destKey);
}
/**
* Удалить набор элементов кэша середина в пакетном режиме
*
* @param key ключ
* @param values ценить
* @return
*/
public void remove(String key, Object... values) {
redisTemplate.opsForSet().remove(key, values);
}
/**
* по данномуизkeyпросить2индивидуальныйsetпеременнаяиз Разницаценить
*
* @param key ключ
* @param destKey ключ
* @return
*/
public Set<Set> difference(String key, String destKey) {
return redisTemplate.opsForSet().difference(key, destKey);
}
//- - - - - - - - - - - - - - - - - - - - - тип хеша - - - - - - - - - - - - - - - - - - - -
/**
* Добавить в кэш
*
* @param key ключ
* @param map ключ
* @return
*/
public void add(String key, Map<String, String> map) {
redisTemplate.opsForHash().putAll(key, map);
}
/**
* Получать key вниз все hashkey и value
*
* @param key ключ
* @return
*/
public Map<Object, Object> getHashEntries(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* Проверьте обозначение key Вниз Есть ли какой-либо указанный hashkey
*
* @param key
* @param hashKey
* @return
*/
public boolean hashKey(String key, String hashKey) {
return redisTemplate.opsForHash().hasKey(key, hashKey);
}
/**
* Получатьобозначениеkeyизценитьstring
*
* @param key ключ
* @param key2 ключ
* @return
*/
public String getMapString(String key, String key2) {
return redisTemplate.opsForHash().get("map1", "key1").toString();
}
/**
* ПолучатьобозначениеизценитьInt
*
* @param key ключ
* @param key2 ключ
* @return
*/
public Integer getMapInt(String key, String key2) {
return (Integer) redisTemplate.opsForHash().get("map1", "key1");
}
/**
* Вытащить элемент и удалить
*
* @param key ключ
* @return
*/
public String popValue(String key) {
return redisTemplate.opsForSet().pop(key).toString();
}
/**
* Удалить указанное hash из HashKey
*
* @param key
* @param hashKeys
* @return удалитьуспехиз количество
*/
public Long delete(String key, String... hashKeys) {
return redisTemplate.opsForHash().delete(key, hashKeys);
}
/**
* назначать hash из hashkey Увеличьте или уменьшите операции
*
* @param key
* @param hashKey
* @param number
* @return
*/
public Long increment(String key, String hashKey, long number) {
return redisTemplate.opsForHash().increment(key, hashKey, number);
}
/**
* назначать hash из hashkey Увеличьте или уменьшите операции
*
* @param key
* @param hashKey
* @param number
* @return
*/
public Double increment(String key, String hashKey, Double number) {
return redisTemplate.opsForHash().increment(key, hashKey, number);
}
/**
* Получать key вниз все hashkey Поле
*
* @param key
* @return
*/
public Set<Object> hashKeys(String key) {
return redisTemplate.opsForHash().keys(key);
}
/**
* Получатьобозначение hash Внизлапшаиз ключценить пару количество
*
* @param key
* @return
*/
public Long hashSize(String key) {
return redisTemplate.opsForHash().size(key);
}
//- - - - - - - - - - - - - - - - - - - - - тип списка - - - - - - - - - - - - - - - - - - - -
/**
* 在переменнаялевый添加элементценить
*
* @param key
* @param value
* @return
*/
public void leftPush(String key, Object value) {
redisTemplate.opsForList().leftPush(key, value);
}
/**
* Получатьсобиратьобозначение位置изценить。
*
* @param key
* @param index
* @return
*/
public Object index(String key, long index) {
return redisTemplate.opsForList().index("list", 1);
}
/**
* Получатьобозначение区间изценить。
*
* @param key
* @param start
* @param end
* @return
*/
public List<Object> range(String key, long start, long end) {
return redisTemplate.opsForList().range(key, start, end);
}
/**
* 把最后一индивидуальный参数ценить放приезжатьобозначениесобиратьиз第一индивидуальный出现серединапараметры временииз前лапша,
* еслисерединапараметры времениценитьсуществоватьизразговаривать。
*
* @param key
* @param pivot
* @param value
* @return
*/
public void leftPush(String key, String pivot, String value) {
redisTemplate.opsForList().leftPush(key, pivot, value);
}
/**
* Слева Добавить партиями参数элемент。
*
* @param key
* @param values
* @return
*/
public void leftPushAll(String key, String... values) {
// redisTemplate.opsForList().leftPushAll(key,"w","x","y");
redisTemplate.opsForList().leftPushAll(key, values);
}
/**
* Добавляет элемент в самый правый элемент коллекции.
*
* @param key
* @param value
* @return
*/
public void leftPushAll(String key, String value) {
redisTemplate.opsForList().rightPush(key, value);
}
/**
* Слева Добавить партиями参数элемент。
*
* @param key
* @param values
* @return
*/
public void rightPushAll(String key, String... values) {
//redisTemplate.opsForList().leftPushAll(key,"w","x","y");
redisTemplate.opsForList().rightPushAll(key, values);
}
/**
* Сян Исуществоватьизсобиратьсередина添加элемент。
*
* @param key
* @param value
* @return
*/
public void rightPushIfPresent(String key, Object value) {
redisTemplate.opsForList().rightPushIfPresent(key, value);
}
/**
* Сян Исуществоватьизсобиратьсередина添加элемент。
*
* @param key
* @return
*/
public long listLength(String key) {
return redisTemplate.opsForList().size(key);
}
/**
* 移除собиратьсерединаизлевый第一индивидуальныйэлемент。
*
* @param key
* @return
*/
public void leftPop(String key) {
redisTemplate.opsForList().leftPop(key);
}
/**
* 移除собиратьсерединалевыйизэлемент在等待извремя,еслибольше, чем ожиданиеиз时间仍没иметьэлементно退出。
*
* @param key
* @return
*/
public void leftPop(String key, long timeout, TimeUnit unit) {
redisTemplate.opsForList().leftPop(key, timeout, unit);
}
/**
* 移除собиратьсерединаверноизэлемент。
*
* @param key
* @return
*/
public void rightPop(String key) {
redisTemplate.opsForList().rightPop(key);
}
/**
* 移除собиратьсерединаверноизэлемент在等待извремя,еслибольше, чем ожиданиеиз时间仍没иметьэлементно退出。
*
* @param key
* @return
*/
public void rightPop(String key, long timeout, TimeUnit unit) {
redisTemplate.opsForList().rightPop(key, timeout, unit);
}
}
Вы также можете прочитать этот класс инструментов, чтобы узнать больше об использовании RedisTemplate. При его использовании вам нужно только внедрить этот класс инструмента.
redisиз Сериализация также является тем, что мы используемRedisTemplateизпроцесссерединанужно вниманиеизиметь значение。上лапшаиз Случайсередина,На самом деле никаких особых настроек у нас нет.redisиз Метод сериализации,тогда он действительно используетизэто значение по умолчаниюиз Метод сериализации。RedisTemplate这индивидуальный类из Дженерики<String,Object>,То есть, он поддерживает записьObjectобъектиз,那么这индивидуальныйобъект采取什么方式序列化存入内存серединавот и всеиз Метод сериализации。
Так что же такое сериализация Redis? Это означает, что мы храним объекты в Redis. Это могут быть двоичные данные, xml или json. Например, мы часто используем POJO. хранилище объектовприезжать Redis , обычно используется JSON метод сериализуется в строку и сохраняется в Redis середина 。
Сам Redis предоставляет метод сериализации:
Если мы храним тип String, методом сериализации по умолчанию является StringRedisSerializer. Если мы храним объекты, по умолчанию используется JdkSerializationRedisSerializer, который представляет собой метод сериализации Jdk (реализуемый через ObjectOutputStream и ObjectInputStream. Недостаток заключается в том, что мы не можем интуитивно видеть содержимое хранимых объектов).
Мы можем установить соответствующий метод сериализации в соответствии с различными типами данных, которыми управляет Redis.
Наблюдая за исходным кодом RedisTemplate, мы видим, что по умолчанию используется JdkSerializationRedisSerializer. Самая большая проблема такого типа сериализации заключается в том, что после сохранения объекта нам сложно визуально увидеть хранимый контент, что очень неудобно. нам для решения проблем:
Как правило, наиболее часто используемый метод сериализации объектов: Jackson2JsonRedisSerializer.
设置Метод сериализациииз Основной метод заключается в том, что мы настраиваем класссередина,Создайте объект RedisTemplate самостоятельно.,и создатьизпроцесссерединаобозначение对应из Метод сериализации。
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean(name = "redisTemplate")
public RedisTemplate<String, Object> getRedisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(factory);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer); // ключиз типа сериализации
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// Срок действия метода истек,Изменить на Внизлапша代码
// objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // значениеиз типа сериализации
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
используйте вот такизкогда,будет установлен в соответствии с нашимизjsonМетод сериализации进行存储,Мы также можемredisсередина Посмотреть контентизвремя удобноеиз查看приезжать属性ценить。
Ссылки:
7 способов реализовать распределенные блокировки с помощью Redis —Why414 — Blog Park
Много сценсередина,Нужно использоватьраспределенныйдела、распределенный Блокировки и другие технологии для обеспечения конечной согласованности данных.。иметьизкогда,Нам нужно гарантировать, что определенный метод может выполняться только одним потоком одновременно. В автономной (однопроцессной) среде середина,JAVA предоставляет множество API-интерфейсов, связанных с параллелизмом.,Но в многомашинной (многопроцессной) среде вы ничего не сможете сделать.
Для распределенных блокировок лучше всего соблюдать следующие пункты.
可以保证在распределенныйразвертыватьизкластер приложенийсередина,同一индивидуальный方法在同一时间只能被一台机器上из一индивидуальный线程执行 Если эта блокировка является реентерабельной (чтобы избежать взаимоблокировки) Этот замок предпочтительно является блокирующим замком. Высокодоступные функции захвата и снятия блокировки Улучшена производительность захвата и снятия блокировок.
Обычно существует три способа реализации распределенных блокировок: 1. Оптимистическая блокировка базы данных. 2. Распределенная блокировка на основе Redis. 3. Распределенная блокировка на основе ZooKeeper. В этой статье в основном представлен второй метод.
Идеальная распределенная блокировка должна соответствовать следующим четырем условиям: 1. Взаимная исключительность. В любой момент только один клиент может удерживать блокировку. 2. Тупика не произойдет. Даже если клиент выйдет из строя, удерживая блокировку без ее активной разблокировки, гарантируется, что другие клиенты впоследствии смогут ее заблокировать. 3. Отказоустойчивость. Пока большинство узлов Redis работают нормально, клиент может блокировать и разблокировать. 4. Чтобы развязать колокольчик, надо колокольчик завязать. Блокировка и разблокировка должны выполняться одним и тем же клиентом. Сам клиент не может разблокировать блокировку, добавленную другими.
Принцип распределенной блокировки Redis:
Замокиз Реализация в основном основана наredisизSETNX
Заказ
SETNX key value将 key Значение установлено на value , тогда и только тогда, когда key Не существует. Если дано key уже существует, то SETNX Никаких действий не предпринимается. SETNX Это "SET" if Not существует» (если его не существует, то Сокращение от SET).
**Возвращаемое значение:** Если настройка выполнена успешно, будет возвращено 1. Установка завершается с ошибкой и возвращает 0.
использоватьSETNX
完成同步Замокиз Такие процессы и вопросы, как Вниз:
SETNX
Заказ Получать Замок,Если он возвращает 0 (ключ существовал,Замокужесуществовать)но Получатьнеудача,Напротив ПолучатьуспехSETNX
Заказ总是返回0而进入死Замок状态,需要为Долженkey设置一индивидуальный“Разумный”срок годностиDEL
Заказ将Замок数据удалитьЭта статьясерединадляRedisсерединаиз Замокиз介绍还是比较全лапшаиз。
Существует множество способов реализации блокировок Redis, которые могут вызвать некоторые проблемы. Относительно идеальное решение — использовать скрипты Lua. Самое идеальное решение — использовать RedissionRedLock в рамках Redission. Конкретная реализация не будет приведена. Вы можете следовать этой идее, чтобы найти соответствующую информацию. Я вернусь и добавлю больше, когда у меня будет время и силы.