[{"data":1,"prerenderedAt":1171},["ShallowReactive",2],{"post-\u002Fposts\u002Fgolang-redis-seq":3,"surround-\u002Fposts\u002Fgolang-redis-seq":1166},{"id":4,"title":5,"body":6,"cover":1153,"date":1154,"description":1155,"draft":1156,"extension":1157,"meta":1158,"minutes":71,"navigation":919,"path":1159,"seo":1160,"stem":1161,"tags":1162,"updated":1153,"__hash__":1165},"posts\u002Fposts\u002Fgolang-redis-seq.md","Golang基于Redis生成唯一序列",{"type":7,"value":8,"toc":1146},"minimark",[9,13,16,19,342,345,348,353,475,479,482,540,544,891,895,1096,1100,1139,1142],[10,11,12],"p",{},"在项目中对应数据库的唯一id，我们通常会选择使用数据库自增id，uuid，雪花算法等，每种模式的id都有各自的优缺点，这里将通过Redis来实现一种自定义分布式的id生成模式。",[10,14,15],{},"当然这种实现方式也有一定的缺点，那就是过于依赖redis，一旦出现redis不可用，会导致id生成失败，从而影响整个业务的不可用，所以在设计的时候需要考虑，如果redis不可用如何自动启用其他唯一id生成模式。",[10,17,18],{},"首先看redis实现部分：",[20,21,26],"pre",{"className":22,"code":23,"language":24,"meta":25,"style":25},"language-lua shiki shiki-themes tokyo-night github-light","\u002F\u002F 获取第一个Key\nlocal id_key = KEYS[1]\n\u002F\u002F 获取形参的第一个数，这里是初始化值\nlocal initial = ARGV[1]\n\u002F\u002F 获取形参的第二数据，这里每次增长的量\nlocal step = ARGV[2]\n\u002F\u002F 检查key当前是否存在值\nlocal current = redis.call('get', id_key)\n\u002F\u002F 如果不存在则返回初始值，并在redis中设置初始值\nif current == false then\n        redis.call('set', id_key, initial)\n        return initial\nend\n--redis.log(redis.LOG_NOTICE,' current:'..current..':')\n\u002F\u002F 如果存在值则在当前值上面加入每次的增量，设置到redis后并返回\nlocal result =  tonumber(current)+ tonumber(step)\n--redis.log(redis.LOG_NOTICE,' result:'..result..':')\nredis.call('set', id_key, result)\nreturn tostring(result)\n","lua","",[27,28,29,42,69,77,96,104,123,131,173,181,198,228,237,243,250,258,292,298,327],"code",{"__ignoreMap":25},[30,31,34,38],"span",{"class":32,"line":33},"line",1,[30,35,37],{"class":36},"sNP9S","\u002F\u002F",[30,39,41],{"class":40},"sGNLY"," 获取第一个Key\n",[30,43,45,49,53,56,59,62,66],{"class":32,"line":44},2,[30,46,48],{"class":47},"sBxw3","local",[30,50,52],{"class":51},"s4do5"," id_key",[30,54,55],{"class":36}," =",[30,57,58],{"class":51}," KEYS",[30,60,61],{"class":40},"[",[30,63,65],{"class":64},"sjYRd","1",[30,67,68],{"class":40},"]\n",[30,70,72,74],{"class":32,"line":71},3,[30,73,37],{"class":36},[30,75,76],{"class":40}," 获取形参的第一个数，这里是初始化值\n",[30,78,80,82,85,87,90,92,94],{"class":32,"line":79},4,[30,81,48],{"class":47},[30,83,84],{"class":51}," initial",[30,86,55],{"class":36},[30,88,89],{"class":51}," ARGV",[30,91,61],{"class":40},[30,93,65],{"class":64},[30,95,68],{"class":40},[30,97,99,101],{"class":32,"line":98},5,[30,100,37],{"class":36},[30,102,103],{"class":40}," 获取形参的第二数据，这里每次增长的量\n",[30,105,107,109,112,114,116,118,121],{"class":32,"line":106},6,[30,108,48],{"class":47},[30,110,111],{"class":51}," step",[30,113,55],{"class":36},[30,115,89],{"class":51},[30,117,61],{"class":40},[30,119,120],{"class":64},"2",[30,122,68],{"class":40},[30,124,126,128],{"class":32,"line":125},7,[30,127,37],{"class":36},[30,129,130],{"class":40}," 检查key当前是否存在值\n",[30,132,134,136,139,141,144,147,151,154,158,162,164,167,170],{"class":32,"line":133},8,[30,135,48],{"class":47},[30,137,138],{"class":51}," current",[30,140,55],{"class":36},[30,142,143],{"class":51}," redis",[30,145,146],{"class":40},".",[30,148,150],{"class":149},"sZlli","call",[30,152,153],{"class":40},"(",[30,155,157],{"class":156},"sbW-k","'",[30,159,161],{"class":160},"snP_1","get",[30,163,157],{"class":156},[30,165,166],{"class":40},", ",[30,168,169],{"class":51},"id_key",[30,171,172],{"class":40},")\n",[30,174,176,178],{"class":32,"line":175},9,[30,177,37],{"class":36},[30,179,180],{"class":40}," 如果不存在则返回初始值，并在redis中设置初始值\n",[30,182,184,187,189,192,195],{"class":32,"line":183},10,[30,185,186],{"class":47},"if",[30,188,138],{"class":51},[30,190,191],{"class":36}," ==",[30,193,194],{"class":64}," false",[30,196,197],{"class":47}," then\n",[30,199,201,204,206,208,210,212,215,217,219,221,223,226],{"class":32,"line":200},11,[30,202,203],{"class":51},"        redis",[30,205,146],{"class":40},[30,207,150],{"class":149},[30,209,153],{"class":40},[30,211,157],{"class":156},[30,213,214],{"class":160},"set",[30,216,157],{"class":156},[30,218,166],{"class":40},[30,220,169],{"class":51},[30,222,166],{"class":40},[30,224,225],{"class":51},"initial",[30,227,172],{"class":40},[30,229,231,234],{"class":32,"line":230},12,[30,232,233],{"class":47},"        return",[30,235,236],{"class":51}," initial\n",[30,238,240],{"class":32,"line":239},13,[30,241,242],{"class":47},"end\n",[30,244,246],{"class":32,"line":245},14,[30,247,249],{"class":248},"sSWvG","--redis.log(redis.LOG_NOTICE,' current:'..current..':')\n",[30,251,253,255],{"class":32,"line":252},15,[30,254,37],{"class":36},[30,256,257],{"class":40}," 如果存在值则在当前值上面加入每次的增量，设置到redis后并返回\n",[30,259,261,263,266,268,271,273,276,279,282,285,287,290],{"class":32,"line":260},16,[30,262,48],{"class":47},[30,264,265],{"class":51}," result",[30,267,55],{"class":36},[30,269,270],{"class":149},"  tonumber",[30,272,153],{"class":40},[30,274,275],{"class":51},"current",[30,277,278],{"class":40},")",[30,280,281],{"class":36},"+",[30,283,284],{"class":149}," tonumber",[30,286,153],{"class":40},[30,288,289],{"class":51},"step",[30,291,172],{"class":40},[30,293,295],{"class":32,"line":294},17,[30,296,297],{"class":248},"--redis.log(redis.LOG_NOTICE,' result:'..result..':')\n",[30,299,301,304,306,308,310,312,314,316,318,320,322,325],{"class":32,"line":300},18,[30,302,303],{"class":51},"redis",[30,305,146],{"class":40},[30,307,150],{"class":149},[30,309,153],{"class":40},[30,311,157],{"class":156},[30,313,214],{"class":160},[30,315,157],{"class":156},[30,317,166],{"class":40},[30,319,169],{"class":51},[30,321,166],{"class":40},[30,323,324],{"class":51},"result",[30,326,172],{"class":40},[30,328,330,333,336,338,340],{"class":32,"line":329},19,[30,331,332],{"class":47},"return",[30,334,335],{"class":149}," tostring",[30,337,153],{"class":40},[30,339,324],{"class":51},[30,341,172],{"class":40},[10,343,344],{},"实现完lua脚本后，我们知道一共需要传递三个参数，有个是业务key，用来标识每个表的，第二参数是id的初始值，比如从1开始或者从1000开始，就是通过第二个参数来设置的，最后一个是每次的增长量：比如我们需要每次在原来的基础+1，那么就传递1，如果需要+10，对应的传递10即可。",[10,346,347],{},"脚本有了之后我们开始在golang中实现具体的功能。",[349,350,352],"h2",{"id":351},"_1定义配置对象","1.定义配置对象",[20,354,358],{"className":355,"code":356,"language":357,"meta":25,"style":25},"language-go shiki shiki-themes tokyo-night github-light","type Config struct {\n    Prefix  string `json:\"prefix\"`  \u002F\u002F 编号前缀\n    Initial int64  `json:\"initial\"` \u002F\u002F 初始值\n    Step    int    `json:\"step\"`    \u002F\u002F 每次递增数量\n    Remark  string `json:\"remark\"`  \u002F\u002F 备注\n    Key     string `json:\"key\"`     \u002F\u002F key名称\n}\n","go",[27,359,360,376,397,416,435,452,470],{"__ignoreMap":25},[30,361,362,365,369,372],{"class":32,"line":33},[30,363,364],{"class":47},"type",[30,366,368],{"class":367},"sirr2"," Config",[30,370,371],{"class":47}," struct",[30,373,375],{"class":374},"sjXpA"," {\n",[30,377,378,382,385,388,391,394],{"class":32,"line":44},[30,379,381],{"class":380},"sVZrm","    Prefix",[30,383,384],{"class":47},"  string",[30,386,387],{"class":156}," `",[30,389,390],{"class":160},"json:\"prefix\"",[30,392,393],{"class":156},"`",[30,395,396],{"class":248},"  \u002F\u002F 编号前缀\n",[30,398,399,402,405,408,411,413],{"class":32,"line":71},[30,400,401],{"class":380},"    Initial",[30,403,404],{"class":47}," int64",[30,406,407],{"class":156},"  `",[30,409,410],{"class":160},"json:\"initial\"",[30,412,393],{"class":156},[30,414,415],{"class":248}," \u002F\u002F 初始值\n",[30,417,418,421,424,427,430,432],{"class":32,"line":79},[30,419,420],{"class":380},"    Step",[30,422,423],{"class":47},"    int",[30,425,426],{"class":156},"    `",[30,428,429],{"class":160},"json:\"step\"",[30,431,393],{"class":156},[30,433,434],{"class":248},"    \u002F\u002F 每次递增数量\n",[30,436,437,440,442,444,447,449],{"class":32,"line":98},[30,438,439],{"class":380},"    Remark",[30,441,384],{"class":47},[30,443,387],{"class":156},[30,445,446],{"class":160},"json:\"remark\"",[30,448,393],{"class":156},[30,450,451],{"class":248},"  \u002F\u002F 备注\n",[30,453,454,457,460,462,465,467],{"class":32,"line":106},[30,455,456],{"class":380},"    Key",[30,458,459],{"class":47},"     string",[30,461,387],{"class":156},[30,463,464],{"class":160},"json:\"key\"",[30,466,393],{"class":156},[30,468,469],{"class":248},"     \u002F\u002F key名称\n",[30,471,472],{"class":32,"line":125},[30,473,474],{"class":374},"}\n",[349,476,478],{"id":477},"_2定义接口","2.定义接口",[10,480,481],{},"这里需要定义一个接口来满足不同的id需求。",[20,483,485],{"className":355,"code":484,"language":357,"meta":25,"style":25},"\u002F\u002F Sequence 序列接口\ntype Sequence interface {\n    \u002F\u002F GetConfig 获取序列配置\n    GetConfig() Config\n    \u002F\u002F NextCode 获取下一个序列化\n    NextCode() string\n}\n",[27,486,487,492,504,509,521,526,536],{"__ignoreMap":25},[30,488,489],{"class":32,"line":33},[30,490,491],{"class":248},"\u002F\u002F Sequence 序列接口\n",[30,493,494,496,499,502],{"class":32,"line":44},[30,495,364],{"class":47},[30,497,498],{"class":367}," Sequence",[30,500,501],{"class":47}," interface",[30,503,375],{"class":374},[30,505,506],{"class":32,"line":71},[30,507,508],{"class":248},"    \u002F\u002F GetConfig 获取序列配置\n",[30,510,511,515,518],{"class":32,"line":79},[30,512,514],{"class":513},"sxkyg","    GetConfig",[30,516,517],{"class":374},"()",[30,519,520],{"class":367}," Config\n",[30,522,523],{"class":32,"line":98},[30,524,525],{"class":248},"    \u002F\u002F NextCode 获取下一个序列化\n",[30,527,528,531,533],{"class":32,"line":106},[30,529,530],{"class":513},"    NextCode",[30,532,517],{"class":374},[30,534,535],{"class":47}," string\n",[30,537,538],{"class":32,"line":125},[30,539,474],{"class":374},[349,541,543],{"id":542},"_3id生成","3.ID生成",[20,545,547],{"className":355,"code":546,"language":357,"meta":25,"style":25},"\u002F\u002F 执行lua脚本获取id\nfunc execute(conf Config) string {\n    luaId := redis.NewScript(`\n        local id_key = KEYS[1]\n        local initial = ARGV[1]\n        local step = ARGV[2]\n        local current = redis.call('get', id_key)\n        if current == false then\n            redis.call('set', id_key, initial)\n            return initial\n        end\n        --redis.log(redis.LOG_NOTICE,' current:'..current..':')\n        local result =  tonumber(current)+ tonumber(step)\n        --redis.log(redis.LOG_NOTICE,' result:'..result..':')\n        redis.call('set', id_key, result)\n        return tostring(result)\n    `)\n    var ctx = context.Background()\n    n, err := luaId.Run(ctx, cache.RedisClient, []string{conf.Key}, conf.Initial, conf.Step).Int64()\n    if err != nil {\n        log.Log.Errorf(\"生成序列id错误:%s\", err.Error())\n        return \"\"\n    }\n    return fmt.Sprintf(\"%s%d\", conf.Prefix, n)\n}\n",[27,548,549,554,577,598,603,608,613,618,623,628,633,638,643,648,653,658,663,669,690,775,791,833,841,847,886],{"__ignoreMap":25},[30,550,551],{"class":32,"line":33},[30,552,553],{"class":248},"\u002F\u002F 执行lua脚本获取id\n",[30,555,556,559,562,564,568,570,572,575],{"class":32,"line":44},[30,557,558],{"class":47},"func",[30,560,561],{"class":513}," execute",[30,563,153],{"class":374},[30,565,567],{"class":566},"sgjcI","conf",[30,569,368],{"class":367},[30,571,278],{"class":374},[30,573,574],{"class":47}," string",[30,576,375],{"class":374},[30,578,579,582,585,587,590,593,595],{"class":32,"line":71},[30,580,581],{"class":51},"    luaId",[30,583,584],{"class":36}," :=",[30,586,143],{"class":51},[30,588,146],{"class":589},"szu1u",[30,591,592],{"class":513},"NewScript",[30,594,153],{"class":374},[30,596,597],{"class":156},"`\n",[30,599,600],{"class":32,"line":79},[30,601,602],{"class":160},"        local id_key = KEYS[1]\n",[30,604,605],{"class":32,"line":98},[30,606,607],{"class":160},"        local initial = ARGV[1]\n",[30,609,610],{"class":32,"line":106},[30,611,612],{"class":160},"        local step = ARGV[2]\n",[30,614,615],{"class":32,"line":125},[30,616,617],{"class":160},"        local current = redis.call('get', id_key)\n",[30,619,620],{"class":32,"line":133},[30,621,622],{"class":160},"        if current == false then\n",[30,624,625],{"class":32,"line":175},[30,626,627],{"class":160},"            redis.call('set', id_key, initial)\n",[30,629,630],{"class":32,"line":183},[30,631,632],{"class":160},"            return initial\n",[30,634,635],{"class":32,"line":200},[30,636,637],{"class":160},"        end\n",[30,639,640],{"class":32,"line":230},[30,641,642],{"class":160},"        --redis.log(redis.LOG_NOTICE,' current:'..current..':')\n",[30,644,645],{"class":32,"line":239},[30,646,647],{"class":160},"        local result =  tonumber(current)+ tonumber(step)\n",[30,649,650],{"class":32,"line":245},[30,651,652],{"class":160},"        --redis.log(redis.LOG_NOTICE,' result:'..result..':')\n",[30,654,655],{"class":32,"line":252},[30,656,657],{"class":160},"        redis.call('set', id_key, result)\n",[30,659,660],{"class":32,"line":260},[30,661,662],{"class":160},"        return tostring(result)\n",[30,664,665,667],{"class":32,"line":294},[30,666,426],{"class":156},[30,668,172],{"class":374},[30,670,671,674,677,679,682,684,687],{"class":32,"line":300},[30,672,673],{"class":47},"    var",[30,675,676],{"class":51}," ctx",[30,678,55],{"class":36},[30,680,681],{"class":51}," context",[30,683,146],{"class":589},[30,685,686],{"class":513},"Background",[30,688,689],{"class":374},"()\n",[30,691,692,695,698,701,703,706,708,711,713,716,718,721,723,726,728,731,734,737,739,741,744,747,749,752,754,757,759,761,763,766,768,770,773],{"class":32,"line":329},[30,693,694],{"class":51},"    n",[30,696,697],{"class":589},",",[30,699,700],{"class":51}," err",[30,702,584],{"class":36},[30,704,705],{"class":51}," luaId",[30,707,146],{"class":589},[30,709,710],{"class":513},"Run",[30,712,153],{"class":374},[30,714,715],{"class":51},"ctx",[30,717,697],{"class":589},[30,719,720],{"class":51}," cache",[30,722,146],{"class":589},[30,724,725],{"class":51},"RedisClient",[30,727,697],{"class":589},[30,729,730],{"class":374}," []",[30,732,733],{"class":47},"string",[30,735,736],{"class":374},"{",[30,738,567],{"class":51},[30,740,146],{"class":589},[30,742,743],{"class":51},"Key",[30,745,746],{"class":374},"}",[30,748,697],{"class":589},[30,750,751],{"class":51}," conf",[30,753,146],{"class":589},[30,755,756],{"class":51},"Initial",[30,758,697],{"class":589},[30,760,751],{"class":51},[30,762,146],{"class":589},[30,764,765],{"class":51},"Step",[30,767,278],{"class":374},[30,769,146],{"class":589},[30,771,772],{"class":513},"Int64",[30,774,689],{"class":374},[30,776,778,781,783,786,789],{"class":32,"line":777},20,[30,779,780],{"class":47},"    if",[30,782,700],{"class":51},[30,784,785],{"class":47}," !=",[30,787,788],{"class":64}," nil",[30,790,375],{"class":374},[30,792,794,797,799,802,804,807,809,812,815,819,821,823,825,827,830],{"class":32,"line":793},21,[30,795,796],{"class":51},"        log",[30,798,146],{"class":589},[30,800,801],{"class":51},"Log",[30,803,146],{"class":589},[30,805,806],{"class":513},"Errorf",[30,808,153],{"class":374},[30,810,811],{"class":156},"\"",[30,813,814],{"class":160},"生成序列id错误:",[30,816,818],{"class":817},"sAus6","%s",[30,820,811],{"class":156},[30,822,697],{"class":589},[30,824,700],{"class":51},[30,826,146],{"class":589},[30,828,829],{"class":513},"Error",[30,831,832],{"class":374},"())\n",[30,834,836,838],{"class":32,"line":835},22,[30,837,233],{"class":47},[30,839,840],{"class":156}," \"\"\n",[30,842,844],{"class":32,"line":843},23,[30,845,846],{"class":374},"    }\n",[30,848,850,853,856,858,861,863,865,868,870,872,874,876,879,881,884],{"class":32,"line":849},24,[30,851,852],{"class":47},"    return",[30,854,855],{"class":51}," fmt",[30,857,146],{"class":589},[30,859,860],{"class":513},"Sprintf",[30,862,153],{"class":374},[30,864,811],{"class":156},[30,866,867],{"class":817},"%s%d",[30,869,811],{"class":156},[30,871,697],{"class":589},[30,873,751],{"class":51},[30,875,146],{"class":589},[30,877,878],{"class":51},"Prefix",[30,880,697],{"class":589},[30,882,883],{"class":51}," n",[30,885,172],{"class":374},[30,887,889],{"class":32,"line":888},25,[30,890,474],{"class":374},[349,892,894],{"id":893},"_4自定义配置","4.自定义配置",[20,896,898],{"className":355,"code":897,"language":357,"meta":25,"style":25},"type GoodsSeq struct {\n}\n\nfunc (u GoodsSeq) GetConfig() Config {\n    return Config{\n        Prefix:  \"SP\",\n        Initial: 300,\n        Step:    1,\n        Remark:  \"商品配置ID生成器\",\n        Key:     \"goods-id-seq\",\n    }\n}\n\nfunc (u GoodsSeq) NextCode() string {\n    conf := u.GetConfig()\n    return execute(conf)\n}\n",[27,899,900,911,915,921,945,954,973,985,997,1013,1030,1034,1038,1042,1063,1080,1092],{"__ignoreMap":25},[30,901,902,904,907,909],{"class":32,"line":33},[30,903,364],{"class":47},[30,905,906],{"class":367}," GoodsSeq",[30,908,371],{"class":47},[30,910,375],{"class":374},[30,912,913],{"class":32,"line":44},[30,914,474],{"class":374},[30,916,917],{"class":32,"line":71},[30,918,920],{"emptyLinePlaceholder":919},true,"\n",[30,922,923,925,928,931,934,936,939,941,943],{"class":32,"line":79},[30,924,558],{"class":47},[30,926,927],{"class":374}," (",[30,929,930],{"class":566},"u ",[30,932,933],{"class":367},"GoodsSeq",[30,935,278],{"class":374},[30,937,938],{"class":513}," GetConfig",[30,940,517],{"class":374},[30,942,368],{"class":367},[30,944,375],{"class":374},[30,946,947,949,951],{"class":32,"line":98},[30,948,852],{"class":47},[30,950,368],{"class":367},[30,952,953],{"class":374},"{\n",[30,955,956,959,962,965,968,970],{"class":32,"line":106},[30,957,958],{"class":380},"        Prefix",[30,960,961],{"class":589},":",[30,963,964],{"class":156},"  \"",[30,966,967],{"class":160},"SP",[30,969,811],{"class":156},[30,971,972],{"class":589},",\n",[30,974,975,978,980,983],{"class":32,"line":125},[30,976,977],{"class":380},"        Initial",[30,979,961],{"class":589},[30,981,982],{"class":64}," 300",[30,984,972],{"class":589},[30,986,987,990,992,995],{"class":32,"line":133},[30,988,989],{"class":380},"        Step",[30,991,961],{"class":589},[30,993,994],{"class":64},"    1",[30,996,972],{"class":589},[30,998,999,1002,1004,1006,1009,1011],{"class":32,"line":175},[30,1000,1001],{"class":380},"        Remark",[30,1003,961],{"class":589},[30,1005,964],{"class":156},[30,1007,1008],{"class":160},"商品配置ID生成器",[30,1010,811],{"class":156},[30,1012,972],{"class":589},[30,1014,1015,1018,1020,1023,1026,1028],{"class":32,"line":183},[30,1016,1017],{"class":380},"        Key",[30,1019,961],{"class":589},[30,1021,1022],{"class":156},"     \"",[30,1024,1025],{"class":160},"goods-id-seq",[30,1027,811],{"class":156},[30,1029,972],{"class":589},[30,1031,1032],{"class":32,"line":200},[30,1033,846],{"class":374},[30,1035,1036],{"class":32,"line":230},[30,1037,474],{"class":374},[30,1039,1040],{"class":32,"line":239},[30,1041,920],{"emptyLinePlaceholder":919},[30,1043,1044,1046,1048,1050,1052,1054,1057,1059,1061],{"class":32,"line":245},[30,1045,558],{"class":47},[30,1047,927],{"class":374},[30,1049,930],{"class":566},[30,1051,933],{"class":367},[30,1053,278],{"class":374},[30,1055,1056],{"class":513}," NextCode",[30,1058,517],{"class":374},[30,1060,574],{"class":47},[30,1062,375],{"class":374},[30,1064,1065,1068,1070,1073,1075,1078],{"class":32,"line":252},[30,1066,1067],{"class":51},"    conf",[30,1069,584],{"class":36},[30,1071,1072],{"class":51}," u",[30,1074,146],{"class":589},[30,1076,1077],{"class":513},"GetConfig",[30,1079,689],{"class":374},[30,1081,1082,1084,1086,1088,1090],{"class":32,"line":260},[30,1083,852],{"class":47},[30,1085,561],{"class":513},[30,1087,153],{"class":374},[30,1089,567],{"class":51},[30,1091,172],{"class":374},[30,1093,1094],{"class":32,"line":294},[30,1095,474],{"class":374},[349,1097,1099],{"id":1098},"_5调用案例","5.调用案例",[20,1101,1103],{"className":355,"code":1102,"language":357,"meta":25,"style":25},"\u002F\u002F 生成商品ID\nid := sequence.GoodsSeq{}.NextCode()\n\u002F\u002F 输出值：SP300\n",[27,1104,1105,1110,1134],{"__ignoreMap":25},[30,1106,1107],{"class":32,"line":33},[30,1108,1109],{"class":248},"\u002F\u002F 生成商品ID\n",[30,1111,1112,1115,1117,1120,1122,1124,1127,1129,1132],{"class":32,"line":44},[30,1113,1114],{"class":51},"id",[30,1116,584],{"class":36},[30,1118,1119],{"class":367}," sequence",[30,1121,146],{"class":589},[30,1123,933],{"class":367},[30,1125,1126],{"class":374},"{}",[30,1128,146],{"class":589},[30,1130,1131],{"class":513},"NextCode",[30,1133,689],{"class":374},[30,1135,1136],{"class":32,"line":71},[30,1137,1138],{"class":248},"\u002F\u002F 输出值：SP300\n",[10,1140,1141],{},"到这里，一个分布式自定义的id生成器已经实现，给出的样例中，针对redis不可用的情况并没有做处理，在生产环境中需要考虑。",[1143,1144,1145],"style",{},"html pre.shiki code .sBxw3, html code.shiki .sBxw3{--shiki-default:#BB9AF7;--shiki-light:#D73A49}html pre.shiki code .sirr2, html code.shiki .sirr2{--shiki-default:#C0CAF5;--shiki-light:#6F42C1}html pre.shiki code .sjXpA, html code.shiki .sjXpA{--shiki-default:#9ABDF5;--shiki-light:#24292E}html pre.shiki code .sVZrm, html code.shiki .sVZrm{--shiki-default:#7DCFFF;--shiki-light:#24292E}html pre.shiki code .sbW-k, html code.shiki .sbW-k{--shiki-default:#89DDFF;--shiki-light:#032F62}html pre.shiki code .snP_1, html code.shiki .snP_1{--shiki-default:#9ECE6A;--shiki-light:#032F62}html pre.shiki code .sSWvG, html code.shiki .sSWvG{--shiki-default:#51597D;--shiki-default-font-style:italic;--shiki-light:#6A737D;--shiki-light-font-style:inherit}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html pre.shiki code .sxkyg, html code.shiki .sxkyg{--shiki-default:#7AA2F7;--shiki-light:#6F42C1}html pre.shiki code .sgjcI, html code.shiki .sgjcI{--shiki-default:#E0AF68;--shiki-light:#E36209}html pre.shiki code .s4do5, html code.shiki .s4do5{--shiki-default:#C0CAF5;--shiki-light:#24292E}html pre.shiki code .sNP9S, html code.shiki .sNP9S{--shiki-default:#89DDFF;--shiki-light:#D73A49}html pre.shiki code .szu1u, html code.shiki .szu1u{--shiki-default:#89DDFF;--shiki-light:#24292E}html pre.shiki code .sjYRd, html code.shiki .sjYRd{--shiki-default:#FF9E64;--shiki-light:#005CC5}html pre.shiki code .sAus6, html code.shiki .sAus6{--shiki-default:#C0CAF5;--shiki-light:#005CC5}html pre.shiki code .sGNLY, html code.shiki .sGNLY{--shiki-default:#A9B1D6;--shiki-light:#24292E}html pre.shiki code .sZlli, html code.shiki .sZlli{--shiki-default:#0DB9D7;--shiki-light:#005CC5}",{"title":25,"searchDepth":71,"depth":71,"links":1147},[1148,1149,1150,1151,1152],{"id":351,"depth":44,"text":352},{"id":477,"depth":44,"text":478},{"id":542,"depth":44,"text":543},{"id":893,"depth":44,"text":894},{"id":1098,"depth":44,"text":1099},null,"2024-03-15","当前基于Golang 1.22.2 版本实现",false,"md",{},"\u002Fposts\u002Fgolang-redis-seq",{"title":5,"description":1155},"posts\u002Fgolang-redis-seq",[1163,303,1164],"golang","分布式序列号","EoqKq66IuW9m8Ia8T4-_j-4x0gYiIDsIKvjstMTJPFU",[1167,1153],{"title":1168,"path":1169,"stem":1170,"children":-1},"Golang exec.Cmd在Kill后不能关闭进程","\u002Fposts\u002Fgolang-exec-kill","posts\u002Fgolang-exec-kill",1789524989342]