从jedisConnectionFactory获取Jedis实例报错
- 代码
// redisTemplate配置
@Bean(name="redisTemplate")
public RedisTemplate initRedisTemplate() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
//最大空闲数
poolConfig.setMaxIdle(50);
//最大连接数
poolConfig.setMaxTotal(1000);
//最大等待毫秒数
poolConfig.setMaxWaitMillis(20000);
poolConfig.setTestOnBorrow(true);
//创建Jedis连接工厂
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(poolConfig);
connectionFactory.setHostName("localhost");
connectionFactory.setPort(6379);
System.out.println("conn是否为空:"+(connectionFactory == null));
//调用后初始化方法,没有它将抛出异常
connectionFactory.afterPropertiesSet();
//定义Redis序列化器
RedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
RedisSerializer stringRedisSerializer = new StringRedisSerializer();
//定义RedisTemlpate,并设置连接工厂
RedisTemplate redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
//设置序列化器
redisTemplate.setDefaultSerializer(stringRedisSerializer);
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setValueSerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(stringRedisSerializer);
return redisTemplate;
}
-------------------------分割线------------------------------------
//Service中使用的代码
/**
* 使用redis进行操作
* */
@ResponseBody
@RequestMapping("/grapRedPacketByRedis.do")
public Map<String, Object> grapRedPacketByRedis(Integer redPacketId, Integer userId){
//抢红包
int result= userRedPacketService.grapRedPacketByRedis(redPacketId, userId);
Map<String,Object> retMap = new HashMap<>();
boolean flag = result>0;
retMap.put("success", flag);
retMap.put("message", flag?"抢红包成功":"抢红包失败");
return retMap;
}
-------------------------分割线------------------------------------
//在Service中注入
@Autowired
private RedisTemplate redisTemplate = null;
....
//Lua脚本
String script = "local listKey = 'red_pakcet_list_' ..KEYS[1] \n"
+"local redPacket = 'red_packet_' ..KEYS[1] \n"
+"local stock = tonumber(redis.call('hget',redPacket, 'stock')) \n"
+"if stock <=0 then return 0 end \n"
+"stock = stock-1 \n"
+"redis.call('hset',redPacket,'stock',tostring(stock)) \n"
+"redis.call('rpush',listKey, ARGV[1]) \n"
+"if stock ==0 then return 2 end \n"
+"return 1 \n";
//在缓存Lua脚本后,使用该变量保存Redis返回的32位的SHA1编码, 使用它去执行缓存的Lua脚本
String sha1 = null;
//使用的方法
@Override
public Integer grapRedPacketByRedis(Integer redPacketId, Integer userId) {
//当前抢红包用户和日期信息
String args = userId+"-"+System.currentTimeMillis();
Integer result = null;
//获取底层Redis操作对象
Jedis jedis = (Jedis) redisTemplate .getConnectionFactory().getConnection().getNativeConnection();
try {
//如果脚本没有加载过,那么进行加载,这样就会返回一个sha1编码
if(sha1 == null) {
sha1 = jedis.scriptLoad(script);
}
//执行脚本,返回结果
Object res = jedis.evalsha(sha1,1,redPacketId+"",args);
result = Integer.parseInt(res+"");
//返回2 时为最后一个红包,此时将抢红包信息通过异步保存到数据库
if(result == 2) {
//获取单个小金额红包
String unitAmountStr = jedis.hget("red_packet_"+redPacketId, "unit_amount");
//触发保存数据库操作
Double unitAmount = Double.parseDouble(unitAmountStr);
System.out.println("thread_name="+Thread.currentThread().getName());
redisRedPacketService.saveUserRedPacketByRedis(redPacketId, unitAmount);
}
} finally {
//确保jedis关闭
if(jedis != null && !jedis.isConnected()) {
jedis.close();
}
}
return result;
}
-------------------------分割线------------------------------------
// 前端js请求
<script type="text/javascript">
$().ready(function(){
//模拟30000个异步请求,进行并发
var max = 30000;
for (var i = 1; i <= max; i++) {
// jQuery的post请求, 这里是异步请求
$.post({
//请求抢id为1的红包
url:"./userRedPacket/grapRedPacketByRedis.do?redPacketId=3&userId="+i,
success:function(result){
}
});
}
});
</script>
后台异常
三月 01, 2018 3:10:17 下午 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet [dispatcher] in context with path [/RedPacket] threw exception [Request processing failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisException: Could not get a resource from the pool] with root cause
java.util.NoSuchElementException: Timeout waiting for idle object
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449)
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363)
at redis.clients.util.Pool.getResource(Pool.java:49)
at redis.clients.jedis.JedisPool.getResource(JedisPool.java:226)
at redis.clients.jedis.JedisPool.getResource(JedisPool.java:16)
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:194)
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:348)
at com.avc.rp.service.impl.UserRedPacketServiceImpl.grapRedPacketByRedis(UserRedPacketServiceImpl.java:151)
at sun.reflect.GeneratedMethodAccessor62.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy33.grapRedPacketByRedis(Unknown Source)
at com.avc.rp.controller.UserRedPacketController.grapRedPacketByRedis(UserRedPacketController.java:40)
at sun.reflect.GeneratedMethodAccessor60.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:475)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:500)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1376)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
求大神指教!!!!!