Snowflake algorithm is a classical algorithm of distributed generation globally unique ID, the interpretation algorithms plethora of online about snow, mostly copy to copy, here refer to the work of God's great elephant ID generator blog, Twitter snowflakes algorithm (Java)
Online tutorials general there are two problems:
1. Machine ID (. 5 bits) and the data center ID (. 5-bit) configuration is not resolved, when distributed deployment will use the same configuration, though there is any risk of duplicate ID.
2. When used need to be instantiated object tools are not formed out of the box.
In this paper, two solutions for the above problems, the author's solution, WorkId hostName generated using the server, dataCenterId generated using IP, this can be prevented to maximize the machine code 10 is repeated, but since the two ID can not exceed 32, can only take the remainder or hard to avoid repetition, but the actual use, hostName and IP configuration generally continuous or similar, if not exactly the case of 32-bit apart, there would be no problem, moreover, hostName and IP simultaneously separated by 32 more it is almost impossible things usually do a distributed deployment, generally no more than 10 containers.
Using the above method can be used snow zero configuration algorithm, the algorithm set theory snow 10 may be machine code 1024 nodes, using the docker production configuration is generally a compiler, and then distributed to different containers deployed, there will be different configuration, where other companies do not know how to solve, even if a method of using a set of configuration, then read different configurations depending on the runtime container, but the container allocated to each ID, 1024 th (in most cases no so much), it seems unlikely to resolve this issue for another day after the bank added.
Package com.feicent.util; Import org.apache.commons.lang3.RandomUtils; Import org.apache.commons.lang3.StringUtils; Import org.apache.commons.lang3.SystemUtils; Import java.net.Inet4Address; Import Java. net.UnknownHostException; / ** * Twitter_Snowflake <br> * https://blog.csdn.net/u012488504/article/details/82194495 * Snowflake following structure (with each section - apart): <br> * 0 - 0000000000 0 0000000000 0000000000 0000000000 - 0000000000 - 000000000000 <br> * 1-bit identifier, as long basic types are signed in Java, the most significant bit is the sign bit, 0 is a positive number, a negative number is 1, so the id is generally positive , the highest bit is 0 <br> * 41 cut time (milliseconds), it is noted than 41 times the cross-sectional cut-off storage time of the current time, but the difference between the storage time truncated (cut-off the current time - the start time of cut) * Value obtained), where the start time of a truncated, generally the time of our id generator is started, the program specified by our (the following procedure IdWorker class attributes startTime below). Cut-off time 41, 69 may be used in, in = T (1L << 41 is) / (1000L * 60 * 60 * 24 * 365) = 69 <br> * 10-bit data bit machine, can be deployed in 1024 nodes, and including 5 datacenterId <br> 5 workerId * 12 sequence count within milliseconds, the count of sequence number 12 of each support node per millisecond (the same machine, the same cut-off time) to produce the ID number 4096 <br > * add up to just 64 for a Long type. <br> advantage * SnowFlake that the overall increment in time order, and do not generate collisions ID (as distinguished from the data center ID and machine ID) throughout the distributed system, and high efficiency, tested, each Snowflake s capable of producing about 260,000 ID. * / Public class SnowflakeIdWorker { // ============================== Fields =========== ================================ / ** start time cut (2015-01-01) * / Private Final Long = 1489111610226L twepoch ; / **The median share of machine id * / Private Final Long workerIdBits = 5L ; / ** data to identify the number of bits occupied by id * / Private Final Long dataCenterIdBits = 5L ; / ** The maximum supported machine id, the result is 31 (this shift algorithm can quickly calculate the maximum number of decimal binary number can represent several) * / Private Final Long maxWorkerId -1L = ^ (-1L << workerIdBits); / ** the maximum data identification id, result is 31 is * / Private Final Long maxDataCenterId -1L = ^ (-1L << dataCenterIdBits); / ** sequence representing the median id * / Private Final Long sequenceBits = 12L; / ** machine ID 12 to the left * / Private Final Long workerIdShift = sequenceBits; / * data identifying id to the left by 17 (+ 12 is. 5) * / Private Final Long dataCenterIdShift + = sequenceBits workerIdBits; / ** 22 to the left cut-off time (. 5 + + 12 is. 5) * / Private Final Long timestampLeftShift workerIdBits + + = sequenceBits dataCenterIdBits; / ** generating a mask sequence, here 4095 (0b111111111111 = 0xFFF = 4095) * / Private Final Long sequenceMask -1L = ^ (-1L << sequenceBits); / ** work machine ID (~ 31 is 0) * / Private Long workerId; / ** data center ID (~ 31 is 0) * / Private Long dataCenterId; / ** milliseconds sequence (0 ~ 4095) * / Private Long Sequence = 0L ; / ** previously generated ID truncated time * / Private Long LastTimestamp = -1L ; Private static SnowflakeIdWorker idWorker; static { Long workerId = getWorkId (); Long dataCenterId = getDataCenterId (); System.out.println ( "workerId =" + workerId + ", dataCenterId =" + dataCenterId); idWorker = new SnowflakeIdWorker(workerId, dataCenterId); } //==============================Constructors===================================== /** * 构造函数 * @param workerId 工作ID (0~31) * @param dataCenterId 数据中心ID (0~31) */ public SnowflakeIdWorker(long workerId, long dataCenterId) { if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.format("workerId can't be greater than %d or less than 0", maxWorkerId)); } if (dataCenterId > maxDataCenterId || dataCenterId < 0) { throw new IllegalArgumentException(String.format("dataCenterId can't be greater than %d or less than 0", maxDataCenterId)); } this.workerId = workerId; this.dataCenterId = dataCenterId; } // ==============================Methods========================================== /** * 获得下一个ID (该方法是线程安全的) * @returnSnowflakeId * / public the synchronized Long nextId () { Long timestamp = TIMEGEN (); // if the current time is less than the timestamp of the last generation ID, indicating the system clock backoff time should be thrown through the IF (timestamp < LastTimestamp) { the throw new new a RuntimeException ( String.format ( "Clock Moved Backwards ID for refusing to generate% D milliseconds.", LastTimestamp - timestamp)); } // if it is generated at the same time, the sequence is performed within milliseconds IF (LastTimestamp == timestamp ) { Sequence = (+ Sequence. 1) & sequenceMask; //Serial overrun milliseconds IF (Sequence == 0 ) { // blocking the next millisecond, obtain a new timestamp timestamp = tilNextMillis (LastTimestamp); } } // timestamp changes milliseconds reset sequence the else { Sequence = 0L ; } // last time generation ID sectional LastTimestamp = timestamp; // shift to fight and consisting of 64-bit ID ORed together return ((timestamp - twepoch) << timestampLeftShift) | (dataCenterId << dataCenterIdShift) | (workerId << workerIdShift) |Sequence; } / ** * obstruction to the next millisecond, until a new timestamp * @param LastTimestamp time cut previously generated ID * @return current timestamp * / protected Long tilNextMillis ( Long LastTimestamp) { Long timestamp = TIMEGEN (); the while (timestamp <= LastTimestamp) { timestamp = TIMEGEN (); } return timestamp; } / ** * returns the current time in milliseconds * @return current time (ms) * / protected long timeGen() { return System.currentTimeMillis(); } private static long getWorkId(){ try { String hostAddress = Inet4Address.getLocalHost().getHostAddress(); System.out.println("hostAddress: " + hostAddress); int[] ints = StringUtils.toCodePoints(hostAddress); int sums = 0; for(int b : ints){ sums += b; } return (Long ) (32% sums ); } the catch (UnknownHostException E) { // If the acquisition has failed, the backup using a random number return RandomUtils.nextLong (0, 32 ); } } Private static Long getDataCenterId () { System.out.println ( "of hostName:" + SystemUtils.getHostName ()); int [] = INTS StringUtils.toCodePoints (SystemUtils.getHostName ()); int sums = 0 ; for ( int I: INTS) { sums + = I; } return (long)(sums % 32); } /** * 静态工具类 * * @return */ public static Long generateId(){ return idWorker.nextId(); } /** 测试 */ public static void main(String[] args) { System.out.println(System.currentTimeMillis()); long startTime = System.nanoTime(); int count = 1000000; for (int i = 0; i < count; i++) { Long ID = SnowflakeIdWorker.generateId (); // System.out.println (ID); } System.out.println ( "generated [" + count + "] Processed Total Article ID:" + (System.nanoTime () - the startTime) / 1000000 + "MS" ); } }