Snow algorithm is based on an algorithm for generating random numbers timestamp. The online version also changed a lot, based on our current business scenario has changed our business scenario used in the algorithm.
1, resulting Id can not be longer than 17 ,, maximum value: 160111892926110, i.e. the maximum length of the front end of a digital type of support
2, there is no uniform services to produce ID, Id need to achieve autonomy in their respective service
3, a server may deploy multiple instances
4, examples of expansion at any time based on traffic volume, capacity expansion.
Based on the above-described embodiment changes the algorithm is as follows:
As a unique identifier stored in the database, which would form a unique ID in the library Mysql based service where the machine's IP and PORT. After the location list can be acquired in an ascending current IP PORT resides and, thus may inherently an IP correspondence table, while the number of bits occupied by the machine identification information less, currently set at 127, only 7 bits BIT . The value of a single sequence supports a maximum of 31 seconds, which is required 5 BIT bits. In this way there will be a 12-bit BIT, where the remaining digits are the median time stamp. The remaining 41 can support 69 years, for an ordinary product, it is enough. The following figure shows the specific
11111111111111111111111111111111111111111 1111111 11111
Time stamp machine serial number
Specific code implementation:
/ ** * <P> * based on the transformation algorithm snow ID generator * <P> * * @author woniu * @date 14 January 2020 * @version 1.0 * / public class IdUtils { Private static Final Logger LOGGER = LoggerFactory.getLogger (idUtils. class ); Private static idUtils idUtils; / ** * last updated time * / Private static Long lastStamp = -1L ; Private static Long sqlNUm = 0L ; Private static Integer = -1 hostId; Private IpListService ipListService = AppContext.getAppObject (IpListService. Class ); / ** * Based on 2020 January 1 start to * / Private static Final Long BEGIN_TIME = 1577808000000L ; Private static Final Integer SEQ_NUM_LEN = 5 ; / ** * Machine placeholder, the current maximum support 127 example * / Private static Final Integer. 7 = HOST_LEN ; / ** * maximum sequence number, SEQ_NUM_LEN (5) 2-th power of minus 1: 2 ^ 5-1 = 31 * / Private static Final Integer = 31 is MAX_SEQ_NUM ; / ** * Timestamp offset bits * distal support for a maximum: 9007199254740991, after removal of 11, and 41, 69 supported in * / Private static Final Integer TIME_STAMP_SHIFT + = HOST_LEN SEQ_NUM_LEN; / ** * initialize instance * @return * / Private static idUtils the getInstance () { IF (idUtils == null ) { idUtils = new new idUtils (); } return idUtils; } / ** * Id warehousing generated * / public static the synchronized Long genID () { IF (hostId == -1L) { initIp(); } Long currentTime = System.currentTimeMillis(); if (sqlNUm > MAX_SEQ_NUM) { try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } currentTime = System.currentTimeMillis(); sqlNUm = 0L; } if (currentTime.longValue() == lastStamp.longValue()) { return ((currentTime - BEGIN_TIME) << 11) | (hostId << 6) | (sqlNUm ++); } else { sqlNUm = 0L; lastStamp = currentTime; return ((currentTime - BEGIN_TIME) << 11) | (hostId << 6) | (sqlNUm ++); } } /** * 初始化IP信息 */ private static void initIp() { try { String localIp = IpPortUtils.getLocalIp(); String port = String.valueOf(IpPortUtils.getHttpPort()); if (!getHostId(localIp, port)) { IpList localIpList = new IpList(); localIpList.setIp(localIp); localIpList.setPort(port); localIpList.setCreateTime(new Date()); localIpList.setUpdateTime(new Date()); getInstance().ipListService.saveOrUpdate(localIpList); getHostId(localIp, port); } } catch (Exception e) { LOGGER.error("init ip error", e); throw new RuntimeException(); } } /** * 获取hostId信息,如果获取则返回true,反之false * @param localIp * @param port * @return */ private static boolean getHostId(String localIp, String port) { List<IpList> ipList = getInstance().ipListService.findAllByAsc(); for (int i = 0; i < ipList.size(); i++) { IpList ip = ipList.get(i); if (ip.getIp().equals(localIp) && ip.getPort().equals(port)) { hostId = i; return true; } } return false; } }