Вы не зашли.
Главная » SQL » Выдача картинок с mysql с помощью nginx
#1. TLENS Off (14)
Moderator
2015.10.31 15:03
Есть ли такая возможность что бы не вмешивать в эту задачу php.
Перерыл интернет что то ничего не нашел на эту тему. Находил там работу nginx с mysql но совсем не понятно как реализовать данную задачу
#2. TLENS Off (14)
Moderator
2015.11.01 16:04
Уточню задачу. Нужно хранить картинки в базе так как при хранении просто на фс то сильно перегружается винт постоянно нагружен по максимуму и в следствии висит сайт.
Вот только как это реализовать что бы не давать еще нагрузку на php я хз. Хотя может и стоит это сделать через php. Хоть так хоть так изображение будет полностью выгружатся в память
#3. Gemorroj Off (107)
Administrator
2015.11.01 19:07
что-то я сомневаюсь, что нагрузка на винт большая из-за статики. много операций записи? имхо, настроить nginx с http кэшированием в большинстве случаев достаточно.
#4. TLENS Off (14)
Moderator
2015.11.07 03:03
В обьщем там кроме картинок на диске кешировались еще много файлов. И нагрузка на винт была постоянно на максимум. Переписал кеш на mysql плюс подключил memcache сайт начал летать.
Добавлено спустя   7 минут  55 секунд:
Кстати был прикол с этим хешем. Хотел удалить папку кеша >20млн. файлов(Дождался при подсчете этой цыфры потом полюнул может там и 100 лямов) и тупонул выполнив несколько раз удаление папок через nohup. В общем почему то решил ребутнуть сервер но после ребута при запуске вообще подвис так как кеш хранился в папке tmp и система начала ее чистить. Пришлось загружатся в режиме востановления и переименовывать папку))
Досихпор не могу вычистить /tmp2. Поспешил я с хранением кеша в файлах. Решил секономить время
#5. Gemorroj Off (107)
Administrator
2015.11.07 11:11
думаю, тут и mysql не лучшее решение. возможно, подошла бы какая-нибудь nosql база. например, couchdb. там можно сразу ссылку на файл в БД давать (встроенный http сервер), минуя nginx.
#6. TLENS Off (14)
Moderator
2015.11.07 20:08
Gemorroj написал:
думаю, тут и mysql не лучшее решение. возможно, подошла бы какая-нибудь nosql база. например, couchdb. там можно сразу ссылку на файл в БД давать (встроенный http сервер), минуя nginx.
Я так понял речь идет о картинках или весь кеш сайта предлагаешь хранить на этой базе?
Кеш картинок пока что не трогал. Сейчас винт нагружен примерно на 5-10%. Сейчас задача выдачи картинок стоит такова:
Получаем ссылку на оригинал картинки с базы данных далее загружаем ее через курл в память + imagecreatefromstring($data) пошаманим немного и сохраняем в файл после выдаем в браузер.
Далее этим занимается nginx смотрит есть ли картинка в кеше если есть выдает в браузер, нет перенаправляет на данный скрипт. Пока что там 240т. картинок. работает быстро. Просто тогда было очень много операций чтения записи
#7. Gemorroj Off (107)
Administrator
2015.11.08 12:12
так проблема в плохо оптимизированном php коде? ну так блин, с этого и начинал бы)
#8. TLENS Off (14)
Moderator
2015.11.08 15:03
Gemorroj написал:
так проблема в плохо оптимизированном php коде? ну так блин, с этого и начинал бы)
Не понял с чего ты взял что проблема в php. Была проблема из-за хранения данных на винте. вот функция кеша (старая)
Код:
span style="color: #0000BB"><?php private function _cacheVideoSet ($data, $id) { $fp = fopen($this->_dirInfoCache . $id . '.txt', 'c+'); if (!$fp) { file_put_contents($this->_errorLogFile, 'cacheVideoSet failed no open file['.__LINE__.']'."\n", FILE_APPEND); return false; } $old_data = ''; while (!feof($fp)) { $old_data .= fread($fp, 8192); } rewind($fp); if (!$old_data) { $data['expire'] = $_SERVER['REQUEST_TIME']; fputs($fp, serialize($data)); } else { $old_data = unserialize($old_data); if (!is_array($old_data)) { file_put_contents($this->_errorLogFile, 'cacheVideoSet unserialize ['.__LINE__.']: '. $str . "\n", FILE_APPEND); fputs($fp, serialize($data)); } else { if (@$data['title']) $old_data['title'] = $data['title']; /* if ($data['description']) $old_data['description'] = $data['description']; */ if ($data['img']) $old_data['img'] = $data['img']; if ($data['localIp']) { $old_data['localIp'] = $data['localIp']; } $old_data['errno'] = @$data['errno']; $old_data['expire'] = $_SERVER['REQUEST_TIME']; if (@$data['downLinks']) $old_data['downLinks'] = $data['downLinks']; fputs($fp, serialize($old_data)); } } fclose($fp); }
А вот новая
Код:
span style="color: #0000BB"><?phppublic function setVideosInfo($arrayData) { $insert = "INSERT INTO `$this->_INFO_TABLE_NAME` " . "(`id`, `title`, `description`, `duration`, `img`, `errno`, `expire`, `data`, `relative_ids`)\n"; $values = []; foreach ($arrayData as $data) { $id = "'{$data['id']}'"; $title = "'" .$this->_mysqli->real_escape_string($data['title']) . "'"; $description = "'" . $this->_mysqli->real_escape_string(@$data['description']) . "'"; $duration = $data['duration']; $img = "'" . $data['img'] . "'"; $errno = (int)@$data['errno']; $otherData = @$data['data'] ? "'".$this->_mysqli->real_escape_string(serialize($data['data']))."'" : "''"; if (@$data['data']['downLinks']) $expire = $_SERVER['REQUEST_TIME']; else $expire = 0; $relative_ids = "'" . $this->_mysqli->real_escape_string(@$data['relative_ids'])."'"; $values[] = "($id, $title, $description, $duration, $img, $errno, $expire, $otherData, $relative_ids)"; } $insert .= 'VALUES '. implode (",\n", $values) . "\n" . "ON DUPLICATE KEY UPDATE\n" . "`title` = COALESCE(VALUES(title), description),\n" . "`description` = COALESCE(VALUES(description), description),\n" . "`img` = COALESCE(VALUES(img), img),\n" . "`errno` = VALUES(errno),\n" . "`expire` = VALUES(expire),\n" . "`data`= COALESCE(VALUES(data), data)\n"; if ($result = $this->_mysqli->query($insert)) { //$result->close(); } else { //echo $this->_mysqli->error; //echo $insert; } //echo $insert; }
Добавлено спустя   5 минут  24 секунды:
Просто когда все данные хранились на тупо по файлах. То увеличивалось время доступа к каждому файлу по мере их накопления.
Сейчас работает все гораздо быстрее. А если ты имеешь в виду за получение картинок то вот функция.
Код:
span style="color: #0000BB"><?phppublic function previewAction($m, $id, $type) { $path_cache = '/tmp/previews/'; $path = "{$path_cache}{$m}_{$id}"; if (!is_dir($path_cache)) { if (mkdir($path_cache)) { log(__FILE__ . ': '. __LINE__); return $this->errorAction(Response::HTTP_INTERNAL_SERVER_ERROR); } chmod($path_cache, 0777); } $video = new \Video\Video($m .'_'.$id); $video->initById(); \CurlMulti::exec(true); if (@$video->getOriginalImg() == '/images/x_null.gif') { return $this->_getDefaultImage($type); } if (!$video->getOriginalImg()) { return $this->errorAction(Response::HTTP_NOT_FOUND); } $ch = curl_init($video->getOriginalImg()); $headers = array( 'Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language:ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4,uk;q=0.2,und;q=0.2', 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36', 'Connection: close'); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_ENCODING ,""); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $data = curl_exec($ch); $info = curl_getinfo($ch); $error = curl_error($ch); if ($info['http_code'] != 200 || $error || $info['content_type'] != 'image/jpeg') { log(__FILE__ . ': '. __LINE__); return $this->_getDefaultImage($type); } $src_img = imagecreatefromstring($data); $src_w = imagesx($src_img); $src_h = imagesy($src_img); // исходное соотношение //$src_rate = $src_w / $src_h; // необходимое соотношение $dst_rate = 1.777777777777778; // ширина нового изображения $dst_w = $src_w < 320 ? $src_w : 320; // высота результата $dst_h = round($dst_w / $dst_rate); // новая высота оригинала $src_h_new = $src_w / $dst_rate; // отступы вырезаемой части $src_indent = round(($src_h - $src_h_new) / 2); $src_x = 0; $src_y = $src_indent; // отступы результата $dst_x = 0; $dst_y = 0; $img_hq = imagecreatetruecolor($dst_w, $dst_h); // копируем прямоугольник imagecopyresampled($img_hq, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h_new); imagedestroy($src_img); imagejpeg($img_hq, "{$path}_HQ.jpg"); // create mq image $mq_w = 128; $mq_h = $mq_w/$dst_rate; $img_mq = imagecreatetruecolor($mq_w, $mq_h); imagecopyresampled($img_mq, $img_hq, 0, 0, 0, 0, $mq_w, $mq_h, $dst_w, $dst_h); imagejpeg($img_mq, "{$path}_MQ.jpg"); $response = new Response(); switch($type) { case 'HQ': ob_start(); imagejpeg($img_hq); $response->setContent(ob_get_clean()); $response->headers->set('Content-Type', image_type_to_mime_type(IMAGETYPE_JPEG)); $response->setStatusCode = 200; break; case 'MQ': ob_start(); imagejpeg($img_mq); $response->setContent(ob_get_clean()); $response->setStatusCode = 200; $response->headers->set('Content-Type', image_type_to_mime_type(IMAGETYPE_JPEG)); break; default: return $this->errorAction(404); } imagedestroy($img_hq); imagedestroy($img_mq); return $response; }
#9. TLENS Off (14)
Moderator
2015.11.08 15:03
Можно было бы и выдавать картинку после сохранения с помощью nginx передав заголовок X-Accel-Redirect но хз че так не сделал. Может посчитал лишним.


Ну и собственно выдача в nginx
Код:
location ~* "^/(.*)/(HQ|MQ).jpg$" {
set $imageType $2;
set_escape_uri $imageName $1;
set $slash '_';
set $path $imageName$slash$imageType.jpg;
root /tmp/previews/;
if (-f /tmp/previews/$path) {
expires 3d;
rewrite (.*) /$path break;
}
rewrite (.*) /$path last;
}
#10. Gemorroj Off (107)
Administrator
2015.11.10 13:01
у тебя все файлы в 1 папке были? возможно проблема в этом
Страниц: 1 2 Все
Главная
WEB
PunBB Mod v0.6.2
0.032 s