форум vBSupport.ru > vBSupport.ru > How-Tos, Hints & Tips > Статьи, обзоры, каталоги
Register Меню vBsupport Изображения Files Manager О рекламе Today's Posts Search
  • Родная гавань
  • Блок РКН снят
  • Premoderation
  • For English speaking users
  • Каталог Фрилансеров
  • If you want to buy some product or script
  • Администраторам
VBsupport перешел с домена .ORG на родной .RU Ура! Пожалуйста, обновите свои закладки - VBsupport.ru
Блок РКН снят, форум доступен на всей территории России, включая новые терртории, без VPN
На форуме введена премодерация ВСЕХ новых пользователей

Почта с временных сервисов, типа mailinator.com, gawab.com и/или прочих, которые предоставляют временный почтовый ящик без регистрации и/или почтовый ящик для рассылки спама, отслеживается и блокируется, а так же заносится в спам-блок форума, аккаунты удаляются
for English speaking users:
You may be surprised with restriction of access to the attachments of the forum. The reason is the recent change in vbsupport.org strategy:

- users with reputation < 10 belong to "simple_users" users' group
- if your reputation > 10 then administrator (kerk, Luvilla) can decide to move you into an "improved" group, but only manually

Main idea is to increase motivation of community members to share their ideas and willingness to support to each other. You may write an article for the subject where you are good enough, you may answer questions, you may share vbulletin.com/org content with vbsupport.org users, receiving "thanks" equal your reputation points. We should not only consume, we should produce something.

- you may:
* increase your reputation (doing something useful for another members of community) and being improved
* purchase temporary access to the improved category:
10 $ for 3 months. - this group can download attachments, reputation/posts do not matter.
20 $ for 3 months. - this group can download attachments, reputation/posts do not matter + adds eliminated + Inbox capacity increased + files manager increased permissions.

Please contact kerk or Luvilla regarding payments.

Important!:
- if your reputation will become less then 0, you will be moved into "simple_users" users' group automatically.*
*for temporary groups (pre-paid for 3 months) reputation/posts do not matter.
Уважаемые пользователи!

На форуме открыт новый раздел "Каталог фрилансеров"

и отдельный раздел для платных заказов "Куплю/Закажу"

Если вы хотите приобрести какой то скрипт/продукт/хак из каталогов перечисленных ниже:
Каталог модулей/хаков
Ещё раз обращаем Ваше внимание: всё, что Вы скачиваете и устанавливаете на свой форум, Вы устанавливаете исключительно на свой страх и риск.
Сообщество vBSupport'а физически не в состоянии проверять все стили, хаки и нули, выкладываемые пользователями.
Помните: безопасность Вашего проекта - Ваша забота.
Убедительная просьба: при обнаружении уязвимостей или сомнительных кодов обязательно отписывайтесь в теме хака/стиля
Спасибо за понимание
 
 
 
 
adamsadriane
Продвинутый
Post Настройка связки apache + rpaf + nginx + mySQL + apf. Отдача статики через nginx
10

Здравствуйте.
Первый пост дополнен. Остальные можете не учитывать.
Описываю настройку сервера для высоконагруженных форумов.
Задача: максимально уменьшить нагрузку на систему при максимальном количестве пользователей.
Исходная система: CentOS.
Предустановленная панель управления сервером: ISPManager
Версия веб-сервера: Apache 2.x
Версия сервера БД: MySQL 5.5.х
Версия веб-сервера nginx 1.x
Дополнительно:
- система кэширования xcache;
- advanced policy firewall (apf).
Замечание: отключаем всё логирование; где возможно – переносим папки на tmpfs.
Конфиг apache:
- основной (/etc/httpd/conf):
Code:
 
ServerTokens OS
ServerRoot "/etc/httpd"
PidFile run/httpd.pid
Timeout 65
KeepAlive Off
MaxKeepAliveRequests 0
KeepAliveTimeout  15
<IfModule prefork.c>
StartServers       8
MinSpareServers    5
MaxSpareServers   20
ServerLimit      256
MaxClients       256
MaxRequestsPerChild  4000
</IfModule>

<IfModule worker.c>
StartServers         8
ServerLimit      400
MaxClients         1000
MinSpareThreads     25
MaxSpareThreads     200 
ThreadsPerChild     25
MaxRequestsPerChild  0
</IfModule>
Listen 8081 #Сервер Apache слушает порт 8081, куда перебрасывает запросы динамических файлов nginx, который, в свою очередь, слушает дефолтный порт 80.

# Для отображения реальных ip пользователей мы используем модуль rpaf.
# Страница с модулем: http://stderr.net/apache/rpaf/
LoadModule rpaf_module modules/mod_rpaf-2.0.so
RPAFenable On
RPAFsethostname On
RPAFproxy_ips ip_вашего_сервера

LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_owner_module modules/mod_authz_owner.so
LoadModule include_module modules/mod_include.so 
LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule mime_module modules/mod_mime.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule vhost_alias_module modules/mod_vhost_alias.so
LoadModule dir_module modules/mod_dir.so
LoadModule actions_module modules/mod_actions.so
LoadModule userdir_module modules/mod_userdir.so
LoadModule alias_module modules/mod_alias.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule cache_module modules/mod_cache.so
LoadModule suexec_module modules/mod_suexec.so
#Модуль кэширования в оперативную память:
LoadModule mem_cache_module modules/mod_mem_cache.so
<IfModule mod_mem_cache.c>
 CacheEnable mem /
 MCacheSize 4096000 #объём кэша в оперативной памяти, КБ.
 MCacheMaxObjectCount 100000 # максимально возможное количество объектов в кэше, шт.
 MCacheMinObjectSize 1# минимальный размер объекта в кэше, байт.
 MCacheMaxObjectSize 20480000 # максимальный размер объекта в кэше, байт.
 CacheIgnoreCacheControl On # игнорировать факт некеширования на стороне клиента.
 CacheMaxExpire 604800 #максимальное время жизни объекта в кэше.
 CacheStorePrivate On #кэшировать ответы private.
 </IfModule>


LoadModule cgi_module modules/mod_cgi.so
Include conf.d/*.conf
ExtendedStatus On # чтобы работал server-status: 127.0.0.1:8081/server-status Тут мы сможем наблюдать то, как упал трафик Apache с отдачей вложений через nginx
Конфигурационный файл fcgid.conf (/etc/httpd/conf.d):
Code:
LoadModule fcgid_module modules/mod_fcgid.so
AddHandler fcgid-script fcg fcgi fpl
FcgidIPCDir /var/run/mod_fcgid
FcgidProcessTableFile /var/run/mod_fcgid/fcgid_shm
          FcgidMaxRequestsPerProcess 5000 # максимальное количество запросов на каждый процесс, шт.
          FcgidFixPathinfo 1
          FcgidIdleTimeout 36 # тайм-аут, сек.
          FcgidProcessLifeTime 72 # время жизни каждого процесса, сек.
          FcgidBusyTimeout 14 # время жизни занятых процессов.
          FcgidInitialEnv RAILS_ENV production # имя переменной окружения.
          FcgidIOTimeout 60 # таймаут передачи в приложение FastCGI, сек.
          FcgidMaxProcessesPerClass 5000 # максимальное количество процессов одного класса приложения FastCGI, шт.
          FcgidMinProcessesPerClass 1 # минимальное количество процессов одного класса приложения FastCGI, шт.
        FcgidMaxRequestInMem 8G # максимальный размер запроса, который будет сохранен в памяти, байт. Ставьте 25% от ОЗУ.
        FcgidMaxRequestLen 5120000000 # максимальная длина запроса HTTP, байт. Ставьте примерно 128М.
        FcgidOutputBufferSize 8G # размер буфера вывода CGI, байт. Ставьте 25% ОЗУ.
XCache.
Дистрибутив: http://xcache.lighttpd.net/
Конфигурационный файл xcache.ini (/etc/php.d):
Code:
[xcache-common]
zend_extension = /usr/lib64/php/modules/xcache.so #путь у установленному xcache
[xcache.admin]
xcache.admin.enable_auth = Off
xcache.admin.user = "Ваш_логин"
; xcache.admin.pass = md5($your_password)
xcache.admin.pass = "сгенерированный_md5_пароль"

[xcache]
xcache.shm_scheme =        "mmap"
xcache.size  =               3072M # размер кэша. Ставьте, если позволяет ОЗУ, не менее 128М.
xcache.count =                 8 # число потоков
xcache.slots =                64K
xcache.ttl   =                 0
xcache.gc_interval =           0
xcache.var_size  =            64M
xcache.var_count =             1
xcache.var_slots =            64K
xcache.var_ttl   =             0
xcache.var_maxttl   =          0
xcache.var_gc_interval =     300
xcache.test =                Off
xcache.readonly_protection = Off
xcache.mmap_path =    "/dev/zero"
xcache.coredump_directory =   ""
xcache.cacher =               On
xcache.stat   =               On
xcache.optimizer =           Off
[xcache.coverager]
xcache_coverager_start/stop/get/clean() functions (will hurt executing performance)
xcache.coverager =          Off
xcache.coveragedump_directory = ""
Конфигурационный файл my.cnf (/etc/):
Code:
[mysqld]
datadir=/var/lib/mysql
tmpdir=/var/mysqltmp # директория с временными файлами.
socket=/var/lib/mysql/mysql.sock
init_file=/var/lib/mysql/start.sql
character-set-server = utf8 # кодировка сервера БД. 
user=mysql
default-storage-engine=MYISAM # выбираем это, для более быстрой скорости
symbolic-links=0
skip-external-locking
key_buffer_size = 8G # 25% ОЗУ.
max_allowed_packet = 1G # 10% ОЗУ.
table_cache = 8192
max_tmp_tables = 8192
sort_buffer_size = 10G # 25% ОЗУ.
read_buffer_size = 2000M # 10% ОЗУ.
read_rnd_buffer_size = 256K
net_buffer_length = 2K
thread_stack = 128K
query_cache_size=10G # 25% ОЗУ.
query_cache_limit=1G # 10%, но не менее 32М.
query_cache_type=1

join_buffer_size = 4294967295 # 10% ОЗУ.
tmp_table_size=6G # 15% ОЗУ.
max_heap_table_size=6G # 15% ОЗУ.
max_user_connections=15000
myisam_sort_buffer_size = 4294967295 # 10% ОЗУ.
max_connections = 15000
thread_cache_size = 120

innodb_data_home_dir              = /var/lib/mysql
innodb_data_file_path             = ibdata1:10M:autoextend
innodb_file_per_table
innodb_buffer_pool_size           = 10G		
innodb_additional_mem_pool_size   = 32M
innodb_max_dirty_pages_pct        = 80
innodb_lock_wait_timeout          = 50
innodb_flush_method               = O_DIRECT
innodb_thread_concurrency         = 32
innodb_autoinc_lock_mode = 1
innodb_fast_shutdown              = 1
innodb_max_purge_lag              = 0
 [mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
connect-string="nodeid=2;host=localhost:1186"
[ndb_mgm]
connect-string="host=localhost:1186"
Конфигурационный файл nginx (/usr/local/nginx/conf):
Code:
#user www www;
worker_processes 12; #ставьте по сумме ядер процессоров
timer_resolution 100ms;
worker_priority -20; # ставим максимальный приоритет для nginx
error_log         off; # отключаем этот лог
pid        logs/nginx.pid;
events {
    worker_connections  4000; # максимальное число соединений
use epoll;
    multi_accept on;
}
http {
server_tokens off;
limit_req_zone  $binary_remote_addr  zone=one:10m rate=5r/s; #устанавливайте нужно вам ограничение на количество запросов в секунду с одного хоста.
include       mime.types;
 default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] $request '
                      '"$status" $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log off; # и этот лог отключаем
    sendfile        on;
    tcp_nopush     on;
    tcp_nodelay on;
    keepalive_timeout  65; # ставим максимально возможное время тайм-аута
reset_timedout_connection on; 
    gzip  on; # включаем сжатие (и выключаем в cp форума).
    gzip_min_length 10; # минимальный размер объекта сжатия, байт. 
    gzip_buffers 64 8k;
    gzip_comp_level 9; # ставим максимальный уровень сжатия
    gzip_http_version 1.1;
    gzip_proxied any; 
    gzip_types text/plain application/xml application/x-javascript text/css text/xml text/javascript; # перечисляем типы сжимаемых данных
    server {
    listen        ip_вашего_сервера:80; #не забывайте указать порт 80 для прослушивания
    server_name ~^(www\.)?(?<name>.*)$; # позволяет серверу отдавать данные и от доменов с www, и без них, в папках без www
    access_log off; # и этот лог выключаем
     location / {
limit_req   zone=one  burst=7; # устанавливаете пиковое количество запросов для одного хоста, если превышено первое условие максимального регулярного количества хостов
limit_rate 5000k; #устанавливаете максимальную полосу отдачи для каждого хоста. 
            proxy_pass         http://ip_вашего_сервера:8081; #не забывайте о порте 8081
            proxy_redirect off;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            client_max_body_size       1024m; # устанавливаете по величине post_max_size из php.ini т.к. , при меньшем значении client_max_body_size, не будет возможности загружать вложения, размером более client_max_body_size.
            client_body_buffer_size    128K;
# три значения ниже аналогичны таковым в директиве keepalive_timeout
            proxy_connect_timeout      65; 
            proxy_send_timeout         65;
            proxy_read_timeout         65;
            proxy_buffer_size          4k;
            proxy_buffers              4 32k;
            proxy_busy_buffers_size    64k;
            proxy_ignore_client_abort on;
        }
#Static files location
       location ~* ^.+\.(jpg|jpeg|gif|png|zip|tgz|gz|rar|bz2|xls|exe|pdf|ppt|txt|tar|wav|mp3|bmp|rtf|flv|swf|avi|mp4|chm|djvu|chm|exe)$ {  #перечисляете все типы статических файлов, которые у вас имеются
 expires max;  #задаём время жизни кэша для них. Здесь выбран максимальный срок.
           add_header Cache-Control public;
           root  /путь_к_папке_с_сайтом_на_сервере/$name;
        }
# Ниже делаем отдачу вложений локальной (для предотвращения показа изображений или скачивания файлов не из вашего сайта
location = /uploads/attachments  { #путь_к_папке_с_вложениями
                   root  /путь_к_папке_с_доменами_на_сервере/$name; 
                  internal; 
                 }
#задаём время жизни кэша для разных типов файлов на форуме (в предыдущем случае мы делали обобщающее правило для статики)
location ~* /uploads/attachments/(.*)\.thumb$ {
    expires max;
root  / путь_к_папке_с_доменами_на_сервере /$name; 
}
location /images/ {
    expires max;
root  / путь_к_папке_с_доменами_на_сервере /$name; 
}
location /clientscript/ {
    expires max;
root  / путь_к_папке_с_доменами_на_сервере /$name; 
}         
    }
}
Конфигурационные файлы apf (/etc/apf):
-allow_hosts.rules:
Code:
127.0.0.1
IP_вашего_сервера
-config.apf (здесь настраиваете нужные вам порты т.к. сорс файла большой для приведения примера).
Установка nginx:
Диструбутив nginx: http://nginx.org/ru/download.html
Дистрибутив pcre: http://www.pcre.org/
Дистрибутив zlib: http://zlib.net/
Code:
./configure --prefix=/usr/local/nginx --with-http_gzip_static_module --without-http_charset_module --without-http_ssi_module --without-http_userid_module --without-http_access_module --without-http_auth_basic_module --without-http_empty_gif_module --with-pcre=/путь к pcre на сервере/pcre-8.12(номер версии pcre) --with-zlib=/путь к zlib на сервере/zlib-1.2.5(номер версии zlib)
make
make test
make install
Создаём в папках с временными файлами tmpfs диски командой:
mount -t tmpfs -o size=размер_диска_tmpfs,nr_inodes=10k,mode=0775,noatime,nodiratime путь_куда_монтировать
Code:
Например, mount -t tmpfs -o size=1G,nr_inodes=10k,mode=0775,noatime,nodiratime tmpfs /tmp
Папки, с которыми нужно проделать предыдущее:
- временные данные MySQL (смотрим переменную tmpdir в my.cnf);
- временные файлы сервера (обычно директория /tmp);
- логи Apache;
- сессии php;
- временные файлы nginx:
--/путь_к_nginx/nginx/proxy_temp
--/путь_к_nginx/nginx/client_body_temp
После этого добавить в fstab монтирование tmpfs при загрузке в предыдущие папки командой вида:
Code:
 /dev/ramdisk            /путь_к_папке   tmpfs   defaults        0 0

Source и инструкция по установке модуля vb accelerator (который даёт настроить отдачу через nginx быстро):
Инструкция по установке: сохраняете в xml код и импортируете на форум. Всё.
Код модуля (версия 0.7):
Code:
<?xml version="1.0" encoding="ISO-8859-1"?>

<product productid="vb_accelerator" active="1">
<title>vB Accelerator</title>
<description>Optimise attachments processing</description>
<version>0.9</version>
<url><![CDATA[http://www.vbulletin.org/forum/misc.php?do=producthelp&pid=vb_accelerator]]></url>
<versioncheckurl><![CDATA[http://www.vbulletin.org/forum/misc.php?do=productcheck&pid=vb_accelerator]]></versioncheckurl>
<apm_releasedate>0</apm_releasedate>
<apm_author />
<apm_relatedurl />
<apm_extrainfo />
<apm_extraedit />
<dependencies>
</dependencies>
<codes>
<code version="0.7">
<installcode><![CDATA[$db->hide_errors();
$db->query_write("ALTER TABLE " . TABLE_PREFIX . "attachment ADD INDEX `vba_coverage` ( `attachmentid` , `filedataid` , `userid` ) ");
$db->show_errors();]]></installcode>
<uninstallcode><![CDATA[$db->hide_errors();
$db->query_write("ALTER TABLE " . TABLE_PREFIX . "attachment DROP INDEX vba_coverage");
$db->show_errors();]]></uninstallcode>
</code>
</codes>
<templates>
</templates>
<stylevardfns>
</stylevardfns>
<stylevars>
</stylevars>
<plugins>
<plugin active="1" executionorder="5">
<title>Accelerate fullsize attachments downloads</title>
<hookname>attachment_display</hookname>
<phpcode><![CDATA[if ( $vbulletin->options['vb_acc_nginx'])
{
@fclose($fp);

require_once(DIR . '/includes/functions_file.php');

$attachuri = fetch_attachment_path(
$attachmentinfo['uploader'],
$attachmentinfo['filedataid'],
(bool)$vbulletin->GPC['thumb'],
$vbulletin->options['vb_acc_www_path_posts']
);

header('X-Accel-Redirect: ' . $attachuri);

// update views counter
if ( !$vbulletin->GPC['thumb']
AND connection_status() == 0
AND $lastbyte == ($attachmentinfo['filesize'] - 1))
{
if ($vbulletin->options['attachmentviewslive'])
{
// doing it as they happen; not using a DM to avoid overhead
$db->query_write("
UPDATE " . TABLE_PREFIX . "attachment SET
counter = counter + 1
WHERE attachmentid = $attachmentinfo[attachmentid]
");
}
else
{
// or doing it once an hour
$db->query_write("
INSERT INTO " . TABLE_PREFIX . "attachmentviews (attachmentid)
VALUES ($attachmentinfo[attachmentid])
");
}
}

exit;
}]]></phpcode>
</plugin>
<plugin active="1" executionorder="2">
<title>Replace Thumbnails Links for HTML</title>
<hookname>global_complete</hookname>
<phpcode><![CDATA[// this hook must eval before VBSeo

if (!isset($cdn_list))
{
$vbulletin->options['vb_acc_cdn_list'] = trim($vbulletin->options['vb_acc_cdn_list']);
if (!empty($vbulletin->options['vb_acc_cdn_list']))
{
$cdn_list = explode("\n", $vbulletin->options['vb_acc_cdn_list']);
$cdn_list = array_map('trim', $cdn_list);
foreach ($cdn_list as $key=>$cdn)
{
if ('/' == $cdn[strlen($cdn)-1])
{
$cdn_list[$key] = substr($cdn, 0, -1);
}
}
}
else
{
$cdn_list[] = $vbulletin->options['bburl'];
}
}


// Only procees if "attachment.php" exists in output html
if (strpos($output, 'attachment.php'))
{
// get thumbnails list
$pattern = '#src=\"((?:' . preg_quote($vbulletin->options['bburl'] . '/') . ')?' . 'attachment.php\?' . preg_quote("{$vbulletin->session->vars['sessionurl']}") . 'attachmentid=(\d+)[\w:\d&=;]*thumb=1[\w:\d&=;]*)\"#';
preg_match_all($pattern, $output, $matches, PREG_SET_ORDER);

$attachment_ids = array();
$attachments = array();
$transformed_attachments = array();
foreach ($matches as $val) {
list( , $url,$attachment_id) = $val;
$attachment_ids[] = $attachment_id;
$attachments[$attachment_id] = $url;
$transformed_attachments[$attachment_id] = $url;
}

if (!empty($attachment_ids))
{
require_once(DIR . '/includes/functions_file.php');

// todo maybe add index to "attachment" table?
$sql = 'SELECT
a.attachmentid, a.filedataid, fd.userid as uploader
FROM ' . TABLE_PREFIX . 'attachment AS a
INNER JOIN ' . TABLE_PREFIX . 'filedata AS fd USING (filedataid)
WHERE
a.attachmentid IN (' . implode(', ', $attachment_ids) . ')';

$result = $vbulletin->db->query_read($sql);
$position = 0;
while ($row = $vbulletin->db->fetch_array($result))
{
$path = $cdn_list[$position] . $vbulletin->options['vb_acc_www_path_posts'];
// extract timestamp
preg_match('#&amp;d=(\d+)#', $transformed_attachments[$row['attachmentid']], $timestamp);
$transformed_attachments[$row['attachmentid']]= fetch_attachment_path(
$row['uploader'],
$row['filedataid'],
true,
$path
) . '?d='. $timestamp[1];
$position = ++$position % count($cdn_list);
}
}
// replace old thumb attachements links
if (!empty($attachments))
{
$output = str_replace($attachments, $transformed_attachments, $output);
}
}

// Only procees if "asset.php" exists in output html
if (strpos($output, 'asset.php'))
{
require_once(DIR . '/includes/functions_file.php');

// get thumbnails list
$pattern = '#src=\"(asset.php\?' . preg_quote("{$vbulletin->session->vars['sessionurl']}") . 'fid=(\d+)&amp;uid=(\d+)&amp;d=(\d+))\"#';
preg_match_all($pattern, $output, $matches, PREG_SET_ORDER);

$attachment_ids = array();
$attachments = array();
$transformed_attachments = array();
$position = 0;
foreach ($matches as $val) {
list( , $url,$attachment_fid,$attachment_uid,$attachment_timestamp) = $val;
$attachments[$attachment_fid] = $url;
$path = $cdn_list[$position] . $vbulletin->options['vb_acc_www_path_posts'];
$transformed_attachments[$attachment_fid]= fetch_attachment_path(
$attachment_uid,
$attachment_fid,
true,
$path
) . '?d=' . $attachment_timestamp;
$position = ++$position % count($cdn_list);
}

// replace thumb links
if (!empty($attachments))
{
$output = str_replace($attachments, $transformed_attachments, $output);
}
}]]></phpcode>
</plugin>
<plugin active="1" executionorder="2">
<title>Replace Thumbnails Links for XML</title>
<hookname>xml_print_output</hookname>
<phpcode><![CDATA[// this hook must eval before VBSeo
global $vbulletin;

if (!isset($cdn_list))
{
$vbulletin->options['vb_acc_cdn_list'] = trim($vbulletin->options['vb_acc_cdn_list']);
if (!empty($vbulletin->options['vb_acc_cdn_list']))
{
$cdn_list = explode("\n", $vbulletin->options['vb_acc_cdn_list']);
$cdn_list = array_map('trim', $cdn_list);
foreach ($cdn_list as $key=>$cdn)
{
if ('/' == $cdn[strlen($cdn)-1])
{
$cdn_list[$key] = substr($cdn, 0, -1);
}
}
}
else
{
$cdn_list[] = $vbulletin->options['bburl'];
}
}


// Only procees if "attachment.php" exists in output html
if (strpos($this->doc, 'attachment.php'))
{
// get thumbnails list
$pattern = '#src=\"((?:' . preg_quote($vbulletin->options['bburl'] . '/') . ')?' . 'attachment.php\?' . preg_quote("{$vbulletin->session->vars['sessionurl']}") . 'attachmentid=(\d+)[\w:\d&=;]*thumb=1[\w:\d&=;]*)\"#';
preg_match_all($pattern, $this->doc, $matches, PREG_SET_ORDER);

$attachment_ids = array();
$attachments = array();
$transformed_attachments = array();
foreach ($matches as $val) {
list( , $url,$attachment_id) = $val;
$attachment_ids[] = $attachment_id;
$attachments[$attachment_id] = $url;
$transformed_attachments[$attachment_id] = $url;
}

if (!empty($attachment_ids))
{
require_once(DIR . '/includes/functions_file.php');

// todo maybe add index to "attachment" table?
$sql = 'SELECT
a.attachmentid, a.filedataid, fd.userid as uploader
FROM ' . TABLE_PREFIX . 'attachment AS a
INNER JOIN ' . TABLE_PREFIX . 'filedata AS fd USING (filedataid)
WHERE
a.attachmentid IN (' . implode(', ', $attachment_ids) . ')';

$result = $vbulletin->db->query_read($sql);
$position = 0;
while ($row = $vbulletin->db->fetch_array($result))
{
$path = $cdn_list[$position] . $vbulletin->options['vb_acc_www_path_posts'];
// extract timestamp
preg_match('#&amp;d=(\d+)#', $transformed_attachments[$row['attachmentid']], $timestamp);
$transformed_attachments[$row['attachmentid']]= fetch_attachment_path(
$row['uploader'],
$row['filedataid'],
true,
$path
) . '?d='. $timestamp[1];
$position = ++$position % count($cdn_list);
}
}
// replace old thumb attachements links
if (!empty($attachments))
{
$this->doc = str_replace($attachments, $transformed_attachments, $this->doc);
}
}

// Only procees if "asset.php" exists in output html
if (strpos($this->doc, 'asset.php'))
{
require_once(DIR . '/includes/functions_file.php');

// get thumbnails list
$pattern = '#src=\"(asset.php\?' . preg_quote("{$vbulletin->session->vars['sessionurl']}") . 'fid=(\d+)&amp;uid=(\d+)&amp;d=(\d+))\"#';
preg_match_all($pattern, $this->doc, $matches, PREG_SET_ORDER);

$attachment_ids = array();
$attachments = array();
$transformed_attachments = array();
$position = 0;
foreach ($matches as $val) {
list( , $url,$attachment_fid,$attachment_uid,$attachment_timestamp) = $val;
$attachments[$attachment_fid] = $url;
$path = $cdn_list[$position] . $vbulletin->options['vb_acc_www_path_posts'];
$transformed_attachments[$attachment_fid]= fetch_attachment_path(
$attachment_uid,
$attachment_fid,
true,
$path
) . '?d=' . $attachment_timestamp;
$position = ++$position % count($cdn_list);
}

// replace thumb links
if (!empty($attachments))
{
$this->doc = str_replace($attachments, $transformed_attachments, $this->doc);
}
}]]></phpcode>
</plugin>
</plugins>
<phrases>
<phrasetype name="vBulletin Settings" fieldname="vbsettings">
<phrase name="setting_vb_acc_cdn_list_desc" date="1276075558" username="Vitaly" version="0.6"><![CDATA[Enter up to 4 mirror domains, to load local images faster. For example:<br>
<br>
http://img1.myforum.com<br>
http://img2.myforum.com<br>
http://img3.myforum.com<br>
http://img4.myforum.com<br>
<br>
If don't use mirrors - leave this field blank or set to forum domain.]]></phrase>
<phrase name="setting_vb_acc_cdn_list_title" date="1276075558" username="Vitaly" version="0.6"><![CDATA[CDN list]]></phrase>
<phrase name="setting_vb_acc_nginx_desc" date="1236190598" username="Vitaly" version="0.2"><![CDATA[ONLY set yes, if you have NGINX websever!!!<br /> <br /> Other webservers don't catch X-Accel-Redirect headers!!!]]></phrase>
<phrase name="setting_vb_acc_nginx_title" date="1236190598" username="Vitaly" version="0.2"><![CDATA[Enable large downloads acceleration]]></phrase>
<phrase name="setting_vb_acc_www_path_posts_desc" date="1275476288" username="varnak" version="0.4"><![CDATA[Relative web-server URI to attachments directory. No trailing slash allowed.]]></phrase>
<phrase name="setting_vb_acc_www_path_posts_title" date="1275476288" username="varnak" version="0.4"><![CDATA[Path to attachments]]></phrase>
<phrase name="settinggroup_vb_accelerator" date="1236189322" username="Dimit" version="0.2"><![CDATA[vB Accelerator]]></phrase>
</phrasetype>
</phrases>
<options>
<settinggroup name="vb_accelerator" displayorder="65535">
<setting varname="vb_acc_www_path_posts" displayorder="10">
<datatype>free</datatype>
<defaultvalue>/uploads</defaultvalue>
</setting>
<setting varname="vb_acc_cdn_list" displayorder="20">
<datatype>free</datatype>
<optioncode>textarea</optioncode>
</setting>
<setting varname="vb_acc_nginx" displayorder="30">
<datatype>boolean</datatype>
<optioncode>yesno</optioncode>
<defaultvalue>0</defaultvalue>
</setting>
</settinggroup>
</options>
<helptopics>
</helptopics>
<cronentries>
</cronentries>
<faqentries>
</faqentries>
<templateedits>
</templateedits>
</product>
Пока можете задавать вопросы.
С уважением.

Last edited by adamsadriane : 10-18-2011 at 09:37 PM.
Bot
Yandex Bot Yandex Bot is online now
 
Join Date: 05.05.2005
Реклама на форуме А что у нас тут интересного? =)
 
 
netwind
Гуру
 
netwind's Avatar
Default
0

Quote:
Originally Posted by adamsadriane View Post
Пока можете задавать вопросы.
А зачем ты указываешь конкретные значения параметров для весьма нехилого сервера?

Просто под "высоконагруженным проектом" люди обычно понимают свой унылый VPS на 512Мб памяти, из которого они хотят выжать все соки - высоко нагрузить.
Вот возмут они твои конфиги с key_buffer_size = 8G, query_cache_size=10G, innodb_buffer_pool_size = 10G, поставят себе и все это благополучно уйдет в своп и помрет.
 
 
adamsadriane
Продвинутый
Default
0

Quote:
Originally Posted by netwind View Post
А зачем ты указываешь конкретные значения параметров для весьма нехилого сервера?
Давайте на "Вы", ибо нужно показывать взаимоуважение собеседников.

Quote:
Просто под "высоконагруженным проектом" люди обычно понимают свой унылый VPS на 512Мб памяти, из которого они хотят выжать все соки - высоко нагрузить.
Вот возмут они твои конфиги с key_buffer_size = 8G, query_cache_size=10G, innodb_buffer_pool_size = 10G, поставят себе и все это благополучно уйдет в своп и помрет.
Мой текущий уровень не позволяет мне редактировать свою тему т.к. выставил бы относительные (относительно ОЗУ) проценты.
Сейчас буду дополнять.
 
 
netwind
Гуру
 
netwind's Avatar
Default
0

Quote:
Originally Posted by adamsadriane View Post
Давайте на "Вы", ибо нужно показывать взаимоуважение собеседников.
а считай, что я фидошник. они все такие.
 
 
adamsadriane
Продвинутый
Default
1

Комментарии.
Сервер Apache слушает порт 8081, куда перебрасывает запросы динамических файлов nginx, который, в свою очередь, слушает дефолтный порт 80.
Для отображения реальных ip пользователей мы используем модуль rpaf.
Страница с модулем: http://stderr.net/apache/rpaf/
Строки в файле httpd.conf, отвечающие за его работу:
Code:
LoadModule rpaf_module modules/mod_rpaf-2.0.so
RPAFenable On
RPAFsethostname On
RPAFproxy_ips ip_вашего_сервера
Из кэширующих модулей Apache используем только кэширование в оперативной памяти модулем mem_cache_module
Строки в файле httpd.conf, отвечающие за его работу:
Code:
LoadModule mem_cache_module modules/mod_mem_cache.so
<IfModule mod_mem_cache.c>
 CacheEnable mem /
 MCacheSize 4096000
 MCacheMaxObjectCount 100000
 MCacheMinObjectSize 1
 MCacheMaxObjectSize 20480000
 CacheIgnoreCacheControl On
 CacheMaxExpire 604800
 CacheStorePrivate On
 </IfModule>
, где:
MCacheSize - объём кэша в оперативной памяти, КБ.
MCacheMaxObjectCount - максимально возможное количество объектов в кэше, шт.
MCacheMinObjectSize - минимальный размер объекта в кэше, байт.
MCacheMaxObjectSize - максимальный размер объекта в кэше, байт.
CacheIgnoreCacheControl - игнорировать факт некеширования на стороне клиента.
CacheMaxExpire - максимальное время жизни объекта в кэше.
CacheStorePrivate - кэшировать ответы private.
Конфигурационный файл fcgid.conf (/etc/httpd/conf.d):

MaxRequestsPerProcess - максимальное количество запросов на каждый процесс, шт.
MaxRequestsPerProcess - устаревшее название директивы, новое название FcgidMaxRequestsPerProcess.
FcgidIdleTimeout - Timeout, сек.
FcgidProcessLifeTime - время жизни каждого процесса, сек.
FcgidBusyTimeout - время жизни busy процессов.
DefaultInitEnv - имя переменной окружения.
DefaultInitEnv - устаревшее название директивы, новое название, - FcgidInitialEnv.
IPCCommTimeout - таймаут передачи в приложение FastCGI, сек.
IPCCommTimeout - устаревшее название директивы, новое название, - FcgidIOTimeout
DefaultMaxClassProcessCount - максимальное количество процессов одного класса приложения FastCGI, шт.

DefaultMaxClassProcessCount - устаревшее название директивы, новое название, - FcgidMaxProcessesPerClass
DefaultMinClassProcessCount- минимальное количество процессов одного класса приложения FastCGI, шт.
DefaultMinClassProcessCount - устаревшее название директивы, новое название, - FcgidMinProcessesPerClass
FcgidMaxRequestInMem - максимальный размер запроса, который будет сохранен в памяти, байт. Ставьте 25% от ОЗУ.
FcgidMaxRequestLen - максимальная длина запроса HTTP, байт. Ставьте примерно 128М.
FcgidOutputBufferSize - размер буфера вывода CGI, байт. Ставьте 25% ОЗУ.

Конфигурационный файл my.cnf:
Code:
tmpdir=/var/mysqltmp - директория с временными файлами. 
key_buffer_size - ставьте 25% ОЗУ.
max_allowed_packet - ставьте 10% ОЗУ.
sort_buffer_size - 25% ОЗУ.
read_buffer_size - 10% ОЗУ.
query_cache_size - 25% ОЗУ.
query_cache_limit - 10%, но не менее 32М.
join_buffer_size - 10% ОЗУ.
tmp_table_size - 15% ОЗУ.
max_heap_table_size - 15% ОЗУ.
myisam_sort_buffer_size - 10% ОЗУ.
Конфигурационный файл nginx:
keepalive_timeout 65; - устанавливаем максимально возможное для nginx значения тайм-аута.
Code:
gzip  on;
    gzip_min_length 10;
    gzip_buffers 64 8k;
    gzip_comp_level 9;
    gzip_http_version 1.1;
    gzip_proxied any;
gzip_types text/plain application/xml application/x-javascript text/css text/xml text/javascript; - устанавливаем максимальный уровень сжатия файлов, минимального размера в 10 байт, перечисленного вида данных.
client_max_body_size - устанавливаете по величине post_max_size из php.ini т.к. , при меньшем значении client_max_body_size, не будет возможности загружать вложения, размером более client_max_body_size.
Code:
 proxy_connect_timeout      65;
proxy_send_timeout         65;
proxy_read_timeout         65;
- величина аналогична keepalive_timeout.
Установка nginx:
Диструбутив nginx: http://nginx.org/ru/download.html
Дистрибутив pcre: http://www.pcre.org/
Дистрибутив zlib: http://zlib.net/
Code:
./configure --prefix=/usr/local/nginx --with-http_gzip_static_module --without-http_charset_module --without-http_ssi_module --without-http_userid_module --without-http_access_module --without-http_auth_basic_module --without-http_empty_gif_module --with-pcre=/путь к pcre на сервере/pcre-8.12(номер версии pcre) --with-zlib=/путь к zlib на сервере/zlib-1.2.5(номер версии zlib)
make
make test
make install
Создаём в папках с временными файлами tmpfs диски командой:
mount -t tmpfs -o size=размер_диска_tmpfs,nr_inodes=10k,mode=0775,noatime,nodiratime путь_куда_монтировать
Code:
Например, mount -t tmpfs -o size=1G,nr_inodes=10k,mode=0775,noatime,nodiratime tmpfs /tmp
Папки, с которыми нужно проделать предыдущее:
- временные данные MySQL (смотрим переменную tmpdir в my.cnf);
- временные файлы сервера (обычно директория /tmp);
- логи Apache;
- сессии php;
- временные файлы nginx:
--/путь_к_nginx/nginx/proxy_temp
--/путь_к_nginx/nginx/client_body_temp
После этого добавить в fstab монтирование tmpfs при загрузке в предыдущие папки командой вида:
Code:
 /dev/ramdisk            /путь_к_папке   tmpfs   defaults        0 0
 
 
Luvilla
Гость
Default

Quote:
Originally Posted by adamsadriane View Post
Мой текущий уровень не позволяет мне редактировать свою тему ...
Сейчас буду дополнять.
переношу тему в раздел Кандидатский, там есть права на редактирование
лучше сделать хороший первый пост, потому что с "дополнениями" будет сложно)
 
 
netwind
Гуру
 
netwind's Avatar
Default
1

Quote:
Originally Posted by adamsadriane View Post
tmpdir=/var/mysqltmp - директория с временными файлами.
key_buffer_size - ставьте 25% ОЗУ.
max_allowed_packet - ставьте 10% ОЗУ.
sort_buffer_size - 25% ОЗУ.
read_buffer_size - 10% ОЗУ.
query_cache_size - 25% ОЗУ.
query_cache_limit - 10%, но не менее 32М.
join_buffer_size - 10% ОЗУ.
tmp_table_size - 15% ОЗУ.
max_heap_table_size - 15% ОЗУ.
myisam_sort_buffer_size - 10% ОЗУ.
тут главное вовремя остановиться. память выделяемая под многие параметры выделяется в каждом потоке отдельно. то есть общий потребленный объем нужно умножать на число потоков mysql.
с другими есть неочевидные проблемы. например, query_cache_size не имеет смысла ставить более 32 мб. этот кеш и так работает плохонько, а когда он большой, то затраты на его поддержку становятся даже больше, чем эффект от него.

И это я только самые вредные параметры раскритиковал. Полноценное руководство, пожалуй, даже нереально создать.
Может остановиться на скрипте mysqltuner.pl? Единственный минус этого искусственного интеллекта - он не понимает, что временные таблицы для vbulletin на самом деле не используют диск и пытается вынудить задрать параметры tmp_table_size и max_heap_table_size до бесконечности.
 
 
adamsadriane
Продвинутый
Default
1

Quote:
Originally Posted by netwind View Post
тут главное вовремя остановиться. память выделяемая под многие параметры выделяется в каждом потоке отдельно. то есть общий потребленный объем нужно умножать на число потоков mysql.
с другими есть неочевидные проблемы. например, query_cache_size не имеет смысла ставить более 32 мб. этот кеш и так работает плохонько, а когда он большой, то затраты на его поддержку становятся даже больше, чем эффект от него.

И это я только самые вредные параметры раскритиковал. Полноценное руководство, пожалуй, даже нереально создать.
Может остановиться на скрипте mysqltuner.pl? Единственный минус этого искусственного интеллекта - он не понимает, что временные таблицы для vbulletin на самом деле не используют диск и пытается вынудить задрать параметры tmp_table_size и max_heap_table_size до бесконечности.
Данные параметры создавались очень долго и зарекомандовали себя на практике, как оптимальные . Это не описательный пост только что осознавшего их значение человека.
Тут дана конкретная конфигурации и конкретные советы с пояснением для получения максимальной отдачи от сервера в данной связке.

adamsadriane добавил 14.10.2011 в 14:56
Первый пост дополнил.

Last edited by adamsadriane : 10-14-2011 at 03:56 PM. Reason: Добавлено сообщение
 
 
netwind
Гуру
 
netwind's Avatar
Default
0

Quote:
Originally Posted by adamsadriane View Post
Это не описательный пост только что осознавшего их значение человека.
но очень сильно похож.
хотя бы запусти у себя mysqltuner.pl и посмотри какой будет диагноз.
там будет предупреждение о максимальном потреблении памяти процентов эдак на 1000 больше физически установленной.
 
 
Юпис
Знаток
vBSponsor
 
Юпис's Avatar
Default
0

adamsadriane, а сколько ваш сервер с такими настройками выдерживает пользователей онлайн? И очень интересно сколько оперативной памяти нужно под такие настройки? Спасибо.
 


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off




All times are GMT +4. The time now is 01:30 AM.


Powered by vBulletin® Version 3.7.6
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.