码迷,mamicode.com
首页 > 其他好文 > 详细

[投机取巧]一个单机服务的并发问题

时间:2020-08-03 23:32:08      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:返回   ring   eof   分布式   简单的   线程   计算方法   进入   rcu   

最近在处理一个单体应该的时候遇到了并发问题

出现并发问题的伪代码:

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。。。后续再续集进行个人的知识储备吧。

 

[投机取巧]一个单机服务的并发问题

标签:返回   ring   eof   分布式   简单的   线程   计算方法   进入   rcu   

原文地址:https://www.cnblogs.com/vince-zww/p/13429934.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!