如何在Web服务器群集上生成唯一ID

时间:2009-10-30 14:02:50

标签: java sql database java-ee cluster-computing

在以下情形中:

1个数据库 4个Web服务器

Web服务器如何为数据库生成唯一ID以使它们是唯一的?是的,可以使用自动增量,但这很容易被抓取/猜测/等。因此,自动增量目前不是一种选择。

5 个答案:

答案 0 :(得分:15)

使用UUID(http://www.ietf.org/rfc/rfc4122.txt)。冲突是不太可能的,并且可以通过重新生成新的UUID来处理它们,或者可以通过连接每个服务器的唯一ID(如mac地址)来阻止它们: -

StringBuilder sb = new StringBuilder(UUID.randomUUID());
InetAddress address = InetAddress.getLocalHost();
String uid = sb.append(NetworkInterface.getByInetAddress(address).getHardwareAddress());

答案 1 :(得分:3)

您可以使用UUID:

import java.util.UUID;        

UUID uuid = UUID.randomUUID();
System.out.println(uuid.toString());

答案 2 :(得分:1)

如果您真的担心冲突,可以预先生成密钥并将其存储在具有唯一索引的数据库表中。然后有一个定期作业,在停机期间填充表格,并偶尔删除/存档使用过的密钥。

答案 3 :(得分:1)

您使用的数据库系统是什么?应用程序是否知道哪个服务器正在发出请求?您是让DB决定密钥还是在代码中设置密钥?

它可以像使用带前缀的自动增量或指示请求密钥的服务器的第二个字段一样简单。

答案 4 :(得分:1)

我不确定为什么自动增量或序列是不可接受的。您希望内部ID不“可猜测”吗?什么,这是一个帐号,你不希望有人能够猜出有效的帐号?

好吧,好吧,除了已经提到的UUID之外,还会想到两个明显的可能性。

  1. 使用序列,然后生成一个随机数,并使用算法从两者的组合中创建帐号,使得两个不同的序列号不能给出相同的最终数字。例如,一个简单的算法是:取下一个序列号,乘以12345678,生成一个0到12345678-1的随机数,并将两者加在一起。

  2. 在数据库上有一个包含一条记录的表,该记录包含最后分配的数字。每次需要新号码时,请锁定此记录,使用上一个值生成下一个值,然后更新记录。只要数字总是增加,就可以保证不会有重复。

  3. 如果您有一些方案使用服务器的标识符作为标识符的一部分,我建议您不要将该标识符简单地存储在某个配置文件中的数字。我正在开发一个系统,现在有人有一个明智的想法,就是给每个服务器一个内置的记录id的“服务器id”,服务器id是一个手动分配的小整数。在只有3台服务器的生产中,这并不算太难。但是在开发和测试中,新服务器一直在变化,测试配置文件不断被抛出,管理起来很痛苦。我会避免使用服务器ID周期,但是如果你打算使用一个,可以让它由某个中央服务器自动分配,或者从IP派生,或安全的东西。