分布式全局序列ID方案之Redis优化方案

1 Redis的Flicker方案 利用redis的lua脚本功能,在每个节点上通过lua脚本生成唯一ID,生成的ID为64位,具体如下: 使用41 bit来存放时间,精确到毫秒,可以使用到2039年 使用12 bit来存放逻辑分片ID,最大分片ID是4095 使用10 bit来存放自增长ID,则每个节点,每毫秒最多可生成1024个ID 比如GTM时间 2018年6月24日11点23分 ,它的距1970年的毫秒数是 1529810591000,假定分片ID是60,自增长序列是20,则生成的ID是: 6416490681073670164 = 1529810591000 << 22 | 60 << 10 | 20 redis提供了TIME命令,取得redis服务器的秒值和微秒值 毫秒值获取命令:EVAL "local current = redis.

分布式全局序列ID方案之Flicker优化方案

1 Flicker的解决方案 MySQL中id自增的特性,可以借此来生成全局的序列号,Flicker在解决全局ID生成方案里就采用了MySQL自增长ID的机制(auto_increment + replace into + MyISAM)。一个生成64位ID方案具体就是这样的: 先创建单独的数据库,然后创建一个表: CREATE TABLE borrow_order ( id bigint(20) unsigned NOT NULL auto_increment, stub char(1) NOT NULL default '', PRIMARY KEY (id), UNIQUE KEY stub (stub) ) ENGINE=MyISAM 当我们插入记录后,执行SELECT * from borrow_order ,查询结果就是这样的:

Spring之动手实现SpringMVC功能

1 简介 SpringMVC大家应该耳熟能详,只要是做Java网站开发的小伙伴,都会使用的框架。SpringMVC以 DispatcherServlet 为核心,负责协调和组织不同组件以完成请求处理并返回响应的工作,实现了MVC模式。接下来我们从 该框架的流程 来整理设计思路,最后自己实现一个mvc框架. 2 SpringMVC运行流程 springmvc的流程如下: API说明 _DispatcherServlet_: Spring提供的前端控制器,所有的请求都有经过它来统一分发。在DispatcherServlet将请求分发给Controller之前,需要借助于Spring提供的HandlerMapping定位到具体的Controller。

Java反射优化之方法句柄

1 简介 java7中为间接调用方法引入了新的api,即 方法句柄 方法句柄中包含两个重要的类,MethodHandle和MethodType MethodHandle 通过句柄我们可以直接调用该句柄所引用的底层方法。从作用上来看,方法句柄类似于反射中的Method类,是对要执行的方法的一个引用,我们也是通过它来调用底层方法,它调用时有两个方法 invoke和invokeExact,后者要求参数类型与底层方法的参数完全匹配,前者则在有出入时做修改如包装类型。 MethodType 方法签名不可变对象,是对方法的一个映射,包含返回值和参数类型。在lookup时也是通过它来寻找的。 每个方法句柄都有一个MethodType实例,用来指明方法的返回类型和参数类型。 2 简单使用 2.1 demo测试 public class MethodHandleDemo { public static void main(String[] args) throws Throwable{ //参数为返回值类型、参数类型 单个参数 MethodType methodType = MethodType.

Spring之动手实现IOC功能

1 背景 我们经常在使用Spring生态中的组件,我们在潜移默化的DI和IOC的思想下,来创建和使用Bean对象,使用过 @Component @ComponentScan @Autowired @Bean @Configuration 等等的注解,所以了解Spring容器是如何创建和管理Bean,是我们必需掌握的技能。 下面我们通过手写DI和IOC的方式来加深对Spring的理解。 #2 依赖注入 DI,Dependency Injection,即依赖注入。具体含义表示组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。对象只提供普通的方法让容器去决定依赖关系。

Spring之Bean加载-解析-生命周期

1 概要 使用Spring框架,我们需要了解Bean的创建加载过程,需要熟悉Bean是如何获取和使用的。 下面我们通过分析下Spring加载XML文件的过程来分析Bean的数据流。 当前调试的Spring 版本是最新的 4.1.0 release 版本 调试代码主入口 ApplicationContext context = new ClassPathXmlApplicationContext("consumer.

并发基础之Condition(等待队列)

1 定义 Condition是在AQS中配合使用的wait/nofity线程通信协调工具类,我们可以称之为等待队列 Condition定义了等待/通知两种类型的方法,当前线程调用这些方法时,需要提前获取到Condition对象关联的锁。Condition对象是调用Lock对象的newCondition()方法创建出来的,换句话说,Condition是依赖Lock对象。 Condition与Object中监视器方法不同点 >condition可以有多个等待队列 monitor只有一个队列在对象头中 condition的等待可以自定义超时时间 conditon的signal 是唤醒等待队列头部的线程节点, Object的notify是随机唤醒 condition对象的属性对开发者透明 2 Condition使用 demo代码如下

Redis注意事项及常见优化

1 键值设计 1.1 key名设计 (1)【建议】: 可读性和可管理性 以业务名(或数据库名)为前缀(防止key冲突),用冒号分隔,比如业务名:表名:id roborder:user:1:amount (2)【建议】:简洁性 保证语义的前提下,控制key的长度,当key较多时,内存占用也不容忽视,例如:

并发基础之AQS同步器(二)

在AQS同步器组件原理分析前,我们需要了解同步队列这个概念,了解同步队列中节点的入队和出队的流程,CHL同步队列的由来,可以参考我之前的文章: 并发基础之AQS同步器(一) 1 同步队列 同步器依赖内部的同步队列(一个FIFO双向队列)来完成同步状态的管理,当前线程获取同步状态失败时,同步器会将当前线程以及等待状态等信息构造成为一个节点(Node)并将其加入同步队列,同时会阻塞当前线程,当同步状态释放时,会把首节点中的线程唤醒,使其再次尝试获取同步状态 FIFO队列Node对象的具体实现如下: static final class Node { static final Node SHARED = new Node(); static final Node EXCLUSIVE = null; static final int CANCELLED = 1; static final int SIGNAL = -1; static final int CONDITION = -2; static final int PROPAGATE = -3; volatile int waitStatus; volatile Node prev; volatile Node next; volatile Thread thread; Node nextWaiter; .