用的webman/database 模型
eventLoop使用 Workerman\Events\Fiber::class;
并发上传,用insertGetId返回数据库id,会重复,数据库里面是正常自增字段
/**
* 上传文件
* @param Request $request
* @return Response
*/
public function upload_file(Request $request): Response
{
try {
add_log('上传文件');
$user = $request->token_user;
$file = $request->file('file');
$type = $request->post('type');
$位置 = $request->post('位置');
if ($file && $type && $file->isValid()) {
$ext = $file->getUploadExtension();
if (in_array($ext, ['php', 'html', 'sql', 'json'])) {
return response('文件类型错误', 503);
}
if (in_array($type, ['头像', '头图', '详情图'])) {
if (!in_array($ext, ['jpg', 'jpeg', 'png', 'gif'])) {
return response('非图片格式', 503);
}
if ($file->getSize() > 1024 * 1024 * 10) {
return response('图片大小不能超过10M', 503);
}
} else if ($type === '附件') {
if (!in_array($ext, ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'zip', 'rar', 'jpg', 'jpeg', 'png', 'gif'])) {
return response('附件格式错误', 503);
}
if ($file->getSize() > 1024 * 1024 * 100) {
return response('附件大小不能超过100M', 503);
}
} else {
return response('参数错误', 503);
}
$format = $file->getExtension();
$upload_name = $file->getUploadName();
if (empty($upload_name)) return response('文件名错误,请修改文件名', 503);
$name = Tool::get_microtime();
$dir = public_path() . '/files/upload/' . date('Ym') . '/' . date('d') . '/';
if (!is_dir($dir)) mkdir($dir, 0777, true);
$file->move($dir . $name . '.' . $ext);
$file_url = 'files/upload/' . date('Ym') . '/' . date('d') . '/' . $name . '.' . $ext;
$path2 = public_path() . '/' . $file_url;
switch ($type) {
case '头像':
Image::load($path2)
->optimize()
->fit(Fit::Stretch, 100, 100)
->quality(75)
->save();
break;
case '详情图':
Image::load($path2)
->optimize()
->fit(Fit::Max, 800)
->quality(75)
->save();
break;
case '头图':
Image::load($path2)
->optimize()
->fit(Fit::Max, 500)
->quality(75)
->save();
break;
default:
break;
}
$imageInfo = getimagesize($path2);
$fileSize = filesize($path2);
$sha1 = sha1_file($path2);
$file_id = UploadFile::insertGetId([
'类型' => $type,
'名称' => $upload_name,
'网址' => $file_url,
'目录' => $path2,
'位置' => $位置,
'文件大小' => $fileSize,
'文件格式' => $format,
'后缀' => $ext,
'录入人' => $user['姓名'],
'sha1' => $sha1,
'width' => $imageInfo[0] ?? 0,
'height' => $imageInfo[1] ?? 0,
]);
return res_success([
'id' => $file_id,
'name' => $upload_name,
'url' => $file_url,
'size' => $fileSize,
'type' => $ext,
], '上传成功');
}
return response('参数错误', 503);
} catch (Throwable $e) {
write_log('exception', 'error', '上传文件', $e);
return response('上传失败', 503);
}
}
并发同时请求就会
这里写具体的系统环境相关信息
不会吧,你不用fiber 试试呢
'eventLoop' => ''也一样
不可能,绝对不可能,你用的那个orm,lv的还是tp的?
webman/database 是 用laravel的illuminate/database
这个我测试过 真没发现还有这个问题呢,我也压力测试过,没出现重复的
并发有小于10毫秒以下吗?
webman内网测试基本都是5ms以内的,除非你的mysql太垃圾了
那就奇怪了,而且数据库是正常的
你在linux测试的嘛,能不能在测试测试截个图,多少并发能复现?
在window测试,就一个上传,同时上传几个文件,就会发生
多个上传都是有重复的
数据库配置
你开启协程了嘛???
window不知道有没有,但这个配置是默认的,不管有没有协程
如果开启协程 或者 你使用swon 那个就会自动变成协程,本地可以卸载然后evenloop => '' windows更不会并发处理就一个进程 你想用多进程必须linux代理多端口 才行,我测试没问题
版本如截图所示
linux上并发设置都没问题建议你看下mysql配置
或者在每个请求结束也就是response上吧lastId写入log文件 也有可能是opcache缓存的问题
这个明显不符合mysql的逻辑 它就不可能返回两个相同的id 主键自增的情况下
这个也确实 毕竟入库数据没问题 基本应该就是业务代码层面的问题了
测试了,跟长id有关系,1000000000000001不会,10000000000000001会重复
数据库表结构,id字段类型.
bigint本身数据库是没问题的,是获取的id有问题
js数字处理的问题吧
楼上说的,JS对bigint的处理问题,要么就用json-bigint包,要么就将id返回时转成string
上面说的对,js支持不了那么大的数字,打印下就能看出来,是乱的重复的。
这还真是js问题,看来打印的时候他没用webman的窗口打印,直接用的js打印的