详解如何使用MongoDB+Springboot实现分布式ID的方法

 更新时间:2019年09月12日 10:28:19   作者:方志朋  
这篇文章主要介绍了详解如何使用MongoDB+Springboot实现分布式ID的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、背景

如何实现分布式id,搜索相关的资料,一般会给出这几种方案:

  • 使用数据库自增Id
  • 使用reids的incr命令
  • 使用UUID
  • Twitter的snowflake算法
  • 利用zookeeper生成唯一ID
  • MongoDB的ObjectId

另外,在我通过爬取知乎用户id发现,知乎的用户id是32位的,初步断定知乎采用的是md5加密,然后全部转换成小写。至于如何爬取知乎用户信息,见我之前分享的文章。本文采取的技术方案采取的是mogoodb的objectId。

二.mongodb如何实现分布式ID

MongoDB的ObjectId设计成轻量型的,不同的机器都能用全局唯一的同种方法方便地生成它。MongoDB 从一开始就设计用来作为分布式数据库,处理多个节点是一个核心要求。使其在分片环境中要容易生成得多。

它的格式:

前4 个字节是从标准纪元开始的时间戳,单位为秒。时间戳,与随后的5 个字节组合起来,提供了秒级别的唯一性。由于时间戳在前,这意味着ObjectId 大致会按照插入的顺序排列。这对于某些方面很有用,如将其作为索引提高效率。这4 个字节也隐含了文档创建的时间。绝大多数客户端类库都会公开一个方法从ObjectId 获取这个信息。

接下来的3 字节是所在主机的唯一标识符。通常是机器主机名的散列值。这样就可以确保不同主机生成不同的ObjectId,不产生冲突。

为了确保在同一台机器上并发的多个进程产生的ObjectId 是唯一的,接下来的两字节来自产生ObjectId 的进程标识符(PID)。

前9 字节保证了同一秒钟不同机器不同进程产生的ObjectId 是唯一的。

后3 字节就是一个自动增加的计数器,确保相同进程同一秒产生的ObjectId 也是不一样的。同一秒钟最多允许每个进程拥有2563(16 777 216)个不同的ObjectId。

三、编码

在springboot中引入mongodb:

  <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
 </dependency>

 <!-- 开启web-->
 <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 

    <!--mongodb -->
 <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-mongodb</artifactId>
 </dependency>

创建一个实体类:

public class Customer {

  @Id
  public String id;

  public String firstName;
  public String lastName;

  public Customer() {}

  public Customer(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  @Override
  public String toString() {
    return String.format(
        "Customer[id=%s, firstName='%s', lastName='%s']",
        id, firstName, lastName);
  }


  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
}

创建mongodb 接口类:

/**
 * Created by fangzhipeng on 2017/4/1.
 */


public interface CustomerRepository extends MongoRepository<Customer, String> {

  public Customer findByFirstName(String firstName);
  public List<Customer> findByLastName(String lastName);

}

测试类:

 @Autowired
  CustomerRepository customerRepository;


@Test
public void mongodbIdTest(){
Customer customer=new Customer("lxdxil","dd");
    customer=customerRepository.save(customer);
    logger.info( "mongodbId:"+customer.getId());
}

四、参考资料

Accessing Data with MongoDB

MongoDB深究之ObjectId

MongoDB 教程

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Java中的Phaser并发阶段器详解

    Java中的Phaser并发阶段器详解

    这篇文章主要介绍了Java中的Phaser并发阶段器详解,Phaser由JDK1.7提出,是一个复杂强大的同步辅助类,是对同步工具类CountDownLatch和CyclicBarrier的综合升级,能够支持分阶段实现等待的业务场景,需要的朋友可以参考下
    2023-12-12
  • Java实现简单的抽牌游戏

    Java实现简单的抽牌游戏

    这篇文章主要为大家详细介绍了Java实现简单的抽牌游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • Java中常用的数据库连接池_动力节点Java学院整理

    Java中常用的数据库连接池_动力节点Java学院整理

    数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏
    2017-08-08
  • java servlet 几种页面跳转的方法

    java servlet 几种页面跳转的方法

    java servlet 几种页面跳转的方法,需要的朋友可以参考一下
    2013-04-04
  • java使用jna调用c#中dll的方法详解

    java使用jna调用c#中dll的方法详解

    前一段时间接了个项目,需要用到第三方提供的C#编写的dll,本身项目是java语言,所以便有了下面这篇文章,本文给大家介绍了关于java中如何使用jna调用c#中dll的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-09-09
  • bool当成函数参数错误理解

    bool当成函数参数错误理解

    经常会在函数的参数里使用bool参数,这会大大地降低代码的可读性
    2012-11-11
  • @JsonSerialize不起作用的解决方案

    @JsonSerialize不起作用的解决方案

    这篇文章主要介绍了@JsonSerialize不起作用的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • idea项目debug模式启动,断点失效,断点红点内无对勾问题及解决

    idea项目debug模式启动,断点失效,断点红点内无对勾问题及解决

    这篇文章主要介绍了idea项目debug模式启动,断点失效,断点红点内无对勾问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • 关于struts2中Action名字的大小写问题浅谈

    关于struts2中Action名字的大小写问题浅谈

    这篇文章主要给大家介绍了关于struts2中Action名字大小写问题的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编一起来学习学习吧。
    2017-06-06
  • 详解Java设计模式中的装饰模式

    详解Java设计模式中的装饰模式

    装饰模式是指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。本文将为大家详细介绍一下装饰模式,感兴趣的可以了解一下
    2021-12-12

最新评论