谷粒商城学习笔记---补充部分

1、秒杀

1、使用redis进行实现–开启商品的监控----使用redis的watch来保证秒杀的成功–multi-watch
随机运气机制

- MULTI 
- EXEC 
- DISCARD 
- WATCH

MULTI命令 :用于开启一个事务,它总是返回OK。
	MULTI执行之后,客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行,而是被放到一个队列中,
	当 EXEC命令被调用时, 所有队列中的命令才会被执行。

EXEC命令 :负责触发并执行事务中的所有命令: 
	如果客户端成功开启事务后执行EXEC,那么事务中的所有命令都会被执行。 
	如果客户端在使用MULTI开启了事务后,却因为断线而没有成功执行EXEC,那么事务中的所有命令都不会被执行。 
	需要特别注意的是:即使事务中有某条/某些命令执行失败了,事务队列中的其他命令仍然会继续执行
		——Redis不会停止执行事务中的命令,而不会像我们通常使用的关系型数据库一样进行回滚。

DISCARD命令 
	当执行 DISCARD 命令时, 事务会被放弃, 事务队列会被清空,并且客户端会从事务状态中退出。

WATCH 命令 
	可以为Redis事务提供 check-and-set (CAS)行为。
	被WATCH的键会被监视,并会发觉这些键是否被改动过了。 
	如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消, EXEC 返回nil-reply来表示事务已经失败。
  //高并发的情况下,不加入事务控制,抢购出现多人抢一个的问题
    @RequestMapping("kill")
    @ResponseBody
    public String kill(){//redis方法可能出现点的慢的比点的快的抢到--随机运气机制秒杀

        String memberId = "XXXX";
        Jedis jedis = redisUtil.getJedis();
        //开启商品的监控----使用redis的watch来保证秒杀的成功
        jedis.watch("106");
        int count = Integer.parseInt(jedis.get("106"));
        if(count > 0){
            Transaction multi = jedis.multi();//开启事务---保证redis的安全
            jedis.incrBy("106", -1);
            List<Object> exec = multi.exec();
            if(exec != null && exec.size() > 0){
                System.out.println("当前库存剩余数量为:" + count + ",用户" + memberId + "抢购成功!!当前抢购人数为:" + (1000 - count));
                //用消息队列发出订单消息---后续再发送
            }else{
                System.out.println("当前库存剩余数量为:" + count + ",用户" + memberId + "抢购失败!!");
            }
        }
        jedis.close();
        return "1";
    }
}

2、使用Redisson进行实现—getSemaphore-----tryAcquire();
先到先得机制

   @RequestMapping("secKill")
    @ResponseBody
    public String secKill(){//使用Redisson---与redis不同---先到先得机制秒杀

        Jedis jedis = redisUtil.getJedis();//redis只是单纯的查一下数量
        String memberId = "XXXX";
        RSemaphore semaphore = redissonClient.getSemaphore("106");
        boolean b = semaphore.tryAcquire();
        int count = Integer.parseInt(jedis.get("106"));

        if(b){
            System.out.println("当前库存剩余数量为:" + count + ",用户" + memberId + "抢购成功!!当前抢购人数为:" + (1000 - count));
            //用消息队列发出订单消息---后续再发送
            System.out.println("发出订单的消息队列,由订单系统对当前抢购生成订单。");
        }else{
            System.out.println("当前库存剩余数量为:" + count + ",用户" + memberId + "抢购失败!!");
        }
        jedis.close();
        return "1";
    }
    
  

2、限流

限流,限制服务器的流量,单位时间内的吞吐数,处理请求的数量。

**漏桶算法:**设置一个桶的容量,即最大承载值,如果大于这个容量直接false,时间间隔乘速率。
谷粒商城学习笔记---补充部分_第1张图片

long timeStamp = getNowTime(); 
int capacity = 10000;// 桶的容量,即最大承载值
int rate = 1;//水漏出的速度,即服务器的处理请求的能力
int water = 100;//当前水量,即当前的即时请求压力

//当前请求线程进入漏桶方法,true则不被拒绝,false则说明当前服务器负载水量不足,则被拒绝
public static bool control() {
long  now = getNowTime();//当前请求时间
//先执行漏水代码
//rate是固定的代表服务器的处理能力,所以可以认为“时间间隔*rate”即为漏出的水量
    water = Math.max(0, water - (now - timeStamp) * rate);//请求时间-上次请求时间=时间间隔
    timeStamp = now;//更新时间,为下次请求计算间隔做准备
    if (water < capacity) { // 执行漏水代码后,发现漏桶未满,则可以继续加水,即没有到服务器可以承担的上线
        water ++; 
        return true; 
    } else { 
        return false;//水满,拒绝加水,到服务器可以承担的上线,拒绝请求
   } 
}

令牌桶算法:以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。

谷粒商城学习笔记---补充部分_第2张图片

long timeStamp=getNowTime(); 
int capacity; // 桶的容量 
int rate ;//令牌放入速度
int tokens;//当前水量  

bool control() {
   //先执行添加令牌的操作
   long  now = getNowTime();
   tokens = max(capacity, tokens+ (now - timeStamp)*rate); 
   timeStamp = now;  
   if(tokens<1){
     return false; //令牌已用完,拒绝访问
   }else{ 
     tokens--;
     retun true; //还有令牌,领取令牌
   }
 }

3、docker+K8s

1、云容器
云容器的架构能够提供一整套的,自动提交,自动打包,自动部署,自动重启,动态配置的解决方案,

云容器代替原始部署完成以下工作:搭建虚拟机,安装redis,nginx,mq,mysql,tomcat,jdk,maven。
然后搭完以后镜像出来,换到另外一台上,换个ip,单独做测试环境。
然后每次部署,通过ssh连接到linux服务器,kill -9,然后备份,重启服务器,打war包等等等

2、云容器的整体结构

流程:
1 ->程序员提交代码到git
2 ->Jenkins对新版本进行打包测试
3 ->提交docker进行自动部署
4 ->通过webui动态配置nginx反向代理

谷粒商城学习笔记---补充部分_第3张图片

1 git 代码版本控制(svn)
2 jenkins 自动打包测试工具(将写好的代码从git上拉下来,然后打成为服务的jar包)
3 glusterfs 分布式文件存储系统,相当于fastdfs
4 docker 把(springboot)微服务作为一个个单独的容器,单独运行
5 Kubernetes解决的就是docker集群以及各处网络访问的阻碍(它还有负载均衡功能,我们用的是nginx+springcloud)
6 etcd+confd+nginx 将nginx的配置实现动态化,在webui页面上就可以配置nginx的反向代理

你可能感兴趣的:(Java,redis,秒杀,限流,云容器,漏桶算法)