January 13, 2011

mysql_process_kill.php

サーバがしょぼかったりSQLのチューニングができてなかったりテーブル設計が悪かったりすると、MySQLのスレッドが溜まってToo many connectionsの状態になりWebが死んだりします。

一つ一つ殺すのはやたら面倒なので条件指定で一括で殺れるようなPHPを書いてみました。デキる人はシェルで書くんでしょうけど。
※にしてもDBマシンにPHPなんか入れないこともあるので本当によくない。

【オプション】
--user=USER_NAME
--host=CLIENT_IP
--db=DB_NAME
--command=COMMAND
--time=TIME

【例1:192.168.1.100からの接続を全てKILL】
$ php mysql_process_kill.php --host=192.168.1.100

【例2:192.168.1.100からのmydbへの接続を全てKILL】
$ php mysql_process_kill.php --host=192.168.1.100 --db=mydb

【例3:Sleep状態で60秒以上接続してるのをKILL】
$ php mysql_process_kill.php --command=sleep --time=60

どれをKILLしたらいいかはMySQL入って "show processlist;" や "show full processlist;" を見て判断してください。

--- 以下ソース ---

<?php $mysqlexe = "/usr/local/mysql/bin/mysql -u root"; array_shift($_SERVER["argv"]); $opts = array(); $optKeys = array("user", "host", "db", "command", "time"); foreach ($_SERVER["argv"] as $arg) { list ($key, $val) = explode("=", $arg, 2); $key = trim($key, "-"); if (in_array($key, $optKeys) && !empty($val)) { $opts[$key] = $val; } } if (empty($opts)) { echo "\n"; echo "Please specify some options.\n"; echo "\n"; exit; } $proc = array(); foreach (explode("\n", shell_exec("echo 'show processlist\G' | {$mysqlexe}")) as $i => $line) { if ($i === 0) continue; $line = trim($line); if (empty($line)) continue; if ($line[0] === "*") { if (!empty($proc)) { $kill = true; if (isset($opts["user"]) && $opts["user"] !== $proc["user"]) { $kill = false; } if (isset($opts["host"])) { list ($host) = explode(":", $proc["host"]); if ($opts["host"] !== $host) { $kill = false; } } if (isset($opts["db"]) && $opts["db"] !== $proc["db"]) { $kill = false; } if (isset($opts["command"]) && $opts["command"] !== strtolower($proc["command"])) { $kill = false; } if (isset($opts["time"]) && (int)$opts["time"] > (int)$proc["time"]) { $kill = false; } if ($kill) { shell_exec("echo 'kill " . $proc["id"] . ";' | {$mysqlexe}"); } $proc = array(); } continue; } @list ($key, $val) = explode(":", $line, 2); $proc[strtolower(trim($key))] = trim($val); }


December 03, 2010

Sabelでざっと画像掲示板を作るざっとした説明

はい、こんばんは。
画像付きフォームとかって、面倒ですよね。
Sabelを使うと、なんと、ちょっと面倒ですみます。

まず、bbsテーブルを作りましょう。

[migration/default/1_Bbs_create.php] <?php $create->column("id")->type(_INT)->primary(true)->increment(true); $create->column("title")->type(_STRING)->nullable(false); $create->column("body")->type(_TEXT)->nullable(false); $create->column("imgname")->type(_STRING); $create->column("added")->type(_DATETIME)->nullable(false);

$ Sabel/bin/sakle Migration development head

bbsテーブル用のフォームクラスを定義します。

[app/forms] <?php class Forms_Bbs extends Form_Model { protected $displayNames = array( "title" => "タイトル", "body" => "本文", "imgname" => "画像", ); }

そしたら、コントローラからこいつをセットします。

[app/index/controllers/Index.php] <?php class Index_Controllers_Index extends Sabel_Controller_Page { public function index() { $this->bbsForm = new Forms_Bbs(); } }

テンプレートを書きましょう。

[app/index/views/index/index.tpl] <?php if ($bbsForm->hasError()) : ?> <?php echo $this->partial("error", array("errors" => $bbsForm->getErrors())) ?> <?php endif ?> <form action="<?php echo uri('a: post') ?>" method="post" enctype="multipart/form-data"> <dl> <dt><?php echo h($bbsForm->n("title")) ?></dt> <dd><?php echo $bbsForm->text("title") ?></dd> <dt><?php echo h($bbsForm->n("body")) ?></dt> <dd><?php echo $bbsForm->textarea("body") ?></dd> <dt><?php echo h($bbsForm->n("imgname")) ?></dt> <dd><?php echo $bbsForm->file("imgname") ?></dd> <dd><input type="submit" value="書き込む" /></dd> </dl> </form>

ちなみにフォーム上の面倒なエラー表示のやつは renderer アドオン使うと下ので済みますよ。

<formerr form="bbs" /> <form action="<?php echo uri('a: post') ?>" method="post" enctype="multipart/form-data"> ... </form>

さてさて、やっと投稿まできました。
postアクションをいつもの感じで実装しましょう。

[app/index/controllers/Index.php] <?php class Index_Controllers_Index extends Sabel_Controller_Page { ... public function post() { $this->bbsForm = $bbsForm = new Forms_Bbs(); $bbsForm->submit($this->request->fetchPostValues(), array( "title", "body", "imgname" )); if ($bbsForm->validate()) { // DBへの保存処理 } else { // エラーだよ $this->view->setName("index"); } } }

何も入力しないで投稿してみましょう。
タイトルを入力してくださいとかエラーがちゃんと出ますね。

さて、画像をどうするかなんですが、imgname カラムは _STRING で定義しました。そうです。ここには画像ファイル名を入れるわけです。
カラムは文字列として定義、入ってくるのは画像データ、その違いを自動で何とかしてくれるほどSabelは賢くありません。

ということで、それをフォームに教えてあげましょう。

[app/forms] <?php class Forms_Bbs extends Form_Model { ... protected $validators = array( "imgname" => array("-strwidth", "image"), ); }

_STRING カラムは勝手に strwidth バリデータが実行されてしまうのでそれを "-" をつけて削除します。で、画像用のバリデータ image を追加します。
下のように書けばサイズ上限とか jpeg, gif だけとか指定できます。
デフォルトは300K以下、jpeg, gif, png を受け入れます。

protected $validators = array( "imgname" => array("-strwidth", "image('1M', array('jpeg', 'gif'))"), );

先ほどのコードでは画像データをsubmitできていなかったので、次のように変えます。

[app/index/controllers/Index.php] <?php class Index_Controllers_Index extends Sabel_Controller_Page { ... public function post() { $this->bbsForm = $bbsForm = new Forms_Bbs(); $values = $this->request->fetchPostValues(); $values["imgname"] = $this->request->getFile("imgname"); $bbsForm->submit($values, array( "title", "body", "imgname" )); ... } }

これで変なファイルあげれば「画像の形式が不正です」とかなります。

DBへの保存処理をする前にImanageアドオンというのを入れましょう。

$ Sabel/bin/sakle Install -a imanage

コンフィグで有効にします。

[config/Addon.php] <?php class Config_Addon implements Sabel_Config { public function configure() { $addons = array(); $addons[] = "imanage"; return $addons; } }

では、DBへの保存処理を実装します。

まず、Bbsモデルに、フォームの値をまとめてセットします。
その後、もし imgname がセットされていたら、それは画像データ(正確には Sabel_Request_Fileオブジェクト)なので、それをImanageアドオンに渡して画像ファイルとして保存してもらいます。そして、その返り値のファイル名(ランダムに生成される)をモデルの imgname にセットし直しています。

[app/index/controllers/Index.php] <?php class Index_Controllers_Index extends Sabel_Controller_Page { ... public function post() { ... if ($bbsForm->validate()) { $bbs = MODEL("Bbs"); $bbs->setValues($bbsForm->getValues()); if ($bbs->imgname) { $bbs->imgname = $this->imanage->save($bbs->imgname); } $bbs->added = now(); $bbs->save(); $this->redirect->to("a: index"); } else { ... } } }

投稿できるようになったので、あとは表示するだけですね。
ページャを使って、ささっとやってしまいましょう。

[app/index/controllers/Index.php] <?php class Index_Controllers_Index extends Sabel_Controller_Page { public function index() { ... $paginator = new Paginator("Bbs"); $paginator->setDefaultOrder("added", "desc"); $this->paginator = $paginator->build(10, $this->request->fetchGetValues()); } }

投稿フォームの下に、書込みを表示します。

[app/index/views/index/index.tpl] ... <?php if ($paginator->results) : ?> <?php foreach ($paginator->results as $bbs) : ?> <hr /> タイトル:<?php echo h($bbs->title) ?>(<?php echo $bbs->added ?>)<br /> <?php echo nl2br(h($bbs->body)) ?><br /> <?php if ($bbs->imgname) : ?> <a href="<?php echo $imanage->getUrl($bbs->imgname) ?>"> <?php echo $imanage->thumbImage($bbs->imgname, 120, 120) ?> </a> <?php endif ?> <?php endforeach ?> <?php echo $this->partial("pager") ?> <?php endif ?>

そういえばさっきコントローラにもいた $imanage というのは、Imanageアドオンをインストールすると勝手に現れるオブジェクトです。こいつのthumbImage()メソッドは、画像をサムネイル表示してくれます。

$imanage->thumbImage(ファイル名, 縦, 横);

$imanage->getUrl()メソッドは画像のURLを返します。

なお、サムネイルは元画像の縦・横と引数の縦・横の比率が一致しなければ白い余白が作られ、生成後の画像は必ず引数の縦・横のサイズとなります。
この白い余白を作らずに、単に小さく(リサイズ)したい場合はresizeImage()メソッドが使用できます。

$imanage->resizeImage(ファイル名, 縦, 横);

といった感じで、画像掲示板ができました。

driveool at 01:27Sabel この記事をクリップ!

September 29, 2010

swfmill インストール

フラッシュゲームを個々のユーザに合わせ加工・出力するためにswfmillを使う。
swfmill-0.2.12はsjisがダメなようで、klabがそれを何とかするパッチを公開してくれてるのでそれを使う。

パッチあててコンパイルする方法はその辺に情報あり。

で、swf > xml変換時にエラーが出るのでバージョンかなぁとか思いつつ最新の0.3.1のインストールを試みるが、コンパイル時にxslt.hが無いとかほざきやがるので、最新のソースを持ってくると解決する。

$ yum install bzr $ bzr export swfmill lp:swfmil $ cd swfmill $ ./configure $ make && make install

ちなみに、libxml, libxslt-devel, libpng, freetype-devel あたりが必要。

0.3.0だか0.3.1はsjisパッチが取り込まれたようなので、そのまま "-e cp932" オプションが使える。

September 08, 2010

肩書き

あと3週間くらいで新人さんが来る

新人さんといっても

よく知ってるし

すごい出来る人だけど

んで、

名刺の肩書きどうしようかなぁと

「システムエンジニア」

これ

自分の中ではあまり良いイメージじゃないので悩む

でも現場を知らない人たちには「プログラマ」より偉い(できる)人ってイメージだよね

正規化とかインターフェースとかJavaとかぺちぺとかよくわかんないけど

システムのことなーんとなくわかってて

きれいな(面倒な)フォーマットで文書とか図とか書ける人たち

それがシステムエンジニアのイメージかな
(お客さんを納得させるひとつの成果物にはなるので重要だけど)

プログラマは

仕様も書けるし、設計もできるし、実装もできるし、テストもできる

世の中のイメージとは違う本当はすごい人達

何にしようかな

「システムエンジニア/プログラマ」とかありなのかな

でも

「システムエンジニア/プログラマ」より「システムエンジニア」の方が偉そうだよね

うーむむむ




driveool at 02:53 この記事をクリップ!

July 16, 2010

QueryLogアドオン

あったら便利なのに、でもあるのに、誰も知らない、作った人さえ忘れていたQueryLogアドオンの紹介です。
アドオンインストーラもとりあえずちゃんと動くので、インストールは簡単です。
$sakle Install -a QueryLog

コンフィグでアドオンを有効にしてください。(ここまで自動化できればいいですね)
class Config_Addon implements Sabel_Config
{
  public function configure()
  {
    $addons = array();
    
    $addons[] = "querylog";
    ...
    
    return $addons;
  }
}

最後にbodyの一番下などで $QUERY_LOG_HTML を出力すればOKです。レイアウトに書くと全ページで出力されるので良いかもしれません。
app/view/layout.tpl

<html xmlns="...">
  <head>
    ...
  </head>
  <body>
    ...
    <?php echo $QUERY_LOG_HTML ?>
  </body>
</html>

こんな感じで表示されます。
テーブルださっとか思う人はQueryLogアドオン内にhtml.tplがあるのでそれをいじってください。

ではでは。

driveool at 15:12Sabel この記事をクリップ!
Search