人人网框架导入uidGenerator的ID生成方式

2019-03-11
LIUREN
 

人人网框架导入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-apiio.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-apiio.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-apiio.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-apisrc/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生成方式的更多相关文章

  1. 一口气说出 9种 分布式ID生成方式,面试官有点懵了

    整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 本文作者:程序员内点事 原文链接:https://mp.weix ...

  2. 一口气说出9种分布式ID生成方式,面试官有点懵

    一.为什么要用分布式ID? 在说分布式ID的具体实现之前,我们来简单分析一下为什么用分布式ID?分布式ID应该满足哪些特征? 1.1.什么是分布式ID? 拿MySQL数据库举个栗子:在我们业务数据量不 ...

  3. 序列化人人网框架下的DAO?也就是在Spring下序列化DAO的问题(spring+quartz集群下)

    人人网框架地址:http://code.google.com/p/paoding-rose/ 问题发生: 用Quartz作集群时用JobDataMap传递DAO,提示DAO未序列化,可框架的DAO为接 ...

  4. 实用向—总结一些唯一ID生成方式

    在日常的项目开发中,我们经常会遇到需要生成唯一ID的业务场景,不同的业务对唯一ID的生成方式与要求都会不尽相同,一是生成方式多种多样,如UUID.雪花算法.数据库递增等:其次业务要求上也各有不同,有的 ...

  5. html框架—多对话框(相同id)处理

    一个网站的数据大多数都是异步刷新的,这没什么好说的,然后现在很多前后端框架,大家都知道框架很好用,不用自己写样式,只要利用框架上的语法就能做出漂亮的动态的效果来,而用框架的话大多数的动态效果都是动态生 ...

  6. SQLSERVER如何导入数据保持ID不变(ID为自增主键)

    使用SQL SERVER最操蛋的就是导入数据,以前用企业管理器直接导数据,导一次骂N次娘,在骂了微软无数次娘之后总结了一个方法揍合着还算受用. 其核心要点就是要将数据结构导入到目标数据库服务器上,再来 ...

  7. iOS AFNetworking 2.6.0框架导入报错解决方法

    最近手动导入AFNetworking 2.6.0框架时发现Xcode报如下3个错误: 1. Use of undeclared identifier ‘kSecFormatUnknown‘ 2. Us ...

  8. openCV(一)---将openCV框架导入iOS工程中

    开发环境: Xcode 6.4   openCV for iOS 3.0    配置openCV开发环境 在OpenCV官网中下载OpenCV开发包(官网地址:http://opencv.org/) ...

  9. vue框架导入百度地图API接口的方法

    百度请求API接口:

随机推荐

  1. 今天这篇内容分享Apache由http自动跳转到https的多种方法

    本文主要和大家分享Apache http自动跳转到https的几种方法,非常不错,具有参考借鉴价值,需要的朋友参考下 本文主要和大家分享Apache http自动跳转到https的几种方法,当你的站点 ...

  2. Java中的不同遍历方式

    已知一个Person类: public class Person implements Comparable<Person>{ String name; String id; public ...

  3. python-飞机大战

    效果图 main.py import time import pygame from EnemyPlane import EnemyPlane from HeroPlane import HeroPl ...

  4. VS2017 下载离线MSDN文档

    VS2017 下载离线MSDN文档 点开帮助窗口的时候发现没有添加和删除帮助内容选项.处理方法如下: 1.打开vs2017安装包,如果你找不到安装包,可在相应你下载vs2017的浏览器上找到下载内容, ...

  5. Java内存管理-掌握虚拟机类加载机制(四)

    勿在流沙筑高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 上一篇介绍了整个JVM运行时的区域,以及简单对比了JDK7和JDK8中JVM运行时区域 ...

  6. logback实践笔记

    前言 ​ 每次看公司配置好的logback文件的时候,都不知道什么意思.导致有的时候,一些项目发到测试环境的时候,有的项目没有打印日志,自己都不知道哪里有问题.所以自己新建一个springboot项目 ...

  7. 多AG自动生成apk说明

    -----------自动生成apk说明.txt 1017202130405658626378 自动实现思路几个变化的地方 就是 第一次放入文件10, 修改apktype 100130 10生成apk ...

  8. 2017-9-17-Windows Live Writer常用快捷键

    Window Live Writer常用的快捷键: 将当前文章发布到博客:CTRL+SHIFT+P 打开新文章: CTRL+N 将草稿保存到计算机上: CTRL+S 切换到"普通" ...

  9. Java -- 内部类(二)

    在上一篇博客Java --内部类(一)中已经提过了,java中的内部类主要有四种:成员内部类.局部内部类.匿名内部类.静态内部类. 该文主要介绍这几种内部类. 成员内部类 成员内部类也是最普通的内部类 ...

  10. Windows环境下Composer的安装教程

    1.先下载Composer-Setup.exe,下载地址:下载Composer .会自动搜索php.exe的安装路径,如果没有,就手动找到php路径下的php.exe. 2.在PHP目录下,打开php ...