2018/08/15

Spring BootでJDBCの設定を確認する

JDBCの設定は難しい

なかなか避けて通れないDB。JavaでDBを使うなんてよくあることだし、ググれば簡単かと思いきや、まともに使うための設定が書いてあるページにたどり着くのは困難。サンプル通りに作ったのに、1日経ったらエラーで止まっているなんてのはよくある話。

地雷が何箇所にもあるので、トラブルシューティングに従ってやってみたところで、原因が違えば何の効果もない。が、意図した通りに設定されているということに確証が持てなければ、何をやっても無駄だ。というわけで、設定を確認する方法をまとめてみる。

Tomcat DBCPを設定する

JDBCというか、Connection Pooling。Javaなら普通Poolingするでしょうから、Spring Boot + Tomcat DBCP + MySQLのパターンに絞ってみる。

Tomcat DBCP(Tomcat JDBC Pool)については、Commons DBCPを超えるTomcat JDBC Poolとは (1/2):Tomcat 7の新機能で何ができるようになるのか?(番外編) - @ITがわかりやすい。

Spring Boot は Tomcat DBCPをサポートしているので、設定でうまくやれる。はずなのだが、Spring Bootのバージョンによって設定パラメータ名が変わっているので、どのバージョンについて話しているのかを確認しないと、悩むことになる。

MySQLのtime out系はよく見かけるトラブル。

  • Lost connection to server during query
  • MySQL server has gone away
といったものが、よく食らうエラー。

time outに関係するパラメータをうまく設定すれば解決できるのだが、Spring Bootだと、パラメータ名何だったっけ?ということになる。特に、別々のDB Serverに同時に接続できるよう、パラメータ名を変更した場合はわからなくなりがち。

設定内容を表示させる

設定内容をログに出すなり、APIのレスポンスとして返すようにするなりすれば、確認できる。というのが、Spring Boot configuration for Tomcat’s pooling data source | The Art of Codeに書かれている。具体的なコードが書かれているので、英語アレルギーでもコードだけ見ればわかるだろう。
DataSourceオブジェクトを作って、そのプロパティを表示するコードなのだが、どんな設定がされているのか、このアプローチなら確かに確認できる。

タイムアウトに対処する設定

ググるとtestOnBorrowをセットすればよいとかvalidityQueryをセットしろとか見つかるが、不十分な設定を書いている記事も多い。まだブラウザで開いていたページは

といったところ。

ネットワークが絡んでくるのでシステム構成の違いによる影響が大きく、一般化してまとめるのが難しい、というか、具体的でなくなってしまうのかな。ただ、「使う前or定期的に DBにクエリーを投げて、接続が使える状態かどうか確認する」というアプローチなので、それを実現するための設定を行っていくというのが解決方法になる。



2018/05/20

ポケモンGOにmoto G5sはパワー不足

画面が大きめのスマホが欲しい

今までiPhone SEでポケモンGOをやっていたのだが、画面がちょっと小さい。メールやスケジュールの文字が見難く感じることが多くなってきたので、画面が大きいスマホを買うことにした。

最近のAndroidは持っていなかったので、Androidでほどほどのお値段で外国製の中からチョイス。国産メーカーだと、アップデートがすぐに終わってしまって、データ盗られ放題のまま使わざるをえないことになってしまうからね。
IIJmioでキャンペーンをやっていたので、モトローラ Moto G5sに決定。

moto G5s開封の儀

パッキングはもうスマホでおなじみの形式。


ふたを開けると

裏はすっきり。カメラ部分の出っ張りは気になる。

simフリーだからIIJ mioで扱っている

当然、IIJ mioのsimを入れても、問題なく認識される。ちなみに、タイプD。
サイズはnanoなので、iPhone SEで使っていたsimを持ってきた。

ポケモンGOはちょっとカクカクする

ARモードも使えるのだが、ジムバトルでポケモンを選ぶ画面のスクロールがもたつく。また、ジムの画面から通常のフィールド画面に戻るとき、画面の描画が半分くらいでいったん止まる。後者はともかく、前者は意図しないポケモンが選ばれることがあり、ちょっとイラつく。
G5から画面を大きくしたので、処理が追いつかないのかもしれない。

moto g5sのケースと保護フィルム

スマホには付き物。特殊素材で衝撃を吸収! 『衝撃吸収【光沢】保護フィルム Moto G5s』Moto G5S ケース TopACE 超スリム クリア TPU ソフトケース 落下防止 指紋防止 耐スクラッチ全面保護 Moto G5S対応をチョイス。

もう少し小さいのがいい

5.2インチサイズはちょっと大きい。胸ポケットに入るか入らないかくらいなので、もう一回り小さくてもいいかなぁというのが正直なところ。世界市場的には、ニーズのない大きさなのかなぁ?



2018/04/29

遅いSQLをあぶり出す

犯人は誰だ

DBが遅いという。サーバのスペックや処理内容、開発会社のレベルを考えると、どうも設計やSQLに問題がありそうだ。
「DBアクセスが遅い」と文句を言っても「サーバのスペックをあげてくれ」としか回答してこないレベルなので、ボトルネックになっているSQLを調べることにした。

スロークエリの調べ方

Postgresだと、 スロークエリの分析 | Let's Postgres というページにまとまっている。
しかし、

  • Amazon RDS for PostgreSQL | AWSって、pg_stat_statements使えたっけ?
  • スロークエリって、何秒以上をログ出力するようにすればいい?そのクエリって、頻繁に使われるの?
といった問題があり、今回は保留。

MySQLの場合、 Kazuho@Cybozu Labs: MySQL のボトルネックを統計的に監視・解析する方法で紹介されている、GitHub - kazuho/mprofile: http://developer.cybozu.co.jp/archives/kazuho/2009/07/mysql-539d.htmlが使える。 Postgres向けを探したが、調べ方がよくなかったのか、見つけられなかった。

pg_stat_activityを使う

pg_stat_activityで現在発行中のsqlを見る - メモス\(^o^)/。これを定期的に実行すれば、よく実行されるSQLがあぶり出される。
必要な情報をまとめると、実行するSQLは

SELECT now(),query_start, query FROM pg_stat_activity WHERE state='active';
でOK。cronに書いて出力をファイルにリダイレクトすれば、後でゆっくり分析できる。

どのクエリとどのクエリが同じなのか、判断する必要がある。とりあえずはよく出てくるSQLのうち、query_start - now()が大きな値になっているものを調べるのがよさそう。大体の時間も見えてくるので、スロークエリを設定するときにも役に立つ。

作り逃げに注意

よろしくないSQLも、データ量が少ない頃は問題が見えてこないことが多い。開発を外注して自社で運用なんてスタイルをやっていると、こういう爆弾をつかまされることになりがちだ。



2018/02/11

簡単! Mackerel Pluginの作り方

Mackerel、それは鯖管のためのサービス

Mackerel(日本語では鯖)はいわゆる監視サービス。監視データを送るagentを動かせば、データを受け取ってグラフにし、指定した条件になった場合にはアラートをメールやチャットで送ることができる。

監視対象項目はプラグインで拡張することができる。公式のPluginも用意されており、有名どころのミドルウェアやWebのアクセス監視はカバーされている。

プラグインの作り方

「アプリケーションのログを監視したい」「公式プラグインでは用意されていないxxxというソフトのログを監視したい」という場合、プラグインを作る必要がある。ただ、プラグインはSensuと互換性があり、また、MuninのPluginを動かすためのプラグインもあるので、それらをプラグインを探すのはアリだと思う。

とはいえ、なければ作る必要がある。

名前 値 時刻
を標準出力に出せばよいので、作ると言っても、基本的にはそれほど大げさなものにはならない。
名前
Mackerelのグラフでは、「custom.名前」で表示される。
  • ピリオドを2つ以上含むこと
  • 一番右のピリオドより右側にあるものが、グラフになる
値。測定値とか、グラフにする値。
時刻
値はいつの時点だったかを示す時刻。過去の時刻でもよい。
Bash scriptだと
#!/bin/bash
NAME='sample.script.test1'
D=$(date +%s)
V=1
echo $NAME $V $D
でOK。適当に名前をつけて(ただしtestという名前はやめておくこと)実行できるようにchmodしておく。
agentの設定ファイルであるmackerel-agent.confの最後の方に
[plugin.metrics.sample]
command = "上記scriptのフルパス"
と書き足してagentをreloadすれば、準備完了。2,3分でグラフが描かれる。

プラグイン自体、標準出力に値を出力するだけなので、debugもしやすい。ただ、実行時間が1分に制限されているので、ネットワーク越しに値を持ってくるときなどは注意しておいた方がよい。

ここまで抑えると、他人の書いたプラグインも読みやすくなる。例えば、mackerelでWeb Siteのステータスをチェックするも、このルールの中で行っているし、さらに、「名前」「値」「時刻」を複数行出すのもOKだということが読み取れる。

アプリのログを監視する

「〜という文字列が現れたら警告してほしい」というのであれば、check-log プラグインで十分対応できる。出現回数に対してアラートを出すまでの閾値も設定でき、柔軟性も高い。
しかし、「出現の傾向をグラフ化したい」となると、プラグインを作る必要がある。

単純にログファイルをgrep -cしてしまうと、累積値になってしまう。そこで、監視対象の期間に絞り込んだログファイルを一時的に生成する。

#!/bin/bash
ORG_LOG="/var/log/sample.log"
LOG="/tmp/$(basename $0).tmp.$$"

TARGET="$(date +%Y%m%d%H%M -d '1 minute ago')"
grep $TARGET $ORG_LOG > $LOG

NAME='sample.script.test2'
D=$(date +%s)
V=$(grep -c '対象文字列' $LOG)
echo $NAME $V $D

rm -f $LOG
ポイントは、TARGET=の行とその次のgrep。
ログファイルと同じ日付フォーマットを、dateコマンドで出力させる。ただし、「秒」は出力させない。そうすることで、1分の間に出力されたログに絞り込むことができる。
もう1つ、'1 minute ago'オプション。単純に時分までで絞り込むと、プラグインが10秒くらいで起動された時、対象のログは10秒分しか存在していないことになってしまう。1分程度のズレを許容すればこの2行で1分分のログを抽出できるので、妥協するかどうか、判断が必要になるところではある。そもそも、そこまで正確な値が必要であれば、アプリケーション側でそういったメトリクス収集の口を用意すべきだとは思うが。

細かい設定も可能だが

単純に「名前」「値」「時刻」を出力するだけだと、グラフのタイトルに「custom」というprefixがついてしまう。もちろん、これを回避する方法はあるのだが、プラグインが少し複雑になってしまう。ホストのカスタムメトリックを投稿する - Mackerel ヘルプにちゃんと記載されているので、頑張りたい人はそちらを見てほしい。あ、「名前」「値」「時刻」はタブで区切るべきなのか。ヘルプはちゃんと読まないと。

お決まりの一文。本サイトに掲載する情報に関しては、正しいものを提供することを務めていますが、掲載内容から、いかなる損失や損害などの被害が発生しても、責任は負いません。自己責任でご活用ください。



2018/02/04

無線LANに繋げるEthernet子機を新調

Ethernetアダプター

NURO光のONUは2階、WindowsデスクトップマシンやNASのある自室は1階で、LANケーブルを引き延ばすのは無理なため、無線LANでつないでいる。今までは NEC Aterm WL300NE-AG (Ethernet子機) PA-WL300NE/AGでつないでいたが、壊れたので、新しくNEC Wi-Fiホームルーター Aterm ブラック PA-WG1200HS2を購入した。2.4GHzでも5GHzでも、NURO光のONUにつながっている。

有線LANを無線LANに繋げるときは、Ethernet子機を使う

メーカーによって呼び方が異なるが、NEC Atermシリーズでは「子機」という。USB接続のWifiアダプターを子機と呼ぶメーカーもあって非常にまぎらわしいのだが。親機との接続については、自社製品とだけ確認するのが普通で、無線機能をもったONUと接続できるかどうかは、がんばって調べるか自ら人柱になって試すしかない。

NURO光のONUとしてHG8045Qを使っているので、試した結果、2.4GHzでも5GHzでも接続できた。当然、自分の環境ではうまくいったが、どの環境でもうまくいくという保証はない。この結果は自己責任で判断するものであり、うまくいかなくても誰かが責任を負うようなものではない。

子機モードでのWifi設定

子機モードの場合、LANケーブルの途中が無線になったようなイメージで使うことになるため、子機そのものにアクセスすることはない。

どうやって設定を行うのだろうと思ったら、ユーザーズマニュアルにちゃんと書いてあった。「らくらく設定ボタン」を押しながら電源を入れると強制的にDHCPサーバが起動するので、Webの画面から設定できる。設定が終われば内容を反映してから再起動して、DHCPサーバは止まる。

WindowsやAndroid, iOSでは、探し出すアプリがあるようだ。が、そうそう設定画面を呼び出すようなものでもない。有線LANがあれば「ボタンを押しながらスイッチオン」で十分だ。


HG8045jとWL300NE-AG も繋がった

NURO光のONUは、最初、HG8045jだった。無線が速くないので交換してもらったのだが、この時もWL300NE-AGで繋いでいた。WL300NE-AG も速くないのだが。



2018/01/03

2018年年賀状


今年もよろしくお願いします。


2017/12/09

Virtual Hostのログをmackerel-plugin-accesslogで見える化する

アクセスログもMackerelで見える化

Mackerel(マカレル): 新世代のサーバ管理・監視ツールにWebのアクセスログを解析するmackerel-plugin-accesslogというプラグインがある。アクセス数をHttp Status Code別にグラフ化してくれる便利なプラグインだが、Virtual Host別にアクセスログを分けている場合も、使える。

オプションmetric-key-prefix

プラグインのReadMeには書いていないのだが、

-metric-key-prefix
というオプションがある。データを送信するときのキーのprefixを指定するオプションだ。アクセスログごとに異なるprefixを指定すれば、複数のアクセスログを扱うことができる。

mackerel-agent.confの書き方

confファイルの[]の部分をどう書けばよいか迷うが、この部分は重複しなければよい。2つのピリオドで区切られた文字列であるので、plugin.metric.ユニークな文字列 とする。


[plugin.metric.hostA]
command = "mackerel-plugin-accesslog -metric-key-prefix hostA /var/log/httpd/hostA.access_log"

[plugin.metric.hostB]
command = "mackerel-plugin-accesslog -metric-key-prefix hostB /var/log/httpd/hostB.access_log"
のように書けば、hostAのグラフとhostBのグラフがそれぞれ生成される。職場で7個Virtual Hostが動いているApache Httpd Serverがいるが、この設定でそれぞれのグラフが描かれている。

自作プラグインも簡単

便利なプラグインが増えてきているとはいえ、ニーズを満たすようなものがないこともある。プラグインは書きやすいので、自分で書いてみるのもあり。



2017/11/29

Infrastructure As Codeの道のりは長い

Mackerelを入れてカオスなサーバ管理から脱出する道を作る

転職して2月から働いている職場は、100台以上のサーバから構成されるシステムを構築、運用している。
処理しているデータ量からするとオーバースペックのように思えたので、台数を減らそうとした。が、サーバリソースの使用状況がわからない。Zabbixで監視しているサーバもあるようなのだが、Zabbixの画面がカオスなので、諦めた。

そうは言っても、リソース監視を行わないと削る余裕のあるサーバ群がわからない。というわけで、プライベートで使っているMackerel(マカレル)を導入した。

Mackerelは、AWSインテグレーションやAzureインテグレーションの機能を使って、対象のサーバにmackerel-agentをインストールせずにリソース監視を行うことができる。しかし、mackerel-agentを入れたほうが、より細かいメトリクスを収集できるし、ミドルウェアの状態も監視できる。

構成管理は?

mackerel-agentをインストールしようとして、サーバの構成管理を尋ねた。していなかった。サーバのディスクイメージを取っているとのことだったが、それは管理とは言わない。
構成管理ツールに関して質問しても、回答なし。結局、インフラを見ていた人が退職する時に作った資料に、Ansibleの文字があった。が、すでに構成管理ツールを調べて試用に入っていた段階。横展開する時に再度検討することにした。

これ、今の状況不明な設定状態をベースに構成管理を行っても不安なので、1からやり直す必要がある。先は長い。



2017/10/14

ReadyNASで外付けUSB HDDをフォーマットする

USBハードディスクをReadyNAS102に繋げる

Macのバックアップ先として使うため、ReadyNASに外付けHDDをつないだ。


前に買っておいたIO Dataのもつないで、増設2台。

ところが、ReadyNASを再起動させても、認識されない。ググってみたところ、 遙かデジタリアへ: ReadyNAS DUO v2に、LHR-2BNU3(USB3.0の2ベイHDDケース)で4TB HDDを接続 に、事前にフォーマットが必要という記述を見つける。が、今更ディスプレイの裏にあるReadyNASを引っ張り出すなんてことはしたくない。
というわけで、ReadyNASにsshで入り、dmesgでデバイスの認識状況を確認する。

[7015413.503075] usb 3-1: new SuperSpeed USB device number 2 using xhci_hcd
[7015413.524842] usb 3-1: New USB device found, idVendor=0411, idProduct=0257
[7015413.524862] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[7015413.524872] usb 3-1: Product: HD-LCU3
[7015413.524881] usb 3-1: Manufacturer: BUFFALO
[7015413.524890] usb 3-1: SerialNumber: 0000002F00XXXXXX
[7015413.526591] usb-storage 3-1:1.0: USB Mass Storage device detected
[7015413.552465] scsi host3: usb-storage 3-1:1.0
[7015414.553584] scsi 3:0:0:0: Direct-Access     BUFFALO  External HDD     0000 PQ: 0 ANSI: 3
[7015414.568085] sd 3:0:0:0: Attached scsi generic sg2 type 0
[7015424.405588] sd 3:0:0:0: [sdc] Very big device. Trying to use READ CAPACITY(16).
[7015424.406087] sd 3:0:0:0: [sdc] 5860533168 512-byte logical blocks: (3.00 TB/2.73 TiB)
[7015424.406101] sd 3:0:0:0: [sdc] 4096-byte physical blocks
[7015424.406737] sd 3:0:0:0: [sdc] Write Protect is off
[7015424.406753] sd 3:0:0:0: [sdc] Mode Sense: 73 00 10 08
[7015424.407404] sd 3:0:0:0: [sdc] Write cache: enabled, read cache: enabled, supports DPO and FUA
[7015424.410365] sd 3:0:0:0: [sdc] Very big device. Trying to use READ CAPACITY(16).
[7015424.462484]  sdc: sdc1 sdc2
[7015424.469264] sd 3:0:0:0: [sdc] Very big device. Trying to use READ CAPACITY(16).
[7015424.471199] sd 3:0:0:0: [sdc] Attached SCSI disk
[7015432.763048] usb 3-2: new SuperSpeed USB device number 3 using xhci_hcd
[7015432.783826] usb 3-2: New USB device found, idVendor=04bb, idProduct=014a
[7015432.783847] usb 3-2: New USB device strings: Mfr=10, Product=11, SerialNumber=3
[7015432.783858] usb 3-2: Product: I-O DATA HDCL-UT
[7015432.783867] usb 3-2: Manufacturer: I-O DATA DEVICE, INC.
[7015432.783876] usb 3-2: SerialNumber: 000277A462XXXXXX
[7015432.787721] usb-storage 3-2:1.0: USB Mass Storage device detected
[7015432.803300] scsi host4: usb-storage 3-2:1.0
[7015435.813652] scsi 4:0:0:0: Direct-Access     I-O DATA HDCL-UT          5112 PQ: 0 ANSI: 6
[7015435.828640] sd 4:0:0:0: Attached scsi generic sg3 type 0
[7015441.829106] sd 4:0:0:0: [sdd] Spinning up disk...
[7015443.172944] .ready
[7015443.173560] sd 4:0:0:0: [sdd] 3907029168 512-byte logical blocks: (2.00 TB/1.82 TiB)
[7015443.173898] sd 4:0:0:0: [sdd] Write Protect is off
[7015443.173915] sd 4:0:0:0: [sdd] Mode Sense: 67 00 10 08
[7015443.174229] sd 4:0:0:0: [sdd] Write cache: enabled, read cache: enabled, supports DPO and FUA
[7015443.225334]  sdd: sdd1 sdd2
[7015443.230743] sd 4:0:0:0: [sdd] Attached SCSI disk
2台つなげたので、sdcとsddとして認識されていた。

ReadyNAS上で初期化する

USBディスクとして認識されているのであれば、問題ない。Linuxをインストールするときの一般的なディスクの初期化と同じだ。
fdiskでパーティションを作って、mkfs.ext4でフォーマット。その後、ReadyNASを再起動させたら、管理画面に表示された。



2017/09/02

Mackerelでping監視

ping監視

時々ネットワークが遅くなることがあるので、pingで普段から計測することにした。そういえば、Mackerel(マカレル)ではやっていなかったな。

plugin script

mackerel-agent.confに、ホストメトリックとして送信するように追加する。

[plugin.metrics.ping]
command = "scriptをおいたディレクトリ/mackerel-plugin-ping.sh 監視host1 監視host2 ..."

監視ルール

pingは5秒まで待って、応答がなければ5000という値を送信している。ので、5000より大きい値が送られてくることはない。Mackerelで監視ルールを設定する時の注意点。

追記

Linuxだと表示メッセージが異なるので、awkのscriptを修正して対応。



2017/08/31

iPhoneのケーブルが裂けてきた

Apple認証のケーブル

iTunesの同期や充電に使うためのケーブル。MFi認証がないと問題が生じることがあるというのでAmazonで探して使っていたのだが、1年持たずに皮膜が裂けて、中の金属が見えてきた。

耐久性?

通勤時のみならず、休日もIngressやポケモンGoで出歩く際に丸めて胸ポケットに入れていたので、それなりに負荷がかかっていたが、買って1年持たないとは…。iMacに挿しっぱなしにしてあるものと、予備としてカバンに入れてあるものについては問題ないので、使用頻度が原因だろう。次は丈夫な製品を探そう。



2017/07/30

Smart UPSのバッテリー交換

バッテリー交換にはコツがいる

たまに必要になるバッテリー交換。毎年であればまだ思い出せないことはないのだが、数年に1回、10分程度の作業だと、思い出すのは難しい。

だからと言って、Webにあるような手順ですんなりいくものでもないのが、困ったところ。

久しぶりに交換して、戸惑ったところをメモ。

フロントカバーが外れない

重い本体がカバーの下の部分を踏んづけている構造なので、本体を持ち上げないとフロントカバーが外れない。

これ、狭い場所にきっちり押し込んでいたり、上にいろいろ積み上げていたりすると、たいへん。ま、基本的に、空気が流れるような隙間のある場所におかないとまずいのだけど。

交換バッテリーの端子が違う?

カバーがしてあるだけ。交換バッテリーの端子がむき出しになっている状態にしてからケーブルを接続する。当たり前すぎて書いていない(笑)

最新機種は?

バッテリーを交換すれば使い続けられるので、買い換えようという気がなかなか起きない。最近の機種は、バッテリー交換もわかりやすくなっているのだろうか?