Stand-alone version of the algorithm based on Snow

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;
    }

}

 

Guess you like

Origin www.cnblogs.com/woniu4/p/12194627.html