なんかかきたい

プログラミングなどの個人的なメモやサークル「ゆきいろパラソル」の情報を載せてます

rsyncでpigzするやつ v2

普段よく使っているのでリモートからローカルにコピーする場合に使えるように機能拡張した。

ほとんど同じコードなのに共通化できなくて辛い。ifで分岐して二つのシェルスクリプトを一個にしたような作りがイケてないが使い勝手はよい。

細かい話だと rsync の出力がOSXLinuxで微妙に違うとかそういうところも吸収した。代わりに awk が必要になった。リストの取得に ./ から空行までをawkで出力する。 tailtac は消えた。

gist.github.com

便利

nginxの設定をrspecでテストする

前略。やや複雑な nginx.conf があります。

nginx の設定はたまに変更する必要がありますが、それなりに重要な位置に配置されたnginxだと設定を書き換える際に、既存の構成を壊さないか、あるいは意図した通りに動作するのか事前に調べておきたいということがあります。

本物のnginxを立ててログを調べてもよいですが、手元で再現できて、テストができると便利じゃないかということで、dockerでnginxのやや複雑な設定をテストする環境を作りました。

github.com

続きを読む

MySQLで定期的に SHOW PROCESSLIST を実行して長時間走っているクエリを探す

前略、大きいMySQLのデータベースがあります。すると、大きなデータベースから多くのデータを取得するため、非常に重いクエリが実行されることがあります。 そうするとデータベースが高負荷になるため重い処理を見つけたくなります。 (innodb_query_queued とかが増えて辛くなる)

MySQLには SHOW PROCESSLIST というものがあり、実行中のMySQLのプロセス一覧を見ることができ、 クエリの実行状況や実行時間をみることができるのでスロークエリログより便利なことがあります。 (スロークエリログはクエリが完了した場合に出力されるため実行中やクエリを中断した場合に見ることができない)

しかし、SHOW PROCESSLIST の出力は多いため毎回見るのは疲れます。そこで以下のようなスクリプトSHOW FULL PROCESSLIST の出力をフィルターすると便利です。

require 'mysql2'

MYSQL_USER = ''
MYSQL_PASS = ''
LONG_QUERY_THRESHOLD = 60

client = Mysql2::Client.new(host: 'localhost', username: MYSQL_USER, password: MYSQL_PASS)
client.query('SHOW FULL PROCESSLIST').each do |row|
  next unless row["Command"] == "Query"
  next if row["Time"] < LONG_QUERY_THRESHOLD

  puts ([Time.now] + row.values.map { |v| v.to_s&.gsub("\n", " ") }).join("\t")
end

実行コマンドがQueryかつ実行時間の閾値を超えた場合にのみ出力します。 複数回の出力をフィルターしないので、時間がかかっているクエリはなんども見ることになります。クエリに長い文字列が来ることもあるので、 実運用のことを考えるとある程度の長さで切った方がいいかもですね。

rsyncで圧縮転送したいけどpigzみたいに並列にならなくて困る

ので、tarとsshをパイプでつないで並列で圧縮しながら転送する君を作りました。

tar には指定したファイルのみをアーカイブに含める -T オプションがあるので、 rsync -nの結果をリストにして渡すことで、rsyncの対象になるファイルだけを転送できるようにしてます。

現場からは以上です。

Ansibleのテスト環境をDockerで作ると楽

以前はVagrantを使ってansibleのテスト環境は用意していたんだけど、 vagrantはsnapshotが取れる利点がありつつも、VMを使うのでちょっとというかそれなりに遅くて、 何度も実行するansibleのテスト環境にはちょっと不便だなーと思っていたのですが、 最近Dockerを使ってsshdを起動するだけの環境を用意すれば簡単にテスト環境が作れて便利だったので書いておきます。

Dockerfileを書く

ansibleを流す対象のイメージは DockerfileFROM に書いておけばよくて、 CentOSとかDebianとか好きなOSを選べばいいと思います。

Dockerfileを置いたディレクトリに id_rsa.pub を置いておくと authorized_keys にコピーされるというソリューションです。

FROM amazonlinux:latest

MAINTAINER cyrill

RUN yum install -y sudo shadow-utils
RUN useradd -g wheel ec2-user && echo "ec2-user:ec2-user" | chpasswd ;\
    mkdir /home/ec2-user/.ssh;\
    sed -i -e 's/^\(%wheel\s\+.\+\)/#\1/gi' /etc/sudoers ;\
    echo -e '\n%wheel ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \
    echo -e '\nDefaults:root   !requiretty' >> /etc/sudoers && \
    echo -e '\nDefaults:%wheel !requiretty' >> /etc/sudoers
ADD id_rsa.pub /home/ec2-user/.ssh/authorized_keys
RUN yum install -y openssh-server openssh-clients && \
    ssh-keygen -q -b 1024 -N '' -t rsa -f /etc/ssh/ssh_host_rsa_key && \
    ssh-keygen -q -b 1024 -N '' -t dsa -f /etc/ssh/ssh_host_dsa_key && \
    ssh-keygen -q -b 521 -N '' -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key && \
    sed -i -r 's/.?UseDNS\syes/UseDNS no/' /etc/ssh/sshd_config && \
    sed -i -r 's/.?ChallengeResponseAuthentication.+/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config && \
    sed -i -r 's/.?PermitRootLogin.+/PermitRootLogin yes/' /etc/ssh/sshd_config && \
    echo "root:root" | chpasswd
RUN rm -rf /var/cache/yum/* && yum clean all

CMD ["/usr/sbin/sshd", "-D"]

最近気づいたんですが、AmazonLinuxのDocker Imageとか配布されてるんですね。 EC2環境のテストにも便利です。よいですね。

Makefileを書く

毎回 docker build して docker run してもいいんですが、 正直に言えばdockerのコマンドオプションは覚えやすい感じもないので、 シュッと実行できるようにMakefileを書きます。 シェルスクリプトでもいいのではというご意見もあるかなとは思いますが、 make とか make clean とかテスト環境を作ったり消したりするイメージには合ってる感じがして 割と気に入ってます。気にいらないタイプの方は他の好きなツールを使うといいと思います。

.DEFAULT: all

all: container run

container:
    docker build . -t ansible

run:
    docker run -d --name ansible -p 30022:22 ansible

attach:
    docker run -it --name ansible -p 30022:22 ansible /bin/bash

clean:
    docker stop ansible && docker rm ansible

こんな感じのMakefileを置いておいて、makeするとsshができる環境が用意されます。 テスト環境を捨てたいときは make clean して make すると最初からやり直せます。便利ですね。

ansibleのinventoryファイルを書く

docker run するとローカルでsshできる環境ができるので、 localhost:30022SSHするようにinventoryファイルを用意しておいてansibleではこれを指定して実行するようにします。

ansible-playbook -i inventory/local -K -k playbook.yml

終わりに

まあ便利なんですが、Docker環境に移行し切ったらansibleとかいらないのではとか思いつつ、まああってもいいやという感じで悩み中ですね。

お仕事ではMySQLのでかいDBをいい感じにやってるのであんまり関係ないんですが、シュッとかける話がこれくらいしかなかったので今回はこんなところで。

最近、ラ!関係の旅行で福岡と函館に行ってきたのですが、どちらも最の高という感想なので、みんなも行くといいと思います。

月末は沼津花火大会、来月はコミケ。あ、原稿やります。みんな来てくれ〜〜〜〜

現場からは以上です。

Webアプリケーションをデプロイしたくなったのでsupでやってみる

sup

pressly.github.io

Golangで書かれたシンプルなデプロイ要ツール。

機能がとてもシンプルで、SSHコマンドを手で書くよりは簡単に書ける程度で、 逆に機能が少なすぎて必要なことが書きづらいことも。

大雑把に現時点でサポートしている機能は以下のような感じ。

  • リモートでのコマンド実行(並列可能)
  • ローカルでのコマンド実行
  • ローカルからリモートへのアップロード
  • デプロイ対象の切り替え

Capistranoとかをイメージしていると機能の少なさにびっくりするが、 シンプルゆえに書きやすいところもあるし、 例に挙がっているdockerで使うならいい感じかもしれない。

で、そんなデプロイツールを無理やり感もありつつ、 Webアプリケーションのデプロイに使うとしたらどうするかを考えてみた。

あまりよい例ではなさそうなので、本運用には使えないかもしれない。

というか、ここまでやるならcapistranoを使えという話でもあるが、 諸事情でRubyを入れられないので...

gist91393876ec369f1f1701948b4a648771

時間を取るためにファイルを分けるのは正直微妙だし、変数的な何かは使えなかったのかという気はするけど、 そもそもドキュメントが微妙なので、コード読んで雰囲気でやったしまあこんなもんな気はする(本当か?)

あと、自前でシンボリックリンク張り返したり古いreleaseを消すのは面倒。もうちょっと何とかなってほしい気もする。

うん、微妙だな。なしなし。