SpringBoot+Vue3+Element Plus 仿百度网盘实战

219 阅读3分钟

SpringBoot+Vue3+Element Plus 仿百度网盘实战

核心代码,注释必读

// download: 3w ukoou com

Java 的可变参数与 Collections 类

1. 可变参数

JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化.

格式:

修饰符 返回值类型 方法名(参数类型... 形参名){  }

底层:

​ 其实就是一个数组

好处:

​ 在传递数据的时候,省的我们自己创建数组并添加元素了,JDK底层帮我们自动创建数组并添加元素了

代码演示:

  public class ChangeArgs {
    public static void main(String[] args) {
        int sum = getSum(6, 7, 2, 12, 2121);
        System.out.println(sum);
    }
    
    public static int getSum(int... arr) {
           int sum = 0;
            for (int a : arr) {
         sum += a;
        }
            return sum;
    }
}

注意:

​ 1.一个方法只能有一个可变参数

​ 2.如果方法中有多个参数,可变参数要放到最后。

应用场景: Collections

​ 在Collections中也提供了添加一些元素方法:

​ public static <T> boolean addAll(Collection<T> c, T... elements) :往集合中添加一些元素。

代码演示:

public class CollectionsDemo {
    public static void main(String[] args) {
      ArrayList<Integer> list = new ArrayList<Integer>();
      //原来写法
      //list.add(12);
      //list.add(14);
      //list.add(15);
      //list.add(1000);
      //采用工具类 完成 往集合中添加元素  
      Collections.addAll(list, 5, 222, 12);
      System.out.println(list);
}

2. Collections类

2.1 Collections常用功能

  • java.utils.Collections是集合工具类,用来对集合进行操作。

    常用方法如下:

  • public static void shuffle(List<?> list) :打乱集合顺序。

  • public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。

  • public static <T> void sort(List<T> list,Comparator<? super T> ):将集合中元素按照指定规则排序。

代码演示:

public class CollectionsDemo {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
   
        list.add(100);
        list.add(300);
        list.add(200);
        list.add(50);
        //排序方法 
        Collections.sort(list);
        System.out.println(list);
    }
}
结果:
[50,100, 200, 300]

我们的集合按照默认的自然顺序进行了排列,如果想要指定顺序那该怎么办呢?

SpringBoot+Vue3+Element Plus实战

发生企业级灾难
代码执行描述:
1、用户的余额是通过后台,在每日0点开始进行入账(归入余额)。
2、使用@Scheduled作为定时脚本
3、定时任务需要获取到 redis setnx 锁的权限,才能继续执行下面的代码

@Component      // 1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
public class OrderMoneyToMerchantMoney {
    @Resource
    private JedisPoolUtil jedisPoolUtil;

    @Scheduled(cron = "${scheduled.timedTaskScheduled:*/5 * * * * ?}")
    public void configureTasks() {
        System.err.println("执行静态定时任务时间: " + LocalDateTime.now());
        selectDb();
    }

    @Transactional  // 事务操作
    public void selectDb() {
      ……
      for (Orderlist temp : allList) {
      // 获取锁权限
      boolean setNx = JedisPoolUtil.setNx("D1MoneyToMerchantD0Money:" + temp.getOrderid(), 60 * 10); // 锁10分钟
      if (!setNx) {
          continue;
      }
      ……
    }
}

使用的util工具是

@Component
public class JedisPoolUtil {
    
  private RedisTemplate<String, Object> redisTemplate;

  public RedisTemplate<String, Object> getRedisTemplate() {
      return redisTemplate;
  }

  public boolean setNx(String key, long time) {
    try {
      Boolean lock = getRedisTemplate().opsForValue().setIfAbsent(key, 1, time, TimeUnit.SECONDS);
      if (lock) {
        // 加锁成功
        return true;
      } else {
        // 没有分布式锁,等待,进入自旋
        return false;
      }
      } catch (Exception e) {
        e.printStackTrace();
        return false;
      }
    }
}

redis执行逻辑:
在程序初始化时:创建0~15库的redis连接,并放到map中
使用时,取出map中的一个值,加载到工具类的redisTemplate当中

JedisPoolUtil           redisUtil    = jedisPoolUtil.setRedisTemplate(jedisPoolUtilConfig.getRedisTemplateByDb(10));

服务器:一台 centos7.9
docker:docker19.03.13 + docker composer
java:运行在2个docker容器中(使用docker composer编排)
redis:运行在docker容器中 redis_6.2.6版本 使用docker官方镜像 redis:6.2.6

灾难描述:
1、用户余额在昨日,突然2个在docker中的java进程均获取到了 redis setnx 锁-->导致用户余额重复增加
2、商户余额已经提现,平台金额亏损。

发现原因:
1、猜测redis使用的spingboot2 自动注入的类

@Resource
private JedisPoolUtil jedisPoolUtil;

而不是

JedisPoolUtil redisUtil = jedisPoolUtil.setRedisTemplate(jedisPoolUtilConfig.getRedisTemplateByDb(10));

导致多个java进程(可能)连接到不同的redis库,所以不同redis库在setnx时,可以获取到锁。
2、猜测是否跟使用docker redis+docker java 有关
-->本地启动2个jar+本地redis测试结果:只能1个java进程获取到redis setnx锁,另一个获取不到
-->本地启动1个jar+线上启动2个docker java+本地连接线上redis测试结果:只能1个java进程获取到redis setnx锁,另一个获取不到