人人网框架导入uidGenerator的ID生成方式
人人网框架导入uidGenerator的ID生成方式
人人网框架导入uidGenerator的ID生成方式
人人网框架导入uidGenerator的ID生成方式
安装环境
开发工具:Eclipse
Maven版本:apache-maven-3.5.2
java jdk 1.8
MySQL版本:5.7
一.在renren-api
创建一个节点表worker_node,创建语句:
CREATE TABLE `worker_node` (
  `ID` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'auto increment id',
  `HOST_NAME` varchar(64) NOT NULL COMMENT 'host name',
  `PORT` varchar(64) NOT NULL COMMENT 'port',
  `TYPE` int(11) NOT NULL COMMENT 'node type: ACTUAL or CONTAINER',
  `LAUNCH_DATE` date NOT NULL COMMENT 'launch date',
  `MODIFIED` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'modified time',
  `CREATED` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'created time',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='DB WorkerID Assigner for UID Generator';
二.在renren-security项目中的pom.xml中添加相应的架包
pom.xml添加架包内容如下:
<!--必须放在最后-->
        <dependency>
            <groupId>cn.codesheep</groupId>
            <artifactId>uid-generator</artifactId>
            <version>1.0</version>
        </dependency>
三.在renren-api的io.renren.config的文件中增加文件
CachedUidGeneratorConfig
/**
 * @author lr
 * @date 2019年3月8日 下午4:03:15
 * @version V1.0.0
 */
package io.renren.config;
import com.baidu.fsg.uid.impl.CachedUidGenerator;
import io.renren.service.DisposableWorkerIdAssigner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md
 * 百度id生成器
 * 两种生成器: DefaultUidGenerator、CachedUidGenerator。如对UID生成性能有要求, 请使用CachedUidGenerator
 * 对应Spring配置分别为: default-uid-spring.xml、cached-uid-spring.xml
 */
@Configuration
public class CachedUidGeneratorConfig {
    /**
     * 用完即弃的WorkerIdAssigner, 依赖DB操作
     * @return
     */
    @Bean
    public DisposableWorkerIdAssigner disposableWorkerIdAssigner(){
        return new DisposableWorkerIdAssigner();
    }
    @Bean
    public CachedUidGenerator cachedUidGenerator(DisposableWorkerIdAssigner disposableWorkerIdAssigner){
        CachedUidGenerator cachedUidGenerator = new CachedUidGenerator();
        cachedUidGenerator.setWorkerIdAssigner(disposableWorkerIdAssigner);
        //以下为可选配置, 如未指定将采用默认值
        cachedUidGenerator.setTimeBits(29);
        cachedUidGenerator.setWorkerBits(21);
        cachedUidGenerator.setSeqBits(13);
        cachedUidGenerator.setEpochStr("2016-09-20");
        //RingBuffer size扩容参数, 可提高UID生成的吞吐量
        //默认:3, 原bufferSize=8192, 扩容后bufferSize= 8192 << 3 = 65536
        cachedUidGenerator.setBoostPower(3);
        // 指定何时向RingBuffer中填充UID, 取值为百分比(0, 100), 默认为50
        // 举例: bufferSize=1024, paddingFactor=50 -> threshold=1024 * 50 / 100 = 512.
        // 当环上可用UID数量 < 512时, 将自动对RingBuffer进行填充补全
        //<property name="paddingFactor" value="50"></property>
        //另外一种RingBuffer填充时机, 在Schedule线程中, 周期性检查填充
        //默认:不配置此项, 即不实用Schedule线程. 如需使用, 请指定Schedule线程时间间隔, 单位:秒
        cachedUidGenerator.setScheduleInterval(60L);
        //拒绝策略: 当环已满, 无法继续填充时
        //默认无需指定, 将丢弃Put操作, 仅日志记录. 如有特殊需求, 请实现RejectedPutBufferHandler接口(支持Lambda表达式)
        //<property name="rejectedPutBufferHandler" ref="XxxxYourPutRejectPolicy"></property>
        //cachedUidGenerator.setRejectedPutBufferHandler();
        //拒绝策略: 当环已空, 无法继续获取时 -->
        //默认无需指定, 将记录日志, 并抛出UidGenerateException异常. 如有特殊需求, 请实现RejectedTakeBufferHandler接口(支持Lambda表达式) -->
        //<property name="rejectedTakeBufferHandler" ref="XxxxYourTakeRejectPolicy"></property>
        return cachedUidGenerator;
    }
}
四.在renren-api的io.renren.dao的文件中增加文件
WorkerNodeDao.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 io.renren.dao;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.baidu.fsg.uid.worker.entity.WorkerNodeEntity;
/**
 * DAO for M_WORKER_NODE
 *
 * @author yutianbao
 */
@Mapper
public interface WorkerNodeDao {
    /**
     * 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);
}
五.在renren-api的io.renren.service的文件中增加文件
/*
 * 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 io.renren.service;
import javax.annotation.Resource;
import org.apache.commons.lang.math.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
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 io.renren.dao.WorkerNodeDao;
/**
 * Represents an implementation of {@link WorkerIdAssigner},
 * the worker id will be discarded after assigned to the UidGenerator
 *
 * @author yutianbao
 */
public class DisposableWorkerIdAssigner implements WorkerIdAssigner {
    private static final Logger LOGGER = LoggerFactory.getLogger(DisposableWorkerIdAssigner.class);
    @Resource
    private WorkerNodeDao workerNodeDao;
    /**
     * 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
    public long assignWorkerId() {
        // build worker node entity
        WorkerNodeEntity workerNodeEntity = buildWorkerNode();
        // add worker node for new (ignore the same IP + PORT)
        workerNodeDao.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;
    }
}
六.在renren-api的src/main/resources/mapper/的文件中增加文件WorkerNodeDao.xml
WorkerNodeDao.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="io.renren.dao.WorkerNodeDao">
	<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>
七.在renren-api的Controller中编写生成方法
ApiTestController.java
/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有,侵权必究!
 */
package io.renren.controller;
import io.renren.annotation.Login;
import io.renren.annotation.LoginUser;
import io.renren.common.utils.R;
import io.renren.entity.UserEntity;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baidu.fsg.uid.UidGenerator;
import springfox.documentation.annotations.ApiIgnore;
/**
 * 测试接口
 *
 * @author Mark sunlightcs@gmail.com
 */
@RestController
@RequestMapping("/api")
@Api(tags="测试接口")
public class ApiTestController {
    @Autowired
    private UidGenerator uidGenerator;
    @Login
    @GetMapping("userInfo")
    @ApiOperation(value="获取用户信息", response=UserEntity.class)
    public R userInfo(@ApiIgnore @LoginUser UserEntity user){
        return R.ok().put("user", user);
    }
    @Login
    @GetMapping("userId")
    @ApiOperation("获取用户ID")
    public R userInfo(@ApiIgnore @RequestAttribute("userId") Integer userId){
        return R.ok().put("userId", userId);
    }
    @GetMapping("notToken")
    @ApiOperation("忽略Token验证测试")
    public R notToken(){
        return R.ok().put("msg", "无需token也能访问。。。");
    }
    @GetMapping("uuid")
    @ApiOperation("百度生成uid")
    public R uidGenerator(){
        return R.ok().put("uid", Long.toString(uidGenerator.getUID()));
    }
}
七.在renren-api中执行ApiApplication.java
项目运行后访问地址:http://localhost:8081/renren-api/api/uuid
访问结果:
{"msg":"success","uid":"1340011929288130560","code":0}
=======================================================================================
博客地址:https://www.codepeople.cn
=======================================================================================
微信公众号:
人人网框架导入uidGenerator的ID生成方式的更多相关文章
- 一口气说出 9种 分布式ID生成方式,面试官有点懵了
		
整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 本文作者:程序员内点事 原文链接:https://mp.weix ...
 - 一口气说出9种分布式ID生成方式,面试官有点懵
		
一.为什么要用分布式ID? 在说分布式ID的具体实现之前,我们来简单分析一下为什么用分布式ID?分布式ID应该满足哪些特征? 1.1.什么是分布式ID? 拿MySQL数据库举个栗子:在我们业务数据量不 ...
 - 序列化人人网框架下的DAO?也就是在Spring下序列化DAO的问题(spring+quartz集群下)
		
人人网框架地址:http://code.google.com/p/paoding-rose/ 问题发生: 用Quartz作集群时用JobDataMap传递DAO,提示DAO未序列化,可框架的DAO为接 ...
 - 实用向—总结一些唯一ID生成方式
		
在日常的项目开发中,我们经常会遇到需要生成唯一ID的业务场景,不同的业务对唯一ID的生成方式与要求都会不尽相同,一是生成方式多种多样,如UUID.雪花算法.数据库递增等:其次业务要求上也各有不同,有的 ...
 - html框架—多对话框(相同id)处理
		
一个网站的数据大多数都是异步刷新的,这没什么好说的,然后现在很多前后端框架,大家都知道框架很好用,不用自己写样式,只要利用框架上的语法就能做出漂亮的动态的效果来,而用框架的话大多数的动态效果都是动态生 ...
 - SQLSERVER如何导入数据保持ID不变(ID为自增主键)
		
使用SQL SERVER最操蛋的就是导入数据,以前用企业管理器直接导数据,导一次骂N次娘,在骂了微软无数次娘之后总结了一个方法揍合着还算受用. 其核心要点就是要将数据结构导入到目标数据库服务器上,再来 ...
 - iOS AFNetworking 2.6.0框架导入报错解决方法
		
最近手动导入AFNetworking 2.6.0框架时发现Xcode报如下3个错误: 1. Use of undeclared identifier ‘kSecFormatUnknown‘ 2. Us ...
 - openCV(一)---将openCV框架导入iOS工程中
		
开发环境: Xcode 6.4 openCV for iOS 3.0 配置openCV开发环境 在OpenCV官网中下载OpenCV开发包(官网地址:http://opencv.org/) ...
 - vue框架导入百度地图API接口的方法
		
百度请求API接口:
 
随机推荐
- HUE的自动化安装部署
			
HUE=Hadoop User Experience(Hadoop用户体验),直白来说就一个开源的Apache Hadoop UI系统,由Cloudera Desktop演化而来,最后Cloudera ...
 - JS获取验证码后倒计时不受刷新及关闭影响
			
HTML部分 <input type="button" id="code_btn" value="获取验证码"> JS部分 // ...
 - Scala-Unit4-Scala数组/集合
			
一.Scala数组 1.数组的定义: 方法一:val arr = new Array[String](3) String代表数据的元素类型.3表示数组的长度 方法二:val arr = Array[I ...
 - pdf文件去掉广告,水印,背景和删除密码方法收藏
			
对于学习资料中,pdf文件中的出现的频繁的广告内容真的让人看了很烦,怎么删除呢,后来发现有一款工具foxitphantom可以直接删除,具体操作是,先用该软件打开,然后选择Edit->Heade ...
 - CodeForces - 862C Mahmoud and Ehab and the xor(构造)【异或】
			
<题目链接> 题目大意: 给出n.m,现在需要你输出任意n个不相同的数(n,m<1e5),使他们的异或结果为m,如果不存在n个不相同的数异或结果为m,则输出"NO" ...
 - Apache系列:Apache的全局配置
			
配置文件组成: 整个配置文件由3段组成: (1)全局配置:对主服务器或虚拟机都有效,且有些功能是服务器自身工作属性: (2)主服务器:主站属性: (3)虚拟主机:虚拟主机及属性定义 注:第二段和第三段 ...
 - Github入门操作实录
			
到目前为止,我已经工作快5年了,这5年最大的感受就是,框架什么的并不难,只要知道api,就能用起来,一开始会遇到一点问题,但是天下的框架都大同小异,无非是jar包,配置文件,模板代码,jar包可以使用 ...
 - C# 简单学习正则表达式
			
第一步先要引入有关正则式的命名空间: using System.Text.RegularExpressions; 第二步用指定的正则式构建一个正则表达式对象,下面的正则式是用来搜 ...
 - 并发编程之I/O模型
			
1.I/O模型介绍 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个 ...
 - Codeforces.472F.Design Tutorial: Change the Goal(构造 线性基 高斯消元)
			
题目链接 \(Description\) 给定两个长为\(n\)的数组\(x_i,y_i\).每次你可以选定\(i,j\),令\(x_i=x_i\ \mathbb{xor}\ x_j\)(\(i,j\ ...