waste of time

主にPHP

posh-gitを入れてCUIのGit操作で入力補完させる

CUIでGit操作するときに、gitコマンドやブランチ名の補完をしてくれたり、プロンプトに現ブランチ名を表示してくれるposh-gitをインストールしてみました。

posh-gitインストール

下記リポジトリからcloneして、中にあるinstall.ps1を実行するだけ。
実行するとコンソール画面が出てくるけど一瞬で完了して消える。簡単。
dahlbyk/posh-git

※ちなみに最初はchocolateyでインストールしてみたのですが、うまく動かず断念

インストール後、PowerShellを再起動すると、以下のように警告が表示されました。
PowerShell3.0に上げてくれとのことです。

f:id:tmysz:20150921011445p:plain

PowerShell3.0にアップグレード

https://www.microsoft.com/en-us/download/details.aspx?id=34595

上記より、自分の環境に合ったWindows Management Framework 3.0をダウンロード・インストールします。
今回はWindows6.1-KB2506143-x64.msuをインストールしました。

インストールした後に、再度PowerShellを立ち上げると警告が表示されなくなります。
ちなみに$PSVersionTablePowerShellのバージョンが確認できるみたいです。

という感じでposh-gitが使えるようになりました。よかったね。

f:id:tmysz:20150921011610p:plain

「nginxをフロントエンドで使う」の意味が分からなかったけど最近なんとなく分かった

ような気がする。

「nginxっていうwebサーバがアツいらしい」という感じで聞いたことはあるけどnginx自体詳しくは知らなかった。最近何かの記事で「nginxをフロントエンドで使う」的な言い回しがあってハァ?ってなったので少しググってみた。

リバースプロキシの機能を持つnginxを、バックエンドwebサーバーの前に置くことで、ロードバランサ(負荷分散)やキャッシュとして使えるという感じ?

一応リバースプロキシの説明もwikipediaより

リバースプロキシ(英: Reverse proxy)または逆プロキシは、特定のサーバへの要求を必ず経由するように設置されたプロキシサーバ。一般的なプロキシとは異なり不特定多数のサーバを対象としない。リバースプロキシは、不特定多数のクライアントから寄せられる要求に対して、応答を肩代わりすることにより特定のサーバの負担を軽減したり、アクセスを制限することにより特定のサーバのセキュリティを高めたりする目的に用いられる。

apacheとnginx両方使うって聞いてウェブサーバ2つナンデ!?!?って最初は思ったけど、nginxをリバースプロキシとしてフロントに置いて、バックエンドのwebサーバとしてapacheを使うってことね。なるほどね。 なんとなく上辺だけ分かった。

WindowsでAnemoneを使う

業務でクローラー作る案件を他の人がやってて興味があったので、自分でも少し試してみました。 rubyインストールからAnemone(Ruby製のクローラー)でスクレイピングするまで。

Rubyインストール

chocolateyでrubyrubygemsをインストールする。 Powershellで以下のコマンドを入力する。

> cinst ruby
> ruby --version    => ruby 2.1.6p336 (2015-04-13 revision 50298) [x64-mingw32]

> cinst rubygems
> gem --version     => 2.4.1

Anemoneインストール

rubygemsでインストールしようとしたらエラーが出た。

> gem install anemone

ERROR:  Could not find a valid gem 'anemone' (>= 0), here is why:
    Unable to download data from https://rubygems.org/ - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (https://api.rubygems.org/specs.4.8.gz)

rubygemsの証明書が古いのが原因らしいので、以下を参考に新しい証明書を追加する。

参考: bundle install がこけるようになった(改訂版)

新しい証明書を追加したあと、再度gem install anemoneしたらインストールできた。

スクリプト作成

Qiitaのトップページ(ログインページ)のURL一覧を取得してみる。

require 'anemone'

url = 'http://qiita.com/'
opts = {
    :skip_query_strings => true,
    :depth_limit => 1
}

Anemone.crawl(url, opts) do |anemone|
    anemone.on_every_page do |page|
        puts page.url
    end
end

こんな感じで出力される↓

f:id:tmysz:20150912183938p:plain

ajaxで返ってきたjsonの参照ができなくてちょっと悩んだ話

$.post(requestURL, params, function(res) {
    console.log(res.hoge);
});

ajaxで受け取ったjsonデータを上記のように参照しようとしたらundefinedが返ってきた。 $.post()の最後にdataTypeをちゃんと指定してねってことだった。

$.post(requestURL, params, function(res) {
    console.log(res.hoge);
}, 'json');

JSON.parse()してもアクセスできるけど。

jQuery.post() | jQuery API Documentation

インデックスの効かないSQLを書き換えて一部PHPで処理させようとした話

ORDER BYとLIMITを含むSQLを吐き出すCakePHPのコードがある。

// HogeModel
$params = array(
   'fields' => array(
      略
   ),
   'conditions' => array(
      hoge_id => Configure::read('HOGE_ID')
   ),
   order => array(
      'created' => 'desc'
   ),
   'limit' => $limit
);
$result = $this->find('all', $params);

このままのクエリだとインデックスが効かないが、ORDER BYを消したらインデックスが効くようになる場合。

  • ソートはPHP側で処理させよう!
  • ORDER BY取り除いたクエリを発行したあとPHPでソート処理する
// HogeModel
$params = array(
   'fields' => array(
      略
   ),
   'conditions' => array(
      hoge_id => Configure::read('HOGE_ID')
   ),
   // order => array(
   //    'created' => 'desc'
   // ),
   'limit' => $limit
);
$result = $this->find('all', $params);

$result = Hash::sort($result, '{n}.Hoge.created', 'desc');

最終的な$resultの中身を見るとなんか結果がおかしい。

  • よく考えなくても当たり前だが、LIMITでレコード絞る前にソートした場合とLIMITで絞った後にソートする場合では結果が異なる。
  • クエリを分離するなどして対策しなければならない(JOINして複数テーブルを対象にSELECTしてる場合は、それぞれのテーブルごとにクエリを分けるとインデックスが効きやすい(ような気がする))

LIMITをクエリから外して、PHPでソートした後LIMIT数分array_splice()するとか安直に思いついたけど、マッチした(大量の)レコード全部返すようなクエリはパフォーマンス的にまずいのかなあ
こんな感じで↓

// HogeModel
$params = array(
   'fields' => array(
      略
   ),
   'conditions' => array(
      hoge_id => Configure::read('HOGE_ID')
   ),
   // order => array(
   //    'created' => 'desc'
   // ),
   // 'limit' => $limit
);
$result = $this->find('all', $params);

$result = Hash::sort($result, '{n}.Hoge.created', 'desc');

array_splice($result, $limit);

MySQL インデックスめも

仕事でDBにインデックス貼る機会があったからめも。
初めてだったのでインデックスってなんなのってとこから調べてやった。

  • とりあえずEXPLAINつけて見てみる
  • typeでALLでてたりExtraでUsing temporary, Using filesortは改善の余地あり
  • 基本的にクエリのWHERE句から順番に複合インデックス作ればよい
  • 複合インデックスは順番が大事
  • 選択性の高いカラムを左端に
  • インデックス利用できないならSQLでORDER BYするよりプログラムでソートした方が断然はやい
  • インデックス使える時と使えない時がある。例えば複数の範囲条件とか!=には使われない
  • IN句をうまいこと使う技がある
  • インデックス増えると今度は更新が遅くなるのでほどほどに
  • ビューテーブル使ってる時めんどくさいことになる
  • いろいろ理論あるけど知識から入るの難しそうだからやって慣れる

VPSで名前解決できなかった件

お名前.comのVPSの管理を頼まれて構築作業していたところ、yum -y updateでエラーが出るのに気付く。

ping www.google.comが通らないしnslookupも使えない。
ping 173.194.126.146(google.comのIPアドレス)は通るので、どうやら名前解決ができていないようだ。

resolv.confを見ると初期状態で何か記述されている。

$ sudo vim /etc/resolv.conf

; generated by /sbin/dhclient-script
nameserver hoge.hoge.hoge.hoge
nameserver fuga.fuga.fuga.fuga
nameserver piyo.piyo.piyo.piyo
nameserver poyo.poyo.poyo.poyo

この設定されているIPはなんなんだろう???お名前.comのメールにあったDNSと違うIPだが…
試しにコメントアウトして、お名前.comからのメールに記載されていたDNSサーバIPを追記。

; generated by /sbin/dhclient-script
#nameserver hoge.hoge.hoge.hoge
#nameserver fuga.fuga.fuga.fuga
#nameserver piyo.piyo.piyo.piyo
#nameserver poyo.poyo.poyo.poyo
nameserver お名前.comからのメールに記載されていたDNSサーバIP
nameserver お名前.comからのメールに記載されていたDNSサーバIP2

ifcfg-eth0にも例の謎IPが設定されていたので削除。

$ sudo vim /etc/sysconfig/network-scripts/ifcfg-eth0

...
DNS1=hoge.hoge.hoge.hoge  ←削除
DNS2=fuga.fuga.fuga.fuga  ←削除
DNS3=piyo.piyo.piyo.piyo  ←削除
DNS4=poyo.poyo.poyo.poyo  ←削除

sudo service network restartしてnslookupyum updateもできるようになった。
設定されていたDNSサーバIP(?)はなんだったのだろう…