日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

easyui treegrid获取父节点的id_超简单的分布式ID生成方案!美团开源框架介绍

發布時間:2025/3/20 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 easyui treegrid获取父节点的id_超简单的分布式ID生成方案!美团开源框架介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 闡述背景
  • Leaf snowflake 模式介紹
  • Leaf segment 模式介紹
  • Leaf 改造支持 RPC
  • 闡述背景

    不吹噓,不夸張,項目中用到 ID 生成的場景確實挺多。比如業務要做冪等的時候,如果沒有合適的業務字段去做唯一標識,那就需要單獨生成一個唯一的標識,這個場景相信大家不陌生。

    很多時候為了圖方便可能就是寫一個簡單的 ID 生成工具類,直接開用。做的好點的可能單獨出一個 Jar 包讓其他項目依賴,做的不好的很有可能就是 Copy 了 N 份一樣的代碼。

    單獨搞一個獨立的 ID 生成服務非常有必要,當然我們也沒必要自己做造輪子,有現成開源的直接用就是了。如果人手夠,不差錢,自研也可以。

    今天為大家介紹一款美團開源的 ID 生成框架 Leaf,在 Leaf 的基礎上稍微擴展下,增加 RPC 服務的暴露和調用,提高 ID 獲取的性能。

    Leaf 介紹

    Leaf 最早期需求是各個業務線的訂單 ID 生成需求。在美團早期,有的業務直接通過 DB 自增的方式生成 ID,有的業務通過 redis 緩存來生成 ID,也有的業務直接用 UUID 這種方式來生成 ID。以上的方式各自有各自的問題,因此我們決定實現一套分布式 ID 生成服務來滿足需求。

    具體 Leaf 設計文檔見:https://tech.meituan.com/2017/04/21/mt-leaf.html[1]

    目前 Leaf 覆蓋了美團點評公司內部金融、餐飲、外賣、酒店旅游、貓眼電影等眾多業務線。在 4C8G VM 基礎上,通過公司 RPC 方式調用,QPS 壓測結果近 5w/s,TP999 1ms。

    snowflake 模式

    snowflake 是 Twitter 開源的分布式 ID 生成算法,被廣泛應用于各種生成 ID 的場景。Leaf 中也支持這種方式去生成 ID。

    使用步驟如下:

    修改配置 leaf.snowflake.enable=true 開啟 snowflake 模式。

    修改配置 leaf.snowflake.zk.address 和 leaf.snowflake.port 為你自己的 Zookeeper 地址和端口。

    想必大家很好奇,為什么這里依賴了 Zookeeper 呢?

    那是因為 snowflake 的 ID 組成中有 10bit 的 workerId,如下圖:

    一般如果服務數量不多的話手動設置也沒問題,還有一些框架中會采用約定基于配置的方式,比如基于 IP 生成 wokerID,基于 hostname 最后幾位生成 wokerID,手動在機器上配置,手動在程序啟動時傳入等等方式。

    Leaf 中為了簡化 wokerID 的配置,所以采用了 Zookeeper 來生成 wokerID。就是用了 Zookeeper 持久順序節點的特性自動對 snowflake 節點配置 wokerID。

    如果你公司沒有用 Zookeeper,又不想因為 Leaf 去單獨部署 Zookeeper 的話,你可以將源碼中這塊的邏輯改掉,比如自己提供一個生成順序 ID 的服務來替代 Zookeeper。

    segment 模式

    segment 是 Leaf 基于數據庫實現的 ID 生成方案,如果調用量不大,完全可以用 Mysql 的自增 ID 來實現 ID 的遞增。

    Leaf 雖然也是基于 Mysql,但是做了很多的優化,下面簡單的介紹下 segment 模式的原理。

    首先我們需要在數據庫中新增一張表用于存儲 ID 相關的信息。

    CREATE TABLE `leaf_alloc` (`biz_tag` varchar(128) NOT NULL DEFAULT '',`max_id` bigint(20) NOT NULL DEFAULT '1',`step` int(11) NOT NULL,`description` varchar(256) DEFAULT NULL,`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`biz_tag`) ) ENGINE=InnoDB;

    biz_tag 用于區分業務類型,比如下單,支付等。如果以后有性能需求需要對數據庫擴容,只需要對 biz_tag 分庫分表就行。

    max_id 表示該 biz_tag 目前所被分配的 ID 號段的最大值。

    step 表示每次分配的號段長度。

    下圖是 segment 的架構圖:

    從上圖我們可以看出,當多個服務同時對 Leaf 進行 ID 獲取時,會傳入對應的 biz_tag,biz_tag 之間是相互隔離的,互不影響。

    比如 Leaf 有三個節點,當 test_tag 第一次請求到 Leaf1 的時候,此時 Leaf1 的 ID 范圍就是 1~1000。

    當 test_tag 第二次請求到 Leaf2 的時候,此時 Leaf2 的 ID 范圍就是 1001~2000。

    當 test_tag 第三次請求到 Leaf3 的時候,此時 Leaf3 的 ID 范圍就是 2001~3000。

    比如 Leaf1 已經知道自己的 test_tag 的 ID 范圍是 1~1000,那么后續請求過來獲取 test_tag 對應 ID 時候,就會從 1 開始依次遞增,這個過程是在內存中進行的,性能高。不用每次獲取 ID 都去訪問一次數據庫。

    問題一

    這個時候又有人說了,如果并發量很大的話,1000 的號段長度一下就被用完了啊,此時就得去申請下一個范圍,這期間進來的請求也會因為 DB 號段沒有取回來,導致線程阻塞。

    放心,Leaf 中已經對這種情況做了優化,不會等到 ID 消耗完了才去重新申請,會在還沒用完之前就去申請下一個范圍段。并發量大的問題你可以直接將 step 調大即可。

    問題二

    這個時候又有人說了,如果 Leaf 服務掛掉某個節點會不會有影響呢?

    首先 Leaf 服務是集群部署,一般都會注冊到注冊中心讓其他服務發現。掛掉一個沒關系,還有其他的 N 個服務。問題是對 ID 的獲取有問題嗎? 會不會出現重復的 ID 呢?

    答案是沒問題的,如果 Leaf1 掛了的話,它的范圍是 1~1000,假如它當前正獲取到了 100 這個階段,然后服務掛了。服務重啟后,就會去申請下一個范圍段了,不會再使用 1~1000。所以不會有重復 ID 出現。

    Leaf 改造支持 RPC

    如果你們的調用量很大,為了追求更高的性能,可以自己擴展一下,將 Leaf 改造成 Rpc 協議暴露出去。

    首先將 Leaf 的 Spring 版本升級到 5.1.8.RELEASE,修改父 pom.xml 即可。

    <spring.version>5.1.8.RELEASE</spring.version>`

    然后將 Spring Boot 的版本升級到 2.1.6.RELEASE,修改 leaf-server 的 pom.xml。

    <spring-boot-dependencies.version>2.1.6.RELEASE</spring-boot-dependencies.version>

    還需要在 leaf-server 的 pom 中增加 nacos 相關的依賴,因為我們 kitty-cloud 是用的 nacos。同時還需要依賴 dubbo,才可以暴露 rpc 服務。

    `<dependency><groupId>com.cxytiandi</groupId><artifactId>kitty-spring-cloud-starter-nacos</artifactId><version>1.0-SNAPSHOT</version> </dependency> <dependency><groupId>com.cxytiandi</groupId><artifactId>kitty-spring-cloud-starter-dubbo</artifactId><version>1.0-SNAPSHOT</version> </dependency> <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId> </dependency>`

    在 resource 下創建 bootstrap.properties 文件,增加 nacos 相關的配置信息。

    `spring.application.name=LeafSnowflake dubbo.scan.base-packages=com.sankuai.inf.leaf.server.controller dubbo.protocol.name=dubbo dubbo.protocol.port=20086 dubbo.registry.address=spring-cloud://localhost spring.cloud.nacos.discovery.server-addr=47.105.66.210:8848 spring.cloud.nacos.config.server-addr=${spring.cloud.nacos.discovery.server-addr}

    Leaf 默認暴露的 Rest 服務是 LeafController 中,現在的需求是既要暴露 Rest 又要暴露 RPC 服務,所以我們抽出兩個接口。一個是 Segment 模式,一個是 Snowflake 模式。

    Segment 模式調用客戶端

    `/*** 分布式ID服務客戶端-Segment模式** @作者* @個人微信 * @博客* @GitHub * @作者介紹* @時間 */ @FeignClient("${kitty.id.segment.name:LeafSegment}") public interface DistributedIdLeafSegmentRemoteService {@RequestMapping(value = "/api/segment/get/{key}")String getSegmentId(@PathVariable("key") String key); }`

    Snowflake 模式調用客戶端

    /*** 分布式ID服務客戶端-Snowflake模式** @作者 * @個人微信* @微信公眾號* @GitHub* @作者介紹* @時間 */ @FeignClient("${kitty.id.snowflake.name:LeafSnowflake}") public interface DistributedIdLeafSnowflakeRemoteService {@RequestMapping(value = "/api/snowflake/get/{key}")String getSnowflakeId(@PathVariable("key") String key); }

    使用方可以根據使用場景來決定用 RPC 還是 Http 進行調用,如果用 RPC 就@Reference 注入 Client,如果要用 Http 就用@Autowired 注入 Client。

    最后改造 LeafController 同時暴露兩種協議即可。

    @Service(version = "1.0.0", group = "default") @RestController public class LeafController implements DistributedIdLeafSnowflakeRemoteService, DistributedIdLeafSegmentRemoteService {private Logger logger = LoggerFactory.getLogger(LeafController.class);@Autowiredprivate SegmentService segmentService;@Autowiredprivate SnowflakeService snowflakeService;@Overridepublic String getSegmentId(@PathVariable("key") String key) {return get(key, segmentService.getId(key));}@Overridepublic String getSnowflakeId(@PathVariable("key") String key) {return get(key, snowflakeService.getId(key));}private String get(@PathVariable("key") String key, Result id) {Result result;if (key == null || key.isEmpty()) {throw new NoKeyException();}result = id;if (result.getStatus().equals(Status.EXCEPTION)) {throw new LeafServerException(result.toString());}return String.valueOf(result.getId());} } 與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的easyui treegrid获取父节点的id_超简单的分布式ID生成方案!美团开源框架介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 色图一区 | 台湾swag在线播放 | 好吊妞精品| 奇米影视888| 亚洲v| 亚洲我射av | 成人午夜在线 | 中文写幕一区二区三区免费观成熟 | 黄色永久网站 | 亚洲国产中文字幕在线 | 成人av在线影院 | 激情欧美一区二区免费视频 | 美国三级视频 | 久久综合久久鬼色 | 国产一二三视频 | 蜜臀一区二区三区精品免费视频 | 麻豆视频在线播放 | 中文字幕人妻精品一区 | 人人超碰在线 | 亚洲精品一二区 | 日韩欧美中文字幕在线观看 | 黄色一节片 | 88av网| 日韩精品中文字幕在线播放 | 天堂精品视频 | 成人一区二区三区在线 | 99视频在线免费 | 性高潮久久久久久久久久 | 色永久 | 精品一区二区久久久久久久网站 | 不卡在线 | 成人中文字幕在线 | 国产午夜视频在线观看 | 欧美日本久久 | 免费看污黄网站在线观看 | 欧美激情15p| 综合久草 | 亚洲免费中文 | 91黄在线看 | 精品人伦一区二区三电影 | 欧日韩不卡在线视频 | 最近免费中文字幕中文高清百度 | 精品久久久久久久久久 | 久热超碰| 男人桶女人桶爽30分钟 | 女人十八岁毛片 | 国产在线h| 爆操少妇 | 99在线无码精品入口 | 黄色av网站在线看 | 欧美黑人啪啪 | 日本精品黄 | 国产一级做a爱免费视频 | 国产一区二区在线免费观看 | 久草剧场 | 一区二区三区日韩电影 | 久久怡红院 | 午夜小视频网站 | 性综艺节目av在线播放 | 黑人操中国女人视频 | 久久伊人影视 | 欧美日本二区 | www日本在线观看 | 四川话毛片少妇免费看 | 精品一区二区欧美 | 五月天社区 | youjizz.com日本| 国产成人久久精品流白浆 | 黑人精品一区二区三区 | 超碰在线最新地址 | av黄色天堂| 国产人妖在线观看 | 免费在线看污 | 精品福利在线观看 | 最新av片| 欧美伊人 | 中文字幕资源在线 | sese综合| 91精品国产91综合久久蜜臀 | 中文字幕在线视频一区二区 | 香蕉亚洲| 少妇高潮喷水在线观看 | 中文字幕一区二区三区波野结 | 懂色一区二区 | 欧美午夜精品久久久久久蜜 | 日韩欧美在线观看免费 | 一二三av | 美女丝袜av | 久久激情婷婷 | 日韩在线视频免费播放 | 久久久久玖玖 | 欧美日韩中文字幕在线播放 | 久草视频在 | 片多多在线观看 | 人人草人人 | 日本护士体内she精2xxx | 国产精品美女毛片真酒店 | 国产av一区不卡 | 精品66|