baidu UidGenerator 分布式id生成器, snowflake落地应用

baidu UidGenerator id生成器


baidu/uid-generator GitHub地址:

https://github.com/baidu/uid-generator

一、问题

如果只是引入源码,在springboot中,出抛出以下异常:

‘com.baidu.fsg.uid.worker.dao.WorkerNodeDAO’ that could not be found

二、解决方案

2.1 本地先编译源码生成jar包后引入项目

<dependency>
    <groupId>com.baidu.fsg</groupId>
    <artifactId>uid-generator</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>

2.2 复制源码:

WorkerNodeDAO到自己的工程下,并重命名为WorkerNodeMapper

/*
 * Copyright (c) 2017 Baidu, Inc. All Rights Reserve.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package arthur.dy.lee.mybatisplusdemo.nova.mapper;

import com.baidu.fsg.uid.worker.entity.WorkerNodeEntity;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

/**
 * DAO for M_WORKER_NODE
 *
 * @author arthur.dy.lee
 */
@Repository
public interface WorkerNodeMapper {

    /**
     * Get {@link WorkerNodeEntity} by node host
     * 
     * @param host
     * @param port
     * @return
     */
    WorkerNodeEntity getWorkerNodeByHostPort(@Param("host") String host, @Param("port") String port);

    /**
     * Add {@link WorkerNodeEntity}
     * 
     * @param workerNodeEntity
     */
    void addWorkerNode(WorkerNodeEntity workerNodeEntity);

}

WORKER_NODE.xml–> WorkerNodeMapper.xml,注意修改命名空间

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="arthur.dy.lee.mybatisplusdemo.nova.mapper.WorkerNodeMapper">
   <resultMap id="workerNodeRes"
            type="com.baidu.fsg.uid.worker.entity.WorkerNodeEntity">
      <id column="ID" jdbcType="BIGINT" property="id" />
      <result column="HOST_NAME" jdbcType="VARCHAR" property="hostName" />
      <result column="PORT" jdbcType="VARCHAR" property="port" />
      <result column="TYPE" jdbcType="INTEGER" property="type" />
      <result column="LAUNCH_DATE" jdbcType="DATE" property="launchDate" />
      <result column="MODIFIED" jdbcType="TIMESTAMP" property="modified" />
      <result column="CREATED" jdbcType="TIMESTAMP" property="created" />
   </resultMap>

   <insert id="addWorkerNode" useGeneratedKeys="true" keyProperty="id"
      parameterType="com.baidu.fsg.uid.worker.entity.WorkerNodeEntity">
      INSERT INTO WORKER_NODE
      (HOST_NAME,
      PORT,
      TYPE,
      LAUNCH_DATE,
      MODIFIED,
      CREATED)
      VALUES (
      #{hostName},
      #{port},
      #{type},
      #{launchDate},
      NOW(),
      NOW())
   </insert>

   <select id="getWorkerNodeByHostPort" resultMap="workerNodeRes">
      SELECT
      ID,
      HOST_NAME,
      PORT,
      TYPE,
      LAUNCH_DATE,
      MODIFIED,
      CREATED
      FROM
      WORKER_NODE
      WHERE
      HOST_NAME = #{host} AND PORT = #{port}
   </select>
</mapper>

2.3 复制源码DisposableWorkerIdAssigner.java

/*
 * Copyright (c) 2017 Baidu, Inc. All Rights Reserve.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package arthur.dy.lee.mybatisplusdemo.nova.service;

import arthur.dy.lee.mybatisplusdemo.nova.mapper.WorkerNodeMapper;
import com.baidu.fsg.uid.utils.DockerUtils;
import com.baidu.fsg.uid.utils.NetUtils;
import com.baidu.fsg.uid.worker.WorkerIdAssigner;
import com.baidu.fsg.uid.worker.WorkerNodeType;
import com.baidu.fsg.uid.worker.entity.WorkerNodeEntity;
import org.apache.commons.lang.math.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * Represents an implementation of {@link WorkerIdAssigner},
 * the worker id will be discarded after assigned to the UidGenerator
 * 
 * @author arthur.dy.lee
 */

public class DisposableWorkerIdAssigner implements WorkerIdAssigner {
    private static final Logger LOGGER = LoggerFactory.getLogger(com.baidu.fsg.uid.worker.DisposableWorkerIdAssigner.class);

    @Resource
    private WorkerNodeMapper workerNodeMapper;

    /**
     * Assign worker id base on database.<p>
     * If there is host name & port in the environment, we considered that the node runs in Docker container<br>
     * Otherwise, the node runs on an actual machine.
     * 
     * @return assigned worker id
     */
    @Transactional
    @Override
    public long assignWorkerId() {
        // build worker node entity
        WorkerNodeEntity workerNodeEntity = buildWorkerNode();

        // add worker node for new (ignore the same IP + PORT)
        workerNodeMapper.addWorkerNode(workerNodeEntity);
        LOGGER.info("Add worker node:" + workerNodeEntity);

        return workerNodeEntity.getId();
    }

    /**
     * Build worker node entity by IP and PORT
     */
    private WorkerNodeEntity buildWorkerNode() {
        WorkerNodeEntity workerNodeEntity = new WorkerNodeEntity();
        if (DockerUtils.isDocker()) {
            workerNodeEntity.setType(WorkerNodeType.CONTAINER.value());
            workerNodeEntity.setHostName(DockerUtils.getDockerHost());
            workerNodeEntity.setPort(DockerUtils.getDockerPort());

        } else {
            workerNodeEntity.setType(WorkerNodeType.ACTUAL.value());
            workerNodeEntity.setHostName(NetUtils.getLocalAddress());
            workerNodeEntity.setPort(System.currentTimeMillis() + "-" + RandomUtils.nextInt(100000));
        }

        return workerNodeEntity;
    }

}

2.4 引入application-bean.xml,官网配置,修改DisposableWorkerIdAssigner为本地的包路径,如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd"
       default-autowire="byName">


    <!-- DefaultUidGenerator -->
    <bean id="defaultUidGenerator" class="com.baidu.fsg.uid.impl.DefaultUidGenerator" lazy-init="false">
        <property name="workerIdAssigner" ref="disposableWorkerIdAssigner"/>

        <!-- Specified bits & epoch as your demand. No specified the default value will be used -->
        <property name="timeBits" value="29"/>
        <property name="workerBits" value="21"/>
        <property name="seqBits" value="13"/>
        <property name="epochStr" value="2016-09-20"/>
    </bean>

    <!-- 用完即弃的WorkerIdAssigner,依赖DB操作 -->
    <!-- 修改成自己的包路径 -->
    <bean id="disposableWorkerIdAssigner" class="arthur.dy.lee.mybatisplusdemo.nova.service.DisposableWorkerIdAssigner"/>

</beans>

2.5 将xml引入到工程中,由spring容器去管理

package arthur.dy.lee.mybatisplusdemo;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

/**
 * @auther arthur.dy.lee
 * @since 2019/4/27 17:43
 */
@Configuration
@ImportResource(locations = { "classpath:application-bean.xml" })
public class IdGeneratorConfiguration {

}

三、使用

@Slf4j
@RestController
@RequestMapping("/nova/teacher4-test-in")
public class Teacher4testInController {

    @Autowired
    private ITeacher4testInService service;

    //注入
    @Resource
    private UidGenerator uidGenerator;
    
    /**
     * baidu uid生成器
     */
    @RequestMapping("/insert")
    public void insertBatch() {
        Teacher4testIn t = new Teacher4testIn();
        long id = uidGenerator.getUID(); // <-------
        t.setId(id);
        t.setName("lee-" + id);
        t.setIsDelete(false);
        t.setGmtCreate(LocalDate.now());
        t.setGmtModified(LocalDate.now());
        t.setModifier("lee");
        t.setAddress("address-" + id);
        t.setBak("备注1234567890");
        t.setClassNo(1);
        t.setCultivateHobby("我的爱好是运动-" + id);
        t.setCultivateHobby2("我的爱好是写代码-" + id);
        t.setCultivateHobby3("我的爱好是吹牛逼-" + id);
        t.setCultivateHobby4("我的爱好是登山-" + id);
        t.setCultivateHobby5("我的爱好是游泳-" + id);
        t.setCultivateHobby6("我的爱好是弹钢琴-" + id);
        t.setFocus(true);
        t.setHeight(16.0);
        t.setIq(100);
        t.setPhone(123456);
        t.setSex(true);
        boolean ret = service.save(t);
        log.info(JSONObject.toJSONString(ret));
    }
}

四、源码地址:

访问url

http://localhost:8081/nova/teacher4-test-in/insert

码云下载地址:

https://gitee.com/paincupid/mybatis-plus-demo

参考:

springboot2.0集成百度uidgenerator

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值