Analitycs

Показаны сообщения с ярлыком решения. Показать все сообщения
Показаны сообщения с ярлыком решения. Показать все сообщения

среда, 29 февраля 2012 г.

Как правильно деплоить Python сервис запущеный через supervisord?

Иногда supervisord заглючивает и он неправильно определяет необходимость перекомпиляции pyc файлов при обновлении python файлов, что при деплое новой версии сервиса на Python приводит к забавным, но неприятным эффектам

Рекомендуемый порядок действия

# supervisorctl stop my_super_service

Теперь обновляем файлы, затем РУЧКАМИ удаляем pyc

# find path_to_my_service -type f -name "*.pyc" -delete
# supervisorctl start my_super_service

При использовании сервисов автоматического деплоя - имеет смысл повесить эти операции на автоматические хуки - до и после деплоя.

пятница, 24 февраля 2012 г.

Tornado AsyncHTTPTestCase: AssertionError: Async operation timed out after 5 seconds

Тестирование в Торнадо (особенно асинхронных сервисов) имеет много неочевидных нюансов.

Ситуация

Если ваш сервис внутри асинхронных обработчиков сам создает асинхронные задачи - например, для того чтобы забрать что-то с внешнего сервиса - в стиле

class MyAsyncHandler(tornado.web.RequestHandler):

    @tornado.web.asynchronous
    def get(self, *args, **kwargs):
        try:
            # тут чего то берем с внешнего сервера
            self.auth_request({})
        except Exception, ex:
            self.error('Async - %s'%ex)
            self.reply(None)


    def auth_request(self, params, callback=None):
        url = self.application.settings['external_service'] + '?' + urlencode(params)

        if not callback:
            callback = self._on_load

        http = httpclient.AsyncHTTPClient()
        http.fetch(url, callback, validate_cert=False)

    def _on_load(self, response):
        # обрабатываем полученные результат        
        pass

То при написании юнит-тестов через AsyncHTTPTestCase в подобном ключе по официальной документации(!!!)

class MyTestServer(AsyncHTTPTestCase):
    def get_host(self):
        return 'http://%s:%d'%(SERVER['host'], SERVER['port'])
    
    def get_app(self):
        myserver = MyServer()
        myserver.run(SERVER['host'], SERVER['port'])        

        return myserver.app # приложение Tornado
    
    def get_response_obj(self, url, **kwargs):
        if len(kwargs) > 0:
            url += '?' + urllib.urlencode(kwargs)
        
        logging.info('Request [%s]'%url)

        self.http_client.fetch(url, self.stop)
        response = self.wait()
        
        print response

        if response.body: 
            return response.body
        
        return None

При запуске тестов начинаем ловить потрясающие спецэффекты,

Traceback (most recent call last): 
  File "/home/xxxx/test_wait.py", line 9, in test_1 
    self.wait(timeout = 5) 
  File "/xxxxx/site-packages/tornado/ 
testing.py", line 169, in timeout_func 
    timeout) 
AssertionError: Async operation timed out after 5 seconds 

Лечится это добавлением в класс теста переопределенного метода get_new_ioloop

class MyTestServer(AsyncHTTPTestCase):
    ....
    
    def get_new_ioloop(self): 
        return ioloop.IOLoop.instance()  

Такие дела...

Тема в гуглогруппеGist с примером

пятница, 17 февраля 2012 г.

Blogger - Sorry, dynamic views aren't available for this blog.

В динамическом режиме показа блога на Blogger.com выводится сообщение

Sorry, dynamic views aren't available for this blog. 

Это возможно в трех случаях:

  1. Если блог приватный. 
  2. Если на блоге нет RSS лент. 
  3. Если на блоге в лентах показываются обрезанные сообщения (short feeds).
Так что не включаем обрезание постов, только что накололся на этом.

суббота, 11 февраля 2012 г.

Как проверить string ли переменная в Python? - isinstance(val, basestring)

Когда нужно проверить - строка ли переменная в Python - есть небольшой подводный камень, о котором иногда забывают...

Все ли помнят что строки в питоне разные? (например, str и  unicode), так что для общей проверки нужно использовать isinstance(val, basestring):

 Например

$ python
Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

>>> isinstance('abcd', str)
True
>>> isinstance('abcd', basestring)
True
>>> isinstance(u'abcd', str)
False
>>> isinstance(u'abcd', basestring)
True

пятница, 10 февраля 2012 г.

Как запускать периодические задачи на Tornado? PeriodicCallback!

Продолжая тему периодических задач в Twisted, в Tornado это делается немного по другому - с помощью специального tornado.ioloop.PeriodicCallback.

Примерчик - если кому пригодится

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import tornado.web
import tornado.httpserver
import tornado.ioloop

PERIOD = 30 # в минутах

class MyApplication(tornado.web.Application):

  def period_run(self):
    # чего-то тут делаем
    pass

...

app = MyApplication(handlers=urls, **settings)

http_server = tornado.httpserver.HTTPServer(app, xheaders=True)
 
loop = tornado.ioloop.IOLoop.instance()
period_cbk = tornado.ioloop.PeriodicCallback(app.period_run, 1000*60*PERIOD, loop)

period_cbk.start()

loop.start()

вторник, 7 февраля 2012 г.

Как сделать hard-reset на LG Optimus Black?

Шаманство с зажатием Volume Down + Power + Home при включении не прокатило, может граната у меня не той системы?

В итоге - hard-reset через коды

dial 3845#*970#

Разумеется - все данные похерятся.


пятница, 3 февраля 2012 г.

Как перезапустить демонизированный процесс в Supervisord?

Если в supervisord запущено несколько процессов и один из них отвалился, не нужно перезапускать демон целиком - есть консольная утилитка supervisorctl.

# supervisorctl
api-test-data                    RUNNING    pid 22443, uptime 1 day, 16:52:01
api-test-empty                   FATAL      Exited too quickly (process log may have details)
auth-service                     RUNNING    pid 22444, uptime 1 day, 16:52:01

Ага, вот процесс-виновник - перезапускаем халявщика

supervisor> start api-test-empty
api-test-empty: started

supervisor> status
api-test-data                    RUNNING    pid 22443, uptime 1 day, 16:52:29
api-test-empty                   RUNNING    pid 27360, uptime 0:00:13
auth-service                     RUNNING    pid 22444, uptime 1 day, 16:52:29
supervisor> 

Все ОК - "13 секунд, полёт нормальный. Хьюстон, у нас НЕТ проблемы" (с)

понедельник, 30 января 2012 г.

Javascript+Flash мультизагрузчики картинок (SWFUpload, Uploadify) и Error #2038

Иногда мультизагрузчики изображений с использованием Flash (SWFUpload, Uploadify и т.д) дают ошибку #2038 при загрузке на случайных картинках без всяких видимых причин.

Как выяснилось - может быть целая куча разномастных серверных проблем - причем проблем преимущественно backend'овских.

TODO-list
  • обновляем Flash загрузчик до последней версии;
  • проверяем, что POST приходит на сервер в скрипт загрузки нормально - без всяких HTTP авторизаций, сессии нормально передаются, пользователь распознается залогиненным и т.д.;
  • и внимание - ЭПИЧНАЯ ОШИБКА: Размер разрешенных вложений должен быть <= размеру upload_max_filesize в php.ini;

И только потом лезем в настройки сервера - для nginx решение

Открываем nginx.conf и в http секцию добавляем директиву

client_max_body_size 500m;  

И удаляем из конфига директиву keepalive_timeout

Через некоторое время, когда у пользователей обновится кеш браузера - начинает все работать

пятница, 27 января 2012 г.

Python implode/join - TypeError: sequence item 0: expected string, int found

Одна из частых функций в PHP проектах - implode/explode.

На Python (по идее/по мануалу) это делается так

tmp = [1,2,3,4,5]
','.join( tmp )

Но в результате - получаем ошибку TypeError: sequence item 0: expected string, int found

Проблема - в том, что у нас числа, а не строки

 В итоге - нужно так

','.join( map( str, tmp ) )
'1,2,3,4,5'

Но вот пресловутое неявное приведение типов-то в PHP как помогает, а? ;-)

среда, 25 января 2012 г.

Как узнать установленную версию Apache?

Для Red Hat дистрибутивов От рута
# httpd -v
Server version: Apache/2.2.17 (Unix)
Server built:   Oct 19 2010 16:27:47
От простого смертного
# ps aux | grep httpd
web     1152  1.6  0.7 314296 62168 ?        S    00:42   0:03 /usr/sbin/httpd

# /usr/sbin/httpd -v
Server version: Apache/2.2.17 (Unix)
Server built:   Oct 19 2010 16:27:47
Либо
# rpm -qa|grep httpd
httpd-2.2.17-1.el5
httpd-tools-2.2.17-1.el5
Для debian-based, понятное дело - httpd заменить на apache2.

пятница, 20 января 2012 г.

Как полноценно включить UTF-8 для MySQL?

Что нужно добавить в /etc/my.cnf для полноценной поддержки UTF-8 в MySQL, включая вывод данных в консоли mysql


[mysqld]
default-character-set=utf8
default-collation=utf8_general_ci
character-set-server=utf8
collation-server=utf8_general_ci
init-connect='SET NAMES utf8'
 
[client]
default-character-set=utf8
 
[client]
default-character-set=utf8

четверг, 19 января 2012 г.

Python PIP не работает под MacOS X 10.7 Lion - pkg_resources.DistributionNotFound: pip==1.0.2

На новой машинке чудеса с PIP и MacPorts следующего вида - система не видит установленного PIP через MacPorts

Диагноз

$ pip
Traceback (most recent call last):
  File "/usr/local/bin/pip", line 5, in 
    from pkg_resources import load_entry_point
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 2603, in 
    working_set.require(__requires__)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 666, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 565, in resolve
    raise DistributionNotFound(req)  # XXX put more info here
pkg_resources.DistributionNotFound: pip==1.0.2

Самолечение

Не совсем грамотно, но вроде помогло - установка PIP через easy_install
curl -O http://python-distribute.org/distribute_setup.py
sudo python distribute_setup.py
sudo easy_install pip

среда, 18 января 2012 г.

mysqldump: Got error: 1449: The user specified as a definer ('user'@'x.x.x.x') does not exist when using LOCK TABLES

Диагноз

При попытке сдампить базу MySQL получаем ошибку

mysqldump: Got error: 1449: The user specified as a definer ('user'@'x.x.x.x') does not exist when using LOCK TABLES

Причина - отсутсвует пользователь который прописан в хранимых процедурах/триггерах.

Похоже, что эта ошибка возникает, когда исходный/изначальный дамп MYSQL импортируется в сервер с ключем "force" (-f - который игнорирует ошибки), а потом его пытаются сохранить с этой машины.

Лечение

Вариант 1

Правим хранимую процедуру и дампим заново

use mysql;
select * from proc;

Вариант 2

1. Создаем пользователя

GRANT ALL PRIVILEGES ON *.* TO 'misseduser@*' IDENTIFIED BY 'some_pass' WITH GRANT OPTION

2. Дампим базу

3. Правим в дампе куски с отсутсвующими пользователями на CURRENT_USER Ищем что-то типа

/*!50013 DEFINER=`missed user`@`some_host` SQL SECURITY DEFINER */

и

DEFINER=`some_user`@`some_host`

заменяется на

DEFINER=CURRENT_USER

По мотивам этой заметки.

вторник, 17 января 2012 г.

Email от PHPBB падает в spam

Диагноз и причина

Оповещения от русской версии PHPBB падают в спам.

X-Amavis-Alert: BAD HEADER SECTION, Non-encoded 8-bit data (char D3 hex): 
   Subject: 323342345344356354353345355350345 356341 
   356[...] 
X-Spam-Flag: NO 
X-Spam-Score: 4.301 
X-Spam-Level: **** 
X-Spam-Status: No, score=4.301 tagged_above=-10 required=5 
   tests=[BAYES_50=0.8, RCVD_IN_DNSWL_NONE=-0.0001, 
   SUBJECT_NEEDS_ENCODING=0.049, SUBJ_ILLEGAL_CHARS=1.518, 
   TO_NO_BRKTS_MSFT=1.934] autolearn=no

subject уходит с сервера в iso-8859-1/quoted. В этой кодировке русских букв нет.

Subject: 
   =?iso-8859-1?Q?=D3=E2=E5=E4=EE=EC=EB=E5=ED=E8=E5_=EE=E1_=EE=F2=E2?= 
   =?iso-8859-1?Q?=E5=F2=E5_=E2_=F2=E5=EC=E5_-_=D7=F2=EE_=ED=E5_=ED=F0=E0=E2?= 
   =?iso-8859-1?Q?=E8=F2=F1=FF_=ED=E0_=F1=E0=E9=F2=E5?=

Хотя тело сообщения - нормально в Windows-1251

MIME-Version: 1.0
Content-type: text/plain; charset=windows-1251 
Content-transfer-encoding: 8bit 

Лечение


Нужно изменить кодировку Subject на необходимую с русскими буквами(win1251, utf8, koi8r).

файл

PHPBB_DIR/include/emailer.php

после строчки

$this->subject = (($this->subject != '') ? $this->subject : 'No Subject');

Добавляется

$this->subject = '=?'.trim($lang['ENCODING']).'?B?'.base64_encode($this->subject).'?=';

И после - вуаля

X-Spam-Flag: NO 
X-Spam-Score: 0.034 
X-Spam-Level: 
X-Spam-Status: No, score=0.034 tagged_above=-10 required=4 
   tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, 
   TO_NO_BRKTS_MSFT=1.934] autolearn=no

По материалам этой темы, спасибо коллеге BW4ever за баг-репорт

среда, 11 января 2012 г.

Проблемы у Lenovo T420s под Ubuntu с подключением 2го монитора

Столкнулся с забавной проблемой  - Lenovo T420s на док-станции под Ubuntu не видит внешнего монитора через HDMI порт.

Кстати, через VGA у дока - тоже оказалось не все гладко, ибо тогда включается либо зеркальное отображение (одинаковая картинка и там и там), либо - на втором мониторе пустой рабочий стол, и окошки туда не перетащить (можно поменять местами по Fn+F7). Ну и заодно - разрешение и там и там одинаковое, что привело к размытому изображению на внешнем мониторе

Найдено простое GUI решение.

Устанавливается ARandR


И через него - спокойно меняются разрешения, и что самое интересное - нормально таскаются окошки.

Не иначе - как какое-то "злобное колдунство" (с). Вопрос с HDMI пока остается открытым.

понедельник, 9 января 2012 г.

Как подключить Яндекс-Спеллер (Yandex-Speller) к PHPBB?

Есть у Яндекс одна хорошая штука, до которой у меня долго не доходили руки...  а именно - проверка орфографии в формочках ввода - Яндекс-Спеллер. Оказалось, что зря откладывал - не так сложно.

Как подключить к форуму PHPBB2 (как модуль на RunCMS)? По идее - в чистом PHPBB2/3 не должно сильно отличаться, разве что файлы  будут другие, скорей всего...

1) Разместить на сайте папку с самим спеллером в /class/xoopsform/yandex_speller/ Затем

2) файл include/viewtopic_quickreply.php
 
$addon_html = '
<script type="text/javascript" src="'.XOOPS_URL.'/class/xoopsform/yandex_speller/spell.js"></script>

// YandexSpeller 

var speller = 

new Speller({ url:"/class/xoopsform/yandex_speller", lang:"ru", options:Speller.IGNORE_URLS });
// Настройка параметров проверки http://api.yandex.ru/speller/doc/dg/reference/speller-js.xml  

<button name="cmdSpell_message" onclick="speller.check([document.getElementById(\'message\')])" type="button">'._CORE_CHECK_ORPHO.'</button>
';

$template->assign_vars(array(
  'U_POST_SQR_TOPIC' => 'javascript:sqr_show_hide();',
  'SQR_IMG' => $images['quickreply'],
  'L_POST_SQR_TOPIC' => $lang['Show_hide_quick_reply_form'],

  'L_EMPTY_MESSAGE' => $lang['Empty_message'],
  'L_QUICK_REPLY' => $lang['Quick_Reply'],
  'L_USERNAME' => $lang['Username'],
  'L_NO_TEXT_SELECTED' => $lang['Qreply_no_text_selected'],
  'L_SUBJECT' => $lang['Subject'],
  'L_MESSAGE_BODY' => $lang['Message_body'],
  'L_PREVIEW' => $lang['Preview'],
  'L_SUBMIT' => $lang['Submit'],
  'S_POST_ACTION' => append_sid("posting.php"),
  'S_HIDDEN_FORM_FIELDS' => $hidden_form_fields,
  'ADDON_HTML' => $addon_html,
  )
);

где _CORE_CHECK_ORPHO - наш новый языковой дефайн, 'ADDON_HTML' => $addon_html, - добавленная строчка в код и шаблон.

3) правим шаблон

Особо расписывать не вижу смысла - все просто как грабли.


Как подключить спеллер к формам - читать тут.
Полное API
Навеяно вот этим хаком

пятница, 6 января 2012 г.

Как оптимизировать RunCMS? или Оптимизация CMS для начинающих

Решил перевыложить свою старую статью - она местами уже потеряла актуальность, да и RunCMS практически уже умерла, к сожалению - оставив после себя несколько веток-форков -на одной из которых и работает ScaleModels.ru, но люди спрашивают. Увы - некоторые вещи, приведенные тут уже устарели за несколько лет, некоторые - спорны, но  пусть будет в этом блоге - до кучи. 

RunCMS - достаточно неплохая система, дружественная для новичка в Web, которая позволяет худо-бедно, но решить большинство типовых задач для небольшого сайта одним приемом - «из коробки». Однако сайты имеют свойство либо умирать, либо развиваться, и в случае когда ваш ресурс выходит из категории «homepage про меня и моего хомячка Вову» (c) - начинаются проблемы с производительностью. Ситуация осложняется тем, что большие и серьезные CMS (такие как Drupal или Joomla) давно прошли этот этап «детских болезней» и способы решения подобных проблем для них давно известны и доступны. К сожалению, крупных проектов на RunCMS встречается не много, и информации о ней очень мало. На правах бывшего coreteam разработчика RunCMS я хочу рассказать о способах увеличения ее производительности.

Данная статья не предназначена для полных новичков - подразумевается, что вы в состоянии отличить PHP от Perl, способны разбираться в чужом коде, и примерно представляете архитектуру RunCMS (или XOOPS-like систем). Желательно, чтобы вы знали что такое my.cnf и где его искать ;-)

Есть два варианта хостинга - обычный и VPS/VDS.

Обычный хостинг

В плане оптимизаций - это жопа (если вкратце). Особенно если у вас провайдер, который не хочет ставить дополнительный софт и его настраивать. Начиная этак от 500 уников в день - готовьтесь к прессингу с его стороны - «давайте-ка переедем на выделенный сервер» (с) Один мой прошлый хостер на просьбу установить поддержку mbstring на свой шаред-хостинг спросил - «А зачем он вам нужен?» Но в принципе, мигрировать на свой сервер - это логичный вариант.

Что можно сделать для оптимизации RunCMS непосредственно в ней самой на SHARED хостинге?

MySQL таблицы для сессий

Находим MySQL таблицу sessions и конвертируем ее в тип MEMORY (если стоит PHPBB - то такая судьба должна постигнуть и phpbb_session) Этим мы выиграем небольшое количество скорости - но на КАЖДОЙ страницы сайта. Единственный минус - после перезагрузки сервера всем пользователям прийдется перелогиниваться, но результат того стоит.

Кэш страниц для гостей-анонимусов

Включаем кэширование страниц для гостей на как можно большее время - однако учитывайте, что для этого нужно хотя бы 50-100 мб свободного места на диске?

Включаем кэширование MySQL средствами класса DB

class/database/mysql.php

<?php

    var $file_cache = true;

?>


Это то, что можно было сделать нормальными ШТАТНЫМИ способами RunCMS, а теперь начинаем экспериментировать

Файл-кэш SELECT запросов

Изучаем код сайта и модулей, добавляя для тяжелых запросов кэширование через метод

<?php

$db->query($sql, false, false, ‘имя_файла’,  время_кэширования)

?>


ставя подходящие значения. Учитывайте только то, что кэш отрабатает только в том случае если результат запроса будет прогнан через fetch_row или fetch_array , а вот fetch_object в текущей версии не кэшируется?

Скомпилированное ядро

Включаем экспериментальное компилированное ядро (класс RCCoreApi) файл class/core.php

<?php

var $compiling = true;

?>

Данное «ядро» была введено мной в версии 1.6.1 - оно позволяет сэкономить примерно 6 SQL запросов на каждой странице, но несколько повысит нагрузку на PHP.

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

Вообще если вы любознательны и способны экспериментировать и разбираться с чужим кодом - внимательно изучайте стандартные классы RunCMS 1.6.1 и 1.6.2.

Немного яда и кидания какашек

Несмотря на то, что netshark просто вышвырнул меня из разработки RunCMS и вычеркнул из списка живых team, а впоследствии - передал код в лапы Farsus, который ее успешно и угробил :-) - в коде осталось много экспериментальных неофициальных настроек для увеличения производительности сайта

Например -

Кэш деревьев

Установить в классе xoopstree.php

<?php

define('RC_TREE_CACHE', 1); 

?>

это сильно поможет при работе с большими деревьями категорий - в таких модулях, как news, например

Кэширование блоков

Если внимательно посмотреть на табличку newblocks - вы увидите поле cache_time. При установке его в целое положительное значение N, блок будет закэширован на N минут. Обратите внимание - кэшировать имеет смысл только те блоки, которые выглядят ОДИНАКОВО для всех пользователей - если содержимое блока будет разным, то возможен конфликт.

RCCache и RCCachedPage

Использование классов RCCache и RCCachedPage, написанных совместно с Shurik2k5. В репозитории RunLiveCMS можно найти версии этих классов не только для файлового кэша (как в RunCMS), так и в базу MySQL и Memcache - что предпочтительней, с (или без) serializing данных

Настройка выделенного сервера (VPS/VDS)

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

Ниже только ОБЩИЕ рекомендации, куда стоит смотреть
  • Имеет смысл поставить PHP акселератор - на моем сервере стоит Zend Optimizer + eAccelerator. 
  • Тщательно настроить сервер MySQL - не забывайте про кэш запросов самого сервера и ограничение по времени медленных запросов
  • После настройки Apache - отключите access логи на картинках, оставив для них только error
  • Имеет смысл избавиться от .htaccess файлов, снеся все редиректы и настройки непосредственно в httpd.conf
  • Повесить на front-end (перед Apache) nginx и настройте его на отдачу статических файлов (таких как картинки, CSS, JS) - либо вообще отказаться в пользу Nginx + PHP-FASTCGI.
  • Используйте RAM-диск для критичных файловых кэшей - в моем случае туда сохраняется файловый кэш класса DB, compiled_kernel, блоки и кэши некоторых страниц
  • Обязательно используйте программы top, mtop и apachetop для мониторинга своей системы - ведь лучше вас ее не знает никто

По настройке выделенных серверов написано достаточно много, в частности тут - про Nginx, PHP, Memcache и тут про MySQL и насморки.


В моем случае - самый сильный выигрыш был от введения (по порядку важности)
  • Гостевое кэширование
  • Nginx
  • настройка MySQL
  • RAM диски на кэши кусков страниц, блоков и темплейтов форума /modules/forum(ну или phpBB2)/cache (всего около 200МБ RAM) - у меня форум, статьи и главная страница - основная нагрузка
  • eAccelerator
  • Таблицы сессии в MySQL MEMORY

Все остальное, честно говоря - из разряда "экономить на спичках" - не помешает, но без этого можно обойтись

Возможно, кому-то эти советы покажутся детским садом и «мурзилкой», но кому-то - сэкономят несколько минут «гугления» и чесания в затылке.

Изначально было опубликовано тут.

четверг, 5 января 2012 г.

Как исправить Permissions 0644 for '/Users/xxx/.ssh/id_dsa' are too open.


При миграции на новый комп после переноса SSH ключей через флешку при коннекте к удаленной машине появляется следующая ошибка

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Permissions 0644 for '/Users/xxx/.ssh/id_dsa' are too open.

It is recommended that your private key files are NOT accessible by others.

This private key will be ignored.

bad permissions: ignore key: /Users/xxx/.ssh/id_dsa

Лечится это следующим - нужно выставить права 700

cd ~/.ssh
chmod 700 id_rsa

понедельник, 26 декабря 2011 г.

Как избавиться от залипающих клавиш в VmWare vSphere Console для Linux Guest?

Возможно, вам знакома эта проблема...

Вы залогинены в vSphere клиент, у вас открыта Linux консоль виртуалки и когда вы что-то печатаете в ней - вместо одного символа появляются несколько одинаковых. Если честно - безумно раздражает, особенно когда нужно что-то сделать БЫСТРО на удаленной машине.

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

Вот тут рецепт как это сделать, правя .vmx файл, но я предпочитаю делать это прямо в клиенте vSphere.
  • Входим в клиент и "застреливаем гостя" (с) ;-)  "Shut Down Guest" (прости, друг ;-) )
  • Клик на "Edit Settings"
  • Выбираем вкладку "Options"
  • В списке под "Advanced" выбираем "General"
  • Справа нажимаем кнопку "Configuration Parameters"
  • Клик на "Add Row"
  • Вписываем имя новой переменной "keyboard.typematicMinDelay" и значение "2000000"
  • Перезагружаем виртуалку

Теперь вы сможете Войти как "root", вместо "rrrroooooott". ;-)

Весьма вольный перевод вот этой заметки, спасибо автору.

суббота, 24 декабря 2011 г.

Как настроить сервер? или оптимизация сайтов на PHP (Nginx, PHP, MySQL, Memcache)

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

Если же вы еще и не профессиональный HighLoad Linux-админ, а, например, разработчик (как я), то в процессе настройки прийдется ловить много-много граблей...  ;-)

Хочу немного улучшить состояние вашего лба, рассказав про те шишки, что набивал самостоятельно или с помощью более "администых" друзей. Специальные оптимизации на уровне правок PHP-кода не рассматриваю, это отдельная тема, сейчас - только сервер, консоль и вы, ну может где пару PHP скриптов немного поправить понадобится - буду считать, что свою CMS вы чуть-чуть знаете.

Ниже рассматривается достаточно часто встречаемая комбинация для сайтов: nginx + php (nginx+apache c php немного отличается - вместо fastcgi_xxx будет proxy_xxx).

Да, и считаем, что сейчас все компоненты вашей системы (nginx, php, mysql, memcache) крутятся на одной машине - как оно обычно и бывает на частных ресурсах.

PHP


  • Пускаем как fastcgi через сокет
  • Pconnect к базе - спорно
  • Не забываем акселератор (моя юзает eAccelerator) - хотя тоже есть спорные моменты

eAccelerator


Только для production машин можно отключить проверку Modified time - это абсолютно не подходит, если на сервере идет отладка скриптов - иначе будете ловить постоянные глюки и проблемы - включать только после того как сайт стал стабилен.

eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="0"
eaccelerator.shm_only="1"

Временые диски

tmpfs для /tmp и сессий PHP - все это сносится в память, если ее достаточно. В /etc/fstab добавляем

tmpfs                   /tmp                    tmpfs   defaults        0 0
tmpfs /var/lib/php tmpfs size=200M,nr_inodes=1m,nosuid 0 0

MySQL

  • Проверяем, включен ли query кэш
  • Также используем сокет
  • Если в вашей CMS используется таблица сессий - ставим для них тип MEMORY (если нет текстовых полей) - это приведет к сбросу всех залогиненных пользователей при перезагрузке сервера, но добавит немного скорости. Ну или если это неприемлемо - то надеюсь, она уже переведена в InnoDB? ;-)
  • Определяем оптимальное количество коннектов - статистика хотя бы за месяц (я юзаю munin). Ставим в 1.5-2 раза больше среднего.
Более подробно про оптимизацию MySQL можно прочитать тут.

Memcache

Если вся солянка крутится на одной машине - то также используем коннект через сокеты (по умолчанию не используется - стоит ip адрес). В таком варианте работы memcache возможны проблемы с некоторыми средствами мониторинга memcache (которые работают также по IP).

Не забываем в PHP использовать сжатие при работе с MEMCACHE.

Nginx

Ограничиваем число коннектов и запросов, особенно на ресурсоемкие скрипты
http {
...
    limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
    limit_zone three $binary_remote_addr 10m;

Включаем кэширование для неавторизованных гостей

http {
...
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=wholepage:50m inactive=15d max_size=5000m;
        location ~ .*\.php$ {
            limit_conn three 20;
            include         /etc/nginx/fastcgi.conf;
            fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass    unix:/var/run/php-fastcgi/php.socket;
            #access_log  /var/log/nginx/domain.access.log  my_combined;
            fastcgi_cache wholepage_guest;
            fastcgi_cache_valid 301 302 304 10m;
            fastcgi_cache_valid 200 360m;
            fastcgi_cache_valid 404 5s;
            fastcgi_cache_key "$request_method|$host|$request_uri";
            fastcgi_pass_header "Set-Cookie";
            fastcgi_ignore_headers "Cache-Control" "Expires";
            fastcgi_cache_bypass $cookie_phpbb_session $arg_nocache $arg_PHPSESSID;
            fastcgi_no_cache $cookie_phpbb_session $arg_nocache $arg_PHPSESSID;
    }
Где phpbb_session - имя куки по которой идет авторизация

Все запросы с ?nocache=1 и PHPSESSID попадают на PHP-бэкенд сразу без кэша не забываем открыть скрипт, по которому идет авторизация (в том числе и всякие капчи - их можно переписать на ?nocache=1) - тут возможно прийдется немного поковыряться и в коде CMS тоже.

        location /register.php {
                limit_conn three 20;
                include         /etc/nginx/fastcgi.conf;
                fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass    unix:/var/run/php-fastcgi/php.socket;
        }

Nginx - общие рекомендации

Очень нежелательно использовать location с регекспами - только простые префиксы вида
location /mymodule {}
Если от регекспов никак не избавится - то лучше их обрамлять простым location (Причина - сложноуловимые перехлесты в логике парсинга URL - кто за кем будет следовать)
location /mymodule {
  location ~ \/mymodule\/(.*)\.php$ {
    чего-то
  }

}

Отрубаем access лог для картинок

Разумеется - это только основные моменты оптимизации, на самом деле их гораздо больше. А какие трюки для уменьшения нагрузки на сервер знаете вы? Пишите в комментах.