[投机取巧]解决一个单机服务的并发问题
最近在处理一个单体应该的时候遇到了并发问题
出现并发问题的伪代码:
1 String redisKey="ORDER_CURRENT_KEY"; 2 String orderCurrentKey = redisUtils.get(redisKey); 3 if (Integer.valueOf(orderCurrentKey)<100) { 4 redisUtils.incr(redisKey ,1 ); 5 System.out.println("服务器只能同时处理100个请求"); 6 }else { 7 System.out.println("当前同时处理数已满"); 8 return null; 9 }
压力测试的并发为每秒1000,当前线上生产环境,高峰期每秒2000,日常每秒50
伪代码第二行:
假设会进入300个同时获取,那这300个线程,就会通过第三行的判断,变为同时处理了300个请求,导致测试环境程序奔溃。
而且最终redis中的值是 ORDER_CURRENT_KEY 的值是300.
简单并发问题,测试服务器配置较低...容易出现各种问题;
想法:
解决办法有:
- 加锁,对在获取值,到对比加锁,但是会严重影响程序的并发能力
- 依赖redis或者zookeeper做分布式锁,redis由于知识储备问题,没有实现;依赖zookeeper,就因为一个锁,依赖多一个组件,不划算!
- 最终,使用了一种投机取巧的办法!
看伪代码:
1 Long lockOrder = redisUtils.incr("ORDER_CURRENT_LOCK_KEY",1); 2 String redisKey="ORDER_CURRENT_KEY"; 3 if (lockOrder<100) { 4 redisUtils.incr(redisKey ,1 ); 5 System.out.println("服务器只能同时处理100个请求"); 6 }else { 7 System.out.println("当前同时处理数已满"); 8 return null; 9 }
思路是,加多一个redis键值对;
利用 redisUtils.incr(key,1);内部的计算方法!还有redis天然的单线程!
所以算出来值不会存在重复值!并发再高也不会!lockOrder值就是请求数!
lockOrder !!!既然不重复!
在第三行对比的时候,lockOrder 的值是:0-99,都会进入服务的内部处理!其他都直接返回结果!
好像完美解决!
反正现在压力测试,并没有出现过超出100的同时请求处理!
确实有点投机取巧,利用redis的单线程特性!
确实有点投机取巧,但是并不是每个公司,都会搭建集群,都部署超高配置服务器;
这里生产环境只有一台8核16G的服务器,所有服务都部署在上面,不过业务是非常简单的而已。。
可能后续会拓展吧.......什么高可用,高性能,更高并发5K-10K。。。后续再续集进行个人的知识储备吧。