当前位置: 首页 > news >正文

java uuid第一次性能

在java中产生uuid的方式是使用java.util.UUID。

UUID.randomUUID().toString();

我在测试redis性能时,使用uuid产生测试数据,发现多线程测试redis的rpush接口的时候,性能老是上不去。 查看cpu利用率也不高,网卡流量也不大。就是tps上不去。但是如果用两台client去测,又可以达到更高的tps。

后来直接用jstack查看了下堆栈,发现大多数线程停留在:

java.lang.Thread.State: BLOCKED (on object monitor) at java.security.SecureRandom.nextBytes(Unknown Source) - waiting to lock <0x00000005ffe1c548> (a java.security.SecureRandom) at java.util.UUID.randomUUID(Unknown Source)

原来uuid的生成遇到了性能瓶颈。于是我单独测试了下生成随机uuid的性能,发现无论是1个线程还是32个线程还是300个线程,它的tps只能到10万级别。 甚至是线程数越大,tps越低。tps在每个机器上都不一样,有的机器上测试tps只有5万。我们就以一台双核4G内存的虚拟机为例:

tps在 140000+

我们看randomUUID方法的javadoc的描述是: The UUID is generated using a cryptographically strong pseudo random number generator 也就是说uuid使用了一个强随机数,也也保证了uuid的不重复性。

public static UUID randomUUID() { SecureRandom ng=numberGenerator; if(ng == null) numberGenerator=ng=new SecureRandom();   byte[] randomBytes=new byte[16]; ng.nextBytes(randomBytes); return new UUID(randomBytes); }

再看SecureRandom的javadoc Note: Depending on the implementation, the generateSeed and nextBytes methods may block as entropy is being gathered, for example, if they need to read from /dev/random on various unix-like operating systems.

也就是说SecureRandom的nextBytes方法,依赖随机数的产生,如果随机数不够了,它有可能就会堵塞在那边。 比如随机数的产生是读取unix类系统的/dev/random文件。

我们再去看有关/dev/random的信息:

Linux中的随机数可以从两个特殊的文件中产生,一个是/dev/urandom.另外一个是/dev/random。他们产生随机数的原理是利用当前系统的熵池来计算出固定一定数量的随机比特,然后将这些比特作为字节流返回。熵池就是当前系统的环境噪音,熵指的是一个系统的混乱程度,系统噪音可以通过很多参数来评估,如内存的使用,文件的使用量,不同类型的进程数量等等。如果当前环境噪音变化的不是很剧烈或者当前环境噪音很小,比如刚开机的时候,而当前需要大量的随机比特,这时产生的随机数的随机效果就不是很好了。

这就是为什么会有/dev/urandom和/dev/random这两种不同的文件,后者在不能产生新的随机数时会阻塞程序,而前者不会(ublock),当然产生的随机数效果就不太好了,这对加密解密这样的应用来说就不是一种很好的选择。/dev/random会阻塞当前的程序,直到根据熵池产生新的随机字节之后才返回,所以使用/dev/random比使用/dev/urandom产生大量随机数的速度要慢。

jdk默认的是读取/dev/random文件产生强随机数,但是如果不是为了产生加密随机数,我们可以设置jdk读取/dev/urandom产生随机数,从而生成随机uuid。

在java启动项中增加-Djava.security.egd=file:/dev/./urandom 配置项(不能写作/dev/urandom,关于这个,网上有相关八卦历史~)

再去相同的机器上测试uuid的性能:

tps在 720000+

相关文章:

  • 精度计算-大数乘小数
  • C#~异步编程再续~await与async引起的w3wp.exe崩溃-问题友好的解决
  • Android 中文API (68) —— BluetoothClass.Service
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • Binlog中最容易踩到的坑
  • 图解HashMap(二)
  • 安装编译bind
  • Deepin桌面版更新:基于最新Ubuntu 17.10
  • java-信息安全(二)-对称加密算法DES,3DES,AES,Blowfish,RC2,RC4
  • Linux系统管理员级别需要掌握的操作(第一部分)
  • 协程
  • C#中for循环的交换排序案例
  • Apache Server 负载能力测试
  • C#的delegate简单练习
  • 前端学习系列
  • JavaScript 如何正确处理 Unicode 编码问题!
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • es6要点
  • JavaScript创建对象的四种方式
  • Meteor的表单提交:Form
  • mockjs让前端开发独立于后端
  • nfs客户端进程变D,延伸linux的lock
  • SpiderData 2019年2月16日 DApp数据排行榜
  • Wamp集成环境 添加PHP的新版本
  • 阿里云应用高可用服务公测发布
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 安卓应用性能调试和优化经验分享
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 基于HAProxy的高性能缓存服务器nuster
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 前端知识点整理(待续)
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 使用 Docker 部署 Spring Boot项目
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • 主流的CSS水平和垂直居中技术大全
  • #### go map 底层结构 ####
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (13)Hive调优——动态分区导致的小文件问题
  • (MATLAB)第五章-矩阵运算
  • (poj1.3.2)1791(构造法模拟)
  • (ros//EnvironmentVariables)ros环境变量
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (九)One-Wire总线-DS18B20
  • (数据结构)顺序表的定义
  • (学习日记)2024.02.29:UCOSIII第二节
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • *上位机的定义
  • .net开发时的诡异问题,button的onclick事件无效
  • .net用HTML开发怎么调试,如何使用ASP.NET MVC在调试中查看控制器生成的html?
  • .net专家(张羿专栏)
  • /etc/shadow字段详解
  • [Android]RecyclerView添加HeaderView出现宽度问题