melon-idfactory

提供 ID 生成服务的主键工厂
授权协议 GPL
开发语言 Java
所属分类 程序开发、 代码生成工具
软件类型 开源软件
地区 国产
投 递 者 梅飞龙
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

主键工厂,提供ID生成服务,保证ID的唯一性。 

使用motan rpc + restful接口两种调用方式,简单配置,快速部署,使用方便。

目前提供3中ID服务:

  1. 提供唯一有序的,不重复的64位整数id生成服务(推荐使用)

  2. 提供自增长整数ID生产服务

  3. 提供32位UUID生产服务

使用说明

1.依赖安装

项目运行依赖JDK1.8和MongoDB,安装方法自行百度

2.发布版下载

获取最新版本的服务包,目前版本为v1.0.0,下载地址

解压melon-idfactory-server-assembly.tar.gz,目录如下:

  • bin 运行脚本,提供windows和linux两种运行方式

  • conf 配置文件

  • lib 项目库

3.配置说明

melon-idfactory的配置很简单,而且都提供默认配置,一般使用时关注少量配置即可

# conf.properties

# mongodb连接配置
mongo.host=127.0.0.1
mongo.port=27017   #默认为"27017"
mongo.databaseName=MelonIdFactory   #默认MelonMongoDbDefault

# uid-generator配置,与64位有序ID的功能有关,可以不做改动,全部使用默配置
#uid-generator配置详细介绍
uid.boostPower=3
uid.paddingFactor=50
uid.scheduleInterval=60
uid.timeBits=28
uid.workerBits=22
uid.seqBits=13
uid.epochStr=2017-10-1

# RPC远程调用配置,使用motan提供rpc服务和restful接口
motan.service.export=8002   # Java服务暴露端口,默认为"8002"
motan.restful.export=8004    # Restful接口暴露端口,默认为"8004"

# Java服务支持使用zookeeper或consul为注册中心,配置如下,默认为direct直连,可以不配置 motan.registry.regProtocol=zookeeper
motan.registry.address=127.0.0.1:2181

4.运行

进入server的bin目录,执行启动脚本

  • start.bat

  • start.sh

  • stop.sh

(windows运行start.bat,linux运行start.sh)

PS:
melon-idfactory-client.jar 为测试调用包,提供了motan rpc的调用封装,使用spring的小伙伴可以引用, 
其他小伙伴可以直接运行server,调用restful接口即可。

调用说明

restful调用说明

client调用说明

引用melon-idfactory-client.jar

可自行编译源码或者直接下载JAR包,下载地址

目前只支持spring项目,可扩展,在你项目的spring配置文件中加入如下配置:

<context:component-scan base-package="com.fetech"/>

<bean id="propertyConfigurer" class="com.fetech.melon.context.property.MelonPropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath*:META-INF/melon/idfactory_conf.properties</value>
        </list>
    </property>
</bean>

# conf.properties

# RPC服务地址配置,无注册中心时使用
motan.referer.directUrl=127.0.0.1:8002
# 如服务使用注册中心发布,需要配置对应的注册中心地址
motan.registry.regProtocol=zookeeper
motan.registry.address=127.0.0.1:2181

代码中直接注入IdFactoryClient即可

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:META-INF/spring/spring-test-idfactory-client.xml"})
public class TestIF {

    @Resource
    private IdFactoryClient idFactoryClient;

    @Test
    public void uuid() {
        LogUtil.debug("uuid:");
        for (int i = 0; i < 10; i++) {
            LogUtil.debug(idFactoryClient.getUUID());
        }
    }

    @Test
    public void uid() {
        LogUtil.debug("64 uid:");
        for (int i = 0; i < 10; i++) {
            long id = idFactoryClient.get64Uid();
            LogUtil.debug(id + "");
            LogUtil.debug(idFactoryClient.parse64Uid(id));
        }
    }

    @Test
    public void incrementId() {
        LogUtil.debug("auto increment id:");
        for (int i = 0; i < 10; i++) {
            LogUtil.debug(idFactoryClient.getIncrementId("test_1") + "");
        }
    }

    @Test
    public void incrementId2() {
        LogUtil.debug("auto increment2 id:");
        boolean ret = idFactoryClient.initIncrementId("test_2", 10);
        Assert.assertTrue(ret);
        for (int i = 0; i < 10; i++) {
            LogUtil.debug(idFactoryClient.getIncrementId("test_2") + "");
        }
    }
}

IdFactoryClient接口说明

/**
 * 获取自增长的主键
 *
 * @param key 主键的key,一般可以使用表名
 * @return long exp:1,2,3...
 */
long getIncrementId(String key);

/**
 * 手动初始化自增长的主键,一般初始化一次即可,如没有初始化,默认getIncrementId从1开始
 *
 * @param key   主键的key,一般可以使用表名
 * @param start 组件的初始值,默认为0,则从1开始
 * @return boolean 初始化成功或失败
 */
boolean initIncrementId(String key, long start);

/**
 * 获取32位的UUID
 *
 * @return String exp:ea5846a348764fc4a7311d6a340e9d14,ae2653087ec84dd59b3adcf4c307cf97...
 */
String getUUID();

/**
 * 获取有序的64位的ID,推荐使用
 *
 * @return long exp:69728553533104128,69728553533104129,69728553533104130...
 */
long get64Uid();

/**
 * 解析有序的64位的ID
 *
 * @param uid 有序的64位的ID
 * @return json exp:
 * {
 * "UID": "69728553533104129",
 * "timestamp": "2017-11-08 11:42:48",
 * "workerId": "87",
 * "sequence": "1"
 * }
 */
String parse64Uid(long uid);

其他说明

  1. 64位有序ID使用了百度uid-generator,是对twitter的snowflake算法的实现

  1. 为什么要使用64d位的有序ID

特别说明,使用melon(甜瓜)开发框架

甜瓜系列不是发明创造,只是想把事情变得简单点,给使用者一点甜头。

  • 本文介绍开源C语言库Melon的cron格式解析。 关于 Melon 库,这是一个开源的 C 语言库,它具有:开箱即用、无第三方依赖、安装部署简单、中英文文档齐全等优势。 Github repo 简介 cron也就是我们常说的Crontab中的时间格式,格式如下: * * * * * 分 时 日 月 周 例如: 30 21 * * * 表示:每晚的21:30 使用 Melon中cr

  • 3437 melon Alice 和 Bob 开始了吃瓜比赛。现在有  个单位的瓜,两个人每次可以拿起  到  某个整数单位的瓜,拿了  单位的瓜后必须花  单位的时间吃掉手里的瓜才能继续拿瓜吃,直到瓜全都被吃完。而且 Alice 和 Bob 不能拿对方手里的瓜。假设拿瓜是可以在瞬间完成的。还假设 Alice 的反应速度总是比 Bob 快,意思是:若两人在一瞬间内同时拿瓜,则必定是 Alice 先

  • 本篇介绍开源C语言库Melon的斐波那契堆的使用。关于 Melon 库,这是一个开源的 C 语言库,它具有:开箱即用、无第三方依赖、安装部署简单、中英文文档齐全等优势。 Github repo 简介 关于斐波那契堆,感兴趣的朋友可以参考《算法导论》或者是各类讲解博客。 本篇介绍的是斐波那契最小堆,但对于判断条件和初始化属性进行调整后,也可实现最大堆。 数据结构各类操作时间复杂度: 创建堆:O(1)

  • 本文对Melon库中的红黑树进行介绍,关于Melon库,这是一个开源的C语言库,它具有:开箱即用、无第三方依赖、安装部署简单、中英文文档齐全等优势。 Github repo 简介 红黑树是一种被应用的非常广泛的数据结构,用于快速搜索指定数据集中的数据。 这里我们不对红黑树的原理进行展开,仅给出其时间复杂度和使用场景介绍。 时间复杂度 插入:O(logN) 删除:O(logN) 搜索:O(logN)

 相关资料
  • 在以太坊兼容的浏览器中使用web3.js时,web3.givenProvider属性将返回浏览器设置的原生 服务提供器,否则返回null。 调用: web3.givenProvider web3.eth.givenProvider web3.shh.givenProvider web3.bzz.givenProvider ... 返回值: Object: 浏览器设置好的提供器,或者null;

  • 简介 服务提供者是所有 Lumen 应用程序启动的中心所在。包括你自己的应用程序,以及所有的 Lumen 核心服务,都是通过服务提供者启动的。 但是,我们所说的「启动」指的是什么?一般而言,我们指的是 注册 事物,包括注册服务容器绑定、事件侦听器、中间件,甚至路由。服务提供者是设置你的应用程序的中心所在。 若你打开 Lumen 的 bootstrap/app.php 文件,你将会看到 $app->

  • 服务提供者是组件和CatLib联系的桥梁。同时也是CatLib启动的中心,所有的服务都是通过服务提供者定义的。 名词定义 组件 组件与CatLib没有任何关系,她们可以独立的运行在不同的框架中。 服务 是由服务提供者将由一个或者多个组件组合而成,并提供一组可以被开发者使用的接口。 容器 CatLib 依赖注入容器。 架构图 创建服务提供者 服务提供者是用来描述一个服务如何为使用者提供服务的,这些关

  • 问题内容: 什么是之间的差异,并在AngularJS? 问题答案: 从AngularJS邮件列表中,我得到了一个很棒的线程,它解释了服务,工厂,提供者及其注入用法。汇编答案: 语法: 结果:在将serviceName声明为可注入参数时 ,将为您提供函数实例。 换句话说 。 工厂名称 语法: 结果:在将factoryName声明为可注入参数时,将为您提供 通过调用传递给module.factory的

  • 简介 服务提供器是所有 Laravel 应用程序引导中心。你的应用程序以及 Laravel 的所有核心服务都是通过服务提供器进行引导。 在这里,我们说的「引导」其实是指 注册 ,比如注册服务容器绑定、事件监听器、中间件,甚至是路由的注册。服务提供器是配置你的应用程序的中心。 Laravel 的 config/app.php 文件中有一个 providers 数组。数组中的内容是应用程序要加载的所有

  • 使用提供函数生成的键与提供的对象相同的值创建一个对象。 使用 Object.keys(obj) 来迭代对象的键。 使用 Array.reduce() 创建一个具有相同值的新对象,并使用 fn 来映射键。 const mapKeys = (obj, fn) => Object.keys(obj).reduce((acc, k) => { acc[fn(obj[k], k, obj)] =