人人网框架导入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接口:
随机推荐
- day 34 编程之补充内容
生产消费者模型(必须要理解并且牢记,默写内容): from multiprocessing import Process,Queue import time,random,os def procduc ...
- TensorFlow卷积层-函数
函数1:tf.nn.conv2d是TensorFlow里面实现卷积的函数,实际上这是搭建卷积神经网络比较核心的一个方法 函数原型: tf.nn.conv2d(input,filter,strides, ...
- miniui中可以设置是否让页面进行分页 <div id="datagrid1" class="mini-datagrid" style="width:100%" allowAlternating="true" showpager="true"/> 就是设置showpager属性为true
<div id="datagrid1" class="mini-datagrid" style="width:100%" allowA ...
- 函数模拟sort快排
设计一个对一维数组进行排序的sort函数,并调用它实现数组排序 思路:函数调用不止调用一个,最主要对函数不熟悉: #include<stdio.h> #define N 10 int ma ...
- 【基础】链表的储存结构说明(python)
[实现链表的添加] class aNode(): def __init__(self,data=None,nxt=None): self.data=data self.nxt=nxt class ru ...
- JetBrain(Pycharm,Clion...)的使用优化
我们知道,在JetBrain系列软件中,另起一行继续编辑的快捷是Shift+Enter,这样即使指针没有到达当前行结尾,也可以另起一行,如图1中的情况: >>> Shift+ ...
- 上海市2019年公务员录用考试第一轮首批面试名单(A类)
上海市2019年公务员录用考试第一轮首批面试名单(A类) 注册编号 总成绩 注册编号 总成绩 注册编号 总成绩 注册编号 总成绩 4016574 127.4 5112479 145.9 5125732 ...
- iOS APP提交上架流程
转载自CocoaChina,链接地址:http://www.cocoachina.com/bbs/read.php?tid=330302 后面问题我也遇到了,参考该文章解决的 转自http://blo ...
- Windows下的Hadoop安装(本地模式)
时隔许久的博客.. 系统为Windows 10,Hadoop版本2.8.3. 虽然之前已经在Linux虚拟机上成功运行了Hadoop,但我还是在Windows上编码更加习惯,所以尝试了在Window上 ...
- 牛客国庆集训派对Day1.B.Attack on Titan(思路 最短路Dijkstra)
题目链接 \(Description\) 给定\(n,m,C\)及大小为\((n+1)(m+1)\)的矩阵\(c[i][j]\).平面上有\((n+1)(m+1)\)个点,从\((0,0)\)编号到\ ...