Как я боролся с тормозами на одном там сервере

У клиента начал дико тормозить сервер (сборка bitnami-lampstack). Работало-работало, и вдруг стало тормозить.

Пока искал в чём проблема, обнаружил, что за последние пару лет в линуксах появилось много нового и интересного! Я отключил пару вещей, после чего тормоза исчезли. Но «после» — это не всегда значит «в следствие». В общем пока наблюдаю за ситуацией. Что я отключил:

Apport
======================
Это вообще интересная софтина. Она мониторит процессы и собирает сообщения об ошибках. Что ними потом делать, я не понял. Видимо надо отправлять разработчикам, а может оно само шлёт это всё сразу на серверы Ubuntu.

В общем штука , которая вообще-то нужна разработчикам всего этого open-source, но точно никак не окончательным пользователям. Кстати по-умолчанию она должна быть выключена. Почему она оказалось включённой в этой сборке bitnami … фиг знает..

Как выключить Apport:

sudo nano /etc/default/apport

и установить поле enabled в 0. Ну или соответственно 1 если хотите его включить.

Прочитать подробнее, что это такое: https://wiki.ubuntu.com/Apport

mod_pagespeed
==========================
Сначала небольшая предыстория, как я это нашёл. Тут вообще хохма!

Сначала я обнаружил в логах апача, что кто-то усиленно качает статические файлы! Сайт тормозит, страницы открываются по 10 минут, а этот не останавливается прям! И что характерно качает только статику, картинки, стили, скрипты! И качает из локальной сетки (у AWS кроме публичного IP есть адрес локальный в сети 10.*.*.*)! И вдруг я понял что это собственно и есть адрес моего сервера…

User-agent у этих обращений такой «Serf/1.1.0 mod_pagespeed/1.7.30.4-«

После чтения мануалов стало понятно, что это модуль для апача. В целом хорошая вещь (наверное), которая занимается кешированием/архивированием статики и должно бы теоретически ускорить загрузку страницы у конечного пользователя. При наличии достаточных ресурсов на сервере. Но сервер тормозит дико, просто умирает, и я решил отключить эту опцию.

Отключается mod_pagespeed легко. Надо найти в конфиге нужную строчку:

……
# Turn on mod_pagespeed. To completely disable mod_pagespeed, you # can set this to «off». ModPagespeed off ……

Вместо заключения
======================
Сервер пока стоит. Будем смотреть дальше
А вообще я заметил за собой, что я практически всегда отключаю всякие ненужные на мой взгляд опции, а не подключаю новые. Эдакий мастер-ломастер.

Adsence + Rapida. Новые правила

Недавно Adsence поменял правила выплат через Рапиду, после чего мне пришлось проходить целый квест по заведения аккаунта, персонификации и созданию шаблона (да, я слоупок) . Зато теперь средства с Adsence должны капать мне прямо на банковский счёт. Теперь я буду платить с налоги!! Уииииии!!! =)

Вот! И пока не ничто забыто, хочу зафиксировать всю эту адову последовательность. Начинаем по-порядку.

Исходное состояние — предполагается, что у вас есть аккаунт Adsence, который надо привязать к рапиде.

Создание аккаунта в Рапиде
=========================================
Никаких сложностей не вызвало. Кроме самого факта создания ещё-одного-аккаунта. Кстати, логином, идентификатором и просто номером кошелька в рапиде является номер вашего мобильного телефона.

Персонификация аккаунта
=========================================
Со временем эта информация может устареть, поэтому не поленитесь посмотреть инструкцию

Вот тут целая история! Просто так сидя за компьютером аккаунт персонифицировать не получится. Придётся тащить своё бренное тело в офис Рапиды, если таковой есть в вашем городе. А если нет, то можно пойти на почту, но придётся ещё и потратить деньги.

Чтобы выполнить персонификацию через почтовый перевод, зайдите в свой личный кабинет Рапиды и найдите ссылку «Пополнить«. Затем надо найти вариант «Почтовым переводом«. После этого Вам будет предложено заполнить свои анкетные данные. В качестве суммы рекомендуют указывать сумму 50 рублей. Эти 50 рублей просто упадут в ваш кошелёк.

Если всё сделано правильно, вам будет предложено скачать и распечатать PDF-файл, который фактически является заполненным бланком почтового перевода, который принимают в почтовых отделениях. У меня, по крайней мере, приняли. Почта возьмёт с вас комиссию 40 рублей сверх самой суммы.

После того как всё сделано, сосканируйте или сфотографируйте чек и отправьте письмом на адрес client@rapida.ru. Кроме чека надо приложить сканы паспорта. Я приложил скан разворота с фотографией и с пропиской. Все эти сканы должны быть цветными, но не более 2Мб.

Всё. После этого остаётся подождать несколько рабочих дней.

Создание шаблона
=========================================
После того как вы удачно персонифицированы, вы можете создавать свой шаблон. Рапида поддерживает тьму шаблонов, но меня интересовал именно шаблон вывода денег на банковский счёт. В анкете надо просто подробно и аккуратно заполнить все реквизиты. В поле сумма пишите любую сумму в пределах возможного. На переводы это влиять не будет.

В поле «Назначение платежа» я написал «Вознаграждение Adsence«. Если вы зачисляете средства сразу на лицевой счёт физ.лица (что не совсем законно), то укажите там то, что вам скажет ваш банкир.

После того как шаблон создан и сохранён, поищите поле «Уникальный номер (Для пользователей Google AdSense)». Это то что вам нужно.

Ссылки, которые мне помогли
=========================================
Вообще говоря ссылок я нашёл не так и мало, но эти две показались мне наиболее полезными и ценными.

  • Классное видео Как стать персонифицированным пользователем в Rapida!
  • Подробный пост Изменения выплат Adsense: составляем правильный шаблон без комиссий

У меня были тормоза в чате скайпа.


А сейчас будет немного оффтопа.

Представьте, вы разговариваете с заказчиком через чат скайпа, вы обсуждаете важные нюансы реализации, в это время включен трекер времени(!) и тикают деньги. И в это время скайп начинает тормозить. Вы задали вопрос заказчику, а он его не видит. Вы находитесь онлайн, заказчик находится онлайн, а сообщения не доходят. Потом через некий случайный промежуток времени почему-то сообщения таки дойдут. Но канва беседы уже потеряна, время упущено.

Знакомая ситуация?

Так вот, я вылечился! Мне помогло просто отключение на моей стороне uPNP.
Настройки -> Дополнительно -> Соединение -> Включить uPNP

Зачем вообще нужна эта опция, даже не знаю. Вот так. Пока всё работает нормально.

Git — автоконвертация CRLF и всё такое


Недавно пришлось поразбираться с автоконвертацией Git. Там не всё так очевидно, как кажется. Вот казалось бы — просто редактируй файл и делай свои коммиты. Но нет!

Всё началось с того, мы начали получать дикие конфликты, приглядевшись мы поняли, что проблема в преобразовании CRLF. Мой редактор под Windows сохранял файлы с CRLF в качестве знака окончания строки, а редактор моего коллеги, работающего под линуксом — LF. Причём иногда редактор сохраняет так, а иногда эдак, и логика его поведения не очевидна. В результате мы получали конфликты даже в тех файлах, которые даже не меняли.

В результате гугления выяснилось что с опцией autocrlf всё не так просто

* autocrlf true — git при каждом коммите будет преобразовывать CRLF в LF и наоборот при чтении из репозитория. Таким образом в репозитории будет православный LF а пользовательский редактор будет получит CRLF. Это сделано специально для Windows пользователей.

* autocrlf input — git при каждом коммите будет преобразовывать CRLF в LF, но при чтении из репозитория выдаст всё как есть в оригинале. Эта опция для тех, у кого редактор нормально воспринимает оба окончания строки, но хочет содержать репозиторий в едином формате. Эта опция рекомендуется для линуксоидов.

* autocrlf false — git не выполняет никаких преобразований. Как файлы создаёте — так они и будут сохранены. В общем-то подходит, если кроме вас никто не работает в этом репозитории, или если все разработчики используют софт с одинаковыми принципами сохранения конца строки.

Вот. Теперь мы с коллегой поставили себе нужные настройки. Пока конфликтов не попадалось

Есть у кого-нибудь чем-нибудь дополнить в мою картину мира?

Как получать дополнительные данные от социальных сетей

Недавно я писал про библиотеку работы с социальными сетями. Но для получения дополнительных данных нужно выполнить дополнительные телодвижения. И поскольку я постоянно спотыкаюсь об это дело, то зафиксирую это тут.

Facebook
==========================
Выборка данных, выдаваемая фейсбуком по-умолчанию довольно бедная. Там, например, нет email, который нуже практически всегда. Или например дата рождения. Чтобы их получить нужно определить scope

Например с использованием той OAUTH библиотеки это будет выглядеть так:

$client = new oauth_client_class; $client->server = ‘Facebook’; $client->redirect_uri = ‘http://’.$_SERVER[‘HTTP_HOST’]. dirname(strtok($_SERVER[‘REQUEST_URI’],’?’)).’/this_script_url.php’;
$client->client_id = ‘xxxxxxxxx’; $application_line = __LINE__; $client->client_secret = ‘xxxxxxxxxxxxxx’;
$client->scope = ’email, user_birthday’;

Дополнительные ключи безопасности Facebook можно посмотреть тут

LinkedIn
==========================

Если вы считаете штатную выдачу Facebook малоинформативной — вы не видели штатную выдачу LinkedIn. Там вообще нет ничего, кроме имени пользователя. Для получения нужного набора информации нужно формировать целый запрос, который является частью URL. Не буду приводить весь код, приведу пример URL

‘http://api.linkedin.com/v1/people/~:(first-name,last-name,phone-numbers,email-address,main-address,picture-url,date-of-birth,positions:(title,company))’,

Подробнее о построении таких запросов для LinkedId смотреть тут: http://developer.linkedin.com/documents/field-selectors
Полное описание параметров запроса : http://developer.linkedin.com/documents/profile-fields

Git. Конфликты бывают разные

Это короткий пост, по сути это пост картинка.

Недавно получил такой забавный конфликт. Файл до меня был пустым, и после меня остался пустым. Но обнаружен конфликт и всё тут.

На CRLF вроде не похоже… Я уже и спецсимволы включил. Забавная такая история. У вас такое бывает?

Ещё одна OAUTH библиотека для PHP

Этот пост — просто закладка для себя. Нашёл классную рабочую библиотеку OAUTH с примерами для огромного количества сервисов. Всё просто, понятно, бери и используй!

  • http://www.phpclasses.org/package/7700-PHP-Authorize-and-access-APIs-using-OAuth.html

Библиотека использует этот пакет, так что его тоже надо распаковать и положить рядом.

  • http://www.phpclasses.org/package/3-PHP-HTTP-client-to-access-Web-site-pages.html

Kohana ORM: Удаляем записи с корнем. Целостность БД


Думаю, всем понятно, что при удалении записи нужно следить за ссылочной целостностью. То есть если уж решили удалить запись, то надо сделать чтобы нигде не осталось ссылок на удалённую запись.

Если есть элементы, привязанные к этой записи по схеме много-к-одному или один-к-одному, то логично рассматривать эти записи как подчинённые и соответственно удалять их. Если же где-то в других таблицах есть записи привязанные к удаляемой записи по схеме много-ко-многим, логично удалять только связь.

Для этого надо у каждой модели прописать свою процедуру delete(), в которой и прописать алгоритм удаления. Но если база данных построена правильно, если все подчинённые записи подключены именно как «много-к-одному», а не «многие-ко-многим» и т.д., то можно автоматизировать этот процесс и написать одну функцию на все случаи жизни.

public function delete() { if ($this -> loaded()){ foreach($this->_has_many as $key => $value){ foreach( $this -> {$key}-> find_all() as $element){ if(isset($value[‘through’])){ $this->remove($key, $element); }else{ $element -> delete(); } } } } return parent::delete(); }

Вот так.

Ну и естественно, БД должна быть сделана по уму и модели прописаны правильно. А иначе, можно ведь нечаянно удалить что-то нужное

Kohana ORM. Прикол при добавлении связи


Мы все знаем, что для добавления связи много-ко-многим используется функция ORM add().

Но что делать, если объект только что создан? Тогда есть проблемка.

Вот практический пример:

// Создаём пользователя $user = ORM::factory(«user»); $user->id = 123123; $user->name = «Username»; $user->email = «asd@asdasd.asd»; $user->password = «PaSsWoRd»; $user->save();
// Даём роль $user->add(«roles»,ORM::factory(«role»,1));

Вроде всё делаем правильно, однако мы получим ошибку:

Database_Exception [ 1048 ]: Column ‘user_id’ cannot be null [ INSERT INTO `roles_users` (`user_id`, `role_id`) VALUES (NULL, ‘1’) ] ~ MODPATH/database/classes/kohana/database/mysql.php [ 194 ]

Забавная ошибка. Объект создан и сохранён. Но тем не менее ORM не может найти id пользователя! Попробуйте запросить $user->id сразу после создания объекта, и вы его получите. И более того, я явно присваиваю id, до сохранения. Но ORM не находит. Мистика, однако!

Построенная таким образом модель, какая-то не полная и чего-то ей не хватает. Совсем другое дело, если ещё раз запросить объект.

Вот пример:

// Создаём пользователя $user = ORM::factory(«user»); $user->id = 123123; $user->name = «Username»; $user->email = «asd@asdasd.asd»; $user->password = «PaSsWoRd»; $user->save();
// Сначала переопределяем объект $user = ORM::factory(«user»,$cms_user->id);
// А вот теперь уже даём роль $user->add(«roles»,ORM::factory(«role»,1));

И так — всё работает.

Проблема решена, всё работает, но как-то по-дурацки. Кто знает, как можно сделать это красивее?

UPD: Речь про Kohana 3.2
UPD2: Глюк и правда странный, тем более что модель и правда немного модифицировалась, возможно автор сам дурак.

Яндекс.Метрика