- 投稿日:
adiaryをnginxの上で動作させつつ開発する方法をメモしておく。
前提条件
動作URLとしてはhttps://hoge.example.com/adiary
のようなサブドメイン付きのサブディレクトリとする。
adiaryはネイティブでfcgiをサポートしているらしいが、そこは無視して一般的な環境で起動するのがゴール。
SSLで動かす設定を書いているため、nginxでローカル開発環境向けのhttps環境を作るも参考にすること。
特別な設定は不要で、サブドメインモードにしなくとも動く。
確認環境
Env | Ver |
---|---|
OS | Ubuntu 22.04.3 LTS |
nginx | 1.24.0 |
fcgiwrap | 1.1.0-12 amd64 |
adiary | 3.50n |
手順
nginxはインストールされており、既に稼働している状態として話を進める
# adiaryを格納するディレクトリを作成する
sudo mkdir -p /usr/share/nginx/html/sites
# 既にどっかに展開済みのadiaryをディレクトリに突っ込む
sudo cp -R adiary /usr/share/nginx/html/sites
cd /usr/share/nginx/html/sites
# 所有権とパーミッションの調整
sudo chwon -R $USER:$USER adiary/
cd adiary/
sudo chmod -R 777 __cache/
sudo chmod -R 777 data/
sudo chmod -R 777 pub/
# Image::Magickを入れる
sudo apt install -y libimage-magick-perl
# nginxでCGIを動かすために、fcgiwrapをインストールする
sudo apt install fcgiwrap
# /etc/nginx/conf.dに設定ファイルを作成
cat <<'EOF' | sudo tee -a /etc/nginx/conf.d/hoge.example.com.conf
server {
listen 443 ssl;
server_name hoge.example.com;
ssl_certificate ssl/hoge.example.com.pem;
ssl_certificate_key ssl/hoge.example.com-key.pem;
access_log /var/log/nginx/hoge.example.com.access.log;
error_log /var/log/nginx/hoge.example.com.error.log;
# マルチテナント用にこう書いている
root /usr/share/nginx/html/sites;
# /usr/share/nginx/html/sites/adiaryにadiary一式が入っている想定
location / {
index index.html;
}
location /adiary {
index adiary.cgi;
}
# fastcgi用
location ~ \.cgi$ {
gzip off;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
EOF
# nginxの設定を再読み込みする
sudo service nginx restart
トラブルシューティング
403エラーで起動せず、エラーログにパスがないと出る
以下のコマンドを叩き、パスが整合するまで設定を調整する
sudo strace -f -e trace=file -p $(pidof fcgiwrap)
- 投稿日:
Google Search Consoleで状況を確認してみることにする。(Google Analyticsやレンサバのログ解析も似たような結果になっている)
アクセス数は以前よりかなり落ちている。これはタイミングの問題かもしれない。もし、CMS変更が原因であれば、URL変更やHTMLの構造変更が影響しているのだろう。少なくともコンテンツは丸ごと移してるし、URLのリダイレクトもほとんどは機能しているはずだ。いや実際に機能しているかまで確認はしてないが…。
まぁアクセスが多くても負荷が高まってサーバーが落ちたりするので、このくらいが程よいのかもしれない。
またインデックスについては未登録URLがグッと増えた。グラフを見る感じWordPressのURLがまるっと未登録になり、adiaryの分が増えた感じだろう。adiaryの方が記事URLに対してサイトマップの登録率が高いが、これはadiaryとWordPressでサイトマップのファイル構成が異なることに起因している可能性がある。例えばadiaryはサイトマップが1ファイルなのに対し、WordPressは複数ファイルであるため、Google側の解釈に差が出ているとか、そもそもXMLの内容も違うはずなので、色々影響しているのかもしれない。
インデックス状況についてはWordPressの頃は手動登録しないとインデックスされないことが少なくなかったが、adiaryでは何もせずともインデックスされるので、ここについては大きく満足している。やはりこれはWordPressよりadiaryの方が早いことに起因しているだろう。
- 投稿日:
Node.jsとGoogle Chrome, Microsoft Edgeを用いて、try-catchとif文でエラー処理にかかる時間がどのくらい違うのかを調べた。
計測手法
次の4パターンを100万回実行した結果を記載している。
- Result型としてエラーオブジェクトをreturnし、if文で判定する方式
- Result型としてエラーインスタンスをreturnし、if文で判定する方式
- エラーオブジェクトをthrowし、try-catchで判定する方式
- エラーインスタンスをthrowし、try-catchで判定する方式
確認に使用したコード:https://gist.github.com/Lycolia/304bc9e825e821c2d582f3ef9f700817
計測結果
CPUによって処理速度がかなり変動するが、いずれの環境でも処理速度の速さは以下の通り。
- Result型としてエラーオブジェクトをreturnし、if文で判定する方式
- エラーオブジェクトをthrowし、try-catchで判定する方式
- Result型としてエラーインスタンスをreturnし、if文で判定する方式
- エラーインスタンスをthrowし、try-catchで判定する方式
計測に使用したCPU
CPU | コア | スレッド | クロック | L2キャッシュ | L3キャッシュ |
---|---|---|---|---|---|
Intel Core i7 13700 | 16 | 24 | 5.20GHz | 24.00MB | 30.00MB |
Intel Core i7 1265U | 10 | 12 | 4.80GHz | 6.50MB | 12.00MB |
AMD Ryzen 5 5600G | 6 | 12 | 3.90GHz | 3.00MB | 16.00MB |
Intel Core i7 13700端末
16C24T, 5.20GHz, L2 24.00MB, L3 30.00MB。ミドルタワーPC。
Node.js v16.20.2
処理環境
Env | Ver |
---|---|
CPU | Intel Core i7 13700 |
OS | Ubuntu 20.04.6 LTS (WSL2) |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 802 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 5,942 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 1,847 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 6,527 |
Node.js v18.19.1
処理環境
Env | Ver |
---|---|
CPU | Intel Core i7 13700 |
OS | Ubuntu 20.04.6 LTS (WSL2) |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 887 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 5,826 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 2,006 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 6,464 |
Node.js v20.11.1
処理環境
Env | Ver |
---|---|
CPU | Intel Core i7 13700 |
OS | Ubuntu 20.04.6 LTS (WSL2) |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 720 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 5,375 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 1,690 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 5,978 |
Microsoft Edge 121.0.2277.128
処理環境
Env | Ver |
---|---|
CPU | Intel Core i7 13700 |
OS | Windows 11 Pro 22H2(22621.3155) |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 4,246 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 12,329 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 11,985 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 14,105 |
Google Chrome 122.0.6261.58
処理環境
Env | Ver |
---|---|
CPU | Intel Core i7 13700 |
OS | Windows 11 Pro 22H2(22621.3155) |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 3,507 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 10,793 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 10,482 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 12,452 |
Intel Core i7 1265U端末
10C12T, 4.80GHz, L2 6.50MB, L3 12.00MB。ノートPC。
Node.js v16.20.2
処理環境
Env | Ver |
---|---|
CPU | Intel Core i7 1265U |
OS | Ubuntu 20.04.6 LTS (WSL2) |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 972 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 11,416 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 2,288 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 13,993 |
Node.js v18.19.1
処理環境
Env | Ver |
---|---|
CPU | Intel Core i7 1265U |
OS | Ubuntu 20.04.6 LTS (WSL2) |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 1,102 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 11,333 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 2,441 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 12,827 |
Node.js v20.11.1
処理環境
Env | Ver |
---|---|
CPU | Intel Core i7 1265U |
OS | Ubuntu 20.04.6 LTS (WSL2) |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 888 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 10,881 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 2,269 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 12,254 |
Microsoft Edge 121.0.2277.128
処理環境
Env | Ver |
---|---|
CPU | Intel Core i7 1265U |
OS | Windows 11 Pro 22H2(22621.3155) |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 7,526 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 34,761 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 39,005 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 65,752 |
Google Chrome 122.0.6261.58
処理環境
Env | Ver |
---|---|
CPU | Intel Core i7 1265U |
OS | Windows 11 Pro 22H2(22621.3155) |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 6,303 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 16,460 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 17,979 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 23,378 |
AMD Ryzen 5 5600G端末
6C12T, 3.90GHz, L2 3.00MB, L3 16.00MB。ミニタワーPC。
この端末はOSがUbuntuであるため、これまでのWindows環境との単純比較はできない。
Node.js v16.20.2
処理環境
Env | Ver |
---|---|
CPU | AMD Ryzen 5 5600G |
OS | Ubuntu 22.04.3 LTS |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 1,786 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 11,242 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 3,880 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 12,716 |
Node.js v18.19.1
処理環境
Env | Ver |
---|---|
CPU | AMD Ryzen 5 5600G |
OS | Ubuntu 22.04.3 LTS |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 1,933 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 11,094 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 3,839 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 12,767 |
Node.js v20.11.1
処理環境
Env | Ver |
---|---|
CPU | AMD Ryzen 5 5600G |
OS | Ubuntu 22.04.3 LTS |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 1,714 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 10,741 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 3,444 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 11,978 |
Microsoft Edge 121.0.2277.128
処理環境
Env | Ver |
---|---|
CPU | AMD Ryzen 5 5600G |
OS | Ubuntu 22.04.3 LTS |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 4,348 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 21,584 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 15,543 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 23,119 |
Google Chrome 122.0.6261.57
これだけバージョンが合わなかった。
処理環境
Env | Ver |
---|---|
CPU | AMD Ryzen 5 5600G |
OS | Ubuntu 22.04.3 LTS |
処理結果
処理方式 | 処理時間(ms) |
---|---|
Result型としてエラーオブジェクトをreturnし、if文で判定する方式 | 4,842 |
Result型としてエラーインスタンスをreturnし、if文で判定する方式 | 16,607 |
エラーオブジェクトをthrowし、try-catchで判定する方式 | 15,051 |
エラーインスタンスをthrowし、try-catchで判定する方式 | 18,095 |
全体サマリ表
凡例
- Result型としてエラーオブジェクトをreturnし、if文で判定する方式
- Result型としてエラーインスタンスをreturnし、if文で判定する方式
- エラーオブジェクトをthrowし、try-catchで判定する方式
- エラーインスタンスをthrowし、try-catchで判定する方式
CPUによってかなり差が出ているが、Intel CPUの13700と1265Uを比較した場合、例外を作らない1, 3のケースでは処理に大きな差がないが、例外を作る2, 4のケースでは有意な差が認められるので、モバイル向けとデスクトップ向けでCPUの処理効率に差があることがわかる。
AMD CPUと比較した場合、Node.js環境で例外を作らないケースではIntel CPUに大きく引けを取るが、ブラウザ上でのそれではパフォーマンスは高い。また例外を作るケースでもNode.js・ブラウザ共にIntel CPUと比較した場合のパフォーマンスが比較的よいという、面白い結果になっている。但しOSが違うことの影響もあるため、単純比較はできないが…。
あとがき
ひとまずtry-catchを使うと遅くなるということが確かめられたので良かったし、環境によって劇的遅くなるケースがあるというのは思わない収穫だった。
これを試そうと思った切欠はtry-catchが乱用されているコードを見てパフォーマンス劣化に繋がっているのではないかという疑問を抱いたからだ。try-catchでパフォーマンスの劣化が起きることは知識としても経験としても知っていたのだが、ちゃんとレポートしたことがなかったので今回まとめてみた。
try-catchの利用によりパフォーマンスの劣化が起きるというのは、古い時代にあった開発のお作法を知っている人であれば、それなりに常識だとは思うが、最近は知られていないか、知られていても意識していないことが少なくないと思われるので、今回記事にしてみた感じだ。
100万回の実行なので細かい話になるとは思うがパフォーマンスチューニングは細かいことの積み重ねでもあるので、むやみやたらに例外を使わないことは重要だと思う。そもそも例外は制御しづらいので、可能な限りif文で処理を書くことが望ましいだろう。
処理が遅延する原因としては二つあると考えていて、一つは例外生成時に顕著であることからスタックトレースの生成を初めとしたエラーオブジェクトの生成に時間がかかっているのと、もう一つはcatchでも遅延が出ることから、コールスタックから最寄りのcatchを辿るのに時間を取られていると思われる。今回の検証では特に出してないが、以前確認した時の記憶が確かであれば、catchに入らない限り、tryだけで顕著に処理が遅延することはなかったと思う。
あと、どうでもいいことだがconsole.log()
で結果を出したときにEdgeだけObjectのKeyの順序が他と違ったので転記しているときに微妙に不便だった。何回やっても同じだったので恐らくEdgeだけキーをソートするアルゴリズムが違うのだと思う。まぁObjectとかHashとかMapとかDictionaryみたいなやつは順序が保証されないので別にいいっちゃいいんだけど、まさか実装によってソート方式が違うというのは思いもしなかった。
EdgeとChromeで処理結果が優位に違うのも、恐らくこれが原因なのだろう。分からないが多分JSのエンジンの実装が違う気がする。
それとLinuxのEdgeにはマウスジェスチャー機能がないという悲しいことも分かった。
参考
- 投稿日:
以前WordPressで構築していたサイトが頻繁に落ちていることについて記事にしたが、adiaryに変えてからどうなったかというと、恐らく落ちなくなったと思う。
何故そう思ったかだが、今までGoogleにインデックスさせるときは毎回Search Consoleから手動登録していたが、そんなことをしなくても勝手にインデックスしてくれるようになったからだ。BingにもIndexNowを使わずとも勝手にインデックスされている。いや、BingのクローラーについてはIndexNowの有無による差を検証したことがないので有意に改善しているかは正直不明だが…w
少なくともこれでインデックスされやすくなり、以前よりアクセスしやすくなることだろう。読み込み時間が0.3秒変わるだけでブラウザバックが減るとかいう話も昔どっかで読んだ気がするし、0.3秒どころか6秒くらい改善してそうなので、効果はかなり期待できると考えている。
Markdownのレンダリングについても作者に要望を出しまくったので大分改善した。とはいえ、まだ問題点は残るので、そこはMarkdown parserを自作する事で上手いことやっていきたいと思う。結果としてadiaryへの乗り換えは大成功だったといえる。
adiaryは非常に素晴らしいCMSだと思うので、WordPressを使っていて重さに悩む人や、CDNなどの費用を節減したい人は検討されてもいいのではないだろうか?WordPressのように素晴らしいテーマや有益なプラグインは存在しないが、なければ作ればいいので、そういう気概のある人には非常にお勧めできると思う。
また本体やプラグイン、テーマが勝手にアップデートされることがないので「何もしてないのに壊れた」が起きないのもいいところだ。当然、その分の保守能力はサイト管理者に求められるが、本来ホームページ運営というのはそういうものである。一定のリテラシーがないとできないのは当然のことだ。少なくとも昔のインターネットでは常識だった筈だ。
何よりこのCMSは日本製だ、日本人なら日本製に拘ってみるというのもありだろう。
改善の余地は山ほどあると思うので、最近開発から遠ざかっていた人にも大変お勧めできる。adiaryはOSSなので、コントリビュートするのもよし、フォークするのもよしだ。逆にシンプルで複雑さがないので、これで必要十分というケースもあるだろう。
この機会に昔懐かしいPerlに触ってみるというのも一つの経験になるだろう。かつてCGIを書いていた人も、使っていただけの人も、どっちでもない人も、Perlという言語の魅力に触れてみたり、新しく発見してみる一つの機会になると思う。Perlの言語仕様はもしかしたら余り良くはないかもしれないが、夢中になって書いていれば、そんな言語でも新しい発見があったりして、きっと楽しいと思う。
いろんな意味で自分のホームページを作るという意味では非常に良いCMSだと思うので、私はそこが好きだ。
余談だが記事ID「0268」以降がadiaryの記事で、それ以前がWordPressの記事となる。厳密にいうとWordPressの記事の中には、はてなダイアリーやQiitaで書いた記事も入っているのだが、区別する術がないのでWordPressの記事ということで一緒くたにしている。特にない限りCMSの乗り換えはもうしないと思うので、この法則がずれることは恐らくないだろう。
因みに私がフォークしているバージョンでは暫定的にクリップボードの画像を直接アップロードできるように改造している。実験的な機能であるため動作保証などは一切しないが、もし画像が貼り付けられずに不便を感じる人がいたら使ってみてほしい。
- 投稿日:
skel
- 書き替えたいコードの所在をgrepする
skel/
の中に該当する行を見つけるskel.local/
に該当ファイルをコピーする- 該当行を編集
- ブログの管理>ブログを再構築する
plugin
skel書き換えでうまくいかない場合
- 書き替えたいコードの所在をgrepする
plugin/
配下のmodule.html
に該当する行を見つける- 該当行を編集
- プラグイン設定>リセット>再インストール
参考
- adiary開発マニュアル
- 大まかな全体の考えを知るのに役立つが細かい情報はなく、リファレンスとしては微妙