技術者派遣の技術日誌ブログ

August 30, 2009

nswin32版 Ruby 1.8.7-p160 以降で Rails のビュー処理が遅すぎる

Filed under: Ruby/Ruby on Rails — Tags: , , , — AspAnn @ 6:11 am

僕の Ruby で何か作るときは、Windows 上で ActiveScriptRuby を使って開発しています。

 

今日、ActiveScriptRuby を 1.8.7-p72 から 1.8.7-p174 に変えてみたところ、Rails のビューの処理速度が極端に遅くなってしまいました。 検索してみると、どうやら ActiveScriptRuby というよりは nswin32版 Ruby が p72 → p160 になるときに、ビューの処理速度が遅くなってしまったようです。*1

ということで、一旦 ActiveScriptRuby を 1.8.7-p72 に戻そうと思ったのですが、探してみた限り 1.8.7 系のアーカイブはどこからもダウンロードできないっぽい(?)ので、arton さんのブログに p72 公開して欲しいですというコメントを投稿しました。その後、arton さんが Twitter をされていることがわかり、そちらにもメッセージを送ったところ、お返事を頂けました。

 

http://twitter.com/arton/status/2613686287

@kusakari http://www.artonx.org/data/asr/previous/ActiveRuby.msi が、多分、p72

ということで、早速 p72 をインストールして、再び快適に開発できるようになりました。

同じ問題で困っている ActionScriptRuby 同志のためにこの記事を残しておきます。

August 29, 2009

Rubyによりコーディングを行う際の規約について述べる

Filed under: LAMP, Ruby/Ruby on Rails — Tags: , , , — Sayuri @ 6:25 am

はじめに
本文書は、Rubyによりコーディングを行う際の規約について述べる。実際のプロジェクトに適用する際には、このコーディング規約をカスタマイズして用いることを推奨する。

ソースコードの整形
インデント
プログラムを読みやすくするため、インデントを適宜行う。インデント幅は2とする。また、インデントにはスペースのみを使用し、タブは使用しない。(環境によりタブ幅が異なるため。)

例:

if x > 0
if y > 0
puts “x > 0 && y > 0″
end
end
一行の桁数
一行の桁数は最大80桁までとする。

空行
複数のクラスの区切には空行を挿入する。

例:

class Foo

end

class Bar

end
誤った例:

class Foo

end
class Bar

end
また、クラス内の各構成要素の区切にも空行を挿入する。ただし、最初の構成要素の前や、最後の構成要素の後には空行は挿入しない。

例:

class Foo
attr :bar

def baz

end

def quux
..
end
end
誤った例:

class Foo

attr :bar

def baz

end

def quux

end

end
コメント
メソッド定義の中にはコメントは記述しない。(コメントが必要だと思われるようなコードにはリファクタリングを行う。)

ただし、クラス・モジュールやパブリックなメソッドには仕様をRDocスタイルで記述する。

例:

# コンマ区切の文字列+str+を分割し、結果を配列にして返す。
def split_csv(str)
return str.split(/,/)
end
構文に関する規約
クラスの構成要素
クラスの構成要素は以下の順序で記述する。

モジュールのインクルード
定数の定義
クラス変数・クラスのインスタンス変数の定義
パブリックなクラスメソッドの定義
アクセサの定義
initializeの定義
パブリックなインスタンスメソッドの定義
プロテクティッドなクラスメソッドの定義
プロテクティッドなアクセサの定義
プロテクティッドなインスタンスメソッドの定義
プライベートなクラスメソッドの定義
プライベートなアクセサの定義
プライベートなインスタンスメソッドの定義
ネストしたクラスの定義
アクセサの定義
アクセサの定義には、attr_accessor・attr_reader・ attr_writerを使用する。(attrは使用しない。)

メソッドの定義
メソッド定義の仮引数リストには括弧を付ける。ただし、引数がない場合は、括弧を省略する。

例:

def foo(x, y)

end

def foo

end
誤った例:

def foo x, y

end

def foo()

end
クラスメソッドの定義
クラスメソッドの定義にはselfを使用する。

例:

class Foo
def self.foo

end
end
誤った例:

class Foo
def Foo.foo

end
end
メソッド呼び出し
メソッド呼び出しの引数リストには括弧を付ける。ただし、引数がない場合は、括弧を省略する。また、printやputsやpの場合は、引数の括弧を省略してもよい。

例:

foo(1, “abc”)
obj.foo(1, “abc”)
bar
print “x = “, x, “\n”
誤った例:

foo 1, “abc”
obj.foo 1, “abc”
bar()
ブロック
ブロックは基本的にdo … endを使用する。

例:

foo(x, y) do

end

x = bar(y, z) do

end
誤った例:

foo(x, y) {

}

x = bar(y, z) {

}
ただし、メソッドチェインを行う場合は{ … }を使用する。

例:

s = ary.collect { |i| i.to_s }.join(“,”)
誤った例:

s = ary.collect do |i| i.to_s end.join(“,”)
return
メソッドの値を返す場合は、必ずreturnを使用する。また、returnの括弧は省略する。

例:

def add(x, y)
return x + y
end
誤った例:

def add(x, y)
x + y
end

def add(x, y)
return(x + y)
end
yield
yieldの呼び出し方法はメソッド呼び出しに準ずる。

条件分岐
if式のthenは省略する。また、if !xのような場合は、 unless xに置き換える。ただし、unlessの場合、 elseは使用しない。また、条件が十分に簡単で、一行で書ける場合は、if/while修飾子を使用してもよい。

例:

if x > 0
puts “x > 0″
else
puts “x <= 0"
end

unless x
puts "x is false"
end

puts "x is true" if x
誤った例:

if x > 0 then
puts “x > 0″
end

unless x
puts “x is false”
else
puts “x is true”
end

puts “foo && bar && baz && quux” if foo &&
bar && baz && quux
caseを使用できる場合は、caseを使用する。また、thenは省略する。

例:

case x
when 1

when 2

end
誤った例:

if x == 1

elsif x == 2

end

case x
when 1 then

when 2 then

end
条件分岐の式の値は使用しない。

例:

if x > 0
msg = “x > 0″
else
msg = “x <= 0"
end
誤った例:

msg = if x > 0
“x > 0″
else
“x <= 0″
end
繰り返し
whileのdoは省略する。また、while !xのような場合は、 until xに置き換える。

例:

while cond

end

until cond

end
誤った例:

while cond do

end
また、無限ループにはloopを使用する。

例:

loop do

end
誤った例:

while true

end
論理演算子
論理演算には!や&&や||を使用する。 (not/and/orは使用しない。)

三項演算子
明らかに可読性に問題がない場合を除いて、三項演算子はなるべく使用しない。とくに、括弧が必要なほど条件が複雑な場合や、複数行になってしまう場合は、三項演算子は使用しない。

文字列リテラル
文字列リテラルには基本的に”…”を使用する。ただし、特殊文字を解釈させたくない場合のみ、’…’を使用する。また、原則的にヒアドキュメントは使用しない。

命名規約
全般
原則として、単語の省略は行わない。
スコープが狭いループ変数には、i, j, kという名前をこの順序で使 用する。
スコープが狭い変数名には、クラス名を省略したものを使用してよい。 (例: eo = ExampleObject.new)
クラス・モジュール名
クラス・モジュール名は、各単語の一文字目を大文字にし、`_’などの区切文字は使用しない。ただし、HTTPなどの略語の場合はすべて大文字のままとする。

例:

ExampleClass
HTTPClient
誤った例:

Example_Class
EXAMPLE_CLASS
HttpClient
HTTPclient
HTTP_Client
メソッド名
メソッド名は、すべて小文字とし、単語の区切りに`_’を用いる。メソッド名には動詞の原形を使用する。

例:

add_something
誤った例:

addsSomething
Add_Something
真偽値を返すメソッド名は、動詞または形容詞に`?’を付け、形容詞に `is_’は付けない。

例:

visible?
誤った例:

is_visible
is_visible?
また、破壊的なメソッドと非破壊的なメソッドの両方を提供する場合、破壊的なメソッドには`!’を付ける。

例:

split
split! # splitの破壊的バージョン
定数名
クラス・モジュール名以外の定数名は、すべて大文字とし、単語の区切りに`_’を用いる。

例:

EXAMPLE_CONSTANT
変数名
変数名は、すべて小文字とし、単語の区切りに`_’を用いる。

例:

tmp
local_variable
@instance_variable
$global_variable
ファイル名
ファイル名は、すべて小文字とし、単語の区切りに`-’を用いる。また、ファイル中の主な定義クラスの名前を変換したものをファイル名に使用する。(モジュールを名前空間として使用する場合は、ディレクトリを使用して階層構造を表現する。)

例:

foo.rb # クラスFooを定義
foo-bar.rb # クラスFooBarを定義
foo/bar-baz.rb # クラスFoo::BarBazを定義
Copyright (C) 2007 Shugo Maeda

August 27, 2009

【Tips】C#でオブジェクト<->JSONの変換を行うには

Filed under: C# — Tags: , — strmozo @ 4:10 pm

C#でオブジェクトをJSON形式でシリアライズするにはまずシリアライズするクラスにDataContract属性とそのプロパティにDataMember属性を設定しておく。

[System.Runtime.Serialization.DataContract()]
public class Class1
{
    [System.Runtime.Serialization.DataMember()]
    public int Number001 { get; set; }
    [System.Runtime.Serialization.DataMember()]
    public string Text001 { get; set; }
}

下記のようにしてシリアライズ、デシリアライズを行える。

class Program
{
    static void Main(string[] args)
    {
         var converter = new System.ServiceModel.Dispatcher.JsonQueryStringConverter();

        // Class1のインスタンスをJSONにシリアライズ
        string json1 = converter.ConvertValueToString(new Class1() { Number001 = 123, Text001 = "test" }, typeof(Class1));
        // JSONをClass1のインスタンスにデシリアライズ
        Class1 obj1 = (Class1)converter.ConvertStringToValue("{\"Number001\":123,\"Text001\":\"str\"}", typeof(Class1));
    }
}

[Tips]SQLServer, MySQL, SQLiteで自動採番列の結果を取得するには

Filed under: MS SQL Server, MYSQL — Tags: , , , — citiszo @ 9:07 am

自動採番列で振られた連番の結果はそれぞれ下記のSQLで取得する。

SQL Server
select SCOPE_IDENTITY()
SQLite
select last_insert_rowid()
Mysql
select LAST_INSERT_ID()
自動採番列の作成方法は下記のように「INTEGER PRIMARY KEY」を指定する。

CREATE TABLE `Table1` (`ID` INTEGER PRIMARY KEY ,`Col1` TEXT,`Col2` TEXT)

[How to ]Visual StudioのプロジェクトにSQL ServerのDB(サービスベースのデータベース)を追加できない。

Filed under: MS SQL Server — Tags: , — citiszo @ 8:09 am

Visual Studioで「サービスベースのデータベース」を追加した際に、
「ユーザーインスタンスのプロセス起動中のエラーにより、SQL Server のユーザー インスタンスを生成できませんでした。接続は閉じられます。 」のエラーが発生。
エラーの詳細は「C:\Users\ユーザ名\AppData\Local\Microsoft\Microsoft SQL Server Data\SQLEXPRESS」に出る。エラーの内容が

FCB::Open failed: Could not open file C:\Program Files\Microsoft SQL Server\MSSQL.4\MSSQL\Template Data\model.mdf for file number 1. OS error: 3(指定されたパスが見つかりません。).

などのテンプレートデータベースのパスが原因のエラーの場合は「C:\Users\ユーザ名\AppData\Local\Microsoft\Microsoft SQL Server Data\SQLEXPRESS」中にあるシステムデータベースが古いものである可能性が高いので、一旦全部削除すると起動できるようになる。

【How to】Nginx + PHP(FastCGIモード)で最速なwebサーバ

Filed under: LAMP, MYSQL, PHP — Tags: , , , — Sayuri @ 1:04 am

Nginx + PHP(FastCGIモード)で最速なwebサーバを構築します。
大体の内容は中国の張宴ブログ を参照して翻訳したものです。

Nginx(エンジンエックス)とは
軽量高性能なWebサーバ/リバースプロキシであり、同時に電子メール(IMAP/POP3)プロキシであります。
nginx は当初、Ramblerが運営する各種ウェブサイトのニーズを満たすために開発された。2009年5月のネットクラフトの調査によれば、nginx は6,342,250のドメインで使われており、Webサーバとしてのシェアは第5位であります。

中国とアメリカで、すでに一般的に使われています。

張宴さんのテストよりパフォーマンス的にapacheの10倍です。
筆者もwebbenchを使ってテストしました、張宴さんと似ている結果を得ました。

Nginxはepoll(Linux Kernel2.6)とkqueue(freebsd)のI/Oスケジューラを使用して、伝統的なselectスケジューラを使用するApacheより速いです。
epollのI/OスケジューラはSquidとMemcachedなどに使われています。

selectとepollのイメージを説明すれば
例え、友達は学校の寮に住んでいるあなたを探しに行きます。
select版管理人は友達を連れて、一つ一つの部屋をチェックして探します。
epoll版管理人はまずあなたの部屋番号を記録して、友達が来たら部屋番号を教えて、連れて人を探すのは必要はありません。

インストール(テスト環境:CentOS5.3、4Gメモリサーバ)

一、必要なパッケージをGet

1、基本のパッケージをyumで入れる

yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers

2、最新安定版パッケージをダウンロード(2009年06月26日時点)

mkdir -p /data0/software
cd /data0/software
wget http://sysoev.ru/nginx/nginx-0.7.61.tar.gz
wget http://www.php.net/get/php-5.2.10.tar.gz/from/this/mirror
wget http://blog.s135.com/soft/linux/nginx_php/phpfpm/php-5.2.10-fpm-0.5.11.diff.gz
wget http://dev.mysql.com/get/Downloads/MySQL-5.1/mysql-5.1.35.tar.gz/from/http://mysql.he.net/
wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.13.tar.gz
wget “http://downloads.sourceforge.net/mcrypt/libmcrypt-2.5.8.tar.gz?modtime=1171868460&big_mirror=0″
wget “http://downloads.sourceforge.net/mcrypt/mcrypt-2.6.8.tar.gz?modtime=1194463373&big_mirror=0″
wget http://pecl.php.net/get/memcache-2.2.5.tgz
wget “http://downloads.sourceforge.net/mhash/mhash-0.9.9.9.tar.gz?modtime=1175740843&big_mirror=0″
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-7.9.tar.gz
wget http://bart.eaccelerator.net/source/0.9.5.3/eaccelerator-0.9.5.3.tar.bz2
wget http://pecl.php.net/get/PDO_MYSQL-1.0.2.tgz
wget http://blog.s135.com/soft/linux/nginx_php/imagick/ImageMagick.tar.gz
wget http://pecl.php.net/get/imagick-2.2.2.tgz

二、PHP 5.2.10(FastCGIモード)インストール

FastCGIはプロセスをメモリ上に永続化させることで、HTTPリクエストが来るとsocketを通じてコマンドと結果の交換をするというインタフェースです

1、必要なパッケージ

tar zxvf libiconv-1.13.tar.gz
cd libiconv-1.13/
./configure –prefix=/usr/local
make
make install
cd ../

tar zxvf libmcrypt-2.5.8.tar.gz
cd libmcrypt-2.5.8/
./configure
make
make install
/sbin/ldconfig
cd libltdl/
./configure –enable-ltdl-install
make
make install
cd ../../

tar zxvf mhash-0.9.9.9.tar.gz
cd mhash-0.9.9.9/
./configure
make
make install
cd ../

ln -s /usr/local/lib/libmcrypt.la /usr/lib/libmcrypt.la
ln -s /usr/local/lib/libmcrypt.so /usr/lib/libmcrypt.so
ln -s /usr/local/lib/libmcrypt.so.4 /usr/lib/libmcrypt.so.4
ln -s /usr/local/lib/libmcrypt.so.4.4.8 /usr/lib/libmcrypt.so.4.4.8
ln -s /usr/local/lib/libmhash.a /usr/lib/libmhash.a
ln -s /usr/local/lib/libmhash.la /usr/lib/libmhash.la
ln -s /usr/local/lib/libmhash.so /usr/lib/libmhash.so
ln -s /usr/local/lib/libmhash.so.2 /usr/lib/libmhash.so.2
ln -s /usr/local/lib/libmhash.so.2.0.1 /usr/lib/libmhash.so.2.0.1

tar zxvf mcrypt-2.6.8.tar.gz
cd mcrypt-2.6.8/
/sbin/ldconfig
./configure
make
make install
cd ../

2、MySQL 5.1.35インストール

/usr/sbin/groupadd mysql
/usr/sbin/useradd -g mysql mysql
tar zxvf mysql-5.1.35.tar.gz
cd mysql-5.1.35/
./configure –prefix=/usr/local/webserver/mysql/ –enable-assembler –with-extra-charsets=complex –enable-thread-safe-client –with-big-tables –with-readline –with-ssl –with-embedded-server –enable-local-infile –with-plugins=innobase
make && make install
chmod +w /usr/local/webserver/mysql
chown -R mysql:mysql /usr/local/webserver/mysql
cd ../

①MySQLデータベースフォルダを作成

mkdir -p /data0/mysql/3306/data/
chown -R mysql:mysql /data0/mysql/

②mysqlユーザでDBを作成

/usr/local/webserver/mysql/bin/mysql_install_db –basedir=/usr/local/webserver/mysql –datadir=/data0/mysql/3306/data –user=mysql

③my.cnf作成

vi /data0/mysql/3306/my.cnf

以下の内容を

[client]
default-character-set = utf8
port = 3306
socket = /tmp/mysql.sock

[mysql]
prompt=”(\u:blog.s135.com:)[\d]> ”
no-auto-rehash

[mysqld]
#default-character-set = utf8
user = mysql
port = 3306
socket = /tmp/mysql.sock
basedir = /usr/local/webserver/mysql
datadir = /data0/mysql/3306/data
open_files_limit = 10240
back_log = 600
max_connections = 3000
max_connect_errors = 6000
table_cache = 614
external-locking = FALSE
max_allowed_packet = 32M
sort_buffer_size = 2M
join_buffer_size = 2M
thread_cache_size = 300
thread_concurrency = 8
query_cache_size = 32M
query_cache_limit = 2M
query_cache_min_res_unit = 2k
default-storage-engine = MyISAM
default_table_type = MyISAM
thread_stack = 192K
transaction_isolation = READ-COMMITTED
tmp_table_size = 246M
max_heap_table_size = 246M
long_query_time = 1
log_long_format
log-bin = /data0/mysql/3306/binlog
binlog_cache_size = 4M
binlog_format = MIXED
max_binlog_cache_size = 8M
max_binlog_size = 512M
expire_logs_days = 7
key_buffer_size = 256M
read_buffer_size = 1M
read_rnd_buffer_size = 16M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
myisam_max_extra_sort_file_size = 10G
myisam_repair_threads = 1
myisam_recover

skip-name-resolve
master-connect-retry = 10
slave-skip-errors = 1032,1062,126,1114,1146,1048,1396

server-id = 1

innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 2048M
innodb_data_file_path = ibdata1:1024M:autoextend
innodb_file_io_threads = 4
innodb_thread_concurrency = 8
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 16M
innodb_log_file_size = 128M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120
innodb_file_per_table = 0
[mysqldump]
quick
max_allowed_packet = 32M

④MySQL shellスクリプト作成

vi /data0/mysql/3306/mysql

以下の内容を入力(ユーザ:admin パスワード:12345678)

#!/bin/sh

mysql_port=3306
mysql_username=”admin”
mysql_password=”12345678″

function_start_mysql()
{
printf “Starting MySQL…\n”
/bin/sh /usr/local/webserver/mysql/bin/mysqld_safe –defaults-file=/data0/mysql/${mysql_port}/my.cnf 2>&1 > /dev/null &
}

function_stop_mysql()
{
printf “Stoping MySQL…\n”
/usr/local/webserver/mysql/bin/mysqladmin -u ${mysql_username} -p${mysql_password} -S /tmp/mysql.sock shutdown
}

function_restart_mysql()
{
printf “Restarting MySQL…\n”
function_stop_mysql
sleep 5
function_start_mysql
}

function_kill_mysql()
{
kill -9 $(ps -ef | grep ‘bin/mysqld_safe’ | grep ${mysql_port} | awk ‘{printf $2}’)
kill -9 $(ps -ef | grep ‘libexec/mysqld’ | grep ${mysql_port} | awk ‘{printf $2}’)
}

if [ "$1" = "start" ]; then
function_start_mysql
elif [ "$1" = "stop" ]; then
function_stop_mysql
elif [ "$1" = "restart" ]; then
function_restart_mysql
elif [ "$1" = "kill" ]; then
function_kill_mysql
else
printf “Usage: /data0/mysql/${mysql_port}/mysql {start|stop|restart|kill}\n”
fi

⑤shell実行権限

chmod +x /data0/mysql/3306/mysql

⑥MySQL起動

/data0/mysql/3306/mysql start

⑦登録

/usr/local/webserver/mysql/bin/mysql -u root -p -S /tmp/mysql.sock

⑧ユーザ作成

GRANT ALL PRIVILEGES ON *.* TO ‘admin’@’localhost’ IDENTIFIED BY ‘12345678′;
GRANT ALL PRIVILEGES ON *.* TO ‘admin’@’127.0.0.1′ IDENTIFIED BY ‘12345678′;

⑨MySQL停止の場合

/data0/mysql/3306/mysql stop

3、PHP(FastCGIモード)インストール

tar zxvf php-5.2.10.tar.gz
gzip -cd php-5.2.10-fpm-0.5.11.diff.gz | patch -d php-5.2.10 -p1
cd php-5.2.10/
./configure –prefix=/usr/local/webserver/php –with-config-file-path=/usr/local/webserver/php/etc –with-mysql=/usr/local/webserver/mysql –with-mysqli=/usr/local/webserver/mysql/bin/mysql_config –with-iconv-dir=/usr/local –with-freetype-dir –with-jpeg-dir –with-png-dir –with-zlib –with-libxml-dir=/usr –enable-xml –disable-rpath –enable-discard-path –enable-safe-mode –enable-bcmath –enable-shmop –enable-sysvsem –enable-inline-optimization –with-curl –with-curlwrappers –enable-mbregex –enable-fastcgi –enable-fpm –enable-force-cgi-redirect –enable-mbstring –with-mcrypt –with-gd –enable-gd-native-ttf –with-openssl –with-mhash –enable-pcntl –enable-sockets –with-ldap –with-ldap-sasl –with-xmlrpc –enable-zip –enable-soap –without-pear
make ZEND_EXTRA_LIBS=’-liconv’
make install
cp php.ini-dist /usr/local/webserver/php/etc/php.ini
cd ../

4、PHPモジュール

tar zxvf memcache-2.2.5.tgz
cd memcache-2.2.5/
/usr/local/webserver/php/bin/phpize
./configure –with-php-config=/usr/local/webserver/php/bin/php-config
make
make install
cd ../

tar jxvf eaccelerator-0.9.5.3.tar.bz2
cd eaccelerator-0.9.5.3/
/usr/local/webserver/php/bin/phpize
./configure –enable-eaccelerator=shared –with-php-config=/usr/local/webserver/php/bin/php-config
make
make install
cd ../

tar zxvf PDO_MYSQL-1.0.2.tgz
cd PDO_MYSQL-1.0.2/
/usr/local/webserver/php/bin/phpize
./configure –with-php-config=/usr/local/webserver/php/bin/php-config –with-pdo-mysql=/usr/local/webserver/mysql
make
make install
cd ../

tar zxvf ImageMagick.tar.gz
cd ImageMagick-6.5.1-2/
./configure
make
make install
cd ../

tar zxvf imagick-2.2.2.tgz
cd imagick-2.2.2/
/usr/local/webserver/php/bin/phpize
./configure –with-php-config=/usr/local/webserver/php/bin/php-config
make
make install
cd ../

5、php.ini修正

vi /usr/local/webserver/php/etc/php.ini

extension_dir = “./”

extension_dir = “/usr/local/webserver/php/lib/php/extensions/no-debug-non-zts-20060613/”

に編集、最後に以下の行を追加

extension = “memcache.so”
extension = “pdo_mysql.so”
extension = “imagick.so”

また

output_buffering = Off

output_buffering = On

に編集

或いは、以下の方法でphp.iniを一揆編集

sed -i ’s#extension_dir = “./”#extension_dir = “/usr/local/webserver/php/lib/php/extensions/no-debug-non-zts-20060613/”\nextension = “memcache.so”\nextension = “pdo_mysql.so”\nextension = “imagick.so”\n#’ /usr/local/webserver/php/etc/php.ini
sed -i ’s#output_buffering = Off#output_buffering = On#’ /usr/local/webserver/php/etc/php.ini
sed -i “s#; always_populate_raw_post_data = On#always_populate_raw_post_data = On#g” /usr/local/webserver/php/etc/php.ini

6、eAccelerator

mkdir -p /usr/local/webserver/eaccelerator_cache
vi /usr/local/webserver/php/etc/php.ini

一番最後に以下のを追加

[eaccelerator]
zend_extension=”/usr/local/webserver/php/lib/php/extensions/no-debug-non-zts-20060613/eaccelerator.so”
eaccelerator.shm_size=”64″
eaccelerator.cache_dir=”/usr/local/webserver/eaccelerator_cache”
eaccelerator.enable=”1″
eaccelerator.optimizer=”1″
eaccelerator.check_mtime=”1″
eaccelerator.debug=”0″
eaccelerator.filter=””
eaccelerator.shm_max=”0″
eaccelerator.shm_ttl=”3600″
eaccelerator.shm_prune_period=”3600″
eaccelerator.shm_only=”0″
eaccelerator.compress=”1″
eaccelerator.compress_level=”9″

7、wwwユーザとグループ作成

/usr/sbin/groupadd www
/usr/sbin/useradd -g www www
mkdir -p /data0/htdocs/blog
chmod +w /data0/htdocs/blog
chown -R www:www /data0/htdocs/blog
mkdir -p /data0/htdocs/www
chmod +w /data0/htdocs/www
chown -R www:www /data0/htdocs/www

8、php-fpmコンフィグファイル作成
php.iniが修正された場合、php-cgiを再起動する必要はない(reloadを使える)

vi /usr/local/webserver/php/etc/php-fpm.conf

以下の内容を入力
(Debugの時、<value name=”display_errors”>0</value>を<value name=”display_errors”>1</value>に編集)

<?xml version=”1.0″ ?>
<configuration>

All relative paths in this config are relative to php’s install prefix

<section name=”global_options”>

Pid file
<value name=”pid_file”>/usr/local/webserver/php/logs/php-fpm.pid</value>

Error log file
<value name=”error_log”>/usr/local/webserver/php/logs/php-fpm.log</value>

Log level
<value name=”log_level”>notice</value>

When this amount of php processes exited with SIGSEGV or SIGBUS …
<value name=”emergency_restart_threshold”>10</value>

… in a less than this interval of time, a graceful restart will be initiated.
Useful to work around accidental curruptions in accelerator’s shared memory.
<value name=”emergency_restart_interval”>1m</value>

Time limit on waiting child’s reaction on signals from master
<value name=”process_control_timeout”>5s</value>

Set to ‘no’ to debug fpm
<value name=”daemonize”>yes</value>

</section>

<workers>

<section name=”pool”>

Name of pool. Used in logs and stats.
<value name=”name”>default</value>

Address to accept fastcgi requests on.
Valid syntax is ‘ip.ad.re.ss:port’ or just ‘port’ or ‘/path/to/unix/socket’
<value name=”listen_address”>127.0.0.1:9000</value>

<value name=”listen_options”>

Set listen(2) backlog
<value name=”backlog”>-1</value>

Set permissions for unix socket, if one used.
In Linux read/write permissions must be set in order to allow connections from web server.
Many BSD-derrived systems allow connections regardless of permissions.
<value name=”owner”></value>
<value name=”group”></value>
<value name=”mode”>0666</value>
</value>

Additional php.ini defines, specific to this pool of workers.
<value name=”php_defines”>
<value name=”sendmail_path”>/usr/sbin/sendmail -t -i</value>
<value name=”display_errors”>1</value>
</value>

Unix user of processes
<value name=”user”>www</value>

Unix group of processes
<value name=”group”>www</value>

Process manager settings
<value name=”pm”>

Sets style of controling worker process count.
Valid values are ’static’ and ‘apache-like’
<value name=”style”>static</value>

Sets the limit on the number of simultaneous requests that will be served.
Equivalent to Apache MaxClients directive.
Equivalent to PHP_FCGI_CHILDREN environment in original php.fcgi
Used with any pm_style.
<value name=”max_children”>128</value>

Settings group for ‘apache-like’ pm style
<value name=”apache_like”>

Sets the number of server processes created on startup.
Used only when ‘apache-like’ pm_style is selected
<value name=”StartServers”>20</value>

Sets the desired minimum number of idle server processes.
Used only when ‘apache-like’ pm_style is selected
<value name=”MinSpareServers”>5</value>

Sets the desired maximum number of idle server processes.
Used only when ‘apache-like’ pm_style is selected
<value name=”MaxSpareServers”>35</value>

</value>

</value>

The timeout (in seconds) for serving a single request after which the worker process will be terminated
Should be used when ‘max_execution_time’ ini option does not stop script execution for some reason
‘0s’ means ‘off’
<value name=”request_terminate_timeout”>0s</value>

The timeout (in seconds) for serving of single request after which a php backtrace will be dumped to slow.log file
‘0s’ means ‘off’
<value name=”request_slowlog_timeout”>0s</value>

The log file for slow requests
<value name=”slowlog”>logs/slow.log</value>

Set open file desc rlimit
<value name=”rlimit_files”>51200</value>

Set max core size rlimit
<value name=”rlimit_core”>0</value>

Chroot to this directory at the start, absolute path
<value name=”chroot”></value>

Chdir to this directory at the start, absolute path
<value name=”chdir”></value>

Redirect workers’ stdout and stderr into main error log.
If not set, they will be redirected to /dev/null, according to FastCGI specs
<value name=”catch_workers_output”>yes</value>

How much requests each process should execute before respawn.
Useful to work around memory leaks in 3rd party libraries.
For endless request processing please specify 0
Equivalent to PHP_FCGI_MAX_REQUESTS
<value name=”max_requests”>102400</value>

Comma separated list of ipv4 addresses of FastCGI clients that allowed to connect.
Equivalent to FCGI_WEB_SERVER_ADDRS environment in original php.fcgi (5.2.2+)
Makes sense only with AF_INET listening socket.
<value name=”allowed_clients”>127.0.0.1</value>

Pass environment variables like LD_LIBRARY_PATH
All $VARIABLEs are taken from current environment
<value name=”environment”>
<value name=”HOSTNAME”>$HOSTNAME</value>
<value name=”PATH”>/usr/local/bin:/usr/bin:/bin</value>
<value name=”TMP”>/tmp</value>
<value name=”TMPDIR”>/tmp</value>
<value name=”TEMP”>/tmp</value>
<value name=”OSTYPE”>$OSTYPE</value>
<value name=”MACHTYPE”>$MACHTYPE</value>
<value name=”MALLOC_CHECK_”>2</value>
</value>

</section>

</workers>

</configuration>

9、php-cgiプロセスを起動
127.0.0.1の9000ポートをlistenさせて、プロセス数は200(サーバメモリは3GBに足りてない場合,64プロセスを開いても構わない),ユーザはwww

ulimit -SHn 51200
/usr/local/webserver/php/sbin/php-fpm start

補足:
/usr/local/webserver/php/sbin/php-fpmはstart|stop|quit|restart|reload|logrotateなどのパラメータがある
php.iniを修正する場合、reloadでリロード

三、Nginx 0.7.61インストール
――――――――――――――
1、pcreインストール

tar zxvf pcre-7.9.tar.gz
cd pcre-7.9/
./configure
make && make install
cd ../

2、Nginxインストール

tar zxvf nginx-0.7.61.tar.gz
cd nginx-0.7.61/
./configure –user=www –group=www –prefix=/usr/local/webserver/nginx –with-http_stub_status_module –with-http_ssl_module
make && make install
cd ../

3、ログ作成

mkdir -p /data1/logs
chmod +w /data1/logs
chown -R www:www /data1/logs

4、コンフィグ
①nginxファイルを作成

vi /usr/local/webserver/nginx/conf/nginx.conf

以下の内容を入力

user www www;

worker_processes 8;

error_log /data1/logs/nginx_error.log crit;

pid /usr/local/webserver/nginx/nginx.pid;

#Specifies the value for maximum file descriptors that can be opened by this process.
worker_rlimit_nofile 51200;

events
{
use epoll;
worker_connections 51200;
}

http
{
include mime.types;
default_type application/octet-stream;

#charset gb2312;

server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 8m;

sendfile on;
tcp_nopush on;

keepalive_timeout 60;

tcp_nodelay on;

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;

gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;

#limit_zone crawler $binary_remote_addr 10m;

server
{
listen 80;
server_name blog.s135.com;
index index.html index.htm index.php;
root /data0/htdocs/blog;

#limit_conn crawler 20;

location ~ .*\.(php|php5)?$
{
#fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}

location ~ .*\.(js|css)?$
{
expires 1h;
}

log_format access ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” $http_x_forwarded_for’;
access_log /data1/logs/access.log access;
}

server
{
listen 80;
server_name www.s135.com;
index index.html index.htm index.php;
root /data0/htdocs/www;

location ~ .*\.(php|php5)?$
{
#fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}

log_format wwwlogs ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” $http_x_forwarded_for’;
access_log /data1/logs/wwwlogs.log wwwlogs;
}

server
{
listen 80;
server_name status.blog.s135.com;

location / {
stub_status on;
access_log off;
}
}
}

②fcgi.confコンフィグを作成

vi /usr/local/webserver/nginx/conf/fcgi.conf

以下の内容を入力

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;

fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;

fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;

# PHP only, required if PHP was built with –enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;

5、Nginx起動

ulimit -SHn 51200
/usr/local/webserver/nginx/sbin/nginx

四、Nginx自動起動

vi /etc/rc.local

最後に以下のを追加

ulimit -SHn 51200
/usr/local/webserver/php/sbin/php-fpm start
/usr/local/webserver/nginx/sbin/nginx

五、Linux Kernelパラメータを最適化

vi /etc/sysctl.conf

最後に以下のを追加

# Add
net.ipv4.tcp_max_syn_backlog = 65536
net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768

net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216

net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2

net.ipv4.tcp_tw_recycle = 1
#net.ipv4.tcp_tw_len = 1
net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_max_orphans = 3276800

#net.ipv4.tcp_fin_timeout = 30
#net.ipv4.tcp_keepalive_time = 120
net.ipv4.ip_local_port_range = 1024 65535

設定反映

/sbin/sysctl -p

六、Nginxサービスを停止しないまま、Nginxを設定変更
1、/usr/local/webserver/nginx/conf/nginx.confを修正したら、以下のコマンドで

/usr/local/webserver/nginx/sbin/nginx -t

修正結果が正しいかどうかをチェック

今のメッセージが表示すれば、OK
the configuration file /usr/local/webserver/nginx/conf/nginx.conf syntax is ok
the configuration file /usr/local/webserver/nginx/conf/nginx.conf was tested successfully

2、以下のコマンドでNginxプロセスを調査

ps -ef | grep “nginx: master process” | grep -v “grep” | awk -F ‘ ‘ ‘{print $2}’

例えば、プロセスは
6302
の場合には、以下コマンドで実行すれば設定内容が反映できる

kill -HUP 6302

または、NginxのPidファイルを直接にkill -HUP して、新しい設定が反映できる

kill -HUP `cat /usr/local/webserver/nginx/nginx.pid`

七、crontabでNginxログ管理
1、shellスクリプト作成

vi /usr/local/webserver/nginx/sbin/cut_nginx_log.sh

以下の内容を入力

#!/bin/bash
# This script run at 00:00

# The Nginx logs path
logs_path=”/usr/local/webserver/nginx/logs/”

mkdir -p ${logs_path}$(date -d “yesterday” +”%Y”)/$(date -d “yesterday” +”%m”)/
mv ${logs_path}access.log ${logs_path}$(date -d “yesterday” +”%Y”)/$(date -d “yesterday” +”%m”)/access_$(date -d “yesterday” +”%Y%m%d”).log
kill -USR1 `cat /usr/local/webserver/nginx/nginx.pid`

2、crontab設置,毎日朝00:00からnginxログ管理

crontab -e

以下の内容を入力

00 00 * * * /bin/bash /usr/local/webserver/nginx/sbin/cut_nginx_log.sh

August 26, 2009

[How to]Python + Django でURLにセッションを組み込む(携帯で使えるはず)

Filed under: LAMP, Python — Tags: , — citiszo @ 9:05 pm

Python界では有名なWEBアプリケーションフレームワークであるDjango

いろいろと高機能なんですが、ひとつだけ困ったことが。
それは「セッションがクッキーベース」なこと。

確かにこの方がセキュアですし、おススメなんですが、
携帯向けにECサイトを作成しようとすると必ずネックになるのが
クッキーが使えない!ということ。(一部の端末では対応していますが)

そこでDjangoでセッションキー(セッションID)をURL(またはPOST/GET)に
埋め込む方法を考えてみました。

まずDjangoでクッキーが使えないとどうなるでしょうか?

クッキーが使えない

クッキーでセッションキーを読み書きできない

セッションキーをキーとしてサーバに保存されているセッション情報を読み書きできない

セッション情報に保存されている認証情報を利用できない

認証が行えず、会員制サイトなどが構築できない。

・・・となり、結構根が深い訳です。
これでは携帯でECサイト構築なんてできないですよね。。

そこで無いものは作ってしまえぃ、ということで、
Djangoのセッションと認証周りをソースレベルで調べてみました。

ソースについての詳細は省きますが、
結論としては意外と簡単にできるんです!
以下にやり方を書いておきます。

(1)
一番コアな部分は実は1つだけ。
views.pyに

from django.conf import settings
engine = __import__(settings.SESSION_ENGINE, {}, {}, [''])
def session_url(original):
    def decorated(request, *args, **keywords):
        request.session = engine.SessionStore(request.GET['session_key'] or request.POST['session_key'])
        return original(request, *args, **keywords)
    return decorated

を追加してください。
ここに全てが詰まっています。
あとはこの”session_url”をデコレータとして使います。

(2)
このデコレータの使い方は以下のようになります。

@session_url
@login_required
def index(request):
    return render_to_response(’index.html’, {’session’:request.session})

ここで”@login_required”は認証済みユーザーだけが利用できるようにするためのデコレータで
Djangoに標準で用意されています。(django.contrib.auth.decorators.login_required)

このデコレートされたものをさらに先ほどの”@session_url”でデコレートしています。
この順番は大事ですので気をつけてください。

(3)
あとはログイン時にGETパラメータとしてセッションキーを渡してやればいいはずです。

def login(request):
    if request.method == ‘POST’:
        user = django.contrib.auth.authenticate(username=request.POST['name'], password=request.POST['pass'])
        django.contrib.auth.login(request, user)
        return HttpResponseRedirect(’/index/?session_key=%s’ % (request.session.session_key))
    else:
        return render_to_response(’login.html’, {})

これで”request.session”を従来通りの方法で使用できます。
お試しください。
(もちろん各ページのリンクやフォームでセッションキーを埋め込むのをお忘れなく!)

発展的内容

(1)
さらに今度はGET/POSTではなく、URLのパス部分に埋め込んでみます。
(http://aaa.com/[session_key]/index/ の形での使用を可能にします)

これも簡単で、”session_url”デコレータで

def decorated(request, *args, **keywords):
    request.session = engine.SessionStore(request.GET['session_key'] or request.POST['session_key'])
 ↓
def decorated(request, session_key, *args, **keywords):
    request.session = engine.SessionStore(session_key)

としてください。

(2)
次にログイン部分は

return HttpResponseRedirect(’/index/?session_key=%s’ % (request.session.session_key))
 ↓
return HttpResponseRedirect(’/%s/index/’ % (request.session.session_key))

としてやります。

(3)
URLからセッションキーを取得するので、urls.pyを変更します。
また、URLのパスが変わるので何もしないと元のurls.pyが使えなくなってしまいます。
そこで例えば

(r’^(?P\w+)/’, include(’original.urls’)),

のようにしてやることで、”session_key”を渡しつつ、同時に元のurls.pyを活かして使うことが可能になります。
これでURLのパスに埋め込んでも使えるはずです。

【WPF】【Silverlight】XAML 入門 ~ XML から依存関係プロパティまで~

Filed under: .NET Framework, Asp.Net, WCF/WPF — Tags: , , — strmozo @ 6:47 pm

XAML 入門 ~ XML から依存関係プロパティまで~

概要
リッチでインタラクティブな User Experience を持った UI の作成が行える話題の UI フレームワークである Silverlight や Windows Presentation Foundation (WPF)。これらの利用には XML ベースのマークアップで記述する宣言型プログラミング言語「XAML (ザムル)」の理解は避けて通れません。

XAML の文法そのものについては .NET で開発を行ったことがある方であれば、それほど難しいものではありません。そして、XAML が持つユニークなメカニズムを理解することでより柔軟に UI 表現を行えるようになります。

本セミナーでは、調布技術センターで実施している WPF/Silverlight セミナー内の 1 カリキュラムである「XAML 入門」をベースに、さらに詳細な解説を加えて、より理解しやすい形で再構成しました。

XAML の文法やそのメカニズム、開発時に覚えておいたほうがいいポイントについてデモを交えて解説します。

特に XAML を習得する際に難しいといわれる「依存関係プロパティ」や「添付プロパティ」についても詳細に解説いたします。

開催日時
2009 年 5 月 26 日 火曜日 19:00 ~ 21:00 (18:30 受付開始)

http://www.microsoft.com/japan/mscorp/mic/seminar/xaml_basic.mspx

[tips]OracleのDATA PUMP(expdp/impdp)を使ったバックアップ方法

Filed under: ALL — Tags: — strmozo @ 6:08 pm

sqlplusなどを使ってDBA権限でログオンし、登録しているバックアップ用のディレクトリの情報を確認する。

select * from dba_directories;

新しくディレクトリを登録するには下記コマンドを実行する。

create directory datapump_dir as ‘/usr/lib/oracle/xe/datapump’;

ユーザに権限を付与する。

grant read,write on directory datapump_dir to hr;

OSコマンドラインからexpdpを使用してバックアップを行う。

expdp hr/hr directory=DATA_PUMP_DIR dumpfile=hr.dmp

impdpを使用したリストア方法。下記のようにスキーマや表領域などをリマップすることも可能。

impdp hr2/hr2 dimpfile=DATA_PUMP_DIR:hr.dmp remap_schema=’hr’:’hr2′ remap_tablespace=’users’:’users2′ remap_datafile=’/usr/lib/oracle/xe/oradata/XE/users01.dbf’:/usr/lib/oracle/xe/oradata/XE/users02.dbf’

August 25, 2009

【C#3.0】自動実装するプロパティ

Filed under: ALL — Tags: , — strmozo @ 12:00 pm

C#3.0になって、プロパティ宣言が簡潔に書けるようになりました。これは、Visual Studio2005と2008の「property」のコードスニペットを比較してみると明らかです。「property」のコードスニペットは、「prop」→「Tab」→「Tab」のショートカットで挿入することができます。

Visual Studio2005の場合

private int myVar;
public int MyProperty {
    get { return myVar; }
    set { myVar = value; }
}

Visual Studio2008の場合

public int MyProperty { get; set; }

プロパティを宣言すると、コンパイラはプライベートな匿名バッキング フィールドを作成します。このフィールドにアクセスするには、get アクセサと set アクセサを使用する必要があります。

また、「【C#2.0】プロパティ アクセサのアクセシビリティ」の記事にも書きましたが、アクセシビリティはget アクセサとset アクセサのいずれか片方にしか設定できません。ちなみに両方のアクセサにアクセシビリティを設定すると、次のようなエラーになります。
「アクセシビリティ修飾子は、プロパティまたはインデクサ ‘プロパティ/インデクサ’ の両方のアクセサに指定できません。」

なお、読み取り専用の自動実装プロパティを作成するには、プライベートな set アクセサを用意します。「propg」→「Tab」→「Tab」のショートカットでコードスニペットを挿入することができます。

public int MyProperty { get; private set; }
Older Posts »

Powered by WordPress