博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
测试唯一ID支持多大的并发量
阅读量:6900 次
发布时间:2019-06-27

本文共 3298 字,大约阅读时间需要 10 分钟。

昨天突然考虑到这个问题,在并发比较大的情况下,你用于生成唯一ID的函数是否还能正常运行?也就是说比如我一下子进来40000个订单,你需要生成不重复的订单ID吧?

对于这个问题我以前没考虑过,但是可能是误打误撞,我以前一开始设计的ID生成思路是13位时间戳+随机7位,就是为了凑够20位的ID。因为如果是在同一时间那么可以忽略掉13位时间戳,剩下的7位是需要关注的,我有预选的34个字母+数字,根据排列组合可以得知,可以有34^7个排列组合方法(也就是52523350144)。

那么理论上同一时刻(如果时间戳相同的话)我可以生成52523350144个ID(我已经数过了,是525亿),但是我没有在分布式场景下测试过,不敢保证不出问题。而我也有个猜测,比如我有三台应用服务器做负载均衡,同一时刻这三台生成的相同ID的几率为1/525亿*525亿*525亿,几率也太小了吧,如果还不放心,那么你就生成ID后去检查自己的是否唯一,如果已存在,你就再生成一个咯。

 

以下是测试:ID类

package com.internetsaying.utils;import java.util.Date;import java.util.Random;public class IDUtils {        /**     * 生成20位ID,理论上在同一时刻能生成的ID数为34^7=52523350144[5.2523350144E10]     * @param time     * @return     */    public static String createID20(Date time){        String[] vocabulary = {                "A","B","C","D","E","F","G","H","I","J","K","L","M","N",                "P","Q","R","S","T","U","V","W","X","Y","Z","1","2","3",                "4","5","6","7","8","9"        };        int n = vocabulary.length;        Random rand = new Random();        StringBuilder s = new StringBuilder();        for(int i = 0; i < 7; i++){            s.append(vocabulary[rand.nextInt(n)]);        }        String str = time.getTime() + s.toString();        return str;    }}

 

模拟并发类

package com.isay.test;import java.util.Date;import java.util.Set;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.CountDownLatch;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import org.junit.Test;import com.internetsaying.utils.IDUtils;public class OtherTest {    @Test    public void uniqueID() {        System.out.println(Math.pow(34, 7));    }        public static void main(String[] args) {        int concurrentNum = 70000;    //并发数        CyclicBarrier c = new CyclicBarrier(concurrentNum);        // 让线程同时开始        CountDownLatch l = new CountDownLatch(concurrentNum);    // 所有线程结束在执行统计        ExecutorService es = Executors.newCachedThreadPool();                Set
set = ConcurrentHashMap.newKeySet(); // Set集合,存储生成的ID for (int i = 0; i < concurrentNum; i++) { es.submit(new Demo(set,c,l)); } es.shutdown(); try { l.await(); // 前面的任务执行完才到下一步 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(set.size()); }}class Demo implements Runnable{ private Set
set; private CyclicBarrier c; private CountDownLatch l; public Demo(Set
set, CyclicBarrier c, CountDownLatch l) { super(); this.set = set; this.c = c; this.l = l; } @Override public void run() { try { c.await(); // 等待,直到有足够的线程 } catch (InterruptedException | BrokenBarrierException e) { // TODO Auto-generated catch block e.printStackTrace(); } String id20 = IDUtils.createID20(new Date()); set.add(id20); l.countDown(); // 每当有线程结束就减1 } }

 

结果:输出70000.(如果有n个并发,最终set集合里面的size也是n,就证明生成了n个不重复的id,那么就成功)

说明:如果你的电脑大于8G,可以直接测试70000的并发,如果小于8G,你就要小心了,因为是n个线程(用户)一起开始,电脑吃不消。

 

我希望大家帮我找出这个策略的问题,多多测试

 

转载于:https://www.cnblogs.com/LUA123/p/8447944.html

你可能感兴趣的文章
UITabelView的分割线处理及介绍
查看>>
Spring整合MyBatis
查看>>
打印机拒绝访问无法连接
查看>>
Linux学习路线图
查看>>
Linux系统下常见性能分析工具的使用
查看>>
事件驱动模型
查看>>
ASP.NET MVC 音乐商店 - 3. 视图与模型
查看>>
mcollective安装文档
查看>>
GRE隧道模式与IPSec传输模式构建×××
查看>>
linux命令6--touch命令
查看>>
我的友情链接
查看>>
且谈布局适配和日志框架
查看>>
在论坛中出现的比较难的sql问题:15(行转列2)
查看>>
springboot中的5种通知小例子
查看>>
mysql数据通过jdbc操作作为Spark数据源案例
查看>>
Sersync实现触发式文件同步
查看>>
shell练习题
查看>>
大型网站压力测试及优化方案
查看>>
云计算的特性有这4点
查看>>
IT兄弟连 JavaWeb教程 jQuery对AJAX的支持
查看>>