PHP-PHP中的uniqid在高并发下的重复问题

发布于 2016-12-06 23:55:24 字数 92 浏览 1324 评论 6

项目是一个高并发的web项目,并且会有后台进程(pcntl并发),两者都会利用uniqid去生成唯一id,今天发现一个bug,在高并发情况下,uniqid可能产生重复输出

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

偏爱自由 2017-11-08 15:20:30

以下是测试代码:

<?php
function new_child($func_name) {
$args = func_get_args();
unset($args[0]);
$pid = pcntl_fork();
if($pid == 0) {
function_exists($func_name) and exit(call_user_func_array($func_name, $args)) or exit(-1);
} else if($pid == -1) {
echo "Couldn’t create child process.";
} else {
return $pid;
}
}
function generate() {
$t = array();
while($i ++ < 10) {
$uid = uniqid(true)."/n";
array_push($t, $uid);
}
sort($t);
while(-- $i >=0) {
echo array_shift($t);
}
}
while($i ++ < 1000) {
new_child(generate);
}

?>

测试方法: 命令行运行此程序,重定向输出到文件,然后利用下面程序检查重复:

<?php
$f = file("tttttt");
$f = array_count_values($f);
foreach($f as $k => $c) if($c > 1) echo $c.'_'.$k;
?>

解决方法: 我们现在是在uniqid后又加了rand(1, 10000),在1000并发,每进程10次uniqid的情况下,再没有产生重复。

归属感 2017-11-01 15:08:05

md5($_SERVER['HTTP_USER_AGENT'].gettimeofday(true).lcg_value())

这样的方式应该可以解决重复和并发问题。

灵芸 2017-08-20 00:16:08

uniqid() 函数本身就是基于以微秒计的当前时间,所以在高并发的情况下肯定会出现重复的情况,解决的的方法是你可以在这个前提下再生成一个随机数,然后两者结合后产生出一个新的数,这样就会降低重复的概率。如果还是想要再精确的话还可以加上客户端的IP的Md5码来一同生成,这样应该重复的概率就极低了,可以说是几乎不会重复。

<?php
function getRand(){
return uniqid() . rand(1, 100000);
}
echo getRand();
exit;
?>

浮生未歇 2017-07-20 19:26:27

降低重复率 确实 是好方法,速度也足够快。
完全不会重复,有一个方法,但高并发的IO确实是个问题,可以用memcache,代码很简单

 $id = null;
while($id==null)
{
$id = uniqid();
$row = ClassMemcache::Init()->get("tbl_news_{$id}");
if($row)
{
$id = null;
}
}

虐人心 2017-05-04 12:59:30

uniqid 并不支持并发。即使你加上了rand,理论上还是会出现重复。

浮生未歇 2017-03-30 08:21:07

uniqid(prefix,more_entropy)
prefix 可选。为 ID 规定前缀。如果两个脚本在相同的微妙生成 ID,该参数很有用。
more_entropy 可选。规定位于返回值末尾的更多的熵。
如果 prefix 参数为空,则返回的字符串有 13 个字符串长。如果 more_entropy 参数设置为 true,则是 23 个字符串长。
如果 more_entropy 参数设置为 true,则在返回值的末尾添加额外的熵(使用组合线形同余数生成程序),这样可以结果的唯一性更好。
uniqid(rand(1, 100000)); 这个可以在开头加 但是位数不一样
uniqid('',true); 这样可以末尾添加额外的熵

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文