AWS SQSの代替として使える elasticmq の公式dockerイメージでqueueを起動時に作る方法
elasticmqの公式dockerイメージでqueueを起動時に作成する方法を紹介します。 動作は、softwaremill/elasticmq:0.15.7で確認しました。
TL;DR
- 環境変数JAVA_OPTSに "-Dconfig.override_with_env_vars=true" を追加する
- CONFIG_FORCE_queues<your-queue-name>fifoに "false" を設定する
以下はCircleCIの設定例です。
- image: softwaremill/elasticmq:0.15.7 environment: JAVA_OPTS: "-Dconfig.override_with_env_vars=true" CONFIG_FORCE_queues_queue1_fifo: false
なぜこれが動くのか
elasticmqは設定ファイルとして、typesafe configを使っています。 そのため、System propertiesとして、config.override_with_env_vars=trueを渡すと 環境変数で設定を上書き出来るようになります。 また環境変数は以下のルールで変形された後、設定名として使われます。
- CONFIG_FORCE_ を取り除く
- 単一の アンダースコア
_
を ドット.
に置き換える - 2連続の アンダースコア
__
を ダッシュ-
に置き換える - 3連続の アンダースコア
___
を 単一のアンダースコア_
に置き換える
今回は、queues.<queue-name>がobjectである必要があるので
queues.<queue-name>からネストした値である fifo
に値を与えることで
queues.<queue-name> を objectになるように設定します。
そのため、環境変数としては、CONFIG_FORCE_queues<queue-name>fifoにfalse を設定することで 起動時にqueueが作成されることになります。
終わり
goでJavaのクラスファイルのパーサを書いた
そういえば、書いたことがないなぁと思って、Javaのクラスファイルのパーサを書きました。 Java SE 15のJVM Specification だけを見ながら フルスペックのクラスファイルのパーサを書きました。
書いたけど、パース出来るだけで pretty printが出来たり、なんかいい感じのAPIが生えてたりするわけではないです。
元々、emc(enhanced memory calculator) のために tinycedar/classp の フォークである wreulicke/go-java-class-parser を弄っていましたが メモリ計算のためのツールのために実装したので、フルスペックのパーサではなく、必要な部分しか実装していません。
実装の流れとしては、class File Format の項を上から読みながら実装していきました。 ハマったところは何個かあって、以下のようなところでハマりました。
- Long/DoubleのConstantはなぜかConstantPoolのindexを1つ先にずらすこと
- LineNumberTable attributeの場合になぜか、attributeLengthとlineNumberTableLengthから計算できる消費するバイト数が一致しないこと
- uint8のところをuint16で読み取りしていて、位置がズレてデバッグが大変
- パースする処理を単純に飛ばしてしまっていて、これまた位置がずれて大変
実装に掛かった時間としては、色々やりながら、大体2日で終わりました。 まだちょっと直せる部分とかはあるのと、APIとしては弱いので もう少し弄ろうと思います。
たぶん、これから互換性が失われるところがいくつか出ると思います。 終わり。
Javaでcloud profilerを使ってpprofフォーマットのプロファイルデータをローカルに出力する
cloud profilerにはローカルに、pb.gzフォーマットでプロファイルデータを出力する機能がある。 このファイルは、pprofのprotocol bufferをgzip圧縮したものだ。
やり方は以下のような形でagentに -cprof_profile_filename
パラメータを渡して下さい。パラメータを渡さない場合、GCPにプロファイル結果を投げようとします。
$ java -agentpath:./cprof/profiler_java_agent.so=-cprof_profile_filename=./prof_ test & $ ls prof_cpu_1601995223.pb.gz prof_cpu_1601995253.pb.gz prof_wall_1601995160.pb.gz prof_wall_1601995233.pb.gz prof_wall_1601995243.pb.gz test.class test.java
ちなみに自分が作ったエンドポイントに投げるような機能は存在せず、ローカルに吐くか GCPのほうに投げるかのどちらかになっている。 出てきたプロファイルデータはpprofを使って見て下さい。
pprof -http=: ./prof_cpu_1601995223.pb.gz
ちなみに、ローカルにプロファイルデータを吐く場合 この辺がパラメータとして弄れるようです。