Разработка электроники,
Систем автоматики,
Программного обеспечения
ООО "Антех ПСБ",
Санкт-Петербург
+79811865082
anteh@bk.ru
05.01.2017 https://anteh.ru
Смысл затеи попробовать увеличить лояльность поисковиков к страницам сайта путём снижения трафика, через оптимизацию изображений jpg png gif, под клиентское разрешение. Речь в основном о мобильных пользователях. Исходные: есть компьютер с FreeBSD+Apache+virtual host сайт/сайты с картинками, всё работает как удалённый web сервер.
Если сразу по делу, то смотрим "Альтернатива Adaptive Images под Apache 2.4 FreeBSD 10.x"
Было испробовано несколько подходов для решения вопроса, но ни mod-pagespeed, ни существующий проект AdaptiveImages, под FreeBSD не подошли.
Первым был попробован, существующий более пяти лет, mod-pagespeed. Это открытый проект предлагаемый Google и работающий под CentOS/Fedora 32-bit и 64-bit, Debian/Ubuntu 32-bit и 64-bit. Если коротко, то под FreeBSD установить не удалось, ниже будут описаны причины. Затем было опробовано решение http://adaptive-images.com/ оно оказалось также непригодным, точнее под FreeBSD просто так оно не заработает, нужно поправлять php скрипт и адаптировать решение под virtual host.
По умолчанию порта нет. Он распространяется в виде бинарных файлов. Коротко установка выглядит так: Обновляемся до FreeBSD 10.3, устанавливаем emulators/linux_base-c7 64bit, archivers/rpm4, mod-pagespeed-stable_current_x86_64.rpm, настраиваем mod-pagespeed.
1. Качаем stable версию mod_pagespeed 64-bit .rpm (CentOS/Fedora) с https://developers.google.com/speed/pagespeed/module/download Для апача есть такие файлы:
mod_pagespeed 32-bit .deb (Debian/Ubuntu)
mod_pagespeed 64-bit .deb (Debian/Ubuntu)
mod_pagespeed 32-bit .rpm (CentOS/Fedora)
mod_pagespeed 64-bit .rpm (CentOS/Fedora)
2. Ставим /usr/ports/emulators/linux_base-c7 это CentOS 7.
По умолчанию linux_base-c7 ставится как 32bit, если нужно 64bit, то перед запуском установки, в /etc/make.conf прописываем:
DEFAULT_VERSIONS+=linux=c7_64
64bit ставится на FreeBSD начиная от 10.3 версии, поэтому ,сначала обновляемся до неё.
# freebsd-update -r 10.3-RELEASE upgrade ЕСЛИ ОНО НУЖНО
по ходу дела предлагается сделать merge через vi, выход с сохранением ESC + :wq. Затем:
# /usr/sbin/freebsd-update install
Перезапускаемся и снова:
# /usr/sbin/freebsd-update install
Установилась новая версия с ядром GENERIC. Правим ядро на своё и переустанавливаем. Есть рекомендация добавления в ядро, linux поддержки. Похоже, что для 64bit системы linux64 поддерживается по умолчанию, но если нужно включить поддержку 32bit, то используем опцию: options COMPAT_LINUX32 или LINUX32. Опции в ядро добавлять не нужно.
# cd /usr/src
# make buildkernel KERNCONF=Название вашего ядра
# make installkernel KERNCONF=Название вашего ядра
перезапускаемся. # uname -a, всё должно быть нормально
Устанавливаем linux_base-c7 64bit
# cd /usr/ports/emulators/linux_base-c7
#make clean на всякий, для перекомпиляции в 64bit, если ранее ставилась 32bit версия
#make && make install
В /etc/fstab прописываем:
linprocfs /compat/linux/proc linprocfs rw 0 0
tmpfs /compat/linux/dev/shm tmpfs rw,mode=1777 0 0
В /rc.conf прописываем:
linux_enable="YES"
перезагружаемся и проверяем, что нужные linux модули загружены:
# kldstat и наблюдаем наличие linprocfs.ko, linux_common.ko, tmpfs.ko, linux.ko, linux64.ko
3. Ставим порт archivers/rpm4
# cd /usr/ports/archivers/rpm4
#make clean
#make
#make install
перезагрузка
# cd /compat/linux
Устанавливаем mod-pagespeed-stable_current_x86_64.rpm:
# rpm -i --ignoreos --root /compat/linux --dbpath /var/lib/rpm /[путь]/mod-pagespeed-stable_current_x86_64.rpm
warning: /12/mod-pagespeed-stable_current_x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 7fac5991: NOKEY
error: Failed to resolve symbol syslog_hooks: Undefined symbol "nspr_use_zone_allocator"
error: error reading from file /12/mod-pagespeed-stable_current_x86_64.rpm
Проблема, как оказалась, была в необходимости скачивания некого ключа репозитария. Здесь https://www.google.com/linuxrepositories/ речь о нужном ключе 7fac5991.
Скачиваем linux_signing_key.pub, импортируем его:
# rpm --import linux_signing_key.pub
Segmentation fault (core dumped)
Очередная проблема с rpm. Вместо rpm используем rpm2cpio, но не порт, а команду. rpm2cpio устанавливает пакет в текущую директорию нахождения:
# cd /compat/linux
# rpm2cpio /12/mod-pagespeed-stable_current_x86_64.rpm | cpio -idmv
В /compat/linux будет распакованы необходимые файлы
4. В httpd.conf прописываем:
Include /compat/linux/etc/httpd/conf.d/pagespeed.conf
Include /compat/linux/etc/httpd/conf.d/pagespeed_libraries.conf
В файле /compat/linux/etc/httpd/conf.d/pagespeed.conf оставляем так:
LoadModule pagespeed_module /compat/linux/usr/lib64/httpd/modules/mod_pagespeed_ap24.so
<IfModule pagespeed_module>
...
</IfModule>
Другие строки в начале файла комментируем. Эти модули подгружаются в httpd.conf: mod_version.so, mod_access_compat.so и mod_deflate.so
Перезапускаем апач и Shared object "libm.so.6" not found, required by "mod_pagespeed_ap24.so"
Смотрим, где находится libm.so.6 и где производится поиск библтотек:
# find / -name libm.so.6
/compat/linux/lib64/libm.so.6
/compat/linux/lib/libm.so.6
/compat/linux/lib/i686/nosegneg/libm.so.6
...
Поиск библиотек производится в директориях:
# ldconfig -r
/var/run/ld-elf.so.hints:
search directories: /lib:/usr/lib:/usr/lib/compat:/usr/local/lib:/usr/local/lib/compat:/usr/local/lib/nss:/usr/local/lib/perl5/5.20/mach/CORE
Нужно добавить директорию /compat/linux/lib64/ в каталог поиска разделяемых библиотек.
Для добавления каталога с разделяемыми библиотеками в список поиска, нужно добавить путь к каталогу в переменную ldconfig_paths в файле /etc/rc.conf, или создать файл со списком каталогов в /usr/local/libdata/ldconfig.
в /etc/rc.conf добавляем: ldconfig_paths="/compat/linux/lib64"
Чтобы перечитать rc.conf без перезагрузки нужно перейти в однопользовательский режим, а затем обратно в многопользовательский.
# shutdown now
# return
# exit
Но это если не через SSH. Перезагружаемся. И проверяем:
# ldconfig -r
# apachectl restart
Cannot load /compat/linux/usr/lib64/httpd/modules/mod_pagespeed_ap24.so into server: /usr/lib/librt.so.1: version GLIBC_2.2.5 required by /compat/linux/usr/lib64/httpd/modules/mod_pagespeed_ap24.so not found
Посмотрим, какие библиотеки нужны mod_pagespeed_ap24.so:
Но чтобы не было ошибки, mod_pagespeed_ap24.so нужно отмаркировать Linux маркером:
# brandelf -t Linux my-linux-elf-binary
Проверить маркер:
# brandelf /путь/к/фпйлу
Важно, чтобы устанавливаемые файлы были отмаркированы brant Linux. Этот маркер определяет первоначальный путь, по которому будет производиться поиск необходимых библиотек. Для brandelf=linux поиск библиотек начинается с /compat/linux затем откуда обычно.
readelf -d /compat/linux/lib64/httpd/modules/mod_pagespeed_ap24.so
Dynamic section at offset 0x8c3060 contains 33 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
0x000000000000000e (SONAME) Library soname: [libmod_pagespeed_ap24.so]
Найдём их и поместим в одну директорию, которую пропишем через /etc/rc.conf + ldconfig_paths="/директория"
Проблема с модулем librt.so.1
С модулем по умолчанию:
# apachectl restart
Performing sanity check on apache24 configuration:
httpd: Syntax error on line 182 of /usr/local/etc/apache24/httpd.conf: Cannot load libexec/apache24/mod_pagespeed_ap24.so into server: /usr/lib/librt.so.1: version GLIBC_2.2.5 required by /usr/local/libexec/apache24/mod_pagespeed_ap24.so not found
С новым модулем из /compat/linux/lib64:
# apachectl restart
Performing sanity check on apache24 configuration:
httpd: Syntax error on line 182 of /usr/local/etc/apache24/httpd.conf: Cannot load libexec/apache24/mod_pagespeed_ap24.so into server: /usr/lib/librt.so.1: No space available for static Thread Local Storage
Список используемых mod_pagespeed_ap24.so библиотек:
*ld-2.17.so
@ld-linux-x86-64.so.2
*libc-2.17.so
@libc.so.6
*libgcc_s-4.8~50702.so.1
@libgcc_s.so.1
*libm-2.17.so
@libm.so.6
*libpthread-2.17.so
@libpthread.so.0
*librt-2.17.so
@librt.so.1
@libstdc++.so.6
*libstdc++.so.6.0.19
Снять флаг запрета удаления с @libm.so.6: # chflags noschg file_name
После полной настройки
# apachectl restart
Performing sanity check on apache24 configuration:
httpd: Syntax error on line 188 of /usr/local/etc/apache24/httpd.conf: Cannot load /compat/linux/usr/lib64/httpd/modules/mod_pagespeed_ap24.so into server: /usr/lib/librt.so.1: version GLIBC_2.2.5 required by /compat/linux/usr/lib64/httpd/modules/mod_pagespeed_ap24.so not found
После подмены библиотеки:
# apachectl restart
Performing sanity check on apache24 configuration:
httpd: Syntax error on line 188 of /usr/local/etc/apache24/httpd.conf: Cannot load /compat/linux/usr/lib64/httpd/modules/mod_pagespeed_ap24.so into server: /usr/lib/librt.so.1: No space available for static Thread Local Storage
Проблема в совместимости Linux и FreeBSD:
Linux has gone through two threading model changes. If a Linux application or library has been linked against the old pthreads without fast TLS support or pthreads with internal TLS support libraries it will segfault. This thread describes the threading situation under FreeBSD and Linux in detail: http://lists.freebsd.org/pipermail/freebsd-threads/2003-June/000530.html. This PR is a 2.6.16 stopper since it entirely prevents binaries/libraries compiled against an older Linux threading model from running. As long as this PR doesn't get resolved legacy code (2.4.2 emulation) cannot be removed.
Если приложение Linux или библиотека была связана с старыми Pthreads без быстрой поддержки TLS или Pthreads с внутренними библиотеками поддержки TLS будет сегментации
# apachectl restart
Performing sanity check on apache24 configuration:
Segmentation fault (core dumped)
# apachectl restart
Performing sanity check on apache24 configuration:
httpd: Syntax error on line 181 of /usr/local/etc/apache24/httpd.conf: Cannot load libexec/apache24/mod_pagespeed_ap24.so into server: /usr/lib/librt.so.1: No space available for static Thread Local Storage
Установить не удалось.
Если посмотреть предлагаемое на сайте описание по установке, то всё более чем просто. Оно так и есть, но не всегда. И часть этого "не всегда" здесь рассматривается.
Согласно инструкции, скачиваем архив на сервер, и из архива, в директорию DocumentRoot копируем 2 файла adaptive-images.php и .htaccess. Что за директория DocumentRoot смотрим в файле конфигурации апача httpd.conf. Директория для кешированных картинок будет создана автоматически скриптом adaptive-images.php. Дополнительно прав и владельцев на файлы и папку назначать не нужно.
Проверяем, чтобы в .../extra/httpd-default.conf, или в другом месте, был параметр "AccessFileName .htaccess" определяющий название htaccess файла, должно совпадать с названием того файла, который был скопирован .htaccess.
Разрешаем .htaccess файлы в DocumentRoot, для этого в httpd.conf должны быть такие параметры:
|
AllowOverride All разрешает .htaccess. Предполагается, что порты # cd /usr/ports/lang/php70, # cd /usr/ports/www/mod_php70 и # cd /usr/ports/graphics/php70-gd установлены и PHP работает. php70-gd ставим через php70-extensions. Также включён mod_rewrite, в httpd.conf раскомментированна строка LoadModule rewrite_module libexec/apache24/mod_rewrite.so. И проверяем, чтобы в виртуал хостах, если они используются, с AllowOverride и Options было всё впорядке. Т.е., чтобы этих опций там не было, либо Вы знаете, что делаете.
В header каждой страницы сайта добавляем:
|
Заливаем сайт, с отредактированными страницами на сервер, перезапускаем апач и должно заработать. По необходимости можем подредактировать adaptive-images.php, добавить например дополнительные разрешения для изображений.
Не заработало, при заходе на страницу, не отображалась ни одна картинка, это и плохо и хорошо. Хорошо, что .htaccess запускается, но картинок нет, неправильно работает adaptive-images.php. И действительно, при "ручном" запуске adaptive-images.php скрипта: /usr/local/bin/php /Doc/ument/Root/adaptive-images.php ошибок нет, но изначально отсутствующая директория кэша изображений не создаётся.
Выяснилось, что в файле adaptive-images.php не читается параметр $_SERVER['DOCUMENT_ROOT']; в строке: $document_root = $_SERVER['DOCUMENT_ROOT'];
Поскольку adaptive-images.php находится в DocumentRoot, то
строку "$document_root = $_SERVER['DOCUMENT_ROOT'];" меняем на "$document_root = dirname($_SERVER['PHP_SELF']);", причём в нескольких местах, в том числе в "function sendErrorImage($message)".
При запуске скрипта adaptive-images.php, директория /ai-cache в /Doc/ument/Root создалась, но всё равно ничего не работает, картинки со страниц сайта пропали. Скрипт по прежнему неправильно работает.
Проблема оказалась в том, что .php файл не учитывает ситуацию с Virtual host. .htaccess и adaptive-images.php должны находиться только в корне сайта. В adaptive-images.php "$document_root = $_SERVER['DOCUMENT_ROOT'];" обязательно меняем на "$document_root = dirname($_SERVER['PHP_SELF']);". Директорию /ai-cache в корневой директории сайта нужно создавать вручную, автоматическое создание не работает. Для /ai-cache права 0755, владельцем ставим владельца текущего сайта.
Ко всему, не работает строка RewriteRule \.(?:jpe?g|gif|png)$ adaptive-images.php в .htaccess, а именно не запускается php скрипт. .htaccsess был исключён и все настройки произведены в httpd.conf и конфигурации каждого из Virtual хостов. А обработка изображений, через запуск php скрипта, реализована через ExtFilterDefine.
Поправлена строка javascript скрипта находящегося в head каждой страницы сайта на:
|
Для того, чтобы работали cookies на сторона apache, нужно в httpd.conf разкомментировать: "LoadModule session_module libexec/apache24/mod_session.so" и либо для всех виртуал хостов в httpd.conf, либо для конкретного сайта в httpd-vhosts.conf включить "Session On".
После заливаем сайт на сервер и в браузере смотрим наличие отправленных Cookie:
Чтобы php принимал cookies от клиента и они были доступны через глобальный массив $_COOKIE, в php.ini, в пареметре variables_order должна присутствовать буква "C". $_REQUEST - массив содержащий внутри себя массивы $_GET, $_POST и $_COOKIE;
Проверяем принимает ли апач Cookie:
Команда вывести все куки print_r($_COOKIE); команда печати всего массива в файл file_put_contents('/path/file', print_r($_SERVER, true));
Поступления чего либо в $_COOKIE массив добиться не удалось. Было решено отказаться от $_COOKIE и информациб брать напрямую из заголовка. Далее используя mod_rewrite подменять соответствующее, заранее подготовленное изображение, в зависимости от разрешения. Другими словами решено не заморачиваться с проектом AdaptiveImages и разработать своё решение, о котором речь ниже. Удаляем всё, что связано с php. Здесь до конца не работающий adaptive-images.php скрипт с приведёнными выше измененимми, если кому нужно именно это решение, то дорабатывать будет проще.
Работает так: на каждой html странице сайта, в head размещается javascript скрипт определяющий разрешение экрана клиента. Информация добавляется в заголовог запрса страницы. Апач, через mod_rewrite, читает из заголовка запроса это разрешение и подменяет путь запроса изображения на альтернативный с уже перепакованным изображением, под соответствующее разрешение клиентского экрана. Изображения, под разные разрешения экранов переупаковываются заранее через соответствующий скрипт. Преимуществом подхода является использование только ImageMagik и mod_rewrite. Не нужен php, все изображения формируются заранее, не нужно нагружать сервер на перепаковку на горячую, хоть и однократную, не используется довольно ресурсоёмкий php скрипт. Ко всему скрипт добавляет watermark на каждое перепакованное изображение.
Ниже описан необходимый алгоритм действий для настройки, но некоторые несущественные млочи могут быть упущены:
1. Размещаем bash скрипт adaptimage_creator формирования изображений соответствующих разрешений где либо на сервере.
|
2. В httpd.conf в DocumentRoot Directory: Options None, AllowOverride None, но это не обязательно, важно, чтобы в директории virtual хоста, использующего адаптивную подмену изображений, было добавлено:
|
Важна опция Options FollowSymLinks. Регулярные выражения для диапазона цифр можно сформировать online http://gamon.webfactional.com/regexnumericrangegenerator/
Для каждого диапазона разрешений adaptimage_creator формирует свой набор перепакованных изображений.
3. На каждую страницу сайта, в head добавляем javascript:
|
4. Запускаем скрипт adaptimage_creator, и в корнях/корне сайтов/сайта, указанных в bash массиве DIR, формируются соответствующие папки /320 /480 /600 /800 /1024 /1280 с пережатыми изображениями. Или папки любых других разрешений, указанные в bash массиве разрешений Resolution. Если используем другие разрешения, то не забываем изменить mod_rewrite правила. Что менять, понятно из контекста самих правил.
5. Запускаем скрипт оптимизации сайта, описанный в этой статье. Этот скрипт не обязателен, он оптимизирует изображения, минифицирует css, js, очищает html.
Перезапускаем апач. По аналогии можно перепаковывать изображения под любые необходимые разрешения.
Приведённое решение можно отмасштабировать и переделать под свою задачу