- 浏览: 1146379 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (138)
- JAVA基础 (22)
- Spring (6)
- 设计模式 (2)
- JDK源码 (3)
- java-功能组件 (4)
- 游戏项目 (2)
- linux (13)
- Oracle (2)
- struts (1)
- 字符集 (8)
- HTTP协议 (2)
- java-网络通信 (1)
- 工具软件推荐 (2)
- tomcat (1)
- java-容器框架 (2)
- java-IO框架 (2)
- java-多线程框架 (4)
- java-NIO框架 (0)
- jquery (2)
- 工具使用 (12)
- 加密解密 (1)
- redis (2)
- maven (2)
- svn (1)
- eclipse (1)
- mysql (11)
- 我的收藏 (1)
- JAVA进阶 (26)
- 运维 (3)
- protocol buffer (1)
- 优秀博主 (1)
- nginx (1)
- 算法 (2)
- 故障排查 (4)
- 粤语歌曲 (6)
- 生活总结 (6)
- 高并发 (4)
- 语言训练 (1)
- 读书笔记 (5)
- 诗歌 (1)
- tomcat源码学习 (1)
- 软件词汇 (1)
- git (1)
最新评论
-
ryuhi:
一个是来源source,一个是来源方序列号seq这两个数据要怎 ...
高并发的核心技术-幂等的实现方案 -
xuezhongyu01:
无量 写道Master-Gao 写道理论感觉还行,可以代码我还 ...
高并发的核心技术-幂等的实现方案 -
无量:
Master-Gao 写道理论感觉还行,可以代码我还是不会写。 ...
高并发的核心技术-幂等的实现方案 -
phil_jing:
@RequestParam 默认 true
SpringMVC注解@RequestParam全面解析 -
aguai0:
aguai0 写道第五条里的如果要获取任务执行结果,用Comp ...
JAVA进阶----ThreadPoolExecutor机制
全局主键生成器
介绍:
相对于DB自增序列的全局主键生成器,性能更高,同时保留业务需求的业务含义,
对于有分库分表需求的业务同时可以存储分库和分表的信息,对于高并发的互联网企业分库分表生成主键来说是一种很好的方法
这个确实有问题,已经修改
介绍:
相对于DB自增序列的全局主键生成器,性能更高,同时保留业务需求的业务含义,
对于有分库分表需求的业务同时可以存储分库和分表的信息,对于高并发的互联网企业分库分表生成主键来说是一种很好的方法
package com.tongbanjie.trade.test.base; import java.net.InetAddress; import org.apache.commons.lang.StringUtils; import com.tongbanjie.commons.util.TSS; public class TestGenId { public static void main(String[] args) throws Exception { /** * 项目:交易单分表 * * 需求 * 查询需求: 1. userId维度 * 2. 产品维度 * 3. 商户维度 * 4. 时间区间维度 * * 预计订单量: * 一单平均10000, 一年交易额5000亿, 需要成功订单量 = 500000000000 / 10000 = 50000000 5000万订单 * 购买加回款应该是1亿订单量, 所以, 单表2000万, 一年需要5张表 * * 最后扩展64库 + 64表, 共64*64 = 4096表, 4096 * 2000万 = 819亿订单够用了, 819亿 * 10000 = 8190000亿 819万亿,够用了 * * 全局唯一主键: * 15位时间戳 + 自增序号四位 + 机器后两段IP,6位 + 备用1位 + 分库信息两位 + 分表信息两位 共30位, 回款改造前 * 15位时间戳 + 自增序号四位 + 机器后两段IP,6位 + 备用3位 + 分库信息两位 + 分表信息两位 共32位, 回款改造后 * * 单JVM支持最多1s 1000 * 9999 = 9999000, 999万9千笔订单,后续还可以扩展。 * * 分库规则: * 寻找到数据库 (userId/100) % 64 + 1 找到数据库 订单最多64个库 目前一个库 二分法裂变扩容 * 分表规则: * 寻找到表信息 userId % 64 + 1 找到表信息 一个库最多64个表 目前分8张表 以后二分法裂变扩容 * * 迁移规则: * 迁移方案同步写, 目前用动态表名, 以后分表中间件稳定后, 迁移过去 * * 查询改造: * 原接口不变,对用户无感知, 底层钩子遍历 */ // 只获取本地局域网IP即可 String ip = InetAddress.getLocalHost().getHostAddress(); String[] ipArray = ip.split("\\."); final String lastTwoPhaseIp = StringUtils.rightPad(ipArray[2], 3, '0') + StringUtils.leftPad(ipArray[3], 3, '0'); for (int i = 0; i < 100000; i++) { new Thread(new Runnable() { @Override public void run() { // TSS commons工具类 String tss = TSS.getTimeStampSequence(); String id = tss + lastTwoPhaseIp + "000" + "01" + "08"; System.out.println(id); } }).start(); } } }
package com.tongbanjie.commons.util; import org.apache.commons.lang.StringUtils; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; /** * 时间戳序列器<br> * * 支持同一毫秒最多生成9999笔序列号<br> * @author sanfeng * * 想象力就是生产力 */ public class TSS { // 默认1个大小 private static HashMap<String, AtomicInteger> tssCache = new HashMap<String, AtomicInteger>(1); private static final ReentrantLock lock = new ReentrantLock(); // 因为有锁,所以是变成了线程安全的,省去每次 new 的消耗,耗时降低约一半 private static final SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssSSS"); public static String getTimeStampSequence() { String timestamp = null; String inc = null; lock.lock(); try { timestamp = sdf.format(new Date()); AtomicInteger value = tssCache.get(timestamp); if(value == null) { tssCache.clear(); int defaultStartValue = 0; tssCache.put(timestamp, new AtomicInteger(defaultStartValue)); inc = String.valueOf(defaultStartValue); } else { inc = String.valueOf(value.addAndGet(1)); } } finally { lock.unlock(); } return timestamp + StringUtils.leftPad(inc, 4, '0'); } public static void main(String[] args) throws Exception { // for (int i = 0; i < 1000; i++) { // new Thread(new Runnable() { // // @Override // public void run() { // for (int j = 0; j < 10; j++) { // System.out.println(TSS.getTimeStampSequence()); // } // } // }).start(); // } // 统计重复 HashSet<String> set = new HashSet<String>(); BufferedReader br = new BufferedReader( new InputStreamReader(new FileInputStream("C:/Users/Administrator/Desktop/1.txt"))); String str = br.readLine(); while(str != null) { if(set.contains(str)) { System.out.println(str); } else { set.add(str); } str = br.readLine(); } br.close(); } }
评论
2 楼
无量
2016-07-24
一年e度的夏天 写道
敢问一句测试过了吗?我测试了十个线程就发现了大量一样的订单号
这个确实有问题,已经修改
1 楼
一年e度的夏天
2016-07-15
敢问一句测试过了吗?我测试了十个线程就发现了大量一样的订单号
发表评论
-
区块链!每个人都要了解下--十分钟洞见区块链的前世今生
2018-04-27 12:32 799区块链!每个人都要了解下--十分钟洞见区块链的前世今生 ... -
区块链!每个人都要了解下--十分钟洞见区块链的前世今生
2018-04-27 12:09 0为啥要讲区块链呢,因为它太火了,火到什么程度呢 ... -
项目打包,报软件包、类不存在问题排查过程
2017-05-16 17:13 5978项目打包报,软件包、类不存在问题排查过程 一、背景 ... -
海量数据存储--分库分表策略详解
2017-04-12 19:59 7332海量数据存储--分库分表策略详解 一、背景: 系统刚 ... -
jstack详解
2017-02-17 11:15 1915jstack http://www.open-open.co ... -
jdk-源码中的一些坑
2017-02-13 15:17 1231jdk-源码中的一些坑 1. Runnable接口的命名简直 ... -
金融的逻辑1--读书笔记
2017-02-08 23:26 1463过年在家读了一本书, ... -
git 使用 配置key
2016-12-29 10:55 1304转http://blog.sina.com.cn/s/ ... -
一次mysql死锁的排查过程
2016-11-21 10:04 11323一次mysql死锁的排查过程 一、背景 17号晚上要吃饭 ... -
JVM调优:选择合适的GC collector (三)
2016-11-15 20:51 1270CMS Collector 在很多地方,CMS Collec ... -
JVM调优:选择合适的GC collector (二)
2016-11-15 20:47 995http://blog.csdn.net/historya ... -
JVM调优:选择合适的GC collector (一)
2016-11-15 20:45 1272http://blog.csdn.net/historyas ... -
jstat查看gc情况
2016-11-10 10:11 2493jps(Java Virtual Machine Proces ... -
tomcat源码学习(一) eclipse导入tomcat源码
2016-10-31 20:05 14031. 到官网下载Tomcat源代码,这里用到的是apache- ... -
深入分析ClassLoader
2016-10-27 23:27 782转(原文http://blog.csdn.net/xya ... -
业务架构模板
2016-10-20 19:56 1885业务架构模板 默认一个高大上的业务系统需要具备的技术点和对应 ... -
如何写一个强壮的JOB任务
2016-10-18 15:00 3013如何写一个强壮的JOB任务 1. JOB跑一半断电了,不能产 ... -
mybatis.xml中sql编写规范
2016-10-18 14:54 6259一、越少的代码,越强悍的功能,xml里面应该6个sql语句就够 ... -
数据库设计规范
2016-10-17 23:29 65791. 数据库设计基本规范 领域驱动表内容 ... -
解决并发下累计的问题
2016-04-25 11:58 2125package com.tongbanjie.trade.te ...
相关推荐
【标题】"nginx-upstream-jvm-route-1.15" 涉及的核心知识点是Nginx的upstream模块与JVM路由的整合,特别针对Nginx 1.15版本。这个项目旨在解决在配置Nginx时遇到的特定错误提示“nginx: [emerg] invalid parameter ...
此资源有两个文件,含 nginx-upstream-jvm-route 和 nginx 对应版本,都是tar.gz文件。 安装方法网上很多就不写了,亲测可用。 不用担心版本不匹配造成安装失败,再浪费积分去到处下载尝试的烦恼。 此资源有两个文件...
kotlinx-coroutines-io-jvm-0.1.1.jar
nginx_upstream_jvm_route 是一个 Nginx 的扩展模块,用来实现基于 Cookie 的 Session Sticky 的功能。 安装方法(进入Nginx源码目录): #patch -p0 < /path/to/this/directory/jvm_route.patch # ./configure -...
"nginx-upstream-jvm-route-0.1.tar.gz"正是为了解决这个问题而设计的一个解决方案。 首先,让我们了解一下Nginx的Upstream模块。Upstream模块允许Nginx将接收到的请求转发到一组后端服务器,可以根据配置的策略...
1. JVM整体结构及内存模型: - **堆内存**:这是Java应用中最大的内存区域,主要存储对象实例和数组。堆被分为新生代(Young Generation)和老年代(Old Generation),新生代又分为Eden区、Survivor区(通常两个)...
JVM 的运行机制 多线程 JVM 的内存区域 JVM 会创建操作系统的接口创建一个原生线程。JVM 线程和操作系统线程是一一对应的
JVM调优总结 -Xms -Xmx -Xmn -Xss JVM 调优是 Java virtual machine 的性能优化,通过调整 JVM 的参数来提高 Java 应用程序的性能。其中,-Xms、-Xmx、-Xmn、-Xss 是四个重要的参数,分别控制 JVM 的初始堆大小、...
1. **双亲委派模型**:类加载器首先尝试由父加载器加载,如果父加载器无法加载,则由当前加载器加载。这样保证了核心类库的唯一性。 2. **自定义类加载器**:可以实现特定的类加载逻辑,例如从网络、数据库加载类。...
《深入JVM---JVM命令---invokespecial》 在Java虚拟机(JVM)的世界里,`invokespecial`指令扮演着至关重要的角色。它主要用于执行对象的构造方法(即`<init>`方法),以及调用私有方法和父类非静态方法。本文将...
kotlin-logging-jvm-2.1.21.jar
1. **JVM内存模型**: JVM内存主要分为堆(Heap)、栈(Stack)、方法区(Method Area)、程序计数器(PC Register)和本地方法栈(Native Method Stack)。堆是所有线程共享的区域,用于存储对象实例;栈则与线程...
ktor-utils-jvm-1.0.1.jar
kotlinx-io-jvm-0.1.1.jar
【hibernate主键生成策略】是Hibernate框架中用于生成持久化对象主键的重要机制,它决定了如何在数据库中创建唯一的标识符。在SSH(Spring、Struts、Hibernate)架构中,Hibernate作为持久层框架,主键生成策略的...
kotlin-scripting-jvm.jar
JVM,MIB,可通过SNMP协议监控JVM运行情况
1. **JVM内存模型**:JVM内存主要分为堆内存(Heap)、方法区(Method Area)、虚拟机栈(JVM Stack)、本地方法栈(Native Method Stack)和程序计数器(Program Counter Register)。了解每个区域的作用和配置参数...
MAT,全称Memory Analyzer Tool,是IBM开发的一款强大的Java虚拟机(JVM)内存分析工具,尤其适用于Mac OS X平台。这款工具可以帮助开发者诊断和解决Java应用中的内存泄漏问题,提高应用性能。MAT通过深入分析堆转储...
Jet 是 Swift-to-JVM 字节码编译器,为 Java 8 Runtime 而准备。Jet 使用 ANTLR 编写。 标签:JetANTLR