`

使用redis和spring集成实际中遇到的问题

阅读更多
最近使用redis遇到一些问题,记录一下。
格式就不排了,有时间再弄吧。

一、版本信息
spring 4.2.5
mysql 5.1.18
mybatis 3.2.8
mybatis-spring 1.2.4
jedis 2.8.0
spring-data 1.7.1
...  ...


二、jedis和spring集成
1. 配置数据源
	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="maxTotal" value="${redis.maxTotal}" />
		<property name="maxIdle" value="${redis.maxIdle}" />
		<property name="minIdle" value="${redis.minIdle}" />
		<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
		<!--对拿到的connection进行validateObject校验 -->
		<property name="testOnBorrow" value="${redis.testOnBorrow}" />
		<!--在进行returnObject对返回的connection进行validateObject校验 -->
		<property name="testOnReturn" value="${redis.testOnReturn}" />
		<!--定时对线程池中空闲的链接进行validateObject校验 -->
		<property name="testWhileIdle" value="${redis.testWhileIdle}" />
	</bean>

	<bean id="redisConnectionFactory"
		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="timeout" value="${redis.timeout}" />
		<property name="database" value="${redis.default.database}" />
		<property name="poolConfig" ref="jedisPoolConfig"/>
	</bean>
	<bean id="redis4CacheConnectionFactory"
		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="timeout" value="${redis.timeout}" />
		<property name="database" value="${redis.cache.database}" />
		<property name="poolConfig" ref="jedisPoolConfig"/>
	</bean>


2.配置Template
	<bean id="stringRedisSerializer"
		class="org.springframework.data.redis.serializer.StringRedisSerializer" />
	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
		<property name="connectionFactory" ref="redisConnectionFactory" />
		<property name="keySerializer" ref="stringRedisSerializer" />
		<property name="hashKeySerializer" ref="stringRedisSerializer" />
		<!-- 默认即为 jdkRedisSerializer -->
		<!-- <property name="valueSerializer" ref="jdkRedisSerializer" />
		<property name="hashValueSerializer" ref="jdkRedisSerializer" /> -->
		<!-- <property name="enableTransactionSupport" value="true" /> -->
	</bean>

注:在spring事务中不执行Lua脚本可使用enableTransactionSupport,否则报java.lang.unsupportedclassversion

三、与springCache集成
	<bean id="redis4CacheTemplate" class="org.springframework.data.redis.core.RedisTemplate">
		<property name="connectionFactory" ref="redis4CacheConnectionFactory" />
		<property name="keySerializer" ref="stringRedisSerializer" />
	</bean>

	<!-- 开启缓存注解 -->
	<cache:annotation-driven/>

	<!-- declare Redis Cache Manager -->
	<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
		<constructor-arg name="redisOperations" ref="redis4CacheTemplate" />
		<!-- 是否事务提交,如果事务回滚,缓存也回滚,默认false -->
		<property name="transactionAware" value="true" />
		<!-- 默认有效期1d 3600*24 -->
		<property name="defaultExpiration" value="86400" />
	</bean>


public abstract class BaseCache {
	public String generateKey(String... args) {
		return RedisUtil.generateKey(args);
	}
	@CacheEvict(allEntries = true)
	public abstract void clearCaches(Class<?> clazz);
}

@Component(ActivityCache.SERVICE_NAME)
@CacheConfig(cacheNames = {ActivityCache.SERVICE_NAME})
public class ActivityCache extends BaseCache {
	
	/**
	 * SERVICE_NAME:服务名
	 */
	public static final String SERVICE_NAME = "activityCache";
	
	@Autowired
	private ActivityDao activityDao;
	@Cacheable(key="#root.target.generateKey(#root.targetClass.getSimpleName(), #activityCode)",
			unless="#result == null")
	public Activity getActivityInfo(String activityCode){
		Activity activity = null;
		try {
		} catch (Exception e) {
			log.error(e.getMessage(),e);
		}
		return activity;
	}

	@CachePut(key="#root.target.generateKey(#root.targetClass.getSimpleName(), #activity.activityCode)",
			unless="#result == null")
	public Activity saveOrUpdateActivityInfo(Activity activity)

	@CachePut(key="#root.target.generateKey(#root.targetClass.getSimpleName(), #activityCode)",
			unless="#result == null")
	public int delActivity(String activityCode)

	@CacheEvict(allEntries = true)
	public void clearCaches(Class<?> clazz)
	
}


四、关于取值异常问题
Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring/spring.xml"
//		,
//		"classpath:spring/spring-mvc.xml",
//		"file:src/main/java/com/sinowel/eacpc/**/mapping/*.xml"
		})
public class TestBase {
	
	@Before
	public void setUp() throws Exception {
	}
	
}


public class TestLua2 extends TestBase {
	private final Logger logger = LoggerFactory.getLogger(TestLua2.class);
	
	@Resource(name = RedisService.SERVICE_NAME)
	private RedisService redisService; // redis
	
	@Resource(name = "redisTemplate")
	private RedisTemplate<String, Object> redisTemplate; // redis

	@Test
	public void testInject() throws Exception {
		// 在服务器redis-cli连接预存入Hash key=tt1 field=t1,t2的数值
		String redisKey = "tt1";
		List<String> fieldList = Arrays.asList(new String[] {"t1", "t2"});
		List<Long> list = redisService.getMultiHash(redisKey, fieldList, null);
		System.out.println(list.get(0).longValue());

		// 存入时使用stringRedisSerializer,取值时使用jdkRedisSerializer。xml RedisTemplate时配置
		// 异常,先存,再次取,配置文件切换配置
		String redisKey = "tt2";
		List<String> fieldList = Arrays.asList(new String[] {"t1", "t2"});
		redisService.setHash(redisKey, "t1", "1");
		redisService.setHash(redisKey, "t2", "2");
		BoundHashOperations<String, String, Long> bhOps = redisTemplate
				.boundHashOps(redisKey);
		List<Long> list = bhOps.multiGet(fieldList);
		System.out.println(list.get(0));
		
		// keySerializer 和 hashKeySerializer 设置 stringRedisSerializer
		// valueSerializer 和 hashValueSerializer 设置成默认 jdkRedisSerializer
		// 则可以取得指定值,否则都使用stringRedisSerializer,取到的值一定是String类型
		String redisKey = "tt3";
		List<String> fieldList = Arrays.asList(new String[] {"t1", "t2"});
		BoundHashOperations<String, String, Long> bhOps = redisTemplate
				.boundHashOps(redisKey);
		bhOps.put("t1", 1L);
		bhOps.put("t2", 2L);
		List<Long> list = bhOps.multiGet(fieldList);
		System.out.println(list.get(0));
	}
}


redis-cli取到序列化后的值【1】
stringRedisSerializer:
"\xac\xed\x00\x05t\x00\x011"

jdkRedisSerializer:
"\xac\xed\x00\x05sr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x01"

总结:各个RedisSerializer序列化的值存入redis后,取值时,是不能切换取值的。因为序列化方式不同。
分享到:
评论

相关推荐

    SpringMvc集成Redis项目完整示例

    你可以在遇到任何关于Spring MVC和Redis集成的问题时,与其他开发者交流解决方案。 总结起来,这个项目是一个实践性强、易于学习的教程,涵盖了Spring MVC和Redis集成的各个方面,从配置到实际应用,再到测试验证,...

    java spring集成redis所需库包

    总之,Java Spring集成Redis涉及的库包主要包括Spring Data Redis、Jedis或Lettuce客户端,以及相应的配置和操作API。在集成过程中,要注意依赖管理,确保所有库包版本兼容,以避免出现不兼容问题。通过正确配置和...

    38. Spring Boot分布式Session状态保存Redis【从零开始学Spring Boot】

    Spring Boot提供了多种集成Session的解决方案,其中一种就是使用Redis作为Session的存储介质。Redis是一个高性能的键值数据库,支持丰富的数据结构,如字符串、哈希、列表、集合等,非常适合用来存储Session。 要...

    Spring data redis的简单应用

    在应用中使用Spring Data Redis,你可以声明一个`@Autowired`的`RedisTemplate`实例,然后调用它的方法来存取数据。例如,使用`opsForValue()`方法可以操作字符串类型的键值对: ```java @Autowired private ...

    spring boot+redis单机与集群.zip

    总结来说,这个压缩包文件的内容将涵盖Spring Boot项目中集成Redis的基本步骤,包括设置单机和集群模式,以及如何在应用中使用Redis进行数据缓存。对于初学者,这将是一个很好的实践指南,而对于有经验的开发者,也...

    spring redis 分布式缓存整合详细的注释说明

    在使用Spring Redis时,可能会遇到网络问题、数据序列化错误等异常,应合理捕获并处理这些异常,确保程序的健壮性。 八、最佳实践 1. 合理设置缓存过期时间,避免数据过期后仍被使用。 2. 使用合适的序列化方式,如...

    Shiro集成 Redis 方案

    Apache Shiro 是一个强大且易用的 Java 安全框架,提供身份认证、授权、会话管理和...在实际应用中,你可能还需要结合其他技术,如 Spring Boot 或者 Dubbo,来更好地整合 Shiro 和 Redis,实现完整的安全和缓存管理。

    redis的服务端,客户端,整合spring配置文件

    综上,本资源包提供了一站式的Redis学习资料,从基础的安装配置到高级的Spring集成,覆盖了开发中可能遇到的各种场景。通过深入学习和实践,开发者可以熟练掌握Redis的使用,提升应用的性能和可扩展性。

    spring-boot-redis.zip

    在实际项目中,我们可能会遇到分布式环境下的缓存一致性问题。Spring Boot结合Redis的发布/订阅(Pub/Sub)模式,可以实现消息的实时同步,确保在分布式系统中的数据一致性。 总结来说,"spring-boot-redis.zip...

    Java生态研究(Spring Boot + Redis + Dubbo + RocketMQ)

    Java生态是目前软件开发领域的重要组成部分,其丰富的框架和工具为开发者提供了强大的支持。...这将帮助Java初学者快速掌握核心组件的用法,避免在实践中遇到的常见问题,从而提升他们的开发技能和效率。

    基于java的开发源码-使用Redis存放Session RedisManager.zip

    总的来说,这个项目提供了使用Java和Redis进行Session管理的实例,有助于开发者理解如何在实际应用中实现Session的分布式存储,提高系统的可扩展性和稳定性。通过学习和实践,可以提升处理大型Web应用的能力,并掌握...

    自定义redis序列化和解决穿透问题.docx

    综上所述,解决Java开发中使用Redis缓存时的多线程数据同步延迟和缓存穿透问题,可以通过引入布隆过滤器、空值缓存策略,以及在代码中使用同步关键字或锁机制来实现。在Springboot2.x环境中,可以通过注解和编码方式...

    狂神说Redis笔记.pdf

    在SpringBoot项目中集成Redis可以使用Spring Data Redis模块,它简化了Redis的操作,并且与Spring生态系统紧密结合。 **Nosql概述** Nosql,即“Not Only SQL”,它包括键值对存储、列存储、文档存储、图形数据库...

    配置tomcat-redis-session共享架包

    如果遇到session丢失问题,检查网络连接、Redis配置和Tomcat日志是常见的排查手段。 7. **最佳实践** - 尽量减少session中的数据量,只存储必要信息,避免占用过多的Redis内存。 - 考虑使用Spring Session等更...

    SSM+Shiro+redis项目实例

    SSM+Shiro+Redis项目实例是一个典型的Java Web开发架构,涵盖了Spring、Spring MVC、MyBatis、Apache Shiro和Redis等多种技术。...通过这个项目,开发者可以提升自己的技能,为实际工作中遇到的类似问题提供解决方案。

    redis实战 黄健宏 完整得

    此外,还涵盖了主从复制、哨兵系统和Cluster集群,这些都是在分布式环境中使用Redis时不可或缺的知识点。 在性能优化方面,《Redis实战》探讨了内存管理、命令阻塞问题、过期策略、lua脚本的使用等,帮助读者理解...

    redis_cluster_simple.zip

    在本项目"redis_cluster_simple.zip"中,我们探讨的是如何使用Spring Boot来配置和操作一个Redis集群。Redis是一个高性能的键值存储系统,常用于数据库、缓存和消息中间件等场景。Spring Boot则简化了Java应用的初始...

    重试框架spring-retry以及guava-retry的使用

    1. **集成度**:Spring Retry与Spring框架紧密结合,易于在Spring应用中使用,而Guava Retry作为独立库,可以被任何Java项目采用,但需要手动集成。 2. **使用方式**:Spring Retry更注重声明式编程,注解方式更...

    redis-session-manager-redis-session-manager-2.0.0.zip

    在实际使用过程中,可能会遇到的问题及解决方案包括: 1. **性能优化**:根据业务需求调整Redis的内存大小、过期策略和缓存淘汰策略。 2. **安全性**:为Redis服务器设置访问控制,限制非必要的网络访问,避免...

    Spring Session 2 中文 参考手册 中文文档

    Spring Session是一个为Java平台提供会话管理的库,它提供了一个统一的API和实现用于管理用户会话信息,其核心目的是解决应用程序在分布式系统中处理HTTP会话时可能遇到的常见问题,尤其是在实现集群环境下的会话...

Global site tag (gtag.js) - Google Analytics