xai1981's blog

http://twitter.com/xai1981

PHPのSESSIONと冗長化のお話

リリース間近になって気が付いたことがありました。

今作っているサイトは元々のベース・自作のフレームワークがあって そちらを変更して利用しています。

元々のログインの仕組みは COOKIE に認証トークンを記憶させて 持回る仕組みでしたが

今回は SESSION を利用してサーバー側によく使うデータを記憶させて SESSION_ID を COOKIE に保持して認証する仕組みに変更しました。

いざ本番リリースすると ログインの動きが妙です。

調べて見たら 本番は冗長化(3台構成)されいますが SESSION 情報が3台のサーバー間で 共有されてないのが原因でした。

  • 従来のしくみに戻す
  • NFSなどで SESSION 情報を共有する ** NFSで共有するとロックの関係かもの凄く重いらしい
  • 本番を一時的に1台構成にしてもらう

などの案が浮かびましたが どうしよう。。。

参考サイト

テーブル名の主キーのカラム名

今のプロジェクトでは テーブルの主キーのカラム名が テーブル名 + id です。

たとえば下記のテーブルがあったとします。

今のプロジェクトの場合だと

$user = User::get($id);
echo $user['user_id'];

こんな風に冗長になります。

$user = User::get($id);
echo $user['id'];

こっちの方がよいと思います。 また他のテーブルとマッピングする時は テーブル名 + id を使います。

$user = User::get($id);
echo $user['id'];
echo $user['profile_id'];

こんな感じでどうでしょう。

任意のチケット番号を含む Subversion のコミットログを抽出する

現在 RedmineSubversion が紐づいてない プロジェクトで作業をしています。

紐づいているとコミットメッセージにチケット番号を入れると 勝手にチケットの右側に表示してくれるのですが 紐づいてないのでそれは叶いません。

svn log と grep でを併用して 任意のチケット番号を含むコミットメッセージを出力してみます。

コミット時の書式
svn ci -m "refs #3200 画像の選択機能を追加" app/model/Hoge.php ...
コミットログの書式
$ svn log
xai1981@xxx.xxx's password: 
------------------------------------------------------------------------
r6785 | aokiyai | 2015-02-14 08:29:40 +0000 (Thu, 14 Feb 2015) | 1 line

refs #2060 あうあうのprofile_id更新
------------------------------------------------------------------------
r6784 | shigeoo | 2015-02-14 07:44:31 +0000 (Thu, 14 Feb 2015) | 1 line

refs #2060 ほげを取得するように対応
------------------------------------------------------------------------
r6779 | xai1981 | 2015-02-14 06:25:14 +0000 (Thu, 14 Feb 2015) | 1 line

refs #3200 画像の選択機能を追加
...
チケット番号を含んだコミットログを出力する
$ svn log | grep -P '\-+\nr[0-9]+.*\n\nrefs #3200.*\n'
xai1981@xxx.xxx's password: 
------------------------------------------------------------------------
r6779 | xai1981 | 2015-02-14 06:25:14 +0000 (Thu, 14 Feb 2015) | 1 line

refs #3200 画像の選択機能を追加
------------------------------------------------------------------------
r6776 | xai1981 | 2015-02-14 05:31:11 +0000 (Thu, 14 Feb 2015) | 1 line

refs #3200 画像のアップロードフォームの表示
------------------------------------------------------------------------
r6773 | xai1981 | 2015-02-14 04:00:01 +0000 (Thu, 14 Feb 2015) | 1 line

refs #3200 画像一覧を表示
...

(日付とかいじってあります。)

参考サイト

正方形と長方形の変数名

縦長の長方形、横長の長方形、正方形を PHPで定数定義したくて悩みました。

  • square (正方形)
  • rectangle (長方形)
  • vertical (垂直な)
  • horizontal (水平な)
  • vertical rectangle (縦長の長方形)
  • horizontal rectanble (横長の長方形)

まず、考えたのが下記です。

define('PROFILE_IMAGE_SQUARE', 1);
define('PROFILE_IMAGE_VERTICAL_RECT', 2);
define('PROFILE_IMAGE_HORIZONTAL_RECT', 3);

でも少し冗長な気がして 定数名に IMAGE も入っているので 分かるでしょうということで

define('PROFILE_IMAGE_SQUARE', 1);
define('PROFILE_IMAGE_VERTICAL', 2);
define('PROFILE_IMAGE_HORIZONTAL', 3);

上記のようになりました。 名前でいつも悩むのですが、四角については 今後は何とかなりそうな気がします。

参考サイト

プロキシサーバー経由したHTTPリクエストのnginxのアクセスログ

プロキシサーバー経由した場合のログに大元のIPアドレスが残るのかどうかの検証をしました。

[root@ip-10-0-0-159 nginx]# cat /etc/nginx/nginx.conf

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

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
...
  • 無料の プロキシサーバー から適当に選び Firefox にプロキシサーバーを使うように設定しました。
    • ツール -> オプション -> 詳細 -> ネットワーク -> 接続設定 -> 手動でプロキシを設定する
      • HTTPプロキシ=153.120.6.35
      • ポート = 8090

結果、デフォルトで X-Forwarded-For リクエストヘッダー($http_x_forwarded_for)をログに出力していました。

通常のアクセスログ

AAA.BBB.CCC.115 - - [22/Jan/2015:02:13:15 +0000] "GET / HTTP/1.1" 200 3770 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0" "-"

プロキシサーバー経由のアクセスログ

153.120.6.35 - - [22/Jan/2015:02:14:48 +0000] "GET / HTTP/1.1" 200 3770 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0" "AAA.BBB.CCC.115"
参考サイト

http://okochang.blogspot.jp/2011/10/cloud-load-balancersip.html

Wake On LAN の設定

今後、保守の都合で何かあった場合に自宅作業することが決まりました。 客先にある作業用の SSH サーバーは接続元の IP を見ているため自宅(DHCP 割り当てアドレス)から 直接接続することはできません。

そこで自宅から社内のDELLの開発PC「OPTIPLEX 3010」に リモートデスクトップで接続してそこから保守することにしました。

自宅のPCから作業する場合に、社内の開発PCは常に立ち上がっている必要があります。 ずっと開発PCを起動しておけば問題ありませんが、電気代もかかるしPCに負担もかかるので、できれば必要の際に開発PCの電源を付けたいです。

解決策としては Wake On LAN という技術を使って、ネットワーク経由で電源を付ける方法でした。

  • 用意するもの
    • 自宅のPC
    • 社内のCentOS 6.4(常時起動)
    • 社内の開発PC

社内のCentOS 6.4に ethtool をインストール及び、設定します。これは常時起動している社内のCentOS 6.4から、社内の開発PCの電源を付けるために必要です。

[usar1@kabosu ~]$ sudo yum -y install ethtool
=================================================================
 Package               Arch     Version       Repository    Size
=================================================================
Updating:
 ethtool               x86_64   2:3.5-5.el6   base         101 k

Transaction Summary
=================================================================
Upgrade       1 Package(s)
Complete!

[usar1@kabosu ~]$ sudo su - root
[root@kabosu ~]$ vim /etc/sysconfig/network-scripts/ifcfg-eth0
ETHTOOL_OPTS="wol g" # この1行を最終行に追記する
[root@kabosu ~]$ restart

社内の開発PCを電源が入っていない状態でも、信号を受け取ったら立ち上がるように設定します。

  • スタート -> コンピューター -> プロパティ -> デバイスマネージャー -> ネットワークアダプター -> Realtek PCIe GBE Family Controller
    • 詳細設定 -> Wake on Magic Packet を有効に -> OK
    • 電源の管理 -> Magic Packet でのみ、コンピューターのスタンバイ状態を解除できるようにする にチェックする
  • BIOS

この状態で自宅のPCから電源を付けるテストします。 社内のCentOS 6.4 に SSH で接続したのち、社内の開発PCのMACアドレスを引数に、下記のコマンドを実行します。

[root@kabosu ~]$ ether-wake -i eth0 00:00:00:00:00:00

ダメです、コマンドを実行しても社内の開発PCの電源は入りません。 社内の開発PCは電源が切れた状態だと LAN アダプタが光ってなく、完全に停止している状態です。 これが原因ではないかと、調べたら BIOS の Deep Sleep Control の設定を Disabled に変更したらうまく動きました。

社内の動作テストの際、上司がバカハブとLANケーブル2本を貸してくれました。うまく動かない場合はミニマムで試すようにと Linux サーバーを介さずに動作テストして原因を究明できました。自分用にバカハブとLANケーブルを買おうと思いました。

参考サイト