公共子模塊common模塊entry瑰钮、utils包代碼以及分布式ID生成器

一、上文我們已經(jīng)完成了創(chuàng)建common子模塊
接下來我們在里面創(chuàng)建返回實體類
新建 entry包

image.png

在包下面創(chuàng)建 Result類 用于控制器返回結(jié)果:
public class Result {
/**
* 是否成功
/
private boolean flag;
/
*
* 返回碼
/
private Integer code;
/
*
* 返回信息
/
private String message;
/
*
* 返回數(shù)據(jù)
*/
private Object data;

public Result() {
}

public Result(boolean flag, Integer code, String message) {
    this.flag = flag;
    this.code = code;
    this.message = message;
}

public Result(boolean flag, Integer code, String message, Object data) {
    this.flag = flag;
    this.code = code;
    this.message = message;
    this.data = data;
}

public boolean isFlag() {
    return flag;
}

public void setFlag(boolean flag) {
    this.flag = flag;
}

public Integer getCode() {
    return code;
}

public void setCode(Integer code) {
    this.code = code;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}

public Object getData() {
    return data;
}

public void setData(Object data) {
    this.data = data;
}

這里面我們使用很原始的set get 也可以使用lombook 通過注釋來完成 實體的一些操作微驶。

接下來創(chuàng)建分頁結(jié)果類:

public class PageResult <T>{
private Long total;
private List<T> rows;

public PageResult() {
}

public PageResult(Long total, List<T> rows) {
    this.total = total;
    this.rows = rows;
}

public Long getTotal() {
    return total;
}

public void setTotal(Long total) {
    this.total = total;
}

public List<T> getRows() {
    return rows;
}

public void setRows(List<T> rows) {
    this.rows = rows;
}

}
接下來 創(chuàng)建狀態(tài)碼實體類 :
public class StatusCode {
/**
* 成功
/
public static final int OK=20000;
/
*
* 失敗
/
public static final int ERROR =20001;
/
*
* 用戶名或密碼錯誤
/
public static final int LOGINERROR =20002;
/
*
* 權(quán)限不足
/
public static final int ACCESSERROR =20003;
/
*
* 遠(yuǎn)程調(diào)用失敗
/
public static final int REMOTEERROR =20004;
/
*
* 重復(fù)操作
/
public static final int REPERROR =20005;
/
*
* 驗證碼過期
*/
public static final int VERIFICATION =20006;
}

接下來我們需要解除一個新的分布式的ID生成器:


image.png

image.png

在 comnon包下創(chuàng)建 util包


image.png

IdWorker 代碼如下: 我們直接引用這個代碼 直接來使用:
package util;

import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;

/**

  • <p>名稱:IdWorker.java</p>

  • <p>描述:分布式自增長ID</p>

  • <pre>

  • Twitter的 Snowflake JAVA實現(xiàn)方案
    
  • </pre>

  • 核心代碼為其IdWorker這個類實現(xiàn)浪谴,其原理結(jié)構(gòu)如下,我分別用一個0表示一位因苹,用—分割開部分的作用:

  • 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000

  • 在上面的字符串中苟耻,第一位為未使用(實際上也可作為long的符號位),接下來的41位為毫秒級時間扶檐,

  • 然后5位datacenter標(biāo)識位凶杖,5位機器ID(并不算標(biāo)識符,實際是為線程標(biāo)識)款筑,

  • 然后12位該毫秒內(nèi)的當(dāng)前毫秒內(nèi)的計數(shù)智蝠,加起來剛好64位,為一個Long型奈梳。

  • 這樣的好處是杈湾,整體上按照時間自增排序,并且整個分布式系統(tǒng)內(nèi)不會產(chǎn)生ID碰撞(由datacenter和機器ID作區(qū)分)攘须,

  • 并且效率較高漆撞,經(jīng)測試,snowflake每秒能夠產(chǎn)生26萬ID左右于宙,完全滿足需要浮驳。

  • <p>

  • 64位ID (42(毫秒)+5(機器ID)+5(業(yè)務(wù)編碼)+12(重復(fù)累加))

  • @author Polim
    /
    public class IdWorker {
    /
    *

    • 時間起始標(biāo)記點,作為基準(zhǔn)捞魁,一般取系統(tǒng)的最近時間(一旦確定不能變動)
      /
      private final static long twepoch = 1288834974657L;
      /
      *
    • 機器標(biāo)識位數(shù)
      /
      private final static long workerIdBits = 5L;
      /
      *
    • 數(shù)據(jù)中心標(biāo)識位數(shù)
      /
      private final static long datacenterIdBits = 5L;
      /
      *
    • 機器ID最大值
      /
      private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
      /
      *
    • 數(shù)據(jù)中心ID最大值
      /
      private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
      /
      *
    • 毫秒內(nèi)自增位
      /
      private final static long sequenceBits = 12L;
      /
      *
    • 機器ID偏左移12位
      /
      private final static long workerIdShift = sequenceBits;
      /
      *
    • 數(shù)據(jù)中心ID左移17位
      /
      private final static long datacenterIdShift = sequenceBits + workerIdBits;
      /
      *
    • 時間毫秒左移22位
      */
      private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;

    private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
    /**

    • 上次生產(chǎn)id時間戳
      /
      private static long lastTimestamp = -1L;
      /
      *
    • 0抹恳,并發(fā)控制
      /
      private long sequence = 0L;
      /
      *
    • 工作機器ID
      /
      private final long workerId;
      /
      *
    • 數(shù)據(jù)標(biāo)識id部分
      */
      private final long datacenterId;

    public IdWorker() {
    this.datacenterId = getDatacenterId(maxDatacenterId);
    this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
    }

    /**

    • @param workerId 工作機器ID
    • @param datacenterId 序列號
      */
      public IdWorker(long workerId, long datacenterId) {
      if (workerId > maxWorkerId || workerId < 0) {
      throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
      }
      if (datacenterId > maxDatacenterId || datacenterId < 0) {
      throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
      }
      this.workerId = workerId;
      this.datacenterId = datacenterId;
      }

    /**

    • 獲取下一個ID

    • @return
      */
      public synchronized long nextId() {
      long timestamp = timeGen();
      if (timestamp < lastTimestamp) {
      throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
      }

      if (lastTimestamp == timestamp) {
      // 當(dāng)前毫秒內(nèi),則+1
      sequence = (sequence + 1) & sequenceMask;
      if (sequence == 0) {
      // 當(dāng)前毫秒內(nèi)計數(shù)滿了署驻,則等待下一秒
      timestamp = tilNextMillis(lastTimestamp);
      }
      } else {
      sequence = 0L;
      }
      lastTimestamp = timestamp;
      // ID偏移組合生成最終的ID奋献,并返回ID
      long nextId = ((timestamp - twepoch) << timestampLeftShift)
      | (datacenterId << datacenterIdShift)
      | (workerId << workerIdShift) | sequence;

      return nextId;
      }

    private long tilNextMillis(final long lastTimestamp) {
    long timestamp = this.timeGen();
    while (timestamp <= lastTimestamp) {
    timestamp = this.timeGen();
    }
    return timestamp;
    }

    private long timeGen() {
    return System.currentTimeMillis();
    }

    /**

    • <p>
    • 獲取 maxWorkerId
    • </p>
      /
      protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
      StringBuffer mpid = new StringBuffer();
      mpid.append(datacenterId);
      String name = ManagementFactory.getRuntimeMXBean().getName();
      if (!name.isEmpty()) {
      /

      * GET jvmPid
      /
      mpid.append(name.split("@")[0]);
      }
      /
      • MAC + PID 的 hashcode 獲取16個低位
        */
        return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
        }

    /**

    • <p>
    • 數(shù)據(jù)標(biāo)識id部分
    • </p>
      */
      protected static long getDatacenterId(long maxDatacenterId) {
      long id = 0L;
      try {
      InetAddress ip = InetAddress.getLocalHost();
      NetworkInterface network = NetworkInterface.getByInetAddress(ip);
      if (network == null) {
      id = 1L;
      } else {
      byte[] mac = network.getHardwareAddress();
      id = ((0x000000FF & (long) mac[mac.length - 1])
      | (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;
      id = id % (maxDatacenterId + 1);
      }
      } catch (Exception e) {
      System.out.println(" getDatacenterId: " + e.getMessage());
      }
      return id;
      }

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末健霹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瓶蚂,更是在濱河造成了極大的恐慌糖埋,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窃这,死亡現(xiàn)場離奇詭異瞳别,居然都是意外死亡,警方通過查閱死者的電腦和手機杭攻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門祟敛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人兆解,你說我怎么就攤上這事馆铁。” “怎么了锅睛?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵埠巨,是天一觀的道長。 經(jīng)常有香客問我现拒,道長辣垒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任印蔬,我火速辦了婚禮勋桶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘侥猬。我一直安慰自己例驹,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布陵究。 她就那樣靜靜地躺著,像睡著了一般奥帘。 火紅的嫁衣襯著肌膚如雪铜邮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天寨蹋,我揣著相機與錄音松蒜,去河邊找鬼。 笑死已旧,一個胖子當(dāng)著我的面吹牛秸苗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播运褪,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼惊楼,長吁一口氣:“原來是場噩夢啊……” “哼玖瘸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起檀咙,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤雅倒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后弧可,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蔑匣,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年棕诵,在試婚紗的時候發(fā)現(xiàn)自己被綠了裁良。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡校套,死狀恐怖价脾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情搔确,我是刑警寧澤彼棍,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站膳算,受9級特大地震影響座硕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜涕蜂,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一华匾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧机隙,春花似錦蜘拉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至葱跋,卻和暖如春持寄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背娱俺。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工稍味, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人荠卷。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓模庐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親油宜。 傳聞我的和親對象是個殘疾皇子掂碱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容