Разделы
vvShop | RSS © 2008 – 2017
Контакты
email: igor@veselov.sumy.ua
skype: utz0r2
» » » Страница 10

11 - Готовим CentOS 7. Установка сервера очередей beanstalkd




Устанавливаем git
yum install git -y
cd /tmp

Клонируем репозиторий
git clone git://github.com/kr/beanstalkd.git
cd beanstalkd
make
cp beanstalkd /usr/bin/beanstalkd
mkdir /var/lib/beanstalkd

Создаем скрипт автозапуска
nano -w /etc/systemd/system/beanstalkd.service

[Unit]
Description=Beanstalkd is a simple, fast work queue

[Service]
User=root
ExecStart=/usr/bin/beanstalkd -b /var/lib/beanstalkd

[Install]
WantedBy=multi-user.target

Запускаем и добавляем в автозагрузку
systemctl start beanstalkd
systemctl enable beanstalkd

Проверяем
systemctl status beanstalkd
ps ax | grep beanstalkd

Удостоверимся на практике что сервер очередей работает

Установим композер
cd /tmp
curl -sS https://getcomposer.org/installer | php70
mv composer.phar /usr/local/bin/composer

Установим pheanstalk
cd /var/www/test.dev
php70 /usr/local/bin/composer require pda/pheanstalk

Создадим клиента
nano -w /var/www/test.dev/producer.php

<?php
require_once './vendor/autoload.php';
use Pheanstalk\Pheanstalk;
$pheanstalk = new Pheanstalk('127.0.0.1');
$data = serialize(
	array(
		'do' => 'data',
		'msg' => "job 7 payload goes here\n"
	)
);
$pheanstalk->useTube('default')->put($data);
echo 'added';

Создадим воркер который будет зписывать в файлик наши задачи
nano -w /var/www/test.dev/worker.php

<?php
require_once './vendor/autoload.php';
use Pheanstalk\Pheanstalk;
$pheanstalk = new Pheanstalk('127.0.0.1');
while(1) {
	$job = $pheanstalk->watch('default')->reserve();
	if ( $job->getData() ) {
		$data = unserialize($job->getData());
		if ( $data['do'] == 'data' ) {
			$file = 'data.txt';
			$current = file_get_contents($file);
			$current .= $data['msg'];
			file_put_contents($file, $current);
			echo 'Log: add data'. PHP_EOL;		
		}
		$pheanstalk->delete($job);		
	}
}

Запустим наш воркер
cd /var/www/test.dev
php70 worker.php

Заходим через наш бразуер на http://test.dev/producer.php и клацаем обновить можно менять job-ы, что бы удостовериться что в очередь попадают разные задачи а не одна и та же, и в нашем файлике data.txt проверяем, что все что передано, отправлено в файлик.

Почему Beanstalkd - это сервер очередей, написаный на С, он маленький и простой. И мониторятся очереди.

Сервер — это сам Beanstalkd, который принимает job-ы от клиента
Продюсер(клиент) — это основное PHP приложение, которое отправляет job-ы на сервер
Воркер — это PHP скрипт, который получает сообщение с сервера задач и выполняет какие-то действия

Что за job? Job (задание) — это любая информация, которую клиент отправляет на сервер очередей. Потом эта же информация передается на обработчик (воркер). К примеру, мы хотим отправить почту на сервер очередей, то создаем для него задачу: отправка почты - адрес получаетля, заголовок письма, тело письма.

Задача 1 - он должен запускаться только из консоли
Задача 2 - должен выключаться если сам воркер изменился ( запускать его будет супервизор (об этом будет позже) )
Задача 3 - собственно обрабатывать наши задачи из очереди
Используется https://github.com/pda/pheanstalk
<?php
require_once ENGINE_DIR . '/assets/vendor/autoload.php';
use Pheanstalk\Pheanstalk;
if ( isCommandLine() != true ) {
	header("HTTP/1.0 404 Not Found");
	header('Location: /404');
	die();
}
function isCommandLine() {
   return defined('STDIN');
}
function get_changed_time() {
	$fp = fopen(__FILE__, "r");
	$fstat = fstat($fp);
	$res = $fstat['mtime'];
	return $res;
}
function check_changed_time($changed_time) {
	$time = get_changed_time();
	if ($time !== $changed_time){
		echo "File has been changed!";
		exit(1);
	}		
}
$pheanstalk = new Pheanstalk('127.0.0.1');
$mail = new PHPMailer;
$changed_time = get_changed_time();
while(1) {
	// проверяем не изменился ли наш воркер
	check_changed_time($changed_time);
	// смотрим наш tube default не появилось ли в нем задач, если нет ничего не делаем.
	$job = $pheanstalk->watch('default')->reserve();
	if ( !isset($job) OR !$job ) {
		// return FALSE;
	} else {
		// распаковываем ранее запакованные данные
		$data = unserialize($job->getData());
		// и тд и тп =)
	}
} 

Beanstalk console - Административная консоль для сервера очередей Beanstalk, написанная на PHP
Возможности
- Общий список серверов в конфиге для всех пользователей
- Глобальный список серверов может быть установлен через переменную окружения BEANSTALK_SERVERS
- Каждый пользователь может добавить свой персональный сервер
- Полный список доступных труб
- Полная статистика тасков в трубах
- Realtime-обновление с подсветкой изменившихся значений
- Вы можете просматривать таски в каждой трубе (ready/delayed/buried)
- Вы можете выполнять операции с тасками в каждой трубе (add/kick/delete)
https://github.com/ptrofimov/beanstalk_console

10 - Готовим CentOS 7. Cоздание заглушки для писем




- создаем shell-скрипт:
nano -w /usr/bin/fakesendmail.sh

со следующим содержимым:
#!/bin/sh 
prefix="/var/mail/sendmail/new"
numPath="/var/mail/sendmail"
if [ ! -f $numPath/num ]; then 
echo "0" > $numPath/num 
fi 
num=`cat $numPath/num` 
num=$(($num + 1)) 
echo $num > $numPath/num 
name="$prefix/letter_$num.txt"
while read line 
do 
echo $line >> $name
done 
chmod 777 $name
/bin/true

- делаем файл исполняемым
chmod +x /usr/bin/fakesendmail.sh
chmod 755 /usr/bin/fakesendmail.sh

mkdir /var/mail/sendmail
cd /var/mail/sendmail
mkdir cur && mkdir new && mkdir tmp
chmod -R 777 /var/mail/sendmail	

Найдем где храняться наши настройки для php7
php70 -i | grep "Loaded Configuration File"

- настраиваем php на работу с заглушкой в /etc/opt/remi/php70/php.ini ставим параметр
nano -w /etc/opt/remi/php70/php.ini
sendmail_path = /usr/bin/fakesendmail.sh

- перезапускаем php
systemctl restart php70-php-fpm

sestatus -b | grep -i sendmail
setsebool -P httpd_can_sendmail 1

- cоздадим файл /var/www/test.dev/3.php и дописываем функцию отправки письма
nano -w /var/www/test.dev/3.php

<?php mail("test@test.dev", "My Subject", "Line 1\nLine 2\nLine 3"); echo 'sended';

- обновляем страницу http://test.dev/3.php и проверяем каталог с письмом
/var/mail/sendmail/new создался letter_1.txt с отправленым нами письмом
ls /var/mail/sendmail/new
grep mail /var/log/audit/audit.log

Запускаем эти команды для selinux (в моем случае это 5 раз пока не начали отправляться заполненые письма)
grep mail /var/log/audit/audit.log | audit2allow -m mail > mail.te 
grep mail /var/log/audit/audit.log | audit2allow -M mail 
semodule -i mail.pp

Заглушка готова.

9 - Готовим CentOS 7. Установка и настройка Redis



yum install redis -y

(для успешного выполнения этой команды, нужен epel-release мы его установили вместе с php ранее)

Старт
systemctl start redis

Смотрим статус
systemctl status redis

Подключаемся к redis
redis-cli -h 127.0.0.1 -p 6379 

ping
INFO
exit

Ставим в автозагрузку
systemctl enable redis.service


Настройки
/etc/redis.conf
/etc/redis-sentinel.conf

nano -w /etc/redis.conf

tcp-keepalive 60
bind 127.0.0.1
appendonly yes
appendfilename "appendonly.aof"

В случае с AOF, Redis ведёт лог операций, которые выполняют клиенты и записывает их в файл (по умолчанию каждую секунду). AOF это аббревиатура от Append Only File, а это означает то, что Redis не изменяет уже записанные данные, а лишь добавляет новые в конец. Благодаря тому, что при использовании AOF, Redis по умолчанию пишет данные на диск каждую секунду, максимум, что вы теряете в случае сбоя при использовании этого режима — это 1 секунда.

Перезагружаем
systemctl restart redis

Если заглянуть в /var/log/redis/redis.log
То можно увидеть два предупреждения
WARNING overcommit_memory is set to 0
WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128
Исправим первое
nano /etc/sysctl.conf

вставляем строчку
vm.overcommit_memory = 1

выполняем команду
sysctl vm.overcommit_memory=1

Исправим второе
nano /etc/rc.local

Добавляем строчку
sysctl -w net.core.somaxconn=65535

и заодно выполним ее в консоли
sysctl -w net.core.somaxconn=65535


Перезагружаем и смотрим в /var/log/redis/redis.log что все теперь впорядке
systemctl restart redis

Осталось установить модуль redis для php
Так как для php70 его в портах нет, придеться компилировать самому

cd /tmp
wget https://github.com/phpredis/phpredis/archive/php7.zip
yum install unzip -y
unzip php7.zip
cd phpredis-php7
yum install php70-php-devel m4 autoconf -y
/opt/remi/php70/root/usr/bin/phpize
./configure CFLAGS="-O3" --with-php-config=/opt/remi/php70/root/usr/bin/php-config
make clean all
make test
cp /tmp/phpredis-php7/modules/redis.so /opt/remi/php70/root/lib64/php/modules/
echo extension=redis.so > /etc/opt/remi/php70/php.d/redis.ini
rm -rf /tmp/php7.zip && rm -rf /tmp/phpredis-php7

Рестарт
systemctl restart php70-php-fpm

Проверим
php70 -m | grep -i redis

В ответ
redis
Значит модуль стал.
Создаем тестовый файл
nano -w /var/www/test.dev/2.php

<?php
$redis = new Redis();
$redis->connect('localhost:6379');

Проверяем,если ошибка, что класс Redis не существует, не вылетела, то все отлично.
Можно так же запустить бенчмарк, посмотреть как быстро работатет ваш redis
nano -w /var/www/test.dev/2.php

try {
    $redis = new Redis();
    $redis->connect('localhost:6379');
} catch(RedisException $e) {
    exit('Connect error');
}
$benchmark = microtime(true);
for($i=0;$i < 80000; $i++)
    $redis->set('key','value');

echo microtime(true) - $benchmark;


Ошибка
Uncaught RedisException: Redis server went away
Опять этот SELinux......

setsebool -P httpd_can_network_connect=1
semodule -r redis

Не плохо так же перенести стандартные php сессии на redis, для этого
В php.ini прописываем ( наши сессии теперь будут храниться в redis)
nano -w /etc/opt/remi/php70/php-fpm.d/www.conf

php_value[session.save_handler] = redis
php_value[session.save_path]    = tcp://127.0.0.1:6379
# если с паролем то
# session.save_path = "tcp://127.0.0.1:6379?auth=yourverycomplexpasswordhere"

или прямо в файле php
ini_set('session.save_handler', 'redis');
ini_set('session.save_path',    'tcp://127.0.0.1:6379');

Настройки /etc/redis/redis.conf
Перезапускаем
systemctl restart redis
systemctl restart php70-php-fpm

Дописываем в наш файлик
nano -w /var/www/test.dev/2.php

session_start();

Запускаем в браузере. И проверяем создалась ли сессия у нас в redis.

И не забываем посматривать в /var/log/redis

8 - Готовим CentOS 7. Установка и настройка стабильной версии MongoDB



Создадим файл
nano -w /etc/yum.repos.d/mongodb-org-3.2.repo

Запишем в него
[mongodb-org-3.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.2/x86_64/
gpgcheck=0
enabled=1

Установим
yum -y install mongodb-org
semanage port -a -t mongod_port_t -p tcp 27017

Запустим
systemctl start mongod

Проверим
mongo
> db.version()
> exit

Предупреждение 1
WARNING: Readahead for /var/lib/mongo is set to 4096KB
Предупреждение 2
WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'
Предупреждение 3
WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
Предупреждение 4
WARNING: soft rlimits too low. rlimits set to 4096 processes, 64000 files.

Сейчас это будем исправлять
nano -w /etc/init.d/mongod

Перед Starting mongod вставляем
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
   echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
   echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi

Перезапускаем
systemctl restart mongod
systemctl daemon-reload

df -h
blockdev --report
blockdev --setra 256 /dev/mapper/centos-root

Добавляем в автозагрузку
nano -w /etc/rc.local

blockdev --setra 256 /dev/mapper/centos-root

Перезагружаем
systemctl restart mongod

Почитать про предпочтительные лимиты для монго можно здесь https://docs.mongodb.org/manual/reference/ulimit/
ls /etc/security/limits.d/

nano -w /etc/security/limits.d/20-nproc.conf 

проставляем как просит монго 64000

Перезапустим
systemctl restart mongod

Проверим
systemctl status mongod

Добавим в автозагрузку
systemctl enable mongod
mongo
exit

настройки /etc/mongod.conf

доставим поддержку mongo в нашем php
yum install php70-php-pecl-mongodb -y

перезепустим php
systemctl restart php70-php-fpm

Проверяем что расширение установлено и доступно
php70 -m | grep -i mongodb

В ответ получить должны
mongodb

Создаем файл
nano -w /var/www/test.dev/mongo.php

и пишем в него
<?php $m = new MongoDB\Driver\Manager("mongodb://localhost:27017");

Выполняем, если ошибки нет, то все хорошо.

7 - Готовим CentOS 7. Настройка nginx + php-fpm ключевые моменты



Проверяем что nginx и php работают
systemctl status nginx
systemctl status php70-php-fpm

Основной файл конфигурации nginx
/etc/nginx/nginx.conf

Создаем файл конфигурации для нашего проекта test.dev
nano -w /etc/nginx/conf.d/test.dev.conf
server {
    listen       80;
    server_name  test.dev;
	root   /var/www/test.dev;
    location / {
        index  index.html index.php;
    }
}

Перезапускаем
systemctl restart nginx

3 раза ( после каждого прохода этих команд пробуем зайти на http://test.dev/ ) пока selinux нас не пустит
grep nginx /var/log/audit/audit.log | audit2allow -m nginx > nginx.te 
grep nginx /var/log/audit/audit.log | audit2allow -M nginx 
semodule -i nginx.pp

Пробуем открыть http://test.dev/index.html

если работает html по новому адресу то дописываем секцию обработки php
nano -w /etc/nginx/conf.d/test.dev.conf

location ~ \.php$ {
	try_files $uri =404;
	fastcgi_pass 127.0.0.1:9000;
	fastcgi_param SCRIPT_FILENAME $request_filename;
	fastcgi_index index.php;
	fastcgi_read_timeout 30;
	fastcgi_buffers 16 16k;
	fastcgi_buffer_size 32k;
	include	fastcgi_params;
}

Перезапускаем
systemctl restart nginx

Посмотреть selunux что связано с http и при надобности включить что необходимо
sestatus -b | grep -i httpd

Найдем где храняться наши настройки для php7
php70 -i | grep "Loaded Configuration File"
/etc/opt/remi/php70/php.ini

6 - Готовим CentOS 7. Установка PHP7



Устанавливаем epel-release
yum install epel-release -y && cd /tmp	

Качаем репозиторий
wget http://rpms.remirepo.net/enterprise/remi-release-7.rpm

Добавляем репозиторий
rpm -Uvh remi-release-7*.rpm

Устанавливаем основные компоненты
yum --enablerepo=remi-php70 install php70-php php70-php-common php70-php-fpm php70-php-cli php70-php-opcache php70-php-pecl-apcu php70-php-process php70-php-xml php70-php-gd php70-php-mbstring -y

Проверяем
php70 -v

Стартуем php-fpm
systemctl start php70-php-fpm

Проверяем
systemctl status php70-php-fpm

Проверяем
php70 -a
echo 1+1;
> 2
exit

Отлично php 7 установлен!
Выставляем в автозагрузку php
systemctl enable php70-php-fpm
«»
Вверх