netscaler LBにおいてサーバを使わずにリダイレクトする
これは何
netscaler LBにおいて特定FQDNへのアクセスをパスそのままで他のFQDNにリダイレクトする方法についてまとめる。 この資料は NetScaler version 11.0 で実験した動きを元に書いています。
目次
参考資料
https://support.citrix.com/article/CTX120664 大体これを読めばできるが以下の問題があった(この資料を作るモティベーション)
- LoadBalancing Virtual Server の設定のところがServiceと書いてあり誤植と思われる
- 設定箇所の階層が書いておらず多少読みづらい
- LoadBalancing Virtual ServerにGlobal IPを設定するパターンしか書かれていない
手順
System設定でresponderの有効化
NetScaler -> System -> Settings -> Configure Acvanced Features
responder にチェックを入れる。
Responder Actionの設定をする
- Addする(既存のActionを選択してAddするとそれをテンプレートとして使うことになる。最初から作るなら選択を外してAddする)
- TypeはRedirectを選択
- Expression
例1) http->httpsにリダイレクトするなら、スキーマのところだけhttpsと書いて後は同じ
"https://" + HTTP.REQ.HOSTNAME.HTTP_URL_SAFE + HTTP.REQ.URL.PATH_AND_QUERY.HTTP_URL_SAFE
例2) 特定の別のドメインにリダイレクトする
"http://piyo.jp" + HTTP.REQ.URL.PATH_AND_QUERY.HTTP_URL_SAFE
補足: L7で http://hoge.jp/fuga などで入ってきたLoadBalancing Virtual Server経由でこのactionで http://piyo.jp/fuga に飛ばすイメージ
* Response Status Code を設定する デフォルト 302
Responder Policy の設定をする
- さっきのActionを設定する
- Undefined-Result ActionをRESETにする
- Expressionには HTTP.REQ.IS_VALID を設定(frequently Userd Expressionから選択すると良い)
- 要するにこのpolicyでは特に何もせずに(validかチェックだけして)actionへ流すという意味か
monitor 設定をする
localhost に pingをうつmonitor設定を作る
- name: localhost_ping
- Type: PING
- destination ip: 127.0.0.1
service を作る
上で作成したmonitorを使って常にserviceがUP状態になるようにする。あくまでダミーで、LoadBalancing Virtual Serverが常にUP状態になるようにするためのものの模様
- 上記serverを紐付ける
- ProtocolとPortはHTTPと80とでも適当に設定しておく
- 作成後、Monitoring設定で先程作成したmonitorを設定し、UP状態になることを確認する
LoadBalancing Virtual Serverを作る
- IP Address: WebサイトのIPアドレスもしくはPrivate IP
- Global IPで直接受ける場合にはここに設定
- Content Switching Virtual Server通すならここはPrivate IPを指定する
- 作成後Responder Policyを設定
Content Switching Virtual Server 設定
上記でLoadBalancing Virtual ServerにPrivate IPを設定した場合にはContent Switching Virtual Serverのpolicyに紐付ける この手順はredirector特有というよりもContent Switching Virtual ServerからLoadBalancing Virtual Serverに流す手順と同じなので省略する
キャッシュサーバが遠くなるとレイテンシは上がるのか、pingとtcpdumpで考えた
これは何
私の持っているシステムではフロント系サーバからmemcached サーバへ接続回数が結構ある。
データセンタ内で今まではフロント系サーバもキャッシュサーバも同一セグメント、物理的にも近くにいた。
とある事情でサーバをリプレイスしなくてはならず一時的にそれが違うセグメントで、物理的にも遠く、間にいくつかスイッチとルータが挟まるようになる。
これにより新しいフロント系サーバから古いmemcachedサーバに接続するとレイテンシが問題になるかもしれない。
ネットワーク的に遠くなると実際にアプリケーションの応答性能の視点で問題になるのか、いまと比べて実際は大した事ないのか判断するために考えたことのメモ。
目次
測定
測定方法
ping のtimeの100回の平均を取る。 pingのtimeは何か -> https://linuxjm.osdn.jp/html/netkit/man8/ping.8.html
往復時間 (round-trip time) と消失パケットの統計が計算される。
なので、単なる往復時間。
TCPにおける遅延は? TCPの場合はパケットごとにACKするので、送りたいもののデータサイズが大きく、パケットの個数が増えると全体としてはそれだけ1パケットあたりの遅延が蓄積されていくことになる。 なので、pingのRTTの増加はそのままレスポンスタイムの遅れに繋がると考えられる。
測定実施
2台のサーバが同一セグメントにある 旧frontサーバ(hoge-old-web) => 旧cacheサーバ(hoge-cache)
[myuser@hoge-old-web ~]$ ping -c 100 xx.xx.xx.xx > ./tmp_to_hoge-cache_ping [myuser@hoge-old-web ~]$ grep "time=" ./tmp_to_hoge-cache_ping > ./tmp_to_hoge-cache_latency [myuser@hoge-old-web ~]$ awk '{print $(NF-1)}' tmp_to_hoge-cache_latency | awk -F'=' '{sum+=$2} END{print sum/NR}' 0.14284
0.14 ms くらい
新frontサーバ(hoge-new-web) => 旧cacheサーバ(hoge-cache)
[root@hoge-new-web ~]# ping -c 100 xx.xx.xx.xx > ./tmp_to_hoge-cache_ping [root@hoge-new-web ~]# grep "time=" ./tmp_to_hoge-cache_ping > ./tmp_to_hoge-cache_latency [root@hoge-new-web check_latency]# awk '{print $(NF-1)}' tmp_to_hoge-cache_latency | awk -F'=' '{sum+=$2} END{print sum/NR}' 0.16793
0.16 ms くらい
差分
0.16793 - 0.14284 = 0.02509 ms 割合ていうと 0.02509 / 0.14284 * 100 = 17%。
frontへアクセスした時にmemcachedはどれくらい叩かれている?
コードで呼ばれているcacheメソッドの回数も重要だが、遅延全体を考えるならパケットがどれくらい投げられているかが重要。なのでtcpdump でパケット数がどれくらい投げられているのか確認したい。
myuser@hoge-dev-web [~ ] $ sudo tcpdump -i eth0 > ./tmp_tcpdump_to_memcache tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes ^C7136 packets captured 7136 packets received by filter // 全部でこれだけのパケットが1リクエストで通った 0 packets dropped by kernel
その中で memcachedにつなぎにいっているのは?
myuser@hoge-dev-web [~ ] $ grep "xx.xx.xx.xx.11211 >" tmp_tcpdump_to_memcache -c 1579
memcachedから来ているパケットは1リクエスト1579回。(行きも同数。pingのtimeはRTTなので片方の道を通っている回数がわかれば良い。)
最大で増えるレイテンシはどれくらい?
毎回のパケット 0.02509 ms * 1579 = 39.6 ms。ほとんど誤差。気にしなくてもよさそう。
結論
今回の件ではレイテンシはあまり気にしなくても良い。
ansibleのget_url moduleでSNIのhttpsサイトからダウンロードが出来ない【問題と解決】
これは何
ansible version 2.2。get_url moduleを使ったときの話。 ターゲットサーバのOSはSL6.8。python 2.6。
結論から言うと
証明書期限切れしていただけでした。ドハマリした。 期限切れしていない正常なダウンロードサイトからのものはpython2.6にpipでライブラリいれたら治っていた。
問題
"msg": "Failed to validate the SSL certificate for hogehoge.org:443. Make sure your managed systems have a valid CA certificate installed. If the website serving the url uses SNI you need python >= 2.7.9 on your managed machine or you can install the `urllib3`, `pyopenssl`, `ndg-httpsclient`, and `pyasn1` python modules to perform SNI verification in python >= 2.6. You can use validate_certs=False if you do not need to confirm the servers identity but this is unsafe and not recommended. Paths checked for this platform: /etc/ssl/certs, /etc/pki/ca-trust/extracted/pem, /etc/pki/tls/certs, /usr/share/ca-certificates/cacert.org, /etc/ansible"}
解決策
提示されている解決策とやってみた内容は以下
- python 2.6だとurllib3, pyopenssl, ndg-httpsclient, and pyasn1 を入れると治るかも => pipで入れてみたが、この部分のエラーメッセージだけが消えて他は同じ。解決せず
- python2.7を入れてみる => ソースからビルドして ansible_python_interpreter=/usr/local/bin/python に設定してみた。同じくこの部分のエラーメッセージだけが消えて、解決せず
- 後の問題は、そもそも正しい証明書が系にインストールされていない? 根が深そうなきがするが・・・
じゃあSNI対応しているwget使うとどうか? => 同じように検証でエラーがでる。SNI対応していて治るなら1個め2個めで治っているはずだしね。 結局、ブラウザでアクセスしてよくよく見てみると、
この証明書の有効期限は 2017年8月2日 18:39 に切れています だった。
※これが起こった日は 2017/8/4 最初にダウンロードリンクを取る時にアクセスしてスルーしていたのだった。ちゃんと真っ赤になっていたのに。「ドメインあっているよなあ」などと思って。
結論
思い込みで時間を無駄にした。 やはり違和感は大切にしよう。後で調べる、と思っていたことがトラブルの元になるので、違和感があったらできるだけ説明がつけられるようにしておこう。
swapが出るDBサーバの vm.swappiness と innodb_flush_metho=O_DIRECT設定 について
これはなに
MySQLサーバでswapが出てレプリケーション遅延が起こっていた。その原因を考えた時のメモ(結構昔だけど、掘り起こして少し整理)。
トラブル発生時の状況
swap 全食いつぶしされていた(swapは8Gの設定)。swap が単に発生したというよりも、swap in/out が沢山あったのが問題。3列目がページイン(swapin)、4列目が ページアウト(swapout) 。単位は kbyte/s。
$ sar -f /var/log/sa/sa16 -B | grep '11:20' -A 10 11:20:01 AM 19.96 1528.86 227.95 0.23 306.29 0.00 0.00 0.00 0.00 11:30:01 AM 32.78 1060.79 284.00 0.41 418.23 57.04 2.05 53.95 91.29 11:40:01 AM 35.41 918.87 288.44 0.32 613.35 156.52 4.00 154.15 96.03 11:50:01 AM 30.93 931.70 337.14 0.23 635.15 129.01 3.78 125.92 94.82 12:00:08 PM 1090.31 66591.60 1161.96 38.31 18141.11 264214.86 998791.30 17389.23 1.38 12:10:04 PM 16094.34 73548.50 1853.48 65.37 23471.29 248716.54 1527936.86 22704.65 1.28 12:20:05 PM 25803.10 25574.29 2219.17 183.17 13001.47 45104.96 88174.19 12253.92 9.19 12:30:07 PM 6338.98 27665.28 1886.63 201.32 8700.89 42764.03 85559.13 7997.71 6.23 12:40:05 PM 6489.96 22360.17 1541.27 204.05 7111.80 38805.93 31339.39 6642.17 9.47 12:50:01 PM 7012.49 16050.09 730.82 80.87 14578.10 23819.42 35602.05 3570.47 6.01 01:00:01 PM 0.03 1.32 43.08 0.01 28.28 0.00 0.00 0.00 0.00
cpu 使用率 system 30% と I/o wait 20 % くらいでていた。User は数%程度でそこまで大きく変わらず。
対策
swappiness 設定
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Performance_Tuning_Guide/s-memory-tunables.html anonymous memory か page cache かどちらを優先するのかの度合。値が低ければ スワップアウトを避ける(anonymous memoryをスワップに出さずに、page cacheをディスクに書き戻すのを優先する)。 DBだと低めの値を設定するのが推奨のよう。 RHEL 6.4 からは swappiness = 0 はさらに強くswapout しないような仕様になっているそうなので注意が必要。Oracle Databaseで10が推奨とのこと。
anonyamous memory って何? page cacheとの関係は?
http://nopipi.hatenablog.com/entry/2015/09/13/181026 無名ページ —>メモリが足りない時スワップアウト(スワップへ退避)され、物理メモリから解放されるページ ファイルページ —> メモリが足りない時ディスク同期し解放されるページ スワップする/しない、の差。 どういうこっちゃ? もうちょっと調べる。
http://enakai00.hatenablog.com/entry/20110906/1315315488
http://mkosaki.blog46.fc2.com/blog-entry-884.html
MemTotal = MemFree + File-backedなメモリ + Anonymousなメモリ + カーネル空間が使うメモリ
File-backed(file pageやpage cacheとも)というのは、ディスクからメモリに読み込んだファイルなど、メモリを開放したくなったら、その内容をディスクに書き戻せば開放できるタイプのメモリ。ファイルキャッシュ、バッファ、プロセスのテキスト領域(プログラム本体)
Anonymousというのはそれ以外のメモリで、メモリを開放したくなったら、Swap領域に書き出さないと開放できないタイプのメモリ。プロセスのメモリ(データ/スタック領域)、共有メモリ、tmpfsとか。
maria DBでのswappiness 推奨設定
https://mariadb.com/kb/en/mariadb/configuring-swappiness/ swappiness = 1 がよい。 そもそも メモリがswapであることを想定したアルゴリズムではない、とのこと。mysql でも同様か? 値の参考には出来そう。
結局どのような設定にすべきか?
innodb buffer pool 内に書かれているものは、ディスクにそのまま書き戻せるものではなくて、検索結果や更新途中の処理のデータが乗っている。つまり、mysqldによって作られたanonymous memoryとして持たれていると思われる。anonymous memory は以下のように確認する。18G ちょっとある(データはトラブルの起こっていない他のDB)。
$ grep anon /proc/meminfo -A 2 Active(anon): 19021848 kB Inactive(anon): 1724228 kB Active(file): 1416160 kB Inactive(file): 1705648 kB
バイナリログ/その他ログなどはfile cacheへ置かれていると考えられ、これらがメモリ内に共存することになる。
ここで swappiness が高い(デフォルト60)だと、file cache とanonymous memory のどちらも物理メモリ上に残そうとするため、物理メモリがあふれるとfile cacheの一部がディスクに戻ると共に、anonymous memoryの一部がswapに書きだされる。kernel の mm/vmscan.c を読むと、fille_prio = 200 - anon_prio (デフォルトなら file:anon = 140 :60)となっており、LRU(使ってないものから追い出す)に基づいて追い出す模様(深くは追えていない)。
一方 swappiness が低い(例えば設定値1の)場合には、anonymous memoryを物理メモリ上に置いておく優先順位が高くなり、file cacheが優先的にディスクに戻される。すなわり、swapは起こりにくくなる。
DBにおいてswap が発生するのと、file cacheが揮発するのとどちらがサーバ全体に有利かという点を考える。innodb buffer pool が swap に書きだされるか、主にその他ログファイルがディスクに戻るかとの違い。
file cache に乗る可能性のあるもの。ログファイルの大きさは innodb_log_file_size = 128M であり、そこまで大きくない。slow query log は(肥大化しているとはいえ)300M 以下。DBサーバにおいてメモリに必ず乗っていて欲しい大きなファイルなどは他にない。他に数G単位のがあるならbuffer pool sizeチューニングの話のところで出てくるはずだし、Active(file)あたりにも現れるはず。テーブルスペースから buffer pool にのせる前にfile cache にのせることがある。この buffer pool にのせる前のfile cache については innodb_flush_method 設定で抑制できそう。
結論: 単に各種ログファイル等が開かれることにより乗った古い file cache がディスクに書き戻されても差支えないと考えれば、swap が出るよりは file cacheに乗っているデータをファイルに戻してもらった方がよい。
innodb_flush_method = O_DIRECT設定
設定の意味は? https://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_flush_method データファイルを開くときには O_DIRECT を用いて、flushするときにはfsync() を用いるというオプション。ただし、fsyncするときもOSはデータキャッシュを行わない。 デフォルトでは innodb データファイルから、一回ファイルシステムキャッシュを経由して innodb buffer pool にデータを読みだす。 O_DIRECT設定をいれると、データファイルから直接buffer pool に読み込むことで、システムによるキャッシュとRDBMSによるキャッシュの重複を無くすという感じ。buffer pool にキャッシュされているデータは、まったく内容が同じというわけではないが役割がかぶるので、それだけを使う。
デメリットはあるのか?
http://d.hatena.ne.jp/sh2/20101205 性能を上げるというよりも、メモリ使用量を制限するというためのものだと考えた方がよさそう。 どういうときに入れてもいいのかという話は 「High Performance MySQL」に書かれていた。https://books.google.co.jp/books?id=JXFuCQAAQBAJ&pg=PA363&lpg=PA363&dq=O_DIRECT+raid+write+back&source=bl&ots=8oVbZYwCdj&sig=4vpbTujup-BfTM0bRACIsnOLcA0&hl=ja&sa=X&ved=0ahUKEwi6qdrEseDMAhVBpJQKHVK9D-4Q6AEIHjAA#v=onepage&q=O_DIRECT%20raid%20write%20back&f=false この設定はOSによるキャッシュは無効化するが、RAIDカードによる read-ahead は無効化しない。O_DIRECT を有効化してかつパフォーマンスを落ちないようにする方法は、RAIDカードによる write-back設定をいれたwrite cache が必要。InnoDBと実際のストレージとの間にバッファがなければ、パフォーマンスは劇的に悪くなる。 弊社で使用しているサーバは write-back 設定を入れてあるはずなので大丈夫(構築時に一応確認するが、大体デフォルトで入っている)。 また、設定を入れるとMysqlを起動した直後のパフォーマンスが悪くなりそう。OSがキャッシュしていれば起動後にdiskから直接読みださなくてよいので早くなる。これは、OS再起動後とかだとどちらにせよOSによるファイルキャッシュも消えていると思うので気にしてもしょうがなさそう。
設定手順
vm.swappiness = 1の設定を入れる
sudo su - sysctl vm.swappiness # 確認 sudo cp /etc/sysctl.conf /var/tmp/sysctl.conf sudo vim /etc/sysctl.conf # 末尾に vm.swappiness=1 を追記 diff /var/tmp/sysctl.conf /etc/sysctl.conf sudo sysctl -p # 設定を反映 sysctl vm.swappiness # 反映を確認
innodb_flush_method = O_DIRECT の設定をいれる
[mysqld]ブロックの最後にでも以下の記述を追加する
innodb_flush_method=O_DIRECT
mysql restart する
$ sudo service mysql restart
設定確認する
mysql -uroot -p -e "show global variables ;" | grep innodb_flush_method
納期と障害とElasticBeansTalkのお話
さて、納期がありますね。
急いで開発しますね。
リリースしますね。
喜びますね。
お客さん沢山きますね。
・・・(しばしリリースを喜ぶ)
負荷が上がりますね。
詰まりますね。
障害ですね。
こんにちは。ElasticBeansTalkを作ってとあるキャンペーンの特設サイトを構築した話です。
要件的なやつ
- リリースまで残り10日くらい
- キャンペーン期間は一ヶ月以下
- SSLじゃないとダメ(oauthのコールバックの関係)
- Nodejs, Nginx, 適当なNoSQL
期限的にオンプレでssl証明書買うのは無理だし、ちゃんとしたの買うと短い期間しか使わないのに高い。そしたらクラウドに金払った方が良い。
どうやらAWSでACMというやつで高速で証明書発行してhttpsサイト作れるらしいじゃないの。最高。
そしてElasticBeansTalkというやつで高速にELB+EC2(Nginx+Nodejs)+DynamoDB立てられるらしいじゃないですか。
こりゃ楽勝だな。
やったみた
- ElasticBeansTalk+ACMを使って、サンプルアプリデプロイして動かすまで1日かからず。最高。
- インフラとしては監視を入れたい。ebextensionsを使ってCloudFormation的なものを書く。ほぼサンプルなのでデプロイすれば動く。楽勝。
- ↑のものを何が書いてあるのに理解するのに3日くらい(まだ理解仕切れていない)。AWS普段触らない人には辛い。
- AWSでどれくらいかかるか詳細見積もり(ざっくり見積もりはEC2使うと決めた時点でざっくりとっていたが、インスタンスタイプとかアクセス見積もりとか詳細のやつ)。
- DynamoDBもサンプルデプロイして半日たたずに動く。なるほど。オートスケールはデフォルトじゃないのか。気をつけないとね。楽勝(嫌な予感。伝えておかないと)。サンプル突っ込んだら動いたことを開発側に伝えて、ドキュメント渡してその後ここを丸投げ。
- Slack通知もしたいねということで、LamdaのBlueprintとかいうのを使ってSNSからLamda通してSlack通知へ。
- その他eb設定もebextensionsで管理
slack通知のタスクは残念ながらリリース時間には間に合わなかったけど、アプリ共々動いてるのでリリースはできた。
で、問題は?
リリース後、しばらくしたら5xx返すかクソ重いかになる。
EC2はCPUまあまあ食ってるけど詰まるほどではない。メモリはスカスカ。サーバ内書き込みないからDiskIOなんて起こるはずもない。確かにNodejsなので1プロセスだけ立てててそれが詰まると死ぬのだが、それだったらCPUはりつくのではという感じだし。実際にオートスケールの下限を増やしたが関係なし。
となるとDBだな。
はい。DynamoDB詰まってました。
オートスケールするんじゃないの?
前述した通り、オートスケールはデフォルトではありませんでした。
自分で手作業で検証した時には気がついていたけど伝えてなかった。開発側がebextensions書いてTable作るとのことでそのままお任せしてしまった。
高速Backend開発。忙しすぎる開発者。
そしてリリースされるアプリ。
オートスケールしないクソ弱いDB。
当然詰まる。
死。
はい。雑にまとめておきましょう。
教訓
- なんとなく嫌な予感は大切にしましょう
- 気になることはなんでも伝えましょう
- 忙しい人は細かいこと忘れるので、少しでも余裕がある人が地雷を気にしてあげましょう
- 後で絶対にやる・確認するタスクは分かりやすいところに置きましょう。今回はリリース前に気になりリストを最終確認する時間を取れば問題起こらなかったですね。github issueとかだとめっちゃ急いでいると見るの忘れるので、slackのリマインダ機能使いましょう。
最後の行がこの話で書きたかったこと。忘れそうなものは分かりやすいところへ。PULL型ではなくてPUSHで教えてくれるように。
以上
はじめてnodejsを使った。はじめてbotを作った話。
これは何
nodejsを使ってslack botを作った話。 インフラエンジニアだけどコードもかけるようになりたい、といって少しだけ時間をもらってbotを作る仕事をやった。 その時のメモ的なもの。
何を使う
botkitというツールキットを使う。 hubotと何が違うの? そういうのを調べたりはしてません。お手軽にモダンな感じで作れるよ、とおすすめされたので使った見た感じ。
コード
コードは長くないのでここに貼ってしまう。
npm install --save botkit
とかして、package.json作らせた(と思う)。
channel id はチャンネルがprivateの場合はhttps://api.slack.com/methods/groups.list/test で確認する。publicの場合は /channels.list/test で確認する。slackの場合。facebook messanger とかだとまた別の取得方法だと思う。
token はbot のものを使用する。https://app.slack.com/apps/new/bot から作成したもの。custom botについてはこちらを参照のこと:https://api.slack.com/bot-users。
const Botkit = require('botkit'); const os = require('os'); // 色々変数チェック。他dest,originについてはここの説明では略 if (!process.env.token) { console.warn('Error: Specify token in environment'); process.exit(1); } const controller = Botkit.slackbot({ debug: true, }); controller.spawn({ token: process.env.token, }).startRTM(); const destChannel = process.env.destChannel; const originChannel = process.env.originChannel; controller.hears('.*https?://www.example.com[sS]*', 'ambient', (bot, message) => { // [sS]* は改行含む全一致。.*だと改行入らない。ambient はbotが全発言を拾うということ(direct_messageとかもある)。 // 指定のチャンネルのときのみ発言を拾う if (message.channel === originChannel) { const matchMessage = message.text; const userId = message.user; bot.api.users.info({ user: userId }, (userApiError, userApiRes) => { const userName = userApiRes.user.profile.real_name; bot.api.channels.info({ channel: message.channel }, (channelApiError, channelApiRes) => { // private channel はchannels apiからは情報取得できない。groups apiなら取れるが、privateチャンネル名は知られなくても良い const channelName = (channelApiError !== 'channel_not_found') ? channelApiRes.channel.name : 'どこかprivate channel'; bot.say( { text: `${userName}さんが作品リンクを投稿しました(in #${channelName}) \n -------------------------- \n ${matchMessage} \n --------------------------`, channel: destChannel, }); }); }); } });
起動は
originChannel='<channel_id1>' destChannel='<channel_id2>' token=<bot_token> node urlcopy_bot.js
その他
eslint 使ってみた。 明らかな表記ブレは適当に直してくれるし、コードはきれいになるし、紛らわしい表記とか教えてくれるし、割と良かった。 他のところにもlint入れてみようかなと思った。
追記
slack接続が切れてしまって(close RTMになる) botが死んだように見える現象があった。
最初は自分で close_rtmイベントをフックしてconnectするように書いていたが、botkitはデフォルトで予期せぬ接続断があったらreconnectするようになっているため、両方で接続しに行ってしまい、多重接続(このbotの場合は2回投稿してしまう動き)。参考:https://github.com/howdyai/botkit/blob/bee9c5c70dcf3c024e71f2a10bdb2e425c421988/lib/Slackbot_worker.js#L230-L233
また、その他のエラーでcloseRTMしたときにはretryEnabledがtrueならreconnectしてくれるっぽい。こちらの動作に任せることにした。参考: https://github.com/howdyai/botkit/blob/bee9c5c70dcf3c024e71f2a10bdb2e425c421988/lib/Slackbot_worker.js#L70-L86
そこで、ドキュメントの通り、
const controller = Botkit.slackbot({ retry: Infinity });
みたいにしたらちゃんと接続が切れてもreconnectしてくれるようになった。
elasticsearchのindexを整理するcuratorのactionファイルを整理した話
これは何
elasticsearchのindexを削除するときにはcuratorを使うと思うが、そのactionファイルがわかりにくく、大きくなりがちだったのでメモ。 curator はver 4での記法(ver3だとちょっと違うみたいなので注意)
curator action fileの基本の書き方
1から順番に実行される。
actions: 1: action: delete_indices description: "delete application log indices" options: disable_action: False ignore_empty_list: True filters: - filtertype: pattern kind: prefix value: "application." # elasticsearchのindex名と"kind","value"設定が対応するようにする exclude: False - filtertype: age source: creation_date direction: older timestring: '%Y.%m.%d' unit: days unit_count: "30" # 30日残す設定 2: action: delete_indices description: "delete indices" options: disable_action: False ignore_empty_list: True filters: - filtertype: pattern kind: prefix value: "application." exclude: True # ここでexcludeしておかないと30日保存したいのに10日までになってしまう - filtertype: kibana exclude: True # kibanaを使っている場合には入れたほうがよい。.kibanaファイルが消えて、kibana indexを毎回登録しないといけなくなる。 - filtertype: age source: creation_date direction: older timestring: '%Y.%m.%d' unit: days unit_count: 10
削除日数を細かく制御したい場合(ansible templateで解決)
上の例の1の記述のところみたいなのを並べて、さらに2のexcludeにも突っ込んでいかないといけない。コード量が増えて管理しづらい。 ansibleで配置するなら以下のようにすればvarsのリストに追加するだけで簡単。
- varsで以下のように設定する
CURATOR_DELETE_LIST: - { TARGET: "application." , DAYS: "30" } - { TARGET: "httpd.error." , DAYS: "30" } - { TARGET: "httpd.access.hoge." , DAYS: "7" } - { TARGET: "httpd.access.hoge." , DAYS: "7" }
- loopでまわす
actions: {# 明示的な削除対象のためのブロック-#} {% for t in CURATOR_DELETE_LIST %} {{ loop.index }}: action: delete_indices description: "delete {{ t.TARGET }} indices" options: disable_action: False ignore_empty_list: True filters: - filtertype: pattern kind: prefix value: "{{ t.TARGET }}" exclude: False - filtertype: age source: creation_date direction: older timestring: '%Y.%m.%d' unit: days unit_count: "{{ t.DAYS }}" {% endfor %} {# .kibana を除くその他の index は 10 日間保持。最後のactionになるように99としておく。 #} 99: action: delete_indices description: "delete indices" options: disable_action: False ignore_empty_list: True filters: {% for t in CURATOR_DELETE_LIST %} - filtertype: pattern kind: prefix value: "{{ t.TARGET }}" exclude: True {% endfor %} - filtertype: kibana exclude: True - filtertype: age source: creation_date direction: older timestring: '%Y.%m.%d' unit: days unit_count: 10
もっとまとめて綺麗にできるかも。でもまあ役割ごとにブロックで分けれたからよし。