目錄

  • 什麼是Snowflake算法?
  • 為什麼選擇Snowflake?
  • 詳細集成過程
  • 1. 環境準備與依賴引入
  • 2. 公共配置類:SnowflakeConfig
  • 3. Nacos配置:多模塊YML統一
  • 4. 實體類與數據庫適配
  • 5. 業務層實現
  • 集成中常見問題及解決方案
  • 集成成功驗證
  • 注意事項


什麼是Snowflake算法?

Snowflake是由Twitter(現X)開發的分佈式唯一ID生成算法,專為高併發微服務環境設計。它生成64位整數ID(Long類型),結構清晰:1位符號位(固定0)+41位時間戳(毫秒級,支持69年)+10位機器標識(5位數據中心ID + 5位Worker ID,支持1024節點)+12位序列號(每毫秒4096個ID)。無需中心化數據庫或鎖,通過本地時鐘+機器信息實現去中心化生成。核心優勢在於全局唯一(時間+空間隔離)、趨勢遞增(優化索引)、高吞吐(無IO瓶頸),已成為分佈式系統(如Kafka、MongoDB)標配。

為什麼選擇Snowflake?

微服務時代,Pig4Cloud如pig-oa、pig-upms等業務模塊獨立部署,高QPS下UUID散亂、Redis原子遞增網絡瓶頸凸顯。Snowflake(Twitter開源)以64位結構(時間戳+機器ID+序列)保證全局唯一單調遞增高吞吐,完美適配MyBatis-Plus的IdentifierGenerator。無外部依賴,本地生成,Pig4Cloud的Nacos配置中心更易統一。

詳細集成過程

1. 環境準備與依賴引入

  • 項目架構:Pig4Cloud多模塊(pig-common-core共享工具,pig-oa-biz業務實現,pig-oa-api對外接口)。
  • 添加Hutool:在根pom.xmlpig-common-core/pom.xml
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.28</version>
</dependency>
  • 運行mvn clean install,確保版本>=5.7.0(Snowflake支持)。

2. 公共配置類:SnowflakeConfig

pig-common-core/src/main/java/com/pig4cloud/pig/common/core/config/新建SnowflakeConfig.java

package com.pig4cloud.pig.common.core.config;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import jakarta.annotation.PostConstruct;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.net.InetAddress;
import java.net.UnknownHostException;

@Configuration
public class SnowflakeConfig {
    private long workerId;
    private long datacenterId = 1L;
    private Snowflake snowflake;

    @PostConstruct
    public void init() {
        try {
            String hostAddress = InetAddress.getLocalHost().getHostAddress();
            workerId = NetUtil.ipv4ToLong(hostAddress) % 32L;
            System.out.println("Snowflake 初始化:workerId=" + workerId + ", datacenterId=" + datacenterId);
        } catch (UnknownHostException e) {
            workerId = 0L;
            e.printStackTrace();
        }
        this.snowflake = IdUtil.getSnowflake(workerId, datacenterId);
    }

    @Bean
    @Primary
    public IdentifierGenerator snowflakeIdGenerator() {
        return (Object entity) -> snowflake.nextId();  // 匹配MP接口
    }
}
  • 邏輯:IP轉workerId(0-31),@PostConstruct單例初始化。@Primary優先級,確保覆蓋默認生成器。

3. Nacos配置:多模塊YML統一

Pig4Cloud用Nacos管理DataId(如pig-umps-biz-dev.yml)。編輯每個業務模塊的YML(application-dev.yml作為fallback):

mybatis-plus:
  global-config:
    db-config:
      id-type: ASSIGN_ID  # 核心切換
      logic-delete-field: delFlag  # 統一邏輯刪除(String, 0/1)
      logic-delete-value: 1
      logic-not-delete-value: 0
  # 其他原有配置...
  • 批量操作:Nacos控制枱搜索DataId,替換mybatis-plus塊,發佈。繼承spring.cloud.nacos.config.shared-configs拉取公共配置。
  • Snowflake擴展:可選加snowflake.datacenter-id: 1(模塊區分),用@Value注入。

4. 實體類與數據庫適配

  • 實體:如EmployeesEntity(pig-oa-biz/entity):
@Data
@TableName("employees")
public class EmployeesEntity extends Model<OaEmployeesEntity> {

    @TableId(type = IdType.ASSIGN_ID)  // 可選,優先全局
    private Long id;  // BIGINT對應
    
    @TableLogic
    @TableField(fill = FieldFill.INSERT)
    private String delFlag;  // 邏輯刪除
    // 其他字段...
}
  • 繼承Model自動CRUD,@TableField(fill)填充createTime等。
  • 數據庫:主鍵id BIGINT NOT NULL PRIMARY KEY,確保無默認值(MP自生成)。如MySQL:
ALTER TABLE oa_employees MODIFY id BIGINT NOT NULL COMMENT 'Snowflake ID';

5. 業務層實現

  • Service(biz):EmployeesServiceImpl extends ServiceImpl<...>
@Transactional
public Boolean save(EmployeesEntity entity) {
    entity.setDelFlag("0");
    return this.save(entity);  // ID自動填充
}
  • API(api):Controller POST保存,Feign暴露。

集成中常見問題及解決方案

  • 編譯報錯:Lambda“wrong number of parameters”——MP nextId(Object entity),改(Object entity) -> snowflake.nextId()忽略entity。
  • 方法未解析Cannot resolve 'nextId'——import cn.hutool.core.lang.Snowflake; 刷新Maven。
  • ID未生成:fallback到auto——檢查@Primary Bean加載,日誌無“Snowflake 初始化”?加@ComponentScan掃描common-core。
  • 邏輯刪除失效:字段不匹配——Nacos logic-delete-field: delFlag vs 實體deleted,統一delFlag(Pig4Cloud標準)。
  • 時鐘回撥:容器NTP不同步,ID重複——生產同步時間服務器,或用美團Leaf備選。
  • 高併發碰撞:workerId重複——Docker環境IP不穩,用Nacos動態注入datacenterId。

集成成功驗證

重啓pig-umps-biz,日誌輸出初始化信息。Postman POST保存實體,響應ID為19位Long(e.g., 1786xxxxxxxxxxxxx)。JMeter 1000QPS循環保存,查表ID遞增無重複。Swagger測試CRUD,delFlag=1邏輯刪生效。跨模塊(如upms調用emp Feign)ID全局唯一。

注意事項

  • 性能:本地生成>26k/s,監控序列溢出(12位,夠用)。
  • 擴展:多環境datacenterId不同(dev=1, prod=10);容器用pod標籤注入workerId。
  • 兼容:Long序列化JSON注意;數據庫索引優化趨勢ID。
  • 回滾:YML id-type: auto,刪Bean。