2015/09/15

Dropboxで同期させてるDay Oneのエントリが増殖した

Day One/Journal.dayone/entries の下にエントリが1ファイルずつ存在しているが、
以下のように同じファイルが増殖してた。

4619D4A8395F4163B3CDA61BD40FB1F8 (1).doentry
4619D4A8395F4163B3CDA61BD40FB1F8 (2).doentry
4619D4A8395F4163B3CDA61BD40FB1F8 (3).doentry
4619D4A8395F4163B3CDA61BD40FB1F8.doentry

以下のコマンドで適当に削除して、再同期することで治った

cd ~/Dropbox/アプリ/Day\ One/Journal.dayone/entries
find . -type f -name '*(*' -print0 | xargs -0 rm -f

2015/08/03

php-fpmをServer::Starterを使ってHot deploy

したかったけど、ダメだった。

Server::Starterはサーバプログラムをよしなにホットデプロイしてくれるスーパーデーモンです。

FPM_SOCKETSを使ってsocketは引き継げるが、php-fpmがそもそもgraceful shutdownに対応してないため、Server::StarterがSIGHUPを受けてphp-fpmを切り替える際に処理途中のリクエストが切断される。

なんとかしたい……。

FPM_SOCKETSについて

php-fpmは環境変数のFPM_SOCKETSからsocket情報を引き継ぐ機能がある。

start_serverはsocket情報をSERVER_STARTER_PORTに入れてサーバプログラムに渡すので、FPM_SOCKETSにセットしてphp-fpmを起動するとよい。

ざっくり書くとこういう形

start.sh

#!/bin/bash
start_server --path=`pwd`/php-fpm.sock \
    --interval=15 \
    --signal-on-hup=QUIT -- \
    sh -c 'FPM_SOCKETS=$SERVER_STARTER_PORT php-fpm -y php-fpm.conf'

その他テスト用ファイル

php-fpm.conf

[global]
pid = /Users/yosasaki/devel/php/php-fpm-graceful/php-fpm.pid
error_log = /Users/yosasaki/devel/php/php-fpm-graceful/php-fpm-error_log
daemonize = no

[www]
listen = /Users/yosasaki/devel/php/php-fpm-graceful/php-fpm.sock
listen.backlog = 256
listen.allowed_clients = 127.0.0.1
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
slowlog = /Users/yosasaki/devel/php/php-fpm-graceful/www-slow_log
php_admin_value[error_log] = /Users/yosasaki/devel/php/php-fpm-graceful/www-error_log
php_admin_flag[log_errors] = on

index.php

<?php
sleep(10);
echo "OK";

nginx.conf

worker_processes  1;
daemon off;

events {
  worker_connections  1024;
}

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

  server {
    listen       8080;
    server_name  localhost;
    root /Users/yosasaki/devel/php/php-fpm-graceful;

    location / {
      fastcgi_pass   unix:/Users/yosasaki/devel/php/php-fpm-graceful/php-fpm.sock;
      fastcgi_index  index.php;
      include fastcgi.conf;
    }
  }
}

2015/07/22

CentOS 6.4でyum updateが"Error: Cannot retrieve metalink for repository: epel. Please verify its path and try again"で失敗する

epelの mirrors.fedoraproject.org とSSLコネクションをひらくところでコケている模様

解決方法

  1. /etc/yum.repos.d/epel.repoのmirrorlistがhttpsになっているので、一旦baseurlに変更する

    baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
    #mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch
    
  2. ca-certificatesを更新

    % sudo yum update -y ca-certificates

2015/06/26

DockerでClojureを動かす

Docker containerでClojureのWAFであるLuminusを動かしてみる

事前準備

プロジェクト生成と実行

$ lein new luminus hello-world
$ cd hello-world/
$ lein run
Retrieving org/clojure/clojure/1.7.0-RC2/clojure-1.7.0-RC2.pom from central
Retrieving org/clojure/clojure/1.7.0-RC2/clojure-1.7.0-RC2.jar from central
2015-6-26 13:02:18 +0900 SPC-072.local INFO [hello-world.handler] -
-=[ hello-world started successfullyusing the development profile]=-
2015-06-26 13:02:18.357:INFO:oejs.Server:jetty-7.6.13.v20130916
2015-06-26 13:02:18.439:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:3000

ブラウザで開く

$ open http://localhost:3000

Dockerfile

方針

  • imageはdocker hubのjava8を使う
  • containerにuberjarを含める
    • leiningen runだとcontainer起動後から接続可能になるまで時間がかかる
    • Elastic Beanstalkだと結構致命的
  • CMDexec formじゃなくshell formで書く
    • sh経由で立ち上がるので、ENVでセットした環境変数が受け取れる
    • CMDならdocker run時に簡単に書き換えられる

Dockerfile

    FROM java:8

    ENV TZ JST-9
    ENV JVM_OPTS -server -Xms512m -Xmx512m -Xmn256m

    RUN mkdir -p /home/app
    COPY ./target/hello-worldjar /home/app/

    EXPOSE 3000

    WORKDIR /home/app
    CMD /usr/bin/java $JVM_OPTS -jar hello-world.jar 3000

詳しくはDockerfile referenceを参照。

containerの作成と立ち上げ

uberjar作成

$ lein uberjar
Compiling hello-world.core
Compiling hello-world.handler
Compiling hello-world.layout
Compiling hello-world.middleware
Compiling hello-world.routes.home
Compiling hello-world.session
Created /path/to/project/hello-world/target/hello-world-0.1.0-SNAPSHOT.jar
Created /path/to/project/hello-world/target/hello-world.jar

container作成

$ docker build -t luminus/hello-world .
Sending build context to Docker daemon 56.42 MB
Sending build context to Docker daemon
Step 0 : FROM java:8
 ---> 433801eb0894
Step 1 : ENV TZ JST-9
 ---> Running in ac5801626c85
 ---> 77b3c91b3d78
Removing intermediate container ac5801626c85
Step 2 : ENV JVM_OPTS -server -Xms512m -Xmx512m -Xmn256m
 ---> Running in 5c6a50907c9d
 ---> 9db9e3ecf034
Removing intermediate container 5c6a50907c9d
Step 3 : RUN mkdir -p /home/app
 ---> Running in 4e0e9d8c0b15
 ---> 9af2a4c10750
Removing intermediate container 4e0e9d8c0b15
Step 4 : COPY ./target/hello-world.jar /home/app/
 ---> 4e89615ff644
Removing intermediate container 88d653f5d04f
Step 5 : EXPOSE 3000
 ---> Running in 383fc9ad8ee1
 ---> 0ecb672ec459
Removing intermediate container 383fc9ad8ee1
Step 6 : WORKDIR /home/app
 ---> Running in eb575c33ce63
 ---> 158e8dbc87eb
Removing intermediate container eb575c33ce63
Step 7 : CMD /usr/bin/java $JVM_OPTS -jar hello-world.jar 3000
 ---> Running in 344eac7db8b2
 ---> 132b7b08093a
Removing intermediate container 344eac7db8b2
Successfully built 132b7b08093a

docker run

$ docker run --rm -it -p 3000:3000 luminus/hello-world
2015-Jun-26 13:47:52 +0900 9ae20b5deccf INFO [hello-world.handler] -
-=[ hello-world started successfully]=-
2015-06-26 13:47:52.424:INFO:oejs.Server:jetty-7.x.y-SNAPSHOT
2015-06-26 13:47:52.513:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:3000

-pオプションでcontainer側のTCP/3000をhost側(localhostじゃない)のTCP/3000にマッピングしているので、
boot2dockerコマンドでhost側のIPを調べて接続する

$ open http://$(boot2docker ip):3000

TODO

そのうち以下について書く

  • Docker Compose
  • Docker + ElasticBeanstalk

2015/03/04

Railsアプリをruby-profとqcachegrindでプロファイリング

遅いサイトをなんとかする必要があったので、まずは計測する。

最初に使ったrack-mini-profilerは大して役に立たないので無駄だった。

qcachegrindのインストール

% brew install qcachegrind graphviz

graphvizはqcachegrindでコールグラフの生成に使う

手順

  1. Gemfileにruby-profを追加

    group :profile do
      gem 'ruby-prof'
    end
    
  2. config.ruにprofの設定追加

    if Rails.env.profile?
      use Rack::RubyProf, :path => 'tmp/profile',
        :printers => {
          ::RubyProf::FlatPrinter => 'flat.txt',
          ::RubyProf::GraphPrinter => 'graph.txt',
          ::RubyProf::GraphHtmlPrinter => 'graph.html',
          ::RubyProf::CallStackPrinter => 'call_stack.html',
          ::RubyProf::CallTreePrinter => 'call_grind.txt',
        }
    end
    
  3. RAILS_ENV=profileの設定は適宜developmentあたりをコピーして作成。

  4. サーバを起動して、問題のページにアクセスする。

    ./bundle/bin/spring rails s -p 3001 -e profile
    
  5. tmp/profile/-call_grind.txtが生成されているのでqcachegrindに読み込ませる。

  6. Incl.やSelfの値の大きいところを目安にして、実際に遅い処理の部分を探す