✖
h2o の ssl-session-resumption のストア先を memcached に
internal がデフォルトで、特に問題もないしずっとこれにしていたが、h2o が再起動されるたびにキャッシュが消えるのではないか? どうせ memcached も起動してるのでそっちにストアすべきではないか? と思いはじめたので変えてみた。
まぁ弱小ウェブサイトだとそもそも resumption かかるようなことがぜんぜんないので意味ない。Google Bot も分散アクセスのせいか全く resumption しないし。
となりのトトロに星野源
最近子どもがとなりのトトロにハマってて毎日見てるんだけど、今朝は「お父さん」と「お母さん」が病院で会話しているシーンを見て、「星野源みたいねぇ」「ガッキーみたいねぇ」とか言いだして笑った。メガネかけてると星野源みたいねぇと言うのはしばしばあるんだけど、さらに「ガッキーみたいねぇ」は初めて聞いた。
最近は直接見てないはずなので (というか親が見ようとすると嫌がる)、結構前のを覚えているようだ。
✖
✖
↑ の写真 webp で Google Photos にアップロードしたんだけど、Chrome で見ても jpeg でしか配信されない。うーん…… いまいち webp 配信の条件がわからない。
Google Photos 上のサムネとかは webp になってるけど、大きめの画像は jpeg 固定なんだろうか
Lightroom で webp の一発書きだし
webp のインストール
homebrew で入れる。
$ brew install libtiff $ brew install --HEAD webp
-
- HEAD つけないとコンパイル済みの TIFF 非対応バイナリがインストールされるので注意
Export Actions にシェルスクリプトを置く
~/Library/Application Support/Adobe/Lightroom/Export Actions
にスクリプトを置くと、書き出しダイアログで選べるようになる。書き出したあとスクリプトの引数に現像済みファイル名が渡されるので、これを処理するようにすればよい。
以下のようなファイルを webp.rb という名前で Export Actions フォルダに保存して実行属性をつけておく。
#!/usr/bin/env ruby
require 'logger'
logger = Logger.new('/tmp/webplog')
logger.info ARGV.inspect
begin
ARGV.each do |f|
dir = File.dirname(f)
out = File.join(dir, File.basename(f, ".tif") + '.webp')
logger.info "%s => %s" % [f, out]
IO.popen([
'/usr/local/bin/cwebp',
'-metadata', 'all',
'-preset', 'photo',
'-q', '90',
'-o', out,
'--',
f
], :err=>[:child, :out]) do |io|
while l = io.gets
logger.info l.chomp
end
end
end
rescue Exception => e
logger.fatal e.inspect
end Lightroom の書き出し設定
ファイル設定
- TIFF
- 8 bit/チャンネル
として
「後処理」で「webp」を選ぶ
で書きだし。
問題点
EXIF が消える。cwebp が TIFF の EXIF デコードに非対応のため
h2o の proxy.reverse.url で localhost を指定していたら確率的に connection failure
リバースプロキシとして使っている h2o で
proxy.reverse.url: http://localhost:5001/
みたいに書いていたら確率的に connection failure がでて悩んだ。結局
proxy.reverse.url: http://127.0.0.1:5001/
で解決
なぜこうなったか
/etc/hosts に ::1 localhost のエントリ(IPv6)があり、h2o は解決したアドレスのうちからランダムに1つ選択するため。プロキシ先のバックエンドサーバは IPv6 を bind しておらず、::1 が選択された場合に接続に失敗していた。
メモ
- h2o がホストを選択するところ (rand している)
- nginx でも同様の設定をしていたが、nginx はランダムにしないみたい
h2o で listen するポートを増やしたときは master プロセスの再起動が必要
start_server が listen してないポートは以下のようなエラーになる。
cp socket:(null):80 is not being bound to the server
h2o は SIGHUP で graceful restart が可能だが、listen するポートが変わった場合は実際にlistenしている親プロセス (start_server プロセス) の再起動が必要になる。
nginx をアンインストール
これまで HTTPS (443) だけ h2o で処理していたが、nginx に使ってるぶんのメモリ量がMOTTAINAIのでh2oだけでやるようにした。さようなら nginx。
複雑なことをしているホストは全くなかったので普通に書きかえていっただけ
さくらのVPSのウェブサーバでIPv6の接続をうける
最初からアドレスついてたので意外とやることない。
ifconfig すると既に v6 のアドレスがついている。Scope:Global になっているやつがグローバルIPアドレス (正確にはグローバルユニキャストアドレス)
inet6 addr: 2001:e42:102:1807:160:16:210:51/64 Scope:Global
これを該当ドメインの AAAA レコードでひけるようにする。
nginx
nginx -V の結果に --with-ipv6 があることを確認する。
server {
listen 80;
listen [::]:80;
...
} という感じにして ipv6 側もlistenするようにする。
h2o
listen: 80 と書いてる場合、デフォルトで v6 も listen するようになっているのでやることはない。
DNS サーバの IPv6 対応
ここでの「DNS サーバの IPv6 対応」はDNS サーバへの通信が IPv6 でできるかという話になるが、value-domain の NS1.VALUE-DOMAIN.COM とか、さくらインターネットの ns1.dns.ne.jp は対応していないっぽい?
IPv4 で解決できるなら別に問題ないんだけど、IPv6 オンリーの環境 (あるの?) からだと名前がひけないことになる。
確認
備考
自分に IPv6 アクセス環境がないので、とりあえず1つのドメインだけ対応させた。現状ではとくに IPv6 の対応したからといってメリットがないのが微妙。。。
✖
人と人とは利害が一致する部分と一致しない部分があり、ある言葉を受けとるときにバイアスを補正して受けとる必要がある。自分にとって無意味なことでいちいち気が乱されるようなことを避けるために、相手のポジションと自分のポジションによって生じるバイアスは補正して理解しないといけない。インターネットは大変いろんな立場の人がいるため、いちいち全部の話を真面目に聞いてるとアホになる。
利害の一致(問題なく議論が成立する)
向いてる方向性が一緒なら議論可能なので、素直に意見をもってよい。
利害が不一致(前提が共有化されていないため議論不可。交渉が必要)
このとき必要なのは議論ではなくて交渉なので、議論をもとめられても適当にやっておけば良く、話真剣に受け止める必要はない。
なお経営者対従業員的な文脈だと、経営系の人はこういうことを言うと渋い顔をするので、あくまで「経営者視点を持ってます(キリッ」ってことにして真面目に聞いているフリをしておくこと。
アナログ値
お互いの利害を直交のベクトルとして合成したときの大きさによって、どれぐらい真剣に聞くかを決めたらいい気がする。二項対立というよりは、どのぐらい話を真剣に聞くべきかというアナログ値を感じたほうがよい。
サイトの負荷のシミュレーション
どのぐらいまで生きていられるのか気になったので試してみる。wrk を使う (ab だとうまく高負荷にできなかった) wrk は brew で入る。
ベンチの際いくつか注意する
- Transfer/sec が十分に低いこと
- 帯域を使いきってると負荷をかけきれない
- Non-2xx or 3xx responses がではじめたら限界
- 発生しなかったときは表示されない
$ wrk -c 170 -d 10s -t 16 https://...
Running 10s test @ https://...
16 threads and 170 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 164.27ms 64.53ms 852.22ms 80.26%
Req/Sec 61.56 22.99 170.00 72.60%
9278 requests in 10.10s, 44.31MB read
Non-2xx or 3xx responses: 22
Requests/sec: 918.52
Transfer/sec: 4.39MB 日記システムは、これぐらいでCPUは使いきってちょいちょいエラーが発生する感じだった。
ヤフー砲が瞬間最大で100req/sec、継続的に30req/secぐらいらしいので、現実的にはこの日記が負荷で死ぬことはまずなさそう。他のサービスも同居してて相互に影響してる(バックエンドプロセスのワーカーを共有してる)けど。
Mackerel つかいはじめた
サーバ移行のタイミングでつかいはじめた。監視をちゃんとするようにしようという感じ。loadavg5 と filesystem でひとまず監視。メトリクスの保存とグラフ化はフリープランだと1日だけなのであまり重視してない。
しかし、さくらのVPSはホスト不具合で落ちるってことは滅多にないので、やりたいことはサーバ自体の死活というよりウェブサーバの監視になる。このへんはプラグインでごにょごにょやってみている。パフォーマンス(応答時間のパーセンタイル値とか)とエラー数あたりでアラートが出せればいいかなという感じ。
チップコンデンサ(MLCC)の容量回復
高誘電体 MLCC は容量が時間経過で減少していくが、約125度(キュリー温度)まで加熱すると容量が回復する特性がある、らしい。
エージングで容量が減っていくというのはいいとして、一定より温度をあげると回復するというのを知らなかったのでびっくりした。
PS3/PS4 の修理方法でとにかくホットブローするみたいなのがあるけど、はんだクラックだけではなくて容量回復するという意味合いもあるのだろうか。
ref
✖
welq 問題でいろいろ思うところがあるけど、最終的にこれは「国会議員バカばっかり問題」と一緒ということなのだなと思って、解決にはほど遠いので気が重くなった。
「国会議員バカばっかり」って思うんだけど、あれは有権者が求めて選ばれた存在なわけで、こう思うということは有権者バカばっかりと思うに等しい。
検索エンジンの結果って、人々が求めるもののランクを上げた結果なので、その結果がバカなのって、結局人間がバカってことなんだよなあと思う。検索エンジンは人知を超えて賢くあるべきか?そして教育的であるべきか?はたしてそんな人工知能はバカな人間に受け入れられるのか (ビジネスになるのか)。
PV が稼げるのはなんでか
- 検索エンジンにヒットしやすいということ
検索エンジンにヒットしやすいのはなんでか
- すくなくともグーグルのアルゴリズムは「人にとって役に立つ」と判断しているということ
グーグルはなぜそういう判断をするのか
- 人々がそれを求めるため
人々はなぜそれを求めるのか
- 人はあんがい頭を使ってないから
地道にやることはネトゲから学んだ
ネトゲって最初からエンドコンテンツなので、スキル上げとかが途方もない。とはいえゲームなのでやってればいつか終わるぐらいのバランスにはなっている。結果僕らは学ぶことができる、時間をかければあらゆるタスクは必ず終わる。さらにネトゲに飽きて失った時間に気付いたときにもう一つ学ぶことができる。人生は有限であること。
サーバー移行
さくらのVPSにMongo Rescueのリストアができなかった (未解決) | tech - 氾濫原 の続きで、結局クリーンインストールした。さっき DNS を切り替えたので様子見。一応 DNS の TTL 時間はとっくにすぎたので、変な BOT 以外はいまのところ旧サーバにアクセスない。
どうやったかのメモはまた別にかく
一通り移行できたつもりだけど、元々雑多なサーバ内容かつ長期運用していたのでよくわからない。外形監視を自宅 Raspi からやっておくべきだったかなあ。
プランは東京 2GB SSD にした。前がだいぶ古い大阪 1GB HDD プランだったので SSH で繋いで体感できるぐらいパフォーマンスあがった。ウェブ側も早くなってて Google からの評価があがるといいんだけどな〜
現状のサイト応答速度
Ubuntu 16.4 LTS クリーンインストールして引越
カスタムOSインストールガイド - Ubuntu 16.04 – さくらのサポート情報 を見ながらインストールまでやる。
旧サーバと同じホスト名にしてDNSをふりかえたいが、DNS やホスト名まわりは最後にやる。
SSH の設定
手元からまず copy-id
$ ssh-copy-id user@ufhostname
リモートの設定をかえる
$ sudo vi /etc/ssh/sshd_config PasswordAuthentication no PermitRootLogin no UsePAM no $ sudo /etc/init.d/ssh restart # 別のターミナルを開いて ssh できることを再度確認
Firewall の設定
ssh, http, https と mosh 用の udp ポートをあけておく (該当するソフトウェアをインストールすると勝手に空いたりするのだが念のため)
sudo ufw default deny sudo ufw allow 80 sudo ufw allow 443 sudo ufw allow 22 sudo ufw allow 60000:61000/udp sudo ufw enable
必要なパッケージいれる
sudo apt-get install zsh gcc libncurses5-dev language-pack-ja git daemontools daemontools-run mysql-server ca-certificates cpio curl dnsutils imagemagick imagemagick-common irssi libcairo2-dev libcurl4-openssl-dev mime-support nginx nginx-common nginx-full ntp ntpdate optipng pkg-config rsync shared-mime-info w3m wget xz-utils xml-core zip libxml2-dev libtiff5-dev libssl-dev libsqlite3-dev libreadline-dev libpng12-dev libpango1.0-dev libopenjpeg-dev libmysqlclient-dev libjpeg8-dev libgif-dev libfreetype6-dev libffi-dev cmake screen ruby-dev rrdtool libdb-dev postfix unattended-upgrades
sudo ln -s /etc/service /service
旧サーバから rsync
home ディレクトリごとまるごと移す
一時的に sudo で rsync をつかえるようにする
$ sudo vi /etc/sudoers.d/rsync Defaults env_keep += "SSH_AUTH_SOCK" Defaults!/usr/bin/rsync !requiretty cho45 ALL=(ALL) NOPASSWD: /usr/bin/rsync ||< >|| ## dry-run sudo rsync --dry-run -auvz -e 'ssh -i /home/cho45/.ssh/id_ecdsa' --rsync-path='sudo rsync' --progress /home/cho45/ cho45@160.16.210.51:/home/cho45/
ほかもうつす
/srv /etc/nginx /etc/postfix # /etc/mysql 変更点がなかった。。。あらためて見直そう /etc/letsencrypt # /var/lib/mysql mysqldump でやった # /service 手動でやる
意外とうつすのない?
h2o のインストール
git の HEAD を入れてるので再度コンパイルして /usr/local にインストール
cd ~/project/h2o git clean -f cmake -DWITH_BUNDLED_SSL=on . make sudo make install
ログファイルを /var/log/h2o に作るようにしてるが前もってディレクトリがないとしぬ
sudo mkdir /var/log/h2o
/var/log/h2o/*.log {
daily
missingok
rotate 90
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
svc -h /service/h2o
endscript
} perl のインストールしなおし
5.14.4 が gcc の関係?で入らなかったので、これを期に 5.22.2 に移行
perlbrew install perl-5.22.2 --as perl-5.22
前のマシンで perlbrew list-modules した結果を保存して cpanm にくわせてインストール。入らないやつが無視されるので、完全ではないがだいたい入る。
5.22 で動かなくなったコードを地味に修正したりした。
mysql
db ファイルだけ rsync したらいけるだろと思ったけど割といけなかったので、dump して restore する。mysql 自体のバージョンもあがってるのでまぁこのほうがよさそう。
mysqldump -uroot --routines --all-databases --flush-privileges | ssh cho45@160.16.210.51 'mysql -uroot'
たいしてデータ入ってないので一瞬。--routines でユーザテーブルもコピーしている。 --flush-privileges をつけないとコピーしたユーザデータが反映されないのでつけとく。
動作確認
160.16.210.51 www.lowreal.net 160.16.210.51 lowreal.net 160.16.210.51 cho45.stfuawsc.com 160.16.210.51 coqso.lab.lowreal.net 160.16.210.51 no-real.net 160.16.210.51 block.lab.lowreal.net
みたいなのを /etc/hosts に書いて検証。証明書も転送して設定済みなので DNS だけ書きかえればうごいてくれるという感じのはず。。
DNS 変更
DNS の向き先を新サーバに向ける
ホスト名と逆引きを設定
さくらのVPSはA レコードがひけてないと逆引き設定がつくれないので、Aレコードが適用されたあとにやる。
/etc/hostname も変える。
ここまでやったら一旦リブート。30秒ぐらいで起動するのでたすかる……
cron の再設定
旧サーバからぬいてくる
crontab -l > crontab.user sudo crontab -l > crontab.root
新サーバに適用する
crontab crontab.user sudo crontab crontab.root
カーネルパラメータ
/etc/sysctl.conf に追記
net.core.somaxconn = 50000 net.ipv4.tcp_max_syn_backlog = 30000 net.core.netdev_max_backlog = 5000 net.ipv4.ip_local_port_range= 1024 65535
sudo sysctl -p で反映
ref
Amazon Dash ボタン
これだけ買った。本当はおむつが欲しいんだけど、欲しいブランドのものがなかった…
定期便との併用
定期便でも頼んでるけど、定期便で頼んでいると在庫確認に無頓着になりがちで
- 届きすぎる
- いつのまにかなくなってる
の二択になる。適切な配達間隔を設定すること自体が難しい。定期便自体が月イチの決まった日付前後の配達になるので「なくなりそうだから頼もう」と思ったタイミングだと時既に遅しということがある。
結局
- 常に多めに頼んで、ときどき配送をキャンセル
- 自宅にストックが溜るので邪魔
- 結構頻繁に定期便の設定変更しててめんどい
- 途中で必要なくなったら余計な分がまるまる無駄
- 常に少なめに頼んで、ときどき追加で発送
- 追加分は定期便割引をうけられない
のいずれかになる。
おむつの場合ストックがものすごい邪魔なので、多めに頼むってのが難しい。それと成長にともなって商品変更を迫られるので、そもそも大量に買いたくない。おかげで、なくなりそうになったらプライムで追加発送とか、近くのドラッグストアで買うみたいな運用になる。
Dash Button だと「足りない」と気付いたときにすぐ買うという場合は便利そう。そして物理ボタンなので家族で共有して押せるというところが便利。洗剤とかだと気付いた人が詰めかえるという運用なので「なくなったから買って」「忘れてた」「はやく買って」「カートにはいれた」みたいなことが発生してめんどうくさい。
ただし「もうすぐ定期便で届くし、それまでは在庫持つよ」というケースでも発注してしまうことが予想できてちょっとむずい。
このサイトのキャッシュ
キャッシュの持ちかたを変えて、圧縮 (gzip) して持つように変えた。キャッシュを返すときは gzip ずみのをそのまま返すように。
gzip 非対応ブラウザでおかしくなる気がするけど、昨今そんなブラウザは聞いたことがないので現実的には問題なかろうという気がする。
これによりキャッシュ用のDBファイル(SQLite)のサイズが劇的に減ったので、ファイルキャッシュに乗りやすくなったはず……
「おい」と言うとお茶がでてくるみたいな圧縮アルゴリズム
誤り訂正や、超解像技術みたいなのを前提とした圧縮方法に興味がある。なんとなく面白い感じがする。本来存在していたデータを意図的に削って送って、受取側の「経験」みたいなものを信用する感じが面白い。
画像圧縮も、CPU速度と帯域を比べたときに帯域で律速されるぐらいに高解像度になると、ディープラーニングによる高解像度化や、自動色付けを前提とした画像圧縮アルゴリズムが産まれても不思議ではない。
つまりこれは「おい」と言うとお茶がでてくるみたいなシステム。これがコンピュータで実現すると面白い。送信側の「意図」みたいなものを最大限推論してデータを復元し、転送データを最小限にできる。
Google Photos の webp 対応
前まで webp のアップロードはできなかった気がするんだけど、最近試したらできるようになっていた。
Google Photos はいつからかブラウザによって webp が落ちてくるように変わったけど、そのタイミングでアップロードも変わったのかな?
ちなみに JPEG 2000 や JPEG XR はあいかわらずアップロード不可能
daemontoolsのsetuidgidが補助グループ (supplementary groups) 権限をつけてくれない問題 (python)
いままでハマったことがなかったのだけど、ついにハマってしまった。
補助グループ権限もつけてくれるsetuidgidのようなもの - (ひ)メモ を読んで、どうするかな〜と思いつつsetusergroupsを試してみたが、Unix::Groups がデフォルトで入っておらずちょっと困ったので python で以下のようにした。
#!/usr/bin/python
import os
import sys
import pwd
if len(sys.argv) < 3:
print >> sys.stderr, 'Usage: setusergroups user program'
sys.exit(1)
pw = pwd.getpwnam(sys.argv[1])
pw_name = pw[0]
pw_uid = pw[2]
pw_gid = pw[3]
pw_home = pw[5]
os.environ['HOME'] = pw_home
os.initgroups(pw_name, pw_gid)
os.setgid(pw_gid)
os.setuid(pw_uid)
os.execvp(sys.argv[2], sys.argv[2:]) エラると例外で落ちてトレースバックがでて十分なので特にエラー処理してな
備考
ハマったのは Raspberry Pi の pi ユーザで i2c を触るようなデーモンを作るケースで、この場合 pi ユーザに i2c グループ権限がついてないとダメなのでこういうのが必要になる。
依存なしでどうにかしたかったのは、cpanm が ansible の Core Modules に入ってなくてめんどかったから
builderscon tokyo 2016 で「 Bluetooth キーボードの作りかた」を喋りました
ありがとうございました。
聞いたトークで印象に残ったもの
OSS は Windows で動いてこそ楽しい - builderscon tokyo 2016
mattn さんが思ったより全くオッサン感なくてビビった。。。挨拶しようと思ったけどできなかったので、いつか(いつ?)挨拶したい。発表もおもしろかった。
動け!Golang 〜圧倒的IoTツール開発へようこそ〜 - builderscon tokyo 2016
IoTツール開発は生産管理ツールについてで、ものすごく貴重な話だと思った。懇親会でももうちょっと聞いたりした。
The Open Beer Server - theory and the implementation - builderscon tokyo 2016
今回のゲラゲラ枠っぽいが、ものすごい金かかっててやばかった……
C 言語で行う Web フロントエンドプログラミング - builderscon tokyo 2016
Emscripten の話とか。ブラウザって VR もサポートする予定なのか!と思った。あと Emscripten が頑張って OpenCL を WebGL に変換するとか知らなかった。
「片手間JavaScripter」にも知ってほしい、Vue.jsで実現するMVVMパターン、Fluxアーキテクチャとの距離 - builderscon tokyo 2016
Flux 触ったことなかったのでわかりやすかった。
そろそろプログラマーもFPGAを触ってみよう! - builderscon tokyo 2016
FPGA の話とても聞きやすくて解りやすくてよかった。
一から始めるJavaScriptユニットテスト - builderscon tokyo 2016
JS のテスト、闇雲にググっても萎えるだけなので、こういうまとまった資料ってほんとまじで大事
builderscon tokyo 2016 でしゃべります
16:40〜 自作キーボードの話を1時間ぐらいする予定です。なんか1日の最後なのでゆるめでやりたいという気持ちはあります。
おおむね、事前のトーク概要と変わらない内容で話せそうです。
資料つくってます…… 話がまとまらない……
体調不良
帰宅してから急激に体調が悪化し、悪寒がひどくて眠れないぐらいに。体温を計る余裕がなかったけど、38度〜 ぐらいは出ていた気がする。1時間ぐらい悪寒と戦ったあと、どうしよもないので家で余っていたロキソニンを飲んだら急激に楽になって寝れた。朝には熱はひいたが頭痛がひどかったので病院に。
熱の原因はよくわからなかった。ここ数週間地味に頭痛があったり体調が思わしくないけど、とりあえず緊張性頭痛だろうと言われた。熱にも頭痛にも効くからと葛根湯が処方された。


