<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[atWare Technics]]></title><description><![CDATA[atWare Technologies and Solutions

人々をしあわせにするためのエンジニアリングサイクルの中で経験した開発事例、経験と学習の結果から精錬した推奨技術、および技術に支えられたソリューションを中心に紹介していきます。]]></description><link>https://tech.atware.co.jp/</link><generator>Ghost 0.11</generator><lastBuildDate>Wed, 27 Aug 2025 05:37:21 GMT</lastBuildDate><atom:link href="https://tech.atware.co.jp/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[JDKの最新版を使ったパフォーマンス・最適化チューニングでやったこと]]></title><description><![CDATA[<p>2年ほど前に大量のストリームデータを処理する<a href="https://tech.atware.co.jp/aws-kinesis-stream-poc/">記事を書きました</a>。 <br>
トラフィックはGbpsレベルの量が流れてきますので、実運用においては効率的な処理であることが、コストの大きな削減に繋がります。</p>

<p>この記事では、そんな環境のパフォーマンスの課題に処理の最適化チューニングでどう取り組んだかを紹介します。</p>

<h2 id="">パフォーマンス・最適化チューニングをする前に</h2>

<h3 id="">進め方の方針を立てる</h3>

<p>今回はms単位で処理の効率化に取り組む必要がありました。
パフォーマンスチューニングの際に、よく言われている事に「推測するな、計測せよ」というフレーズがあります。これは、<a href="https://users.ece.utexas.edu/~adnan/pike.html">「Rob Pike's 5 Rules of Programming」</a>で語られています。
感覚的にあたりをつけても実際のボトルネックが違うところにあるという事は多々あります。感覚でチューニングを実施するのではなく、処理に時間がかかっている部分が全体の大部分を占めている事がわかっていない限りは計測することを優先しようという意味合いです。</p>

<p>このフレーズのコンセプトは重要な考えだと捉えています。限りある時間を有効に使って作業効率や方式変更にまで視野に入れて取り組む場合に、影響することは順序立てて着手する事が結果的にいい成果に繋がることを何度も体験したことがあるからです。</p>

<p>そこで、まず最初に計測する事がいかに重要かをチーム内で認識合わせをして、どこにボトルネックがあってどれくらい処理時間がかかっているかを把握しながら、改善に取り取り組むということを計画しました。</p>

<h3 id="">計測ツールの紹介</h3>

<p>今回チューニング対象となっているシステムはJavaで実装されています。計測には様々な方法・ツールが存在しますが、Java周りのエコシステムの魅力のひとつとしてJVMのプロファイリング環境と機能が整っていることがあります。このおかげで、計測・調査作業はとても捗りました。</p>

<p>利用を検討した計測ツールをご紹介します。</p>

<p><img src="https://visualvm.github.io/images/visualvm_screenshot.png" alt="visualvm"></p>

<p>Java向けのプロファイリングツールの代表的なプロダクトとしては<a href="https://visualvm.github.io/">VisualVM</a>があります。</p>

<ul>
<li>プロセスのパフォーマンスとメモリ状況の表示</li>
<li>スレッドの状況を視覚化</li>
<li>メソッド毎の処理時間を計測</li>
</ul>

<p>などを行うことができます。</p>]]></description><link>https://tech.atware.co.jp/java-high-performance-tuning/</link><guid isPermaLink="false">419c8438-d4de-4807-aa44-795eec24bbeb</guid><category><![CDATA[Java]]></category><dc:creator><![CDATA[asano]]></dc:creator><pubDate>Fri, 31 Jan 2020 01:27:00 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2020/01/java-high-performance-tuning-2.png" medium="image"/><content:encoded><![CDATA[<img src="http://tech.atware.co.jp/content/images/2020/01/java-high-performance-tuning-2.png" alt="JDKの最新版を使ったパフォーマンス・最適化チューニングでやったこと"><p>2年ほど前に大量のストリームデータを処理する<a href="https://tech.atware.co.jp/aws-kinesis-stream-poc/">記事を書きました</a>。 <br>
トラフィックはGbpsレベルの量が流れてきますので、実運用においては効率的な処理であることが、コストの大きな削減に繋がります。</p>

<p>この記事では、そんな環境のパフォーマンスの課題に処理の最適化チューニングでどう取り組んだかを紹介します。</p>

<h2 id="">パフォーマンス・最適化チューニングをする前に</h2>

<h3 id="">進め方の方針を立てる</h3>

<p>今回はms単位で処理の効率化に取り組む必要がありました。
パフォーマンスチューニングの際に、よく言われている事に「推測するな、計測せよ」というフレーズがあります。これは、<a href="https://users.ece.utexas.edu/~adnan/pike.html">「Rob Pike's 5 Rules of Programming」</a>で語られています。
感覚的にあたりをつけても実際のボトルネックが違うところにあるという事は多々あります。感覚でチューニングを実施するのではなく、処理に時間がかかっている部分が全体の大部分を占めている事がわかっていない限りは計測することを優先しようという意味合いです。</p>

<p>このフレーズのコンセプトは重要な考えだと捉えています。限りある時間を有効に使って作業効率や方式変更にまで視野に入れて取り組む場合に、影響することは順序立てて着手する事が結果的にいい成果に繋がることを何度も体験したことがあるからです。</p>

<p>そこで、まず最初に計測する事がいかに重要かをチーム内で認識合わせをして、どこにボトルネックがあってどれくらい処理時間がかかっているかを把握しながら、改善に取り取り組むということを計画しました。</p>

<h3 id="">計測ツールの紹介</h3>

<p>今回チューニング対象となっているシステムはJavaで実装されています。計測には様々な方法・ツールが存在しますが、Java周りのエコシステムの魅力のひとつとしてJVMのプロファイリング環境と機能が整っていることがあります。このおかげで、計測・調査作業はとても捗りました。</p>

<p>利用を検討した計測ツールをご紹介します。</p>

<p><img src="https://visualvm.github.io/images/visualvm_screenshot.png" alt="JDKの最新版を使ったパフォーマンス・最適化チューニングでやったこと"></p>

<p>Java向けのプロファイリングツールの代表的なプロダクトとしては<a href="https://visualvm.github.io/">VisualVM</a>があります。</p>

<ul>
<li>プロセスのパフォーマンスとメモリ状況の表示</li>
<li>スレッドの状況を視覚化</li>
<li>メソッド毎の処理時間を計測</li>
</ul>

<p>などを行うことができます。</p>

<p>VisualVM 以外にも 高機能なプロファイリングツールとしてJava Flight Recorderと<a href="https://www.oracle.com/technetwork/jp/java/javaseproducts/mission-control/index.html">Java Mission Control</a>が存在していましたが、最近まで有償でのみ利用可能で、実運用環境への導入にはそれなりのハードルがありました。</p>

<p><img src="https://i.ytimg.com/vi/qytuEgVmhsI/maxresdefault.jpg" alt="JDKの最新版を使ったパフォーマンス・最適化チューニングでやったこと"></p>

<p>JDK8以降でOracle JDKのライセンスが変更となった時期に転機が訪れました。</p>

<p>JDK11以降でこの2つツールがオープンソース化され、プロダクション環境でも無償利用ができるようになったのです。この辺りの詳しい経緯や他記事に譲るとして、OSSとなった恩恵を受けられるようになったのは素晴らしいですね。</p>

<p>Java Flight Recorder とJava Mission Control で着目した点は以下の内容が計測できることです。</p>

<ul>
<li>ガベージコレクションによる停止時間</li>
<li>コンテキストスイッチ回数</li>
<li>並行処理のブロッキングの発生箇所</li>
</ul>

<p>また、VisualVMに比べて、Java Flight Recorder とJava Mission Controlの方が自動診断機能が使いやすかったり、計測できる内容も多かったので、今回はJava Flight RecorderとJava Mission Controlを利用することにしました。</p>

<h3 id="">並行処理とパフォーマンス改善の知識</h3>

<p>並行処理はジョークで「人類には早すぎた」と言われています。
なんとなくでは行き詰まってしまい、メンテナンス性や拡張性が失われてしまうこともあるでしょう。</p>

<p>改めてパフォーマンス改善に関する情報、並行処理に関してキャッチアップして技法や注意点も参考にしました。</p>

<ul>
<li>Java並行処理プログラミング
<ul><li>並行処理の基本が書かれています</li>
<li><a href="https://www.sbcr.jp/product/4797337206/">https://www.sbcr.jp/product/4797337206/</a></li></ul></li>
<li>Effective Java
<ul><li>パフォーマンスに関して度々言及があります</li>
<li><a href="https://www.maruzen-publishing.co.jp/item/?book_no=303054">https://www.maruzen-publishing.co.jp/item/?book_no=303054</a></li></ul></li>
<li>Javaパフォーマンス
<ul><li>パフォーマンスに関する技法や基本から実践的な事まで書かれています</li>
<li><a href="https://www.oreilly.co.jp/books/9784873117188/">https://www.oreilly.co.jp/books/9784873117188/</a></li></ul></li>
<li>Java SE APIリファレンス
<ul><li>パフォーマンスに関するトレードオフやヒントも書かれています</li>
<li><a href="https://docs.oracle.com/javase/jp/13/docs/api/">https://docs.oracle.com/javase/jp/13/docs/api/</a></li></ul></li>
</ul>

<p>また、分散処理の実務経験が豊富な方への相談・ディスカッションも重ねました。</p>

<h2 id="">戦略を立てる</h2>

<h3 id="">リズムを作る</h3>

<p>やったこととしてはまずはリズムを作る事です。
チューニング結果をローカル環境でシミュレーション計測できるようにしてから、実環境でも同様の結果となるか計測できるようにします。
取り組みの序盤で、簡単な変更によるチューニングを利用して、このサイクルがリズムよく回るようにします。</p>

<h4 id="">ローカル環境での計測</h4>

<ul>
<li>計測スクリプト</li>
<li>ローカルファイルから検証用データを取り込み可能なように</li>
</ul>

<p>ローカル検証を行う事で実装・実行・計測のサイクルが可能となり、実環境に投入するサイクルを早くできます。</p>

<h4 id="">実環境での計測</h4>

<p>ほぼ本番データと同じデータ、トラフィック傾向（流量やバーストタイミング）も同じであることが望ましいです。
チーム内で環境を用意していただき、迅速にデプロイ・計測できるようにしました。</p>

<h3 id="">最新の成果を活用する</h3>

<p>システムの保守という側面では、コストを減らすことを考えることが必要です。一つの手法としてはLTSサポートされているバージョンに固定しコード修正やテスト回数を減らすという戦略があります。私の観測範囲の中ではこの戦略が採用されている事が多いと感じています。</p>

<p>今回は、その真逆のアプローチをとります。
主要なライブラリやフレームワークは最新版を迅速に追従し続けるという戦略です。</p>

<p>この戦略はビックバンアップグレードによるアップデートが困難になる状況を防ぐことができ、動作保証さえできれば性能改善の成果や新しい機能を活かす事ができます。</p>

<p>また、JDKのLTSにこだわらない事で、利用バージョンをどんどんとあげていく意識的な内的動機の後押しもついてきます。</p>

<p>最新に保つことはメリットも多いのです。</p>

<h2 id="">初動の分担</h2>

<p>チームでは二手に分かれました。</p>

<ul>
<li>サイクルを回すための整備</li>
<li>コードを修正する前にJDKやフレームワークをバージョンアップ</li>
</ul>

<p>最終的にバージョンアップをするのであれば、コードを書いてから出戻りがあるよりも最初にしてしまおうという事で、JDKやフレームワークの最新化を行いました。追加実装された機能もすぐに使えます。</p>

<h2 id="jdk">JDKの最新版にしたら効果が出た</h2>

<p>このバージョンアップ作業の開始と同時期にJDK13がリリースされました。
元々はJDK8で動作していたプログラムで、LTSのJDK11にあげることは既定路線で決まっていましたが、前述の戦略をステークホルダーに説明・合意を得て最新版のLTSではないJDK13にしました。</p>

<p>数年間のJVMの性能改善に期待して、実際に変更してみると... 効果が明確に数値として現れました！</p>

<p>メモリ使用量が半減したのです。
これには関係者皆が歓喜の声をあげたのは言うまでもありません。</p>

<p>ここで「良かったね」だけで終わってしまうのは、推測の域を脱しず今後も気になってしまいます。
そこでプロファイラを使って分析してみると、文字列のメモリ使用量が減っていたのです。</p>

<p>調べたところ JDK9で導入された <a href="http://openjdk.java.net/jeps/254">JEP 254: Compact Strings</a> の効果が大きかった事がわかりました。これは、「文字列データ内の文字の多くはASCIIなので、ASCII文字についてはchar(2バイト)ではなく、byte(1バイト)で取り扱うように変更しよう、その方がスペース効率あがるよね。」というものです。</p>

<p>Stringクラスを使う側は変更を意識せず利用でき、内部で切り分けくれています。 <br>
今回は扱うデータがほぼASCIIでしたので効果抜群だったというわけです。</p>

<p>そして、メモリ使用量に余裕ができたので、実装上、メモリ利用効率とトレードオフで検討できる方策の範囲も広がりました。</p>

<h2 id="">並行処理改善の着手</h2>

<p>まずは並行処理改善の着手の前に、プロファイリング結果に沿ってコストが大きい処理を探し、プログラムの記述で無駄が発生しないようにゼロコピーとなるような実装に修正したり、データ構造を最適化したり、変換処理を中心に効率化を実施していきました。</p>

<h3 id="">地味な修正を経て</h3>

<p>変換処理でコストがかかっていた例を一つ紹介します。
文字列からLocalDateTimeへの変換処理が特に遅いことがわかったので、DatetimeFormatterの処理実装を調査しました。
そうすると日付に対するパターンマッチで任意のマッチ項目が登場するごとにHashMapをコピーしていることがわかりました。</p>

<p>つまり、パターンマッチ走査回数を減らせば変換処理は速くなるということです。</p>

<p><code>DateTimeFormatter.ofPattern("YYYY[-][/]MM[-][/]DD")</code> </p>

<p>このように4回走査が実行されていたものを</p>

<p><code>DateTimeFormatter.ofPattern("[yyyy/MM/dd][yyyy-MM-dd]")</code></p>

<p>とすることで走査は2回になります。</p>

<p>修正後のプロファイラ結果ではパース処理に掛かる時間が従来の1/3ぐらいに減りました。</p>

<h3 id="">並行処理をよりよい形に</h3>

<p>並行で処理を行うことがこのシステムの中核でしたので、そこも大胆に効率的な処理になるよう改善を試みます。</p>

<p>着手前のコードの特徴としては同期的に並行に処理を行っていました。</p>

<p>プロファイラの計測結果から、同期的な処理となっているので他スレッドの処理完了を待つ待機スレッドが多く、スレッドを有効活用しきれていない事がわかりました。
つまり、スレッド数が同時に実行できる上限数という形となってしまい、最大パフォーマンスを出す為にコンテキストスイッチとのトレードオフの最適値を探り、大量のスレッドを使って性能を稼ぎ出すというアプローチを取らざるを得ない状況でした。</p>

<p>これではスレッド数が多くなればメモリ使用も徐々に増えていきます。</p>

<h4 id="redis">Redisとのやりとりを非同期化</h4>

<p>そこで、スレッドを非同期化できそうな所を探し処理方式を変更していく事を検討しました。
非同期化にすることで少ないスレッドでリソースを使い切りたいという考えです。</p>

<p>JDK8から利用できるようになった<a href="https://docs.oracle.com/javase/jp/8/docs/api/java/util/concurrent/CompletableFuture.html">CompletableFuture</a>を利用をする事を候補として、まずは処理方式を比較するマイクロベンチマークを取ってみて、同期・非同期で性能がどれくらいでるか比べてみました。</p>

<p>簡単なコードを使ったマイクロベンチマークの結果は、同期処理では176スレッドが最大効率だったが、非同期処理では4スレッドで最大効率となりCPU使用率も同期処理に比べて少ない事がわかりました。</p>

<p>CompletableFutureを使って非同期化したら同期版と比べて約5.6倍速い結果となりました。</p>

<p>詳細な比較をしたマイクロベンチマーク調査については別記事でご紹介できればと思います。</p>

<p>こうして、実際プロダクトコードの処理書き換え前にマイクロベンチで測ると、作業価値の期待の見積もりができるという効果だけでなく、最適な選択をした結果で改善されたという理由づけにも繋がりました。</p>

<p>実際のプロダクトコードにも適用したところ、当初200スレッドところが14スレッドで同等のデータ処理を捌く事ができるようになり、使用メモリも50MBほど削減できました。また、若干ですが処理速度も向上しました。</p>

<h4 id="">気をつけたい事</h4>

<p>今回はCompletableFutureを使って全体を非同期処理に書き換えましたが、チームでも慣れている人は少ないという状況でした。
また、CompletableFutureには扱う上で気をつけなければならないポイントがいくつかあります。たとえば処理ステップの途中に同期的な処理や時間の掛かる処理があった場合、著しい性能ダウンが発生してしまいます。</p>

<p>CompletableFutureに馴染んでもらうため、チーム内で勉強会を開催し設計コンセプトをしっかり理解しあって、プロファイラを使った計測の仕方やチェックすべきポイントを共有しました。</p>

<h2 id="">数値で見るコスト削減と成果</h2>

<p>このように順序立てて計測・最適化・パフォーマンスチューニングを繰り返していって</p>

<ul>
<li>GCを極力発生させない</li>
<li>処理時間を短くする</li>
<li>メモリ使用量を減らす</li>
</ul>

<p>ことができ、結果的に利用しているクラウドリソースを大幅に削減し性能要件も満たす事ができました。</p>

<p>もう少し詳細に成果をお伝えすると、チューニング前はピーク時でメモリ使用量が最大20GB程度使用していたところが10GB程度となり、大幅に削減できました。</p>

<p>メモリ使用量がサーバーリソースの量に直結しており、メモリ使用量が少なくなったことで、クラウドの仮想マシンの台数も30%ほど削減することができました。</p>

<h3 id="">最後に</h3>

<p>運用できることが最終ゴールです。</p>

<p>コンピュータリソースを減らした環境でもピーク時間帯でも処理遅延を防ぎ、CPUの頭打ちとOutOfMemoryを発生させず安定的に稼働させる必要があります。実環境で数日間の安定運用確認を経て、メトリクスの分析を重ね成果が確かなことがわかると、実感が湧いてきて歓喜の声がチームに響き渡りました！</p>

<p>地味な作業なのですが、システムを運用していくと、この様なチューニング作業は必要になる事が多いので、今後もこの知見を活かして違う機会に繋げていきたいと思います。</p>]]></content:encoded></item><item><title><![CDATA[ScalaMatsuri 2018 にスポンサードします]]></title><description><![CDATA[<p>日本最大級の Scala のカンファレンス <a href="http://2018.scalamatsuri.org/">ScalaMatsuri 2018</a> が 2018年3月16〜18日 に開催されます。</p>

<p>アットウェアはプログラミング言語としては Java をメインとしていますが、近年、問題解決のアプローチを模索する中で、Scala が持つ可能性を見いだし、　<a href="http://tech.atware.co.jp/scalainterview/">Scala先駆者インタビュー</a> を企画したり、社内ツールの実装言語として採用したり、継続的に取り組んできました。 <br>
その継続的取り組みと、昨年の ScalaMatsuri 2017 スポンサードの甲斐もあり、昨年はいくつもの具体的なお仕事の話をいただき、そのうちのいくつかは現在も鋭意進行中です。幸運なことに Scala 界隈の有識者の方々と一緒にプロジェクトに関われているということもあり、「いい時にいい場所に関われている」という好循環が生まれつつあります。</p>

<p>そこで、今回の <a href="http://2018.scalamatsuri.org/">ScalaMatsuri 2018</a> では、侍スポンサーからアップグレードして、 <em>大名スポンサー</em> としてご協力することとしました。 <br>
引き続き、実績とノウハウの蓄積をコツコツを積み重ねて、「受託 SIer としての Scala との向き合い方」を真剣に考え、弊社なりのポジションを確立すべく邁進していく所存です。</p>

<hr>

<p>アットウェアでは、</p>]]></description><link>https://tech.atware.co.jp/scalamatsuri2018-sponsored/</link><guid isPermaLink="false">44822f8e-108d-4a03-82a6-5fe0d50a452d</guid><category><![CDATA[Scala]]></category><dc:creator><![CDATA[Ryuji Yamashita]]></dc:creator><pubDate>Tue, 13 Mar 2018 04:07:01 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2018/03/66684_normal_1508837789_scala_matsuri_A.png" medium="image"/><content:encoded><![CDATA[<img src="http://tech.atware.co.jp/content/images/2018/03/66684_normal_1508837789_scala_matsuri_A.png" alt="ScalaMatsuri 2018 にスポンサードします"><p>日本最大級の Scala のカンファレンス <a href="http://2018.scalamatsuri.org/">ScalaMatsuri 2018</a> が 2018年3月16〜18日 に開催されます。</p>

<p>アットウェアはプログラミング言語としては Java をメインとしていますが、近年、問題解決のアプローチを模索する中で、Scala が持つ可能性を見いだし、　<a href="http://tech.atware.co.jp/scalainterview/">Scala先駆者インタビュー</a> を企画したり、社内ツールの実装言語として採用したり、継続的に取り組んできました。 <br>
その継続的取り組みと、昨年の ScalaMatsuri 2017 スポンサードの甲斐もあり、昨年はいくつもの具体的なお仕事の話をいただき、そのうちのいくつかは現在も鋭意進行中です。幸運なことに Scala 界隈の有識者の方々と一緒にプロジェクトに関われているということもあり、「いい時にいい場所に関われている」という好循環が生まれつつあります。</p>

<p>そこで、今回の <a href="http://2018.scalamatsuri.org/">ScalaMatsuri 2018</a> では、侍スポンサーからアップグレードして、 <em>大名スポンサー</em> としてご協力することとしました。 <br>
引き続き、実績とノウハウの蓄積をコツコツを積み重ねて、「受託 SIer としての Scala との向き合い方」を真剣に考え、弊社なりのポジションを確立すべく邁進していく所存です。</p>

<hr>

<p>アットウェアでは、一緒に働いてくださる仲間を募集しています。Scala 未経験でもかまいません。 <br>
顧客との直接取引で、技術的決定権があり、プロジェクト推進に裁量をもって、企画から開発・運用まで携わることができます。 <br>
ぜひ、お気軽にお問い合わせください！ <br>
<a href="https://www.atware.co.jp/recruit/">https://www.atware.co.jp/recruit/</a></p>]]></content:encoded></item><item><title><![CDATA[業務フィードバックをきっかけとしてGitBucketにコントリビュートしました]]></title><description><![CDATA[<p>GitBucketを業務プロジェクトで利用していることを<a href="http://tech.atware.co.jp/gitbucket-gitlfs/">前回ご紹介</a>しました。今回は「あったらいいな」を実現すべく、少しずつソースコードの把握・実装を行い、WebHook周りの機能追加をして、GitBucketにコントリビュートしました。</p>

<h2 id="">なぜコントリビュートしようと思ったのか</h2>

<ul>
<li>CIでGitBucketにtagが作成された時にWebHookを実行したかったが未実装であった
<ul><li>ソースをざっと見てみるとWebHookの拡張はやりやすそうであった</li></ul></li>
<li>もしソースに手を加えて独自ビルドしたとしても最新を追っていくとなると運用できつくなる</li>
<li>他のプロジェクトや他のユーザにもニーズがあるのでは</li>
</ul>

<p>と思い、<a href="https://developer.github.com/v3/activity/events/types/#createevent">CreateEvent</a>の実装したいと旨をCreateEventの実装したい旨をGitBucketの開発者にお伝えし、現在の限定的なWebHook対応の意図もお聞きしたところ、「単純にリソース不足で手が回っていなく、Web APIやWebHookに関しては周辺ツール・サービスとの連携を考慮し、極力GitHub互換に近づけたい」とのことで、快くコントリビュートを歓迎してくださいました。 <br>
（OSSなので真っ先にプルリク投げたりやIssueを立てたりするのもありだったかもしれないですが・・・）</p>

<h2 id="">開発に向けておこなったこと</h2>

<ul>
<li>WebHook動作確認のための簡易JSON Echoサーバー構築
<ul><li>Webhookではステータスコード <code>202 Accepted</code> を返却する必要がある</li></ul></li>
<li>GitBucketの起動方法確認
<ul><li><code>sbt ~jetty:start</code> で起動しソースに手を加えながら動作確認を行なった</li></ul></li>
</ul>

<h2 id="">仕様と実装</h2>

<p><img src="https://tech.atware.co.jp/content/images/2017/12/gitbucket_create_event.png" alt=""></p>

<p>Payloadのデータ定義はGitHubからREST API v3 の <a href="https://developer.github.com/v3/activity/events/types/">Event Types &amp; Payloads</a>でドキュメントが公開されているので、サンプルを確認して実装しました。</p>]]></description><link>https://tech.atware.co.jp/gitbucket-contribute/</link><guid isPermaLink="false">b50925f8-9940-4c00-9bfb-5bcca1874a8d</guid><category><![CDATA[OSS]]></category><category><![CDATA[gitbucket]]></category><dc:creator><![CDATA[asano]]></dc:creator><pubDate>Thu, 28 Dec 2017 03:52:11 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2017/12/gitbucket_logo.png" medium="image"/><content:encoded><![CDATA[<img src="http://tech.atware.co.jp/content/images/2017/12/gitbucket_logo.png" alt="業務フィードバックをきっかけとしてGitBucketにコントリビュートしました"><p>GitBucketを業務プロジェクトで利用していることを<a href="http://tech.atware.co.jp/gitbucket-gitlfs/">前回ご紹介</a>しました。今回は「あったらいいな」を実現すべく、少しずつソースコードの把握・実装を行い、WebHook周りの機能追加をして、GitBucketにコントリビュートしました。</p>

<h2 id="">なぜコントリビュートしようと思ったのか</h2>

<ul>
<li>CIでGitBucketにtagが作成された時にWebHookを実行したかったが未実装であった
<ul><li>ソースをざっと見てみるとWebHookの拡張はやりやすそうであった</li></ul></li>
<li>もしソースに手を加えて独自ビルドしたとしても最新を追っていくとなると運用できつくなる</li>
<li>他のプロジェクトや他のユーザにもニーズがあるのでは</li>
</ul>

<p>と思い、<a href="https://developer.github.com/v3/activity/events/types/#createevent">CreateEvent</a>の実装したいと旨をCreateEventの実装したい旨をGitBucketの開発者にお伝えし、現在の限定的なWebHook対応の意図もお聞きしたところ、「単純にリソース不足で手が回っていなく、Web APIやWebHookに関しては周辺ツール・サービスとの連携を考慮し、極力GitHub互換に近づけたい」とのことで、快くコントリビュートを歓迎してくださいました。 <br>
（OSSなので真っ先にプルリク投げたりやIssueを立てたりするのもありだったかもしれないですが・・・）</p>

<h2 id="">開発に向けておこなったこと</h2>

<ul>
<li>WebHook動作確認のための簡易JSON Echoサーバー構築
<ul><li>Webhookではステータスコード <code>202 Accepted</code> を返却する必要がある</li></ul></li>
<li>GitBucketの起動方法確認
<ul><li><code>sbt ~jetty:start</code> で起動しソースに手を加えながら動作確認を行なった</li></ul></li>
</ul>

<h2 id="">仕様と実装</h2>

<p><img src="https://tech.atware.co.jp/content/images/2017/12/gitbucket_create_event.png" alt="業務フィードバックをきっかけとしてGitBucketにコントリビュートしました"></p>

<p>Payloadのデータ定義はGitHubからREST API v3 の <a href="https://developer.github.com/v3/activity/events/types/">Event Types &amp; Payloads</a>でドキュメントが公開されているので、サンプルを確認して実装しました。</p>

<p>また、GitBucketでは未実装のWebHookが既に予約されており、コメントアウトされていた画面の入力フィールドを解除するだけで予約済みのWebHookの画面対応ができます。WebAppのデータベーススキーマやマイグレーションに手を加える必要はありませんでした。</p>

<p>ロジック実装で手を加えるのは、JGitで行なっているGitHook周りとWebHookService周りが中心で、影響範囲が狭かったのでデグレーションの心配が少なく、開発とプルリクの心理的な障壁が低かったです。</p>

<p>本対応は以下のバージョンでマージされリリースされました。 <br>
<a href="https://gitbucket.github.io/gitbucket-news/gitbucket/2017/12/23/gitbucket-4.20.0.html">GitBucket 4.20.0 released! - GitBucket News</a></p>

<h3 id="">ちょっと驚いたこと</h3>

<p>GitHubの挙動調査をしていたところ、GitHubのWebhook CreateEventでは引き渡されるPayloadとドキュメントサンプルで異なる部分があることに気づきました（空文字とNULL）。また、統一性がない部分があるところが気になりました。</p>

<p>そこで、気になったところをGitHubに問い合わせたところ、ドキュメントが間違っているということがわかり、担当チームに伝えてくれることになりましたが、GitHub自身のプロダクトでも「こういうことってあるんだ」と、意外な一面を見て驚きました。</p>

<h2 id="">最後に</h2>

<p>こういうことは、少しずつでもいいので継続性を持ってできるないいなと考えており、普段から使わせてもらっているOSSや界隈に還元していければと思います。</p>]]></content:encoded></item><item><title><![CDATA[Nginx+SSLクライアント証明書とSSHプロトコルを利用した環境でGitBucketのGitLFSを使うには]]></title><description><![CDATA[<p>アットウェアでは開発プロジェクトでGitのホストティングに幾つかのツールを利用しております。その中でも、GitBucketは弊社の業務形態や利用ユースケースにマッチしている事が多く、幾つかのプロジェクトで利用しています。</p>

<p>今回は、クライアント証明を設定して利用したいというようなユースケースがあり、且つGitLFSを使おうとした時にGitLFSの内部仕様にあわせて、幾つか必要な設定があったので、紹介したいと思います。</p>

<h3 id="">本題</h3>

<p>今回の構成として、GitBucketへhttpアクセスする際に、GitBucketの手前にNginxを配置しリバースプロキシさせてGitBucketへアクセスさせます。更に、NginxにSSLクライアント認証設定をしておくことで、クライアント証明書ファイルを取得できる限られたユーザのみがアクセスできるようにします。</p>

<p>sshプロトコルでGitLFSを使ったコミットを含む内容をPushした場合に、git-lfs-authenticateでエラーが発生しました。ログを元にGitLFSの仕様を調べたところ、sshプロトコルで接続された場合でも、GitLFS内部でhttp通信が発生し、http通信周りでエラーが発生していることがわかりました。</p>

<p><img src="https://tech.atware.co.jp/content/images/2017/12/gitbucket_gitlfs.png" alt=""></p>

<p>細かいGitLFS仕様については下記のサイトで解説されているので、参照ください。</p>

<ul>
<li><a href="https://jyn.jp/git-lfs-api/">git-lfsの仕様(サーバ側)を個人的に解説してみる</a></li>
</ul>

<h3 id="gitbucketnginx">GitBucketとNginx設定のポイント</h3>

<ul>
<li>GitLFS内部でhttp通信するのでGitBucketのBASE_URLはクライアントからアクセスできる適切なURLを設定しておく必要がある</li>
<li>GitBucketのBASE_URLへのアクセスする際に、クライアント証明設定がされたサーバを通過する設定されている場合、git configで設定が必要である</li>
<li>Nginxのファイルアップロード容量制限値に引っかかる場合があるので、client<em>max</em>body_size を適切なサイズで設定しておく必要がある</li>
</ul>

<h4 id="gitconfg">git confgへ設定手順</h4>

<p>pfxファイルからクライアント証明書、秘密鍵、CA証明書を取り出します。</p>

<pre><code>$openssl pkcs12 -in exsample.</code></pre>]]></description><link>https://tech.atware.co.jp/gitbucket-gitlfs/</link><guid isPermaLink="false">6f059e2b-69f9-4121-8ebb-d519e984065b</guid><category><![CDATA[git]]></category><category><![CDATA[nginx]]></category><category><![CDATA[gitbucket]]></category><dc:creator><![CDATA[asano]]></dc:creator><pubDate>Thu, 07 Dec 2017 02:14:15 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2017/12/nginx_gitbucket.png" medium="image"/><content:encoded><![CDATA[<img src="http://tech.atware.co.jp/content/images/2017/12/nginx_gitbucket.png" alt="Nginx+SSLクライアント証明書とSSHプロトコルを利用した環境でGitBucketのGitLFSを使うには"><p>アットウェアでは開発プロジェクトでGitのホストティングに幾つかのツールを利用しております。その中でも、GitBucketは弊社の業務形態や利用ユースケースにマッチしている事が多く、幾つかのプロジェクトで利用しています。</p>

<p>今回は、クライアント証明を設定して利用したいというようなユースケースがあり、且つGitLFSを使おうとした時にGitLFSの内部仕様にあわせて、幾つか必要な設定があったので、紹介したいと思います。</p>

<h3 id="">本題</h3>

<p>今回の構成として、GitBucketへhttpアクセスする際に、GitBucketの手前にNginxを配置しリバースプロキシさせてGitBucketへアクセスさせます。更に、NginxにSSLクライアント認証設定をしておくことで、クライアント証明書ファイルを取得できる限られたユーザのみがアクセスできるようにします。</p>

<p>sshプロトコルでGitLFSを使ったコミットを含む内容をPushした場合に、git-lfs-authenticateでエラーが発生しました。ログを元にGitLFSの仕様を調べたところ、sshプロトコルで接続された場合でも、GitLFS内部でhttp通信が発生し、http通信周りでエラーが発生していることがわかりました。</p>

<p><img src="https://tech.atware.co.jp/content/images/2017/12/gitbucket_gitlfs.png" alt="Nginx+SSLクライアント証明書とSSHプロトコルを利用した環境でGitBucketのGitLFSを使うには"></p>

<p>細かいGitLFS仕様については下記のサイトで解説されているので、参照ください。</p>

<ul>
<li><a href="https://jyn.jp/git-lfs-api/">git-lfsの仕様(サーバ側)を個人的に解説してみる</a></li>
</ul>

<h3 id="gitbucketnginx">GitBucketとNginx設定のポイント</h3>

<ul>
<li>GitLFS内部でhttp通信するのでGitBucketのBASE_URLはクライアントからアクセスできる適切なURLを設定しておく必要がある</li>
<li>GitBucketのBASE_URLへのアクセスする際に、クライアント証明設定がされたサーバを通過する設定されている場合、git configで設定が必要である</li>
<li>Nginxのファイルアップロード容量制限値に引っかかる場合があるので、client<em>max</em>body_size を適切なサイズで設定しておく必要がある</li>
</ul>

<h4 id="gitconfg">git confgへ設定手順</h4>

<p>pfxファイルからクライアント証明書、秘密鍵、CA証明書を取り出します。</p>

<pre><code>$openssl pkcs12 -in exsample.com.pfx -clcerts -nokeys -out ~/exsample.com.cert
$openssl pkcs12 -in exsample.com.pfx -nocerts -nodes -out ~/exsample.com.key
$openssl pkcs12 -in exsample.com.pfx -cacerts -nokeys -out ~/exsample.com.ca-bundle
</code></pre>

<p>git configへ証明書関連の設定を行います。</p>

<pre><code>$cd yourrepo
$git config --local http.sslcert ~/exsample.com.cert
$git config --local http.sslkey ~/exsample.com.key
$git config --local http.sslcainfo ~/exsample.com.ca-bundle
</code></pre>

<p>上記の設定を実施後に、sshプロトコル経由で適切なリポジトリへPushした際にGitBucketのGitLFS内部で適切にクライアント証明が行われ、結果がセントラルへ反映されます。</p>

<h2 id="">最後に</h2>

<p>ある程度制約を加えた環境での、GitBucket Tipsでした。 <br>
GitBucketはバージョンアップを含め、とても運用しやすい仕組みになっていますので、利用を進めていきたいと思います。</p>]]></content:encoded></item><item><title><![CDATA[ドコモ AIエージェント・Expert Agent Developer Kit を利用したAndroidアプリケーション]]></title><description><![CDATA[<p>株式会社NTTドコモさんが開発し、公開されている<a href="http://docs.sebastien.ai/">AIエージェント基盤</a>を活用したAndroidアプリケーションのソースコードを弊社<a href="https://github.com/atware/sebastien_android_sample">GitHubリポジトリ</a>に公開しました。</p>

<p>弊社は<a href="http://tech.atware.co.jp/ai-agent/">AIエージェント基盤の開発パートナー</a>として、弊社独自のAIサービスの開発およびAIサービスを提供される企業様に対して開発のご支援等をしてまいります。それに向けた取り組みの一貫で、AIエージェント上のサービスを活用するクライアント（デバイス）のサンプルとしてAndroidアプリケーションを開発しました。ドコモAIエージェント・オープンパートナーイニシアティブの一員として、AIエージェント基盤が広く使われることを願って、このアプリケーションのソースコードを公開するものです。開発者がアプリケーションを開発する際のサンプルとして活用されることを想定しています。</p>

<p>AIエージェント基盤を活用するためのExpert Agent Developer Kitの利用方法や活用法を検証することを目的にしていますので、アプリケーションとしてのデザイン、使い勝手は重要視していません。あくまでも検証を目的としたものですので、特に品質について何ら保証できるものではないことをご了承いただいた上でご利用ください。ソースコードをビルドして作ったアプリケーションの利用に関してなんら保障はいたしませんし、仮に損害等が生じたとしても弊社としては一切の責任は負いかねます。 <br>
このソースコードやExpert Agent Developer Kitの利用方法についてのお問い合わせにも現段階ではお応えしかねます（おそらくはExpert Agent Developer Kitについては今後はコミュニティベースでの交流の機会が設けられるのではないかと思われます）。</p>

<p>もちろん、<strong>AIサービスの提供をされる企業様からの開発のご支援</strong>のお問い合わせは大歓迎です。弊社<a href="https://www.atware.co.jp/contact-us/#contact-form">コンタクトフォーム</a>からご連絡ください。</p>

<p>弊社としても大きな可能性を持つAIエージェント基盤の活用について模索をしていますが、AIによってこれまでにない未来を創造する企業様との恊働の機会をいただければ幸いです。</p>]]></description><link>https://tech.atware.co.jp/sebastien_android_sample/</link><guid isPermaLink="false">28c7ce22-747f-4d33-ba1f-b9375928d4df</guid><category><![CDATA[AI]]></category><category><![CDATA[SEBASTIEN]]></category><dc:creator><![CDATA[MAKINO Takashi]]></dc:creator><pubDate>Thu, 31 Aug 2017 07:11:44 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2017/08/ai-agent-1.png" medium="image"/><content:encoded><![CDATA[<img src="http://tech.atware.co.jp/content/images/2017/08/ai-agent-1.png" alt="ドコモ AIエージェント・Expert Agent Developer Kit を利用したAndroidアプリケーション"><p>株式会社NTTドコモさんが開発し、公開されている<a href="http://docs.sebastien.ai/">AIエージェント基盤</a>を活用したAndroidアプリケーションのソースコードを弊社<a href="https://github.com/atware/sebastien_android_sample">GitHubリポジトリ</a>に公開しました。</p>

<p>弊社は<a href="http://tech.atware.co.jp/ai-agent/">AIエージェント基盤の開発パートナー</a>として、弊社独自のAIサービスの開発およびAIサービスを提供される企業様に対して開発のご支援等をしてまいります。それに向けた取り組みの一貫で、AIエージェント上のサービスを活用するクライアント（デバイス）のサンプルとしてAndroidアプリケーションを開発しました。ドコモAIエージェント・オープンパートナーイニシアティブの一員として、AIエージェント基盤が広く使われることを願って、このアプリケーションのソースコードを公開するものです。開発者がアプリケーションを開発する際のサンプルとして活用されることを想定しています。</p>

<p>AIエージェント基盤を活用するためのExpert Agent Developer Kitの利用方法や活用法を検証することを目的にしていますので、アプリケーションとしてのデザイン、使い勝手は重要視していません。あくまでも検証を目的としたものですので、特に品質について何ら保証できるものではないことをご了承いただいた上でご利用ください。ソースコードをビルドして作ったアプリケーションの利用に関してなんら保障はいたしませんし、仮に損害等が生じたとしても弊社としては一切の責任は負いかねます。 <br>
このソースコードやExpert Agent Developer Kitの利用方法についてのお問い合わせにも現段階ではお応えしかねます（おそらくはExpert Agent Developer Kitについては今後はコミュニティベースでの交流の機会が設けられるのではないかと思われます）。</p>

<p>もちろん、<strong>AIサービスの提供をされる企業様からの開発のご支援</strong>のお問い合わせは大歓迎です。弊社<a href="https://www.atware.co.jp/contact-us/#contact-form">コンタクトフォーム</a>からご連絡ください。</p>

<p>弊社としても大きな可能性を持つAIエージェント基盤の活用について模索をしていますが、AIによってこれまでにない未来を創造する企業様との恊働の機会をいただければ幸いです。</p>]]></content:encoded></item><item><title><![CDATA[AWS Kinesis Stream を大規模データで検証してわかったことの事例紹介]]></title><description><![CDATA[<p>10分間で数億件を超えるIoT関連のデータをストリーム処理するためのPoC（概念実証）をする機会がありました。そこで経験をしてハマったことなど一部事例として紹介します。</p>

<h2 id="">検証の概要</h2>

<p>まずは、何のために検証しようとしたかというと...</p>

<p>IoT機器からKinesis Streamを通して大量のメッセージを受け取り、分散処理で関連付け処理を検証します。</p>

<p>実証検証の目的としては</p>

<ul>
<li>アーキテクチャ構成の妥当性を検証し</li>
<li>コスト軽減のポイントを把握</li>
<li>運用に向けた課題を洗い出す</li>
</ul>

<p>としました。</p>

<h2 id="">データと要件の特性</h2>

<p>今回の検証用データは自前で生成し投入する必要があり、結構なデータ量となります。</p>

<ul>
<li>トラフィック量 およそ数十万件/秒（数億件/10分）</li>
<li>時間帯によってバースト（スパイク）が存在する</li>
<li>メッセージの関連付け処理を行うが、いつ終点メッセージが届くかわからない。</li>
<li>数分後には処理結果を利用したいのでバッチでは実現が困難</li>
</ul>

<p>毎秒平均的にトラフィックを流し続けるのはそれなりのチューニングが必要でしたので、そこに時間をかけず、波はありながらも、都合およそ数十万件/秒となるようにメッセージを10分間流し続けました。</p>

<h2 id="kinesisstream">Kinesis Streamについて</h2>

<p>Kinesis Streamを挟む狙いとしては、アーキテクチャとして要件にあっているということに加え、下記のような特性を活かせるという狙いから採用候補としました。</p>

<ul>
<li>受け取ったストリームデータを損失しないようにする（リトライ含み）</li>
<li>ストリームからデータ取得を担うConsumerが自分のペースで処理を進められる</li>
<li>安定的にストリーム向け分散メッセージキューを運用できる</li>
<li>ストリーム処理を繋ぐところのIn/Outを疎結合にできる
<ul><li>疎結合にすると言っても、お互いがうまく結合できるように動作確認はしておきたい
<ul><li>Producerは大量データでもデータを全てKinesisに送信できているか</li>
<li>Consumerは大量データでもデータを全てKinesisから受信できているか</li></ul></li></ul></li></ul>]]></description><link>https://tech.atware.co.jp/aws-kinesis-stream-poc/</link><guid isPermaLink="false">44fb0482-a3fa-4444-89de-a9d53965fb38</guid><category><![CDATA[Kinesis]]></category><dc:creator><![CDATA[asano]]></dc:creator><pubDate>Mon, 07 Aug 2017 01:09:38 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2017/08/IoT-3.png" medium="image"/><content:encoded><![CDATA[<img src="http://tech.atware.co.jp/content/images/2017/08/IoT-3.png" alt="AWS Kinesis Stream を大規模データで検証してわかったことの事例紹介"><p>10分間で数億件を超えるIoT関連のデータをストリーム処理するためのPoC（概念実証）をする機会がありました。そこで経験をしてハマったことなど一部事例として紹介します。</p>

<h2 id="">検証の概要</h2>

<p>まずは、何のために検証しようとしたかというと...</p>

<p>IoT機器からKinesis Streamを通して大量のメッセージを受け取り、分散処理で関連付け処理を検証します。</p>

<p>実証検証の目的としては</p>

<ul>
<li>アーキテクチャ構成の妥当性を検証し</li>
<li>コスト軽減のポイントを把握</li>
<li>運用に向けた課題を洗い出す</li>
</ul>

<p>としました。</p>

<h2 id="">データと要件の特性</h2>

<p>今回の検証用データは自前で生成し投入する必要があり、結構なデータ量となります。</p>

<ul>
<li>トラフィック量 およそ数十万件/秒（数億件/10分）</li>
<li>時間帯によってバースト（スパイク）が存在する</li>
<li>メッセージの関連付け処理を行うが、いつ終点メッセージが届くかわからない。</li>
<li>数分後には処理結果を利用したいのでバッチでは実現が困難</li>
</ul>

<p>毎秒平均的にトラフィックを流し続けるのはそれなりのチューニングが必要でしたので、そこに時間をかけず、波はありながらも、都合およそ数十万件/秒となるようにメッセージを10分間流し続けました。</p>

<h2 id="kinesisstream">Kinesis Streamについて</h2>

<p>Kinesis Streamを挟む狙いとしては、アーキテクチャとして要件にあっているということに加え、下記のような特性を活かせるという狙いから採用候補としました。</p>

<ul>
<li>受け取ったストリームデータを損失しないようにする（リトライ含み）</li>
<li>ストリームからデータ取得を担うConsumerが自分のペースで処理を進められる</li>
<li>安定的にストリーム向け分散メッセージキューを運用できる</li>
<li>ストリーム処理を繋ぐところのIn/Outを疎結合にできる
<ul><li>疎結合にすると言っても、お互いがうまく結合できるように動作確認はしておきたい
<ul><li>Producerは大量データでもデータを全てKinesisに送信できているか</li>
<li>Consumerは大量データでもデータを全てKinesisから受信できているか</li></ul></li></ul></li>
</ul>

<h2 id="">大規模データと小規模データの違いでおこったこと</h2>

<p>規模の捉え方は、格納するメッセージ容量や要件によって様々ですが、今回は数百バイトのメッセージを大量に扱うという特性をもっていました。10分間の間に扱うメッセージ数は、</p>

<ul>
<li>小規模検証（ロジック動作確認）は数百万程度のメッセージで行う</li>
<li>大規模検証（運用シュミレーション）は数億程度のメッセージで行う</li>
</ul>

<p>としました。</p>

<h3 id="kinesisstream">Kinesis Stream シャード制限とリソースコストの関係</h3>

<p>これくらいのトラフィックだと、処理の効率化でインフラコストが大きく変わってきます。いかにしてそれを抑えることができるかを探りました。</p>

<h4 id="producer">Producerの視点で</h4>

<p>Kinesis Streamの料金は主にシャード数で決まってきます。</p>

<p>まず、Kinesis Streamを使うときは、自分たちがどれくらいの性能を必要としているのかを把握します。1シャードあたり1000メッセージまたは1MB/秒の制限がありますので、これを元にシャード数を指定してStreamとしてのスループットを確保します。</p>

<p>メッセージを投入する際、<a href="http://docs.aws.amazon.com/ja_jp/streams/latest/dev/developing-producers-with-kpl.html">Kinesis Producer Library（KPL）</a>を使うと便利です。シャードスループットを超えるリクエストがあった場合は、KPLが自動的にリトライをしてくれます。</p>

<p>Producer側からみるとより少ないシャード数で効率よくメッセージを詰め込むことで、Kinesis利用料を削減することができるのです。</p>

<p>今回のように小さなサイズのメッセージを大量に流したい場合、シャードあたりの容量制限に余裕があるものの、先にメッセージ数上限に達してしまい、シャード分散量が増えてしまいがちです。そういう時に使えるアプローチがユーザレコードを集約する機能です。</p>

<p>仮に1メッセージが100バイトである場合、10メッセージを1メッセージとして送信すれば、それだけでスループットを10倍稼ぐことが出来ます。同様に1000メッセージを1メッセージに集約させれば約100キロバイトになるので、理論上は1000倍のスループットとなります。</p>

<p>KPLを使ってレコードを集約しKinesis Streamに送信すると、総送信回数も減るので、負荷も軽減されメッセージ送信完了までの速度もあがります。</p>

<p>Producerのインスタンス性能も下げることができ、結果的にKinesis StreamとKPLを実行しているEC2両方の価格を抑えることに繋がります。</p>

<p>いいことづくめですね。</p>

<h5 id="kpl">大規模データでKPLを使ったら...</h5>

<p>ここまでは、<a href="http://docs.aws.amazon.com/ja_jp/streams/latest/dev/developing-producers-with-kpl.html">AWSの公式ドキュメント</a>をみるとわかることなのですが、数百シャードを使って分散されたProducerがレコードを集約して送信したところ、小規模で試した時より送信スループットを得ることができませんでした。</p>

<p>なぜこういうことが起こるのでしょうか。</p>

<p>Kinesisの内部実装を把握しているわけではないのですが、発生した現象をもとにした考察推測を紹介します。 <br>
※後日AWSサポートに問い合わせようかなと考えています</p>

<p>Producer側ではHashKeyを明示的に指定せずにランダムのPartitionKeyを指定して実装していました。シャード数が増えたことにより、KPLによって集約された1レコード内に異なる多数のシャードに格納すべきとされたレコードが存在してしまったため、KPLからリトライするメッセージが増えてしまっていると考えられます。</p>

<p>チューニングすれば解消できる問題ですが、シャード数が多くなればなるほど、シャードが分散されていることを考えてどう処理されるかを意識し実装しないと、Kinesis Streamの性能やコスト削減を最大限にすることから遠ざかってしまいますね。</p>

<h4 id="consumer">Consumerの視点で</h4>

<p>続いて、Consumer処理です。こちらは、<a href="http://docs.aws.amazon.com/ja_jp/streams/latest/dev/developing-consumers-with-kcl.html">Kinesis Client Library（KCL）</a>を使うことで、メッセージを取得する仕組み・状態管理をライブラリに任せることができます。</p>

<p>KCLは下記のような特徴を持っています。</p>

<ul>
<li>複数起動されたKCLプロセスごとに担当シャードが決まる
<ul><li>均等に担当量が配分される</li>
<li>KCLがワーカースレッドを作りメッセージを取得する
<ul><li>担当シャードの数だけワーカースレッドが立ちあがる</li></ul></li></ul></li>
<li>分散起動されたKCLの1台が落ちても他のKCLがシャードを引継ぐことができる</li>
</ul>

<p>シャード数が数百を超える規模になってくると、1台のインスタンスのCPU Coreで賄えなきれなくなることは明白で、どのインスタンスタイプでどれくらいの分散度にするのかが重要なチューニングポイントとなってきます。Consumer側は</p>

<ul>
<li>相互関係にあるパラメータ
<ul><li>Kinesis Streamシャード数</li>
<li>EC2コア数</li>
<li>EC2インスタンス数</li></ul></li>
</ul>

<p>の関係性をパタン化し測定しました。</p>

<p>例えば、EC2インスタンスはc4.8xlargeだと36Coreとなり、c4.4xlargeならば16Coreなので、Core数という面ではc4.8xlargeは有利なのですが、分散化して測定してみると、c4.8xlargeで少ない数のインスタンスで総Core数が多いケースより、c4.4xlargeで多い数のインスタンスで、総Core数が少ない方が処理効率は良い結果となりました。
（あくまで本検証ケースの実装とデータの結果となりますので、異なる前提条件下では同様の結果になるとは限りません。）</p>

<h5 id="kcl">大規模データでKCLを使ったら...</h5>

<p>Consumer周りでも大規模データでの検証になると問題が発生しました。</p>

<p>具体的にいうと、Producerのメッセージ送信量の要件にあわせてシャード数が多くなった場合、KCLの分散度やWorker数が多くなるのですが、メッセージの取りこぼしが発生しました。</p>

<p>調査を重ねた結果、KCLが状態管理に使用している<a href="http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-record-processor-ddb.html">DynamoDBのKinesisストリームアプリケーションテーブル</a>に起因することがわかりました。KCLでは起動時にDynamoDBにテーブルを自動生成するのですが、DynamoDBの初期設定Read・Writeともキャパシティ値を超えてKCLからアクセスが発生していたことが原因でした。</p>

<p>KCLが自動生成したテーブルは、Read・Writeとも10ユニットで設定されます。</p>

<p>測定してみたところ、数百シャードを超える場合は、ピークのアクセスとなる時に</p>

<ul>
<li>Read性能はデフォルト値前後を推移</li>
<li>Write性能は10倍以上が必要</li>
</ul>

<p>ということがわかりました。</p>

<p>そこで、<a href="https://aws.amazon.com/jp/blogs/news/new-auto-scaling-for-amazon-dynamodb/">2017年6月にリリースされたDynamoDBのオートスケール機能</a>を使います。 KCL起動前にCLIを使って手動でテーブル作成しておきキャパシティをオートスケーリング設定にしておくことで、Consumerのメッセージ取りこぼしが発生しなくなりました。</p>

<p>大規模データでの検証を始める前は、<code>管理テーブルだからそんなにアクセス量はないだろう</code> とか <code>KCLがいい感じにやっておいてくれるだろう</code>と想定していました。ところが分散数が増えてくると様々なところで小規模検証では無視できた負荷が大きく現れてきて、様々な事象が発生しました。</p>

<h2 id="">まとめ</h2>

<p>今回は2ケースほど大規模ならではの事例を紹介しました。他にも紹介しきれなかった事象もあり、事象から一つ一つ原因を探っていく地味な作業を繰り返したくさんの知見を得ることができました。また、検証にかかったインフラ利用料金も想定の範囲内に抑えることができ、PoCでの目的を達成することができました。</p>

<p>大規模検証はやってみて初めて発生する事象に出逢うことはよくあることで、逆に言うと事前検証なしで大規模に適用するアーキテクチャを決めることは、何か課題が発生した場合、アーキテクチャを根幹から変更しなくてはならないレベルの影響が及ぶことになりかねません。時間と予算をとってPoCをすることの有用性を改めて感じました。</p>

<p>検証を通してKinesis自身の安定性は抜群で、かつ料金も妥当と思えるものだったので、今後もマッチする要件にはKinesisを提案していく機会が増えていくことでしょう。また、こういう経験をアウトプットすることで、みなさんに少しでも役だてていただければなによりです。</p>]]></content:encoded></item><item><title><![CDATA[ドコモAIエージェント・オープンパートナーイニシアティブ]]></title><description><![CDATA[<p>株式会社アットウェアは、株式会社NTTドコモ様が推進される「<a href="https://www.nttdocomo.co.jp/info/news_release/2017/06/23_00.html">ドコモAIエージェント・オープンパートナーイニシアティブ</a>」に賛同し、パートナーとしてAIエージェント上でのサービス構築を支援する旨の表明をいたしました。</p>

<p>「ドコモAIエージェント・オープンパートナーイニシアティブ」は、ライフスタイルを革新する新AIエージェントの実現に向けてNTTドコモ様が開発された「AIエージェントAPI」をオープン化し、パートナー各社と恊働でAIエージェントサービスの開発期間の最短化を目的としています。
当社は、NTTドコモ様およびサービスを提供される多くの企業様に対し、当社がこれまで取り組んできたクラウド(Amazon Web Services)を利用したWebサービスや分散処理、人工知能技術等を活用した先進的なシステムの構築を支援いたします。</p>

<p>具体的に以下の三点について取り組んで参ります。</p>

<h3 id="ai">独自のAIサービスの開発、提供</h3>

<p>当社および当社のサービス事業子会社である株式会社Zabutonのこれまでの経験を活かした新たなAIサービスを「AIエージェントAPI」を利用して開発、提供して参ります。
具体的には、株式会社Zabutonが提供するAI秘書サービス「Koyomin'」 <a href="https://koyomin.ai/">https://koyomin.ai/</a> をAIエージェントAPIに対応させ、より多くのお客様にご利用いただくことを検討しております。</p>

<h3 id="ai">AIサービス開発支援</h3>

<p>「AIエージェントAPI」を使ったAIサービスの提供をされる企業様に対して開発のご支援をいたします。
当社がこれまで多くの企業様から請け負ってきた先進的なシステム開発の経験、また単にご要求いただいたソフトウェアを作るだけでなく企業様と共にサービスを育てていくためのアジャイルやリーン・スタートアップに基づく恊働開発を行います。
併せて、長期的に自社でのサービス開発や運用を見据えた、システム内製化のための組織作りや育成などの支援も行います</p>

<h3 id="ai">AIを活用した業務改善支援</h3>

<p>「AIエージェントAPI」を活用した企業内業務の改善の企画、技術検証および開発、運用をご支援します。</p>]]></description><link>https://tech.atware.co.jp/ai-agent/</link><guid isPermaLink="false">28a27efd-32e2-43c7-a0dd-b66179c02130</guid><category><![CDATA[AI]]></category><category><![CDATA[SEBASTIEN]]></category><dc:creator><![CDATA[MAKINO Takashi]]></dc:creator><pubDate>Wed, 02 Aug 2017 23:55:26 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2017/08/ai-agent.png" medium="image"/><content:encoded><![CDATA[<img src="http://tech.atware.co.jp/content/images/2017/08/ai-agent.png" alt="ドコモAIエージェント・オープンパートナーイニシアティブ"><p>株式会社アットウェアは、株式会社NTTドコモ様が推進される「<a href="https://www.nttdocomo.co.jp/info/news_release/2017/06/23_00.html">ドコモAIエージェント・オープンパートナーイニシアティブ</a>」に賛同し、パートナーとしてAIエージェント上でのサービス構築を支援する旨の表明をいたしました。</p>

<p>「ドコモAIエージェント・オープンパートナーイニシアティブ」は、ライフスタイルを革新する新AIエージェントの実現に向けてNTTドコモ様が開発された「AIエージェントAPI」をオープン化し、パートナー各社と恊働でAIエージェントサービスの開発期間の最短化を目的としています。
当社は、NTTドコモ様およびサービスを提供される多くの企業様に対し、当社がこれまで取り組んできたクラウド(Amazon Web Services)を利用したWebサービスや分散処理、人工知能技術等を活用した先進的なシステムの構築を支援いたします。</p>

<p>具体的に以下の三点について取り組んで参ります。</p>

<h3 id="ai">独自のAIサービスの開発、提供</h3>

<p>当社および当社のサービス事業子会社である株式会社Zabutonのこれまでの経験を活かした新たなAIサービスを「AIエージェントAPI」を利用して開発、提供して参ります。
具体的には、株式会社Zabutonが提供するAI秘書サービス「Koyomin'」 <a href="https://koyomin.ai/">https://koyomin.ai/</a> をAIエージェントAPIに対応させ、より多くのお客様にご利用いただくことを検討しております。</p>

<h3 id="ai">AIサービス開発支援</h3>

<p>「AIエージェントAPI」を使ったAIサービスの提供をされる企業様に対して開発のご支援をいたします。
当社がこれまで多くの企業様から請け負ってきた先進的なシステム開発の経験、また単にご要求いただいたソフトウェアを作るだけでなく企業様と共にサービスを育てていくためのアジャイルやリーン・スタートアップに基づく恊働開発を行います。
併せて、長期的に自社でのサービス開発や運用を見据えた、システム内製化のための組織作りや育成などの支援も行います</p>

<h3 id="ai">AIを活用した業務改善支援</h3>

<p>「AIエージェントAPI」を活用した企業内業務の改善の企画、技術検証および開発、運用をご支援します。
AIが人の仕事を奪うのではなく、面倒な作業やAIが得意な作業をAIに任せ、人がより集中すべき業務を担って効率化や品質の向上、さらには価値の向上を図るための取り組みを企業様と共にリーン・スタートアップに基いて実施いたします。</p>

<hr>

<ul>
<li>2017.08.03
<a href="https://dev.smt.docomo.ne.jp/?p=common_page&amp;p_name=sebastien_teaser">ドコモ AIエージェント基盤のサイト</a>が公開されました</li>
</ul>]]></content:encoded></item><item><title><![CDATA[Scala で実装した社内ナレッジ共有ツールを OSS にして公開しました]]></title><description><![CDATA[<p>社内の事業部・プロジェクトを跨いで、社員間で技術やノウハウの共有をもっともっと盛んにしたいーそんな社員の声から生まれ、社内で運用中のツールをこの度 OSS にして公開しました。</p>

<h1 id="">公開先</h1>

<p>GitHub 上に公開しています。</p>

<p>Heroku ボタンを記載していますので、すぐに試すこともできます。</p>

<h1 id="scuruto">Scuruto</h1>

<p><img src="https://tech.atware.co.jp/content/images/2018/02/th_scuruto-list.png" alt="">
Markdown で記事が投稿でき、コメントや Like やストックができる情報共有ツールです。 <br>
絵文字入力も可能で、さらにはシーケンス図やフローチャートも Markdown で描けます。 <br>
レスポンシブにしてあるのでスマホやタブレットでも使えます。</p>

<h1 id="">つくるに至った背景など</h1>

<h2 id="">背景</h2>

<p>弊社には以前から、</p>

<ul>
<li>他のプロジェクトでどんな技術が使われているのかよく知らない</li>
<li>また、あまり知る機会がなく、技術資産がうまく活用されていないのでは</li>
</ul>

<p>といった課題がありました。</p>

<p>社内の事業部・プロジェクトを跨いで、社員間で技術やノウハウの共有をもっともっと盛んにしたい、この想いを実現するべく、普段の業務の合間を縫ってこのツールを作成しました。</p>

<p>現在では、約 600 件の記事が投稿されるなど社内の情報共有インフラのひとつに定着しています。</p>

<h2 id="scala">Scala への取り組み</h2>

<p>もうひとつの背景として、開発は 2014年8月に行ったのですが、ちょうどその頃、弊社でも Scala への取り組みをしていこうという機運が出始めていたので、ものすごく難しいシステムでもないしありもののサービスを使うのではなく練習を兼ねて</p>]]></description><link>https://tech.atware.co.jp/scuruto/</link><guid isPermaLink="false">e878a0d0-5c1d-418a-a4d7-3d69a33a84ed</guid><category><![CDATA[Scala]]></category><category><![CDATA[OSS]]></category><dc:creator><![CDATA[Ryuji Yamashita]]></dc:creator><pubDate>Mon, 16 Jan 2017 23:48:45 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2018/02/eyecatch.png" medium="image"/><content:encoded><![CDATA[<img src="http://tech.atware.co.jp/content/images/2018/02/eyecatch.png" alt="Scala で実装した社内ナレッジ共有ツールを OSS にして公開しました"><p>社内の事業部・プロジェクトを跨いで、社員間で技術やノウハウの共有をもっともっと盛んにしたいーそんな社員の声から生まれ、社内で運用中のツールをこの度 OSS にして公開しました。</p>

<h1 id="">公開先</h1>

<p>GitHub 上に公開しています。</p>

<p>Heroku ボタンを記載していますので、すぐに試すこともできます。</p>

<h1 id="scuruto">Scuruto</h1>

<p><img src="https://tech.atware.co.jp/content/images/2018/02/th_scuruto-list.png" alt="Scala で実装した社内ナレッジ共有ツールを OSS にして公開しました">
Markdown で記事が投稿でき、コメントや Like やストックができる情報共有ツールです。 <br>
絵文字入力も可能で、さらにはシーケンス図やフローチャートも Markdown で描けます。 <br>
レスポンシブにしてあるのでスマホやタブレットでも使えます。</p>

<h1 id="">つくるに至った背景など</h1>

<h2 id="">背景</h2>

<p>弊社には以前から、</p>

<ul>
<li>他のプロジェクトでどんな技術が使われているのかよく知らない</li>
<li>また、あまり知る機会がなく、技術資産がうまく活用されていないのでは</li>
</ul>

<p>といった課題がありました。</p>

<p>社内の事業部・プロジェクトを跨いで、社員間で技術やノウハウの共有をもっともっと盛んにしたい、この想いを実現するべく、普段の業務の合間を縫ってこのツールを作成しました。</p>

<p>現在では、約 600 件の記事が投稿されるなど社内の情報共有インフラのひとつに定着しています。</p>

<h2 id="scala">Scala への取り組み</h2>

<p>もうひとつの背景として、開発は 2014年8月に行ったのですが、ちょうどその頃、弊社でも Scala への取り組みをしていこうという機運が出始めていたので、ものすごく難しいシステムでもないしありもののサービスを使うのではなく練習を兼ねて Scala で実装しようと思いました。</p>

<p>フレームワークはフルスタックで学習コストが低くとっつきやすい <a href="http://skinny-framework.org/">Skinny Framework</a> を採用し、Better Java のスタイルではじめてみました。 <br>
Skinny Framework は、Scala on Rails なフルスタックフレームワークで、ドキュメントやサンプル、解凍すればすぐに開発を開始できるブランクプロジェクトも用意されているなど、Scala で Web アプリをはじめるには非常にオススメです。</p>

<h1 id="">さいごに</h1>

<p>アットウェアではオープンソースや Java/Scala に関心があり一緒に働いてくださる仲間を募集しています。<a href="https://www.atware.co.jp/recruit/">ご応募お待ちしております！</a></p>]]></content:encoded></item><item><title><![CDATA[SAV (Smart Access Vehicle) の東京実験成功]]></title><description><![CDATA[<p>2016年12月、NTTドコモ主催によるデマンド乗合い車両の実証実験の一環として、公立はこだて未来大学を中心に研究を進めているSAV (Smart Access Vehicle) を利用した東京都内での走行実験を行いました。</p>

<h3 id="sav">SAV初の東京都内実証実験</h3>

<p>東京お台場エリアにて、完全無人によるリアルタイム配車決定と、決定に従ったデマンド乗合い車両の走行実験を行いました。 
短時間にデマンドが集中し多重乗合いが頻発する想定での実験を行い、全てのデマンドに対する処理（配車決定）に成功しています。</p>

<ul>
<li><p>お台場エリアSAV車両走行状況<br><img src="https://tech.atware.co.jp/content/images/2016/12/tokyo-operator.png" alt="tokyo-ope" title=""></p></li>
<li><p>お台場エリアSAVドライバーの走行ルート<br><img src="https://tech.atware.co.jp/content/images/2016/12/tokyo-daiba.png" alt="tokyo-daiba" title=""></p></li>
</ul>

<p>過去3回函館地区において実証実験を重ねてきたSAVですが、都内主要観光エリアでも十分に機能することが確認できました。今回の実験データ、アンケート結果を元に、<a href="http://www.miraishare.co.jp/sav/" target="_blank">未来シェア</a>や研究者を中心としたSAVの改良が進む見込みです。</p>]]></description><link>https://tech.atware.co.jp/sav-tokyo-exam/</link><guid isPermaLink="false">28cdb380-e682-4f62-91c4-b0369cfca8f1</guid><category><![CDATA[SAV]]></category><dc:creator><![CDATA[Matsudate]]></dc:creator><pubDate>Wed, 21 Dec 2016 03:33:22 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2016/12/tokyosavs.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://tech.atware.co.jp/content/images/2016/12/tokyosavs.jpg" alt="SAV (Smart Access Vehicle) の東京実験成功"><p>2016年12月、NTTドコモ主催によるデマンド乗合い車両の実証実験の一環として、公立はこだて未来大学を中心に研究を進めているSAV (Smart Access Vehicle) を利用した東京都内での走行実験を行いました。</p>

<h3 id="sav">SAV初の東京都内実証実験</h3>

<p>東京お台場エリアにて、完全無人によるリアルタイム配車決定と、決定に従ったデマンド乗合い車両の走行実験を行いました。 
短時間にデマンドが集中し多重乗合いが頻発する想定での実験を行い、全てのデマンドに対する処理（配車決定）に成功しています。</p>

<ul>
<li><p>お台場エリアSAV車両走行状況<br><img src="https://tech.atware.co.jp/content/images/2016/12/tokyo-operator.png" alt="SAV (Smart Access Vehicle) の東京実験成功" title=""></p></li>
<li><p>お台場エリアSAVドライバーの走行ルート<br><img src="https://tech.atware.co.jp/content/images/2016/12/tokyo-daiba.png" alt="SAV (Smart Access Vehicle) の東京実験成功" title=""></p></li>
</ul>

<p>過去3回函館地区において実証実験を重ねてきたSAVですが、都内主要観光エリアでも十分に機能することが確認できました。今回の実験データ、アンケート結果を元に、<a href="http://www.miraishare.co.jp/sav/" target="_blank">未来シェア</a>や研究者を中心としたSAVの改良が進む見込みです。</p>]]></content:encoded></item><item><title><![CDATA[Scala先駆者インタビュー 最終回 ChatWork かとじゅんさん 〜後編〜]]></title><description><![CDATA[<h3 id="scala">サービスの規模も変わってきてScalaの活用も色々と試行錯誤しています</h3>

<p>－－ チャットのサービスが使えなくなると相当困りますよね。AWSのCloudWatchLogsを日本ではChatWorkさんが一番使ってると聞いたことがありますが、それだけ多くの人が当たり前のように使っているということですよね。</p>

<p>かとじゅん：チャットのメッセージはかなりの流量なので技術的にはすごい面白いところではあります。これくらいの規模感にならないとActorなどがそこまで必要ない気もします。</p>

<p>－－ IoTなどのようにクライアントが沢山増えることでトラフィック量やデータ量が明らかに増えますよね。そこで、リアクティブシステムのような流れになるというところでしょうか。</p>

<p>かとじゅん：クライアントが増えて小さいデータがたくさん飛んでくるといった状況が加速していくと、リアクティブシステムのような概念は当たり前の技術になるだろうと思っています。加えて、無停止でデプロイできる、ワークロードに応じたスケーリングが出来る、どんな状況でもとにかく早くレスポンスを返せる、などができることが理想ですね。例えば、普通はDBが落ちたらアプリケーションも落ちてたと思うのですが、Actorの間に先ほど説明したBackoffSupervisorを入れておくと、DBコネクションをハンドルしているActorがリトライするときにバックオフされていくので、DBには負荷がかからなくなっていきます。そして、DBが再起動すると接続が自動的に回復して次のタスクが処理できるようになります。もちろん、このような仕組みがあっても手放しでは運用できませんが、運用負荷は軽減することが可能です。</p>

<p><img src="https://tech.atware.co.jp/content/images/2016/12/scalainterviewvol8-2-1.jpeg" alt="vol8-2-1"></p>

<p>－－ そういった運用設計をしようとすると、インフラ部分だけでなくてプログラミングモデルのところからそういうことを意識する必要があるのかなと思います。ただ、どこまで品質の完璧性を求めるのかというところが個人的には気になっていて、サービスによっては5分ほどのメンテナンスタイムを入れても問題ないといった場合もあるかと思うのですが。</p>

<p>かとじゅん：それは要件次第でしょうね。高い非機能要件が問われるWebサービスであれば、Akkaなどのリアクティブシステムを採用することは比較的検討しやすいと思います。一方で、SIだと一口にリアクティブシステムが良いとは言っても、別の変数の価値基準に引っ張られるので簡単には導入できないかもしれませんね。ただ、例えば、社内システムでも可用性を重視してほしいとか、大量データを扱うバッチ処理を短時間で処理してほしいという要望があった場合、開発側もそれに対応できるのであれば検討の余地はありますよね。とはいえ、教育や運用のコストの問題は無視できないと思いますが…。やはり、エキスパートと呼ばれる人がいるかどうかに起因するかもしれません。加えて、</p>]]></description><link>https://tech.atware.co.jp/scalainterview-vol8-2/</link><guid isPermaLink="false">e8b24fd2-4230-4677-8947-28b7f888cd13</guid><category><![CDATA[Scala]]></category><category><![CDATA[Interview]]></category><dc:creator><![CDATA[asano]]></dc:creator><pubDate>Fri, 09 Dec 2016 10:16:00 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2017/01/scala-vol8-twopart-1.jpg" medium="image"/><content:encoded><![CDATA[<h3 id="scala">サービスの規模も変わってきてScalaの活用も色々と試行錯誤しています</h3>

<img src="http://tech.atware.co.jp/content/images/2017/01/scala-vol8-twopart-1.jpg" alt="Scala先駆者インタビュー 最終回 ChatWork かとじゅんさん 〜後編〜"><p>－－ チャットのサービスが使えなくなると相当困りますよね。AWSのCloudWatchLogsを日本ではChatWorkさんが一番使ってると聞いたことがありますが、それだけ多くの人が当たり前のように使っているということですよね。</p>

<p>かとじゅん：チャットのメッセージはかなりの流量なので技術的にはすごい面白いところではあります。これくらいの規模感にならないとActorなどがそこまで必要ない気もします。</p>

<p>－－ IoTなどのようにクライアントが沢山増えることでトラフィック量やデータ量が明らかに増えますよね。そこで、リアクティブシステムのような流れになるというところでしょうか。</p>

<p>かとじゅん：クライアントが増えて小さいデータがたくさん飛んでくるといった状況が加速していくと、リアクティブシステムのような概念は当たり前の技術になるだろうと思っています。加えて、無停止でデプロイできる、ワークロードに応じたスケーリングが出来る、どんな状況でもとにかく早くレスポンスを返せる、などができることが理想ですね。例えば、普通はDBが落ちたらアプリケーションも落ちてたと思うのですが、Actorの間に先ほど説明したBackoffSupervisorを入れておくと、DBコネクションをハンドルしているActorがリトライするときにバックオフされていくので、DBには負荷がかからなくなっていきます。そして、DBが再起動すると接続が自動的に回復して次のタスクが処理できるようになります。もちろん、このような仕組みがあっても手放しでは運用できませんが、運用負荷は軽減することが可能です。</p>

<p><img src="https://tech.atware.co.jp/content/images/2016/12/scalainterviewvol8-2-1.jpeg" alt="Scala先駆者インタビュー 最終回 ChatWork かとじゅんさん 〜後編〜"></p>

<p>－－ そういった運用設計をしようとすると、インフラ部分だけでなくてプログラミングモデルのところからそういうことを意識する必要があるのかなと思います。ただ、どこまで品質の完璧性を求めるのかというところが個人的には気になっていて、サービスによっては5分ほどのメンテナンスタイムを入れても問題ないといった場合もあるかと思うのですが。</p>

<p>かとじゅん：それは要件次第でしょうね。高い非機能要件が問われるWebサービスであれば、Akkaなどのリアクティブシステムを採用することは比較的検討しやすいと思います。一方で、SIだと一口にリアクティブシステムが良いとは言っても、別の変数の価値基準に引っ張られるので簡単には導入できないかもしれませんね。ただ、例えば、社内システムでも可用性を重視してほしいとか、大量データを扱うバッチ処理を短時間で処理してほしいという要望があった場合、開発側もそれに対応できるのであれば検討の余地はありますよね。とはいえ、教育や運用のコストの問題は無視できないと思いますが…。やはり、エキスパートと呼ばれる人がいるかどうかに起因するかもしれません。加えて、アーキテクチャを考えるときには変数が沢山あるので、自分はエンジニアだから社内の政治は無視するという立場を取っていると、技術的優位性だけを主張してもその技術を採用できなくなるというジレンマがありますね。</p>

<p>－－ 私はスクラムでプロジェクトを回すこともありジレンマわかります。さじ加減や思い切りはいつも悩みます。</p>

<p>かとじゅん：他の面で言うと、自分のブランディングのことを考えたときにとにかく適用事例を増やしたいと考えるならば、他の変数は抑えることもできなくはないですよね。エンジニアとしてのポジショニングを考えると自分の得意なことを明確にしてブランディングした方がやりやすいですし。手段が目的化してしまうのは良くないとは言え、差別化の問題やそれで解決できる問題に効果があったりすると価値があるので、そういったことも戦略として考えてもよいのではないかと思います。</p>

<h3 id="scala">転職を考えた時に目的に応じてScalaが使えるというところを選びました</h3>

<p>－－ かとじゅんさんも、転職されるときにはそういった価値基準があったのでしょうか。</p>

<p><img src="https://tech.atware.co.jp/content/images/2016/12/scalainterviewvol8-2-2.jpeg" alt="Scala先駆者インタビュー 最終回 ChatWork かとじゅんさん 〜後編〜"></p>

<p>かとじゅん：僕が転職したときは、Scalaが使えるところを意図的に選びました（笑）もちろん、単にScalaが使えるだけでなくきちんと目的に応じてScalaを採用できるところを厳選したつもりです。スマホが流行して以来、小さなリクエストを非同期で次々に捌く必要が出てきて、そういった問題解決に対してはScalaが妥当だろうと思っていました。Twitterがそれを証明したという後ろ盾の影響も大きいのですが、PHPだとプロセスモデルなので非同期処理が難しいという印象があります。また、Hack/PHPのランタイムである、FacebookのHHVMでもasync/awaitが使えるようになってきているので、スケールするサービスに対してはそういう課題解決が必要だろうと思っています。なので、ScalaでもJVMのパワーも使って、これからの要求に対応できる可能性がかなり高いと思っていました。チャットもどちらかといえばそんなに大きいメッセージは来ないですし。</p>

<p>－－ 絵文字1文字だったりしますよね。</p>

<p>かとじゅん：そうです。「OK」 とかそんなのがぽろぽろ飛んできて、その度にブロッキングしていたら処理が追いつかないので、そういうサービスを考えたときにScalaは妥当だったかなと思います。ちなみに、ソーシャルゲームプラットフォーム企業のG社でもチャットサービスを作っていました。Finagleをベースに自分でルーティング用のフレームワークを作ったりしながら、10名ぐらいで数ヶ月かけて開発しました。</p>

<p>－－ そこで経験を積めばさらに勉強になりそうという見方もできたのではないですか。</p>

<p>かとじゅん：確かに、リリースした後のハイトラフィックな状態で運用経験を積むことができれば相当な知見は溜まっただろうと思いますが、その当時のG社はサービスのライフサイクルが比較的短い状況にあったので、開発したサービスが安定稼働している状態で次にチャレンジしたいという思いがありました(汗)。そのチャットサービス自体は、よい意味で僕の期待を裏切って、今も現役ですね。ほんとそれはよかったと思います。</p>

<p>結局、次もチャットサービスをやってるのですが（笑）</p>

<p>－－ かとじゅんさんの影響はだいぶ大きかっただろうと想像しているのですが、その後チームはどうなったのでしょうか。</p>

<p>かとじゅん：僕が辞める前にチームの中で十分に共有していましたし、僕の後を技術的に支えてくれる人もいたので問題ありませんでした。ただ、10人中で1人抜けるというのは重みはあったかなと思います。若手の人も結構いたので、客観的に考えて信頼の置けるエンジニアが1人抜けたという不安はあったかもしれないです。でも、自分の人生なので「お前らも頑張ってSurviveしてくれよ！」みたいな感じだったのが正直なところです。当時の関係者の方々にはご迷惑をおかけしました（笑）</p>

<p>技術的な部分を先導している人が全部やると周りの人達の成長を阻害する、伸び代を潰してしまうこともあると思うのでほどほどで退くという選択はアリかなと思ってます。</p>

<h3 id="scala">Scala転職が抵抗なくなるくらい採用事例などが広がっていると感じます</h3>

<p>－－ 転職の話に繋げてなのですが、かとじゅんさんのTwitterに、Scalaで転職を考えている方は連絡くださいと書いてあったのですが実際に紹介する機会などはあったのでしょうか。</p>

<p>かとじゅん：スタートアップだとエージェントが要求するような採用費用を掛けられないので、エンジニアを紹介してくださいという話などもあり、実際に何人か紹介しました。</p>

<p>－－ 企業が求める側面と、エンジニアから転職したいという側面の両面あると思うのですが、それぞれどんな感じでしょうか。</p>

<p>かとじゅん：エンジニアからという側面では、やっぱり僕の過去の現場や会社の繋がりが主です。あとはScalaMatsuriで知り合った人などですかね。もちろん100%の回答はできませんができるかぎりの紹介をしています。</p>

<p>水島：ScalaMatsuriにいけば企業ブースもありますし、今は供給の方が圧倒的に少ないのでScalaをキーワードにした転職の機会は結構あると思います。</p>

<p>かとじゅん：現時点でScalaをやってない人にもっとScalaに興味を持ってもらって、Scalaを使って仕事をしたいという人が増えて行くと良いですね。</p>

<p>－－ 企業側も色んなレベルのエンジニアを求めると思うのですが、具体的な要望があったりするのでしょうか。</p>

<p>かとじゅん：なぜScalaのエンジニアが欲しいのかを企業側に聞くと「Scalaをやってるエンジニアはちゃんと設計もしてくれそうだ」と思っているという話を耳にします。ただ早く作ればよいだけでなく設計もしっかりやってくれそうな人が多そう、というイメージを持っているようです。ひとまとめには言えないですが、カルチャーとしてそういう雰囲気はあると思います。Scala Daysのセッションを見ていると、ドメイン駆動設計の言葉が入っていたりもするので、設計やアーキテクチャを語る人が海外にも結構多い気がします。</p>

<p>水島：そういった上流部分というか、最近はもっぱら設計やアーキテクチャについて語る人が多いですね。</p>

<p>かとじゅん：Konradさんの発表を聞いた時に、高度な設計思想に基づいて問題解決する姿勢に関心しました。聴衆のみんなもあまり難しい顔をせずに聞いていたように思うのですが、Promise、ストリームなどの非同期処理に適したモデルに慣れていない人からすると、割と複雑な概念を話していると思います。なので、Scala界隈には複雑な問題領域に立っている人がいて、特徴が明確になっている気がします。</p>

<p>そもそもTwitterがScalaを採用したのも性能上の問題の限界を感じて導入しようというところからきているので、コミュニティとしても、そういうところに立っている人が多いのかもしれません。大量のトラフィックをどう捌こうかといったような方向に関心が向いている特徴はあるかなと思います。</p>

<p>かとじゅん：転職の話に戻りますが、ScalaMatsuriだとコネクションはすぐできると思うので、気づいたら転職していたみたいなこともあるかと思います。セプテーニさんを始め、将軍スポンサーを筆頭にいくつかの有力な企業がScalaを採用したり、イベントを開催したりしていると思います。</p>

<p>－－ Scala採用の募集は広がっていると思うのですが、その中でもみなさんはどう考えてScalaで転職しようと考えているんでしょうか。</p>

<p>かとじゅん：純粋にこれから新しい言語をやってみようというモチベーションだったり、ハイトラフィックなコンテキストでやっていきたいというところですかね。一昔前のウェブはLL言語で支配されていたので、静的型付き言語は扱いづらいとか大袈裟というような印象があったのですが、今となってはその文化圏にGolangやScalaが食い込んできて昔とは勢力図が違っていますよね。なので、そこそこやっていた中堅の人が静的型付き言語でWebができるらしいということで興味を持ってたりもしているようです。</p>

<p>水島：全世界的にだと思うのですが、静的型付き言語の復権みたいなものがあると思っています。RubyやJavaがいた2000年代前半から中頃だと、Webにおける支配的な静的型付き言語はJavaしかありませんでしたが、その頃はJavaの進歩が止まっていたうえに静的型付き言語を窮屈に感じてLL言語への流出があったのだろうと思います。でも、その時はたまたまJavaの進歩が止まっていただけで、その後にScalaみたいな言語が登場してきて、型推論があったりして静的型が再注目されたのだと思います。</p>

<p>かとじゅん：その話の流れで、RubyがSoft Typingを取り入れる話とかありましたよね。あれは構文チェックのような仕組みなんでしょうか。</p>

<p>水島：構文というか静的型チェッカーを入れるような感じですね。Matzさん曰く、型は書きたくないからそれを推論したいというようなところでしょうか。PythonもType Annotaionみたいなものが入って静的型付きの特徴を取り入れるような動きが見られます。</p>

<p>かとじゅん：またJavaScriptの話になってしまいますが、最近はRx系のプロダクトも意図的にTypeScriptで書いてコンパイル結果のJavaScriptを配布していたり、flowtypeを使う人も増えてきているので、静的型付きの復権みたいなものはあるかもしれませんね。SmartNewsさんやドワンゴさんやGREEさんも使っていて、Scalaは既に実績のある言語として認知されているので転職に対しても抵抗が少なくなったのかなと思います。</p>

<p><img src="https://tech.atware.co.jp/content/images/2016/12/scalainterviewvol8-2-3.jpg" alt="Scala先駆者インタビュー 最終回 ChatWork かとじゅんさん 〜後編〜"></p>

<h3 id="">コミュニティーへのフィードバックを意識して今後も活動していきたいです</h3>

<p>－－ 今後、力を入れたい取り組みとしてはどのようなことを考えていますか。</p>

<p>かとじゅん：先ほども話した通りWebな文脈でいくとハイトラフィックな方向に興味が向かっていますし、障害が起ても全体に波及しないアーキテクチャというような文脈でどんどん実践経験を積んでいきたいと思います。そこに対しては、アクターモデルがベターかと思っているのでこれからも使っていくと思います。あとは、運用で払わないといけないコストが課題になっているので、その辺りの知見を貯めてコミュニティーにフィードバックしていくのと、自分のブランディングの一つとしても活動を継続していければ良いなと思います。</p>

<h3 id="scala">Scala先駆者インタビューはカラーが出た企画としてよかったのでは</h3>

<p>－－ 最後の話題となります。このScala先駆者インタビューという企画をはじめて約2年、今回で終了となりますが、お二人の目からみていかがでしたか。</p>

<p>かとじゅん：こうやって声をかけてもらう前から見ていました。先駆者というだけあって「歴史を築いてきたすごい人達だな」と思いながらも、自分としては「すごい人達だなというよりも一緒に作り上げてきた同志」という風に感じています。前出さんや竹添さんの回など、立場が違えど、色々苦労なさったんだなというのがわかったり、同じ思いでScalaというモノに関わってきたんだなと。こういう方々がいないと今のScalaコミュニティが存在していなかったんだと改めて思いました。</p>

<p>Scalaコミュニティーを一緒に築き上げてきた人達とは、各々で別々の形でScalaに関わってきましたが、それゆえに色んな方向性を持った人が集まれる健全なカルチャーを築けたと思います。例えば、僕はScalaイベントでDDDの話しをしたり、<a href="https://twitter.com/okapies">岡本さん</a>はReactive Streamsの話をしたりと、それぞれカラーがあり、一つの色だけに合わせる必要がないので、個性をもった人がScalaコミュニティから弾かれるようなことはありません。</p>

<p>Scalaのコミュニティはそのような成り立ちから色んな人がいますね。今では、コミュニティも大きくなり、自分の興味ある分野にさらに入っていきやすいのではないでしょうか。</p>

<p>－－ この企画自体も、Scalaを使い出した時に少しでもコミュニティに還元できることはないかと思い始めました。元々縁があったNulabの吉澤さんに声をかけさせて頂いたところから始まり、あまり後先考えずやりはじめましたが、出演だけでなく助言や紹介などしていただくなど、すごくScalaコミュニティの方々の温かさを感じました。</p>

<p>水島：Scalaをやりはじめたような方々に「Scalaのコミュニティはこんな感じの人がいるのか」というのを知ってもらうきっかけになったのも良かったと思います。Scalaに馴染みがある人からすると「この人が今更？」というのがあるかもしれませんが、今回のかとじゅんさんのことでも、付き合いが長い自分自身も知らなかった「きっかけ」が聞けたり、「そういう風に考えていたのか」など新しい発見もありました。</p>

<p>かとじゅん：僕も同様に見えていなかったところに気づけましたし、色んな人にとって、先駆者たちがロールモデルになっているので広く目を通してもらいやすいのかもしれないですね。</p>

<p>－－ ズバリこの企画は成功だったのでしょうか。</p>

<p>水島：たぶん成功だったと思いますよ。</p>

<p>かとじゅん：アリだと思います。改めて個人のパーソナリティに触れる機会ってあまりなかったので、登場している人と「二人で飲みに行きませんか？」って言える人ならいいのかもしれませんが、そうでない人も多くいて、「でも話は聞きたい」という人もいますので、いい機会になったのでは。</p>

<p>－－ そういう意味では、この企画では実は、私が一番ラッキーで得したのかもしれません。話をするのは緊張するのですが、こういう機会でもないとかとじゅんさんや水島さんと長時間お話する時間はとれないですし、「実際のところどうなんでしょうか？」といったオフレコのようなことを聞けたり、私が普段感じたちょっとした疑問やぶつかっている壁や悩みや仮説のことなど相談できました。</p>

<p>かとじゅん：それも、いいんじゃないですか（笑）</p>

<p>－－ 特に会社としての取り組みや、お客さんやチームで一緒にモノづくりをしていく時にどんなことを考えているのか意見が聞けたり、前出さんがあれだけ苦労されていたというのは、話を聞くまではとても意外で、共感を持てるところがたくさんありました。</p>

<p>かとじゅん：Scalaコミュニティ以外のコミュニティの方々にもそういうメッセージが届いているのではないでしょうか。</p>

<h3 id="">こういった企画を続けていけると良いですね</h3>

<p>かとじゅん：ということで、今後この企画どうなるか？という辺りの話ですね。</p>

<p>－－ はい、この企画を始めた序盤に登場していただいた瀬良さんや竹添さんの時点で「やっぱ水島さんですよねー。先駆者と言えば。」という話題も度々出ていて、水島さんに辿り着いたらゴールだと内々心の中では決めていました。そして、最後の水島さんからの紹介いただいたかとじゅんさんで締めさせていただきました。</p>

<p>水島：Twitterで「先駆者といっていいのは@kmizuだけだろ」と言及されたのは印象に残ってます（笑）</p>

<p>－－ ずっと続けていくと、中だるみもでてくるでしょうし、一旦先駆者というテーマ区切りをつけることにしました。</p>

<p>かとじゅん：いいと思います。また、最後に声をかけてもらって光栄です。（笑） 僕は「あちこちでScala入れて回っている」というようなことを、D社時代の同僚から言われました。</p>

<p>まぁ、僕だけじゃないと思いますが（笑）</p>

<p>－－ 私は、みなさんほどScalaを使い込んでいるわけでもないですし、もし、次の企画をするとなると、どういうモノが望まれているんだろうか？私が聞いても話題を引き出し切れるのか？という懸念はありますが、ただ、今回のごきげんよう形式は面白くてよかったので、別テーマで「AWS」「クラウド」などにしたり、またはScalaの別テーマなどをするのもアリじゃないかと思っており、この企画シリーズ自体を続けて、OSSを使わせてもらっているフィードバックや貢献として何かできればいいなと考えています。</p>

<p>かとじゅん：実は瀬良さんと飲んだ時に、この話をしたことがあって、Play FrameworkやAkkaなどの有名なコミッターの方にハングアウトで繋いで、英語ができる方々と一緒にインタビューして記事に起こしたり、LightbendのYokotaさんも巻き込んだりするのも面白いね。と。</p>

<p>半年に一回くらいになってしまうかもしれませんが、こういうことができたらいいですね。</p>

<p>水島：海外の方にインタビューするなら自分も協力できます。</p>

<p>かとじゅん：引き続き日本国内を対象にやるなら、Scalaを採用している会社の話をきかせてもらうのもいいかもしれませんね。ドワンゴさんやサイバーエージェントさんなど、採用サイトで書いてあること以上のことを知るきっかけになるのでは。</p>

<p>日々どういった考え方で、Scalaを仕事にいかしているかなど聞けるとよさそうですね。</p>

<p>－－ パーソナル中心ではなく会社中心で繋げていくという感じですね。</p>

<p>かとじゅん：教育のこともつきまといますし、企業が興味を持っている分野と、個人が転職する時の材料としてそういう情報を見たがると思います。</p>

<p>－－ 最初の一社としたら、お二人から紹介していただけそうな会社ありますか。</p>

<p>かとじゅん：やっぱドワンゴさんじゃないですか（笑）</p>

<p>水島：もしやるなら会社の人にたぶん話もできますし、サイバーエージェントさんを紹介できるかもしれません。</p>

<p>かとじゅん：Scalaが人気でる前からやっていた会社さんからインタビューを始めて、徐々に最近やりだしたところに繋げると良いかもしれませんね。</p>

<p>－－ この企画を続けると喜んでくださる方もいそうなので、続けてみたいという気持ちになっています。</p>

<p>かとじゅん：そうですね。僕に協力できることがあれば。Scala以外を考えているのであれば、JavaScriptをはじめ他の言語やクラウドなどの分野でも紹介できる方もいますよ。</p>

<p>水島：他のプログラミング言語など興味もあります。何か続けていかれるのであれば、協力したいと思うので、できることがあればいつでも言ってください。</p>

<p>－－ どうもありがとうございます！今日は長時間ありがとうございました。また新たな企画を考えた時にはご相談させてください。</p>

<h3 id="">出席者</h3>

<ul>
<li>インタビューイー ChatWork株式会社 かとじゅんさん</li>
<li>インタビューワー アットウェア 浅野・三嶋、 株式会社ドワンゴ／一般社団法人Japan Scala Association 水島さん</li>
</ul>

<nav class="navigation post-navigation">  
  <div class="nav-links">
    <div class="nav-previous">
      <a href="https://tech.atware.co.jp/scalainterview-vol8-1/">> 最終回 ChatWork かとじゅんさん 前編</a>
    </div>
  </div>
</nav>]]></content:encoded></item><item><title><![CDATA[Scala先駆者インタビュー 最終回 ChatWork かとじゅんさん 〜前編〜]]></title><description><![CDATA[<h3 id="">めぐりめぐってたどり着いた最終回</h3>

<p>－－ 過去7人の先駆者をご紹介しましたが今回で最終回を迎えます。最後は水島さんからのご紹介で、かとじゅんさんです。水島さんとかとじゅんさんの出逢いの頃からお話をきかせてください。</p>

<p>かとじゅん：水島さんとの出会いは、ちょうどScalaを実践投入しようと思っていた時でした。</p>

<p>水島：実は、そもそも自分がかとじゅんさんといつどこで出会ったのかをあまり憶えていないんですよね......（笑） かとじゅんさんが書いていたブログに時々出没してコメントしていたのは憶えています。</p>

<p>かとじゅん：ブログにもよくコメントいただいてましたよね。僕が初めて水島さんと出会ったのは、確か僕がD社時代にまだScalaを実践投入してない段階で、Scalaを勉強するために一度社内勉強会を開いたことがあって、そこに水島さんを呼んだ覚えがあります。</p>

<p>水島：なるほど、そう言われると加藤さんに呼ばれた記憶はあります。</p>

<p>かとじゅん：あとは、<a href="https://twitter.com/xuwei_k">吉田さん</a>や<a href="https://twitter.com/yuroyoro">ゆろよろさん</a>も来てくれた気がします。ただ、今みたいには盛り上がっていない状況ではありました。僕が最初に水島さんを見かけたのは、2007年頃に筑波かどこかで開かれたJJUGでScalaの紹介をしていた時だったと思います。</p>

<p>水島：はい、していましたね。</p>

<p>かとじゅん：その頃の僕は、Java寄りの考えがすごく強かったので、Scalaを見た時は「全然訳がわからないな」と感じて1回身を引いたことを憶えています。そこから、3年くらい時間を空けた2010年頃、ちょうどドメイン駆動設計をやり始めて、Viewモデルとドメインモデルやドメインモデルとテーブルモデルの、レイヤをまたいだモデルの変換をmap, foldなどの高階関数を使って考えていた時にScalaをやり始めました。きっかけとしては、Asakusa Frameworkを開発している<a href="http://www.hosei.ac.jp/koho/pickup/ob-og/2011/120306.html]"></a></p>]]></description><link>https://tech.atware.co.jp/scalainterview-vol8-1/</link><guid isPermaLink="false">83793267-d6d6-4af1-9182-4e164f58b994</guid><category><![CDATA[Scala]]></category><category><![CDATA[Interview]]></category><dc:creator><![CDATA[asano]]></dc:creator><pubDate>Thu, 08 Dec 2016 09:22:00 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2017/01/scala-vol8-firstpart.jpg" medium="image"/><content:encoded><![CDATA[<h3 id="">めぐりめぐってたどり着いた最終回</h3>

<img src="http://tech.atware.co.jp/content/images/2017/01/scala-vol8-firstpart.jpg" alt="Scala先駆者インタビュー 最終回 ChatWork かとじゅんさん 〜前編〜"><p>－－ 過去7人の先駆者をご紹介しましたが今回で最終回を迎えます。最後は水島さんからのご紹介で、かとじゅんさんです。水島さんとかとじゅんさんの出逢いの頃からお話をきかせてください。</p>

<p>かとじゅん：水島さんとの出会いは、ちょうどScalaを実践投入しようと思っていた時でした。</p>

<p>水島：実は、そもそも自分がかとじゅんさんといつどこで出会ったのかをあまり憶えていないんですよね......（笑） かとじゅんさんが書いていたブログに時々出没してコメントしていたのは憶えています。</p>

<p>かとじゅん：ブログにもよくコメントいただいてましたよね。僕が初めて水島さんと出会ったのは、確か僕がD社時代にまだScalaを実践投入してない段階で、Scalaを勉強するために一度社内勉強会を開いたことがあって、そこに水島さんを呼んだ覚えがあります。</p>

<p>水島：なるほど、そう言われると加藤さんに呼ばれた記憶はあります。</p>

<p>かとじゅん：あとは、<a href="https://twitter.com/xuwei_k">吉田さん</a>や<a href="https://twitter.com/yuroyoro">ゆろよろさん</a>も来てくれた気がします。ただ、今みたいには盛り上がっていない状況ではありました。僕が最初に水島さんを見かけたのは、2007年頃に筑波かどこかで開かれたJJUGでScalaの紹介をしていた時だったと思います。</p>

<p>水島：はい、していましたね。</p>

<p>かとじゅん：その頃の僕は、Java寄りの考えがすごく強かったので、Scalaを見た時は「全然訳がわからないな」と感じて1回身を引いたことを憶えています。そこから、3年くらい時間を空けた2010年頃、ちょうどドメイン駆動設計をやり始めて、Viewモデルとドメインモデルやドメインモデルとテーブルモデルの、レイヤをまたいだモデルの変換をmap, foldなどの高階関数を使って考えていた時にScalaをやり始めました。きっかけとしては、Asakusa Frameworkを開発している<a href="http://www.hosei.ac.jp/koho/pickup/ob-og/2011/120306.html]">荒川さん</a>から、そういった問題解決には関数型の考え方が役に立つのでScalaをやってみると良い、というアドバイスをもらってそこからアクセルをかけてScalaを実践的に始めました。</p>

<h3 id="scala">色々な障壁がありながらもScala導入の土台作りに取り組んでいました</h3>

<p>水島：加藤さんがScalaを使い始めたのは、どちらかというと、プログラミングの面よりも設計手法として見たところからなんですね。</p>

<p>かとじゅん：そうですね。Scalaを学びたいというよりも問題解決のための設計手法を学びたかったという気持ちがあって、オブジェクト指向をベースにしながら関数型の考え方を取り入れているところは、僕の中ではすごくフィットしてました。実際にやってみるとすごくやりやすかった印象があります。Scalaでは、Javaの資産との結合部分にnullが登場して扱いが辛いなどという話はありますが、mapやreduce、foldなどミクロな解決手法を組み合わせて大きな問題を解くというコンセプトがドメイン駆動設計をやるときにマッチした気がします(ただ、高階関数の名前はユビキタス言語には対応付かないことが多いので、ドメイン層のI/Fではなく、その内部実装で使えそうという話です)。そこが出発点で、そこからはひたすらそういうことばかり考えていた気がします。この時は、まだD社の社内で導入できるかどうかというところではありました。</p>

<p>水島：2011年8月頃に<a href="http://sssslide.com/www.slideshare.net/j5ik2o/scala-9039767">第1回Scala会議</a>を、かとじゅんさんが開催しましたよね。</p>

<p>かとじゅん：やりましたね！いろんな人に助けてもらって開催できましたね。感謝しかないです。記憶が定かではないですが、その年の12月に第二回も開催していたようです…。Scala人口を増やすためにScalaのコミュニティーを育てて、Scalaを使うための土壌を広げたかったという思いがありました。手段を目的化してしまっているような側面もあったのですが、実用言語として実力のある言語だとその当時も感じていたので、課題感が同じ人達が集まって情報共有できると良いなということでやっていました。</p>

<p>－－ その当時で何人くらい集まっていたのでしょうか。</p>

<p>かとじゅん：80人くらいです。</p>

<p><img src="https://tech.atware.co.jp/content/images/2016/12/scalainterviewvol8-1-1.jpeg" alt="Scala先駆者インタビュー 最終回 ChatWork かとじゅんさん 〜前編〜"></p>

<p>水島：今でこそ、ScalaMatsuri(2017年開催はこちら)は海外の人も含めて大勢の方に参加していただけるようになりましたが、当時の浸透度や認知度からすると、かなりの人数が集まっていたと思います。</p>

<p>かとじゅん：今では、ScalaMatsuriの規模感が当たり前みたいになってしまっていますが、僕からすると、あの当時と比べても短期間で劇的に変わったなという印象です。</p>

<p>－－ それは日本だけでなく、海外で見ても同じような盛り上がりなのでしょうか。</p>

<p>水島：そうですね。最近はApache Sparkを使うというところからScalaを使い始めたという人達も多くなっていますよね。</p>

<p>かとじゅん：Sparkを使いたいからScalaを使うのは当たり前みたいな話もあるようですから、違和感なく使い始める人も多くなっていると思います。</p>

<p>水島：Scalaに関して言えば、Sparkが一つの火付け役になって、キラーミドルウェアとして良い影響を与えてくれたと思います。</p>

<p>かとじゅん：Scalaをやり始めた当時は、Scalaをプロダクトで採用する時にはすごく苦労しましたね。PHPとJavaの運用実績があるなかで、それ以外を導入すると運用が大変になるという理由から、新しいモノを導入することについては、インフラを担当する方達が簡単には首を縦に振りませんでした。ただ、Scalaが良かった点として、伝統的なJavaのランタイム上で動くということがかなりのアドバンテージになっていたのは事実です。あの当時は、Javaであるということが導入障壁を下げたという感じです。コンパイルが遅いなどの辛さはありますが、JVM上で動くのであればインフラの人も既存の知識とツールで対応できる、というところがハードルを下げましたね。Scalaと言わずに「Javaのアプリケーションです」と言って使っていました（笑）</p>

<p>水島：今のD社だとチーム単位に裁量があって責任を持つという空気感がありますが、当時は違った雰囲気だったのですね。</p>

<p>かとじゅん：インフラの最高責任者の人が首を縦にふらないと新しい言語やミドルウェアは採用できないという風潮がありました。これは、会社とかインフラ部門が悪という話ではなく、全体最適を考えた場合にすごく妥当な判断だったと思うんですよね。でも、僕らは個別最適も必要と考えていたので、そういう難しいゲームのルールを把握し、インフラ部門の協力者も得て、Scalaの導入に成功したという感じです。ちなみに、D社でScalaを最初に取り入れたのが、友人で元同僚のヨシオリで、彼が当時のチームで<a href="https://github.com/twitter-archive/kestrel">Kestrel</a>を導入しました。僕が<a href="https://www.playframework.com/">Play Framework</a>でRESTサーバを書いていたより前に本番環境に乗っかっていたようです。だから、一緒に飲むと、彼に”最初に道を作ったのは俺だぞ”とツッコミをもらうことがあります(笑)</p>

<p>ただ、Scalaが黎明期だったということもあって、そういうことを大手を振って発言できないカルチャーではありました。なので、D社でScalaを採用しますと最初に表立って発言したのは僕かもしれないですが、それ以前にも隠密で実践している人達はいました（笑）</p>

<p>水島：ひっそりとですか（笑）</p>

<p>かとじゅん：今でこそ、非同期・ノンブロッキングで処理をしたいとなったら一つの選択肢としてScalaは有力候補になるのですが、当時はPHPでもメッセージキューを使えばできるだろうということを言われましたね…。</p>

<h3 id="">土壌がない状態でやるからには覚悟を決めて実践してました</h3>

<p>－－ 何もないさら地からScalaを導入したと言った感じでしょうか。</p>

<p>かとじゅん：最初はScalaの土壌が無い状態で導入を図っていたこともあってか、上司には"ほんとに大丈夫？"などと心配されるようなことがありました。まぁ、上司としては適正な振る舞いだと思います（笑）。そういった事情もあって、Javaアプリケーションだということだけを伝えて(ScalaコンパイラとJVMという分離された信頼性という担保があったから)、表立ってはScalaとは言わずに採用するということをしていました。「許可を求めるのなら謝罪しろ」ということではないですが、エンジニアが良いと思ったものを裁量で導入して、上手くいかなければ謝る覚悟を決めて実践していました。これを真似すればうまくいくとはいいませんが、技術的に裏打ちされた、現場の強い覚悟みたいなものがありましたね…。</p>

<p>－－ 一方で、チーム内での評判はいかがだったんでしょうか。</p>

<p>かとじゅん：チームメンバーの理解が得られやすいものという一定の基準は当然ありますね。実際に、メンバーには新しいものが好きな人が多くて、そもそも大学で関数型の研究をやってた人や<a href="https://ocaml.org/">OCaml</a>ができる人が自分の周りにいたので抵抗なくやっていました。たまに、なぜScalaは引数を型推論できないのかといったような内容の質問を受ると、困るので、「そういうのは水島さんに聞こう」と言って水島さんに質問したりしていました（笑） そういう意味では、無理なく浸透した感はありました。</p>

<p>－－ 水島さんは結構そういう質問を受けたりするんですか。</p>

<p>水島：そういうのはしょっちゅう聞かれていました（笑）引数の型推論の話について言えば、nominalとstructureのタイプの引数の推論について、OCamlの例などを挙げてモヒカンばりに突っ込んだりしていました。</p>

<h3 id="scala">最近では問題解決手法の一つとしてのScalaが段々と認知されてきたように感じます</h3>

<p><img src="https://tech.atware.co.jp/content/images/2016/12/scalainterviewvol8-1-2.jpeg" alt="Scala先駆者インタビュー 最終回 ChatWork かとじゅんさん 〜前編〜"></p>

<p>かとじゅん：さきほどモヒカンという言葉が出ましたが、当時は、社内勉強会に参加してくれていたモヒカン達が勉強会でモナドに代表される型クラスの話を普通にしていて、そういう話を聞いたScala入門者の人達がカルチャーショックを受けて良い刺激になる、というのが何回か繰り返されるのを見てきました。もちろん、実際にScalaを実践投入するならPlay Frameworkや<a href="https://github.com/twitter/finagle">Finagle</a>が良いといった実用的な面での情報交換もありました。ただ、単に仕事で使う言語というだけでなく、自分がもっと上手く扱うことができればコードの表現力を向上させることができると話す人達が結構いて、実用でありながら工学的なことも考えるというコミュニティーのカルチャーにはJavaコミュニティーには感じられなかった学ぶべき世界観があったと感じています。</p>

<p>水島：それもありますが、実用で使っている人でもScalaから何かを学び取ろうという感じで触っているというコミュニティーのカルチャーはあるかと思います。</p>

<p>かとじゅん：そうですね。実用もさることながら、Scalaを使って何かやってみよう、学びを得ようといった入り方は共通認識として通じていましたね。</p>

<p>－－ 関数型から何かを学びたい活かしたいという流れから、数年前に<a href="https://en.wikipedia.org/wiki/Functional_reactive_programming">Functional Reactive Programming(FRP)</a>というプログラミングモデルが話題になりましたよね。</p>

<p>かとじゅん：言わずもがな、FRPを学ぶには関数型プログラミングの知識は必要ですね。ChatWork社の大阪のメンバーも数年前からFunctional Programming in Scala(和訳版は<a href="http://amzn.to/2gHDSHD">Scala関数型デザイン&amp;プログラミング ― Scalazコントリビューターによる関数型徹底ガイド</a>)の勉強会を月1回のペースでやってます。色々な人が集まる中で、Haskellなどの関数型プログラミングに詳しい方からサポートを受けながら進めているそうです。</p>

<p>余談ですが、関数型はパラダイムが違うので難しいと言う人は多いですが、モダンなJavaScriptを書く人達は、高階関数なんて当たり前に使っているので、Scalaにも応用できる広い世界観を持っていると感じています。core.jsのインタフェースを見てるとmapやreduceは元々あって、Scalaに慣れている僕からするとすごくやりやすいです。ファーストクラスファンクションなカルチャーだから自然に慣れてしまうんだなと思いました。逆に、兼ねてからJavaを使っている人達からは、JavaSE 8で導入されたStream APIで記述されたコードを見ると何をやってるか分からないという、声も聞きいたりします。処理の効率性や宣言的な記述としては意味はあるんだろうけど、理解し難いというメンタリティーはあると思います。</p>

<p>ただ、Microsoftが.NET向けの<a href="https://github.com/Reactive-Extensions">Rx(Reactive Extensions)</a>を開発したきっかけで、.NETだけでなくJavaScriptをはじめ様々な言語に広まったことは有名ですが、Springも力を入れているようで<a href="http://www.reactive-streams.org/">Reactive Streams</a>のAPIに準拠した<a href="https://projectreactor.io/">Reactor</a>というプロダクトを開発しているようです。そういう意味ではリアクティブシステムに関連する話題が増えました。つまるところ、最近の、ハードウェア・ソフトウェアに関連するエコシステムの変化は、マーケットの要求に追従するためにそういう方向に向かっていることは間違いないと思っています。だた、コミュニティーとしては、そこまでのメンタリティーを持って追従している人は少数で、多くの人がまだまだこれからという印象があります。</p>

<p>水島：私にもそう見えます。</p>

<p>かとじゅん：サーバサイドをやってるJavaエンジニアからすると、JavaScriptはできるだけ避けるという考え方もあると思いますが、少し触ってみると新しい発見があるかもしれませんし、それによってScalaに対しても意外に悪くないなという印象はもってもらえるかもしれません。少し語弊がありますが「JavaScriptに型がついた言語でしょ？」という感じで、すんなりScalaを使えるようになったJavaScriptエンジニアを何人も知っています。 あ、誤解しないで欲しいのですが、Javaは素晴らしい言語だし、Scalaを学ぶのにJavaScriptを学ぶことが必須と言っているわけではなく、他のパラダイムにも触れることに意味があるって話です(笑）</p>

<p>僕がそうだったのですが、一つの言語で長く育ったエンジニアは、その言語によって価値観が固定化されやすい傾向にあると思っています。これは無理もないことですが、その前提で他の言語を見た時に違和感を覚えたりしますが、少しでも他の言語にも触れていくと、自分が普段使っている言語を違った視点で見ることもできます。エンジニアとして視野が広いということは、そのような多様な価値観を把握し、どういう使い方をすれば、役に立つか提案できることではないかと思っています。</p>

<p>水島：Springでも、Functional Web FrameworkというJava8のラムダに基づいたアノテーションベースでないものが出ていているので、そういう風がJavaにも来てるのかなと思います。</p>

<p>かとじゅん：Spring ReactorはFunctionalな感じがしますね。</p>

<p>水島：この辺りを見ると従来のSpringと世界観が違いますね。</p>

<p>かとじゅん：関数型プログラミングやリアクティブシステムなどの考え方がオブジェクト指向言語のなかでも問題解決の1つの手法として認知されてきたのかなと思います。</p>

<h3 id="scala">リアクティブシステムなどの文脈と絡めてScalaの知見がもっと広まると良い流れができそうです</h3>

<p>－－ リアクティブシステムをSIで適用しようとした場合に、今まではSpringベースでやっていたものをリアクティブシステムに変えるとなると壮大なプロジェクトになりそうですよね。逆に、規模が小さすぎるとメリットを活かしきれなさそうでもありますし、どういう風に導入していければ良いのかなと悩みがあります。それと、どうやって引き継いでいくといいのかという懸念があり、そんな中でも実践を重ねていきたい気持ちもあります。</p>

<p>かとじゅん：教育というところは確かに難しいですね。でも、メッセージパッシングやSupervisorだってErlang/OTPの歴史を紐解けば別段新しくはないですし、リアクティブシステムを構成する一つ一つの考え方(メッセージ駆動、耐障害性、弾力性、即応性)は昔からあったものですよね。ただ、コンセプトとして名前をつけて体系化して共通理解を得やすくなったのは割と最近になってからという気がします。エコシステムとして理解して実用できるまでが難しいって感じかもしれません。</p>

<p>－－ ひと言で言って分かりやすくマニフェスト風にまとめたリアクティブ宣言もそういう助けになっていますよね。</p>

<p><img src="https://tech.atware.co.jp/content/images/2016/12/scalainterviewvol8-1-3.jpeg" alt="Scala先駆者インタビュー 最終回 ChatWork かとじゅんさん 〜前編〜"></p>

<p>かとじゅん：Many Core時代と言われて久しいですが「サーバを跨いでコアを使い切りたい」「サーバのダウンタイムを限りなく0にしたい」「レスポンスタイムを限りなく短くしたい」「終わりのない大量データを効率的に処理したい」など、文脈に合わせて新しい価値観として作り上げたところに大きな意味があります。リアクティブ宣言のコンセプトに賛同している企業も多く、今後も少なからずITを通じていろいろな業界に影響を与えていくのではないかと思っています。そして、その道を最初に作った<a href="http://jonasboner.com/">Jonas Boner</a>さんはすごいなって思います。</p>

<p>－－ SIにもそういった流れが訪れて欲しいものです。</p>

<p>かとじゅん：SIの場合だと、リアクティブシステムを採用して事業的にも良いフィードバックを出せるのかもしれませんが、事業が成功するための変数は他にもあるので導入は簡単ではないですよね。ともすれば手段が目的化してしまうので。リアクティブシステムは考え方がガラッと変わるので、設計、運用面、人材確保など諸々難しい問題はありますね。先ほどおっしゃったように小さすぎる案件だとすぐ終わってしまうので、費用対効果が合わないという問題もありますね。まぁエンジニア個人としては素振りしておきたいというのはありますが、ビジネスとなるとKPIにインパクトを与えられないと難しいですね。</p>

<p>－－ ビジネスのことや運用上のことも考えて価値を出していくというのが大事なので、そういうような知見があるかどうかの差が大きいのかなと思います。</p>

<p>かとじゅん：そういう意味だと、Web業界で大規模なサービスをやってるドワンゴさんやLINEさんといったところが、<a href="http://akka.io/">Akka</a>や<a href="https://www.erlang.org/">Erlang</a>の実用経験を通して溜まった知見をコミュニティーの中でフィードバックしていければ、助けが得られて良い形で広がっていくのかなと思います。個人的にはTISさんに頑張ってもらいたいなという思いもあります。</p>

<p>水島：TISさんは実際にLightbendとパートナーシップを持ったり色々試行錯誤もされていますね。</p>

<p>かとじゅん：前出さんは最近<a href="https://www.transifex.com/akka-ja/akka-doc-ja_2_4_11/">akka.ioの日本語訳サイト</a>を立ち上げたので、そこにも段々と人が集まってきて、Akkaを使う人が増えていくのではないかと思っています。</p>

<p>－－ 前出さんが以前言われていたのは、TISさんだけでなく他の企業さんにも頑張ってもらうと、Scalaの導入障壁を下げることにも繋がると仰られていました。</p>

<p>かとじゅん：最近は、僕も利用者の裾野を広げるためにScalaと組み合わせてドメイン駆動設計(以下 DDD)やリアクティブの話をしているのですが、理解を深めてもらうための活動としてこれからもやっていきたいと思っています。</p>

<h3 id="">コンピュータリソースをフル活用するためのプログラミングモデルとは</h3>

<p>－－ 実際にそういう知見を共有していただける機会などは予定されているんでしょうか。</p>

<p>かとじゅん：仕事ではAkkaを使い込んでいるので、今まさに溜まっている知見をScala Matsuriの時期には共有できる見込みです。実際に、ビジネスロジックでもAkka Streamsで書いているので、プログラミングモデルが今までとは全く変わってしまうことを目の当たりにしています。これは個人的な興味の範囲ですが、PersistentActor(永続化可能なアクター)とActorの位置透過性を利用して、ドメインモデルや集約をどのノードに配置されていてもActorを利用できるようにすることで、スケールアップもスケールアウトも同じプログラミングモデルで実現できるようなシステムを作ってみたいと考えています。</p>

<p>－－ 6年ほど前に、「マルチコアをフル活用するためのプログラミングができる人でなければこの先生き残っていけないし、リソースをフル活用できないと未来はない。」といった話を丸山先生が言っていたのを聞いて衝撃を受けました。最近になってクラウドが台頭してきて、今まさに直面しているという状況ですよね。</p>

<p>かとじゅん：CPUリソースの面でいうと、マルチコア化以降では、単体のコアのクロック数が変わらないか、下がっていく傾向にあるので、それを意識しないプログラミングをしてしまうとスループットが下がるという問題に直結します。単一サーバでマルチコアをいかに使い切るかという話も当然ありますが、さらにサーバを跨いでコアをいくつ使えるかという視点に移っていると思います。CPUリソースの規模の指標が、今まではサーバ台数でしたが、今ではサーバを跨いだコア数に変わってきています。</p>

<p>水島：たとえばIntelのCore i7の性能を見ても、実は最新モデルの1コアあたりの処理性能はあまり伸びていないですよね。8コア16スレッドなど、コアが増える傾向にあるように見えます。</p>

<p>－－ AWSのインスタンスでも1TBのメモリを活用できるようになったので、メモリもCPUコアも増やせるようになりましたね。性能の良いインスタンスでスケールアップできて、性能がそこそこのインスタンスもスケールアウトが出来るので、コアやリソースを使い切るというところがコストに響いてきてお客さんに提供出来る価値にも影響してくるのかなと思います。</p>

<p>かとじゅん：そうですね。スケール戦略を実現する実装手段はいろいろありますが、その1つであるアクターモデルで考えるならば、今までメソッドベースでやってた人達が、アクターが持つ、Fire-and-Forgetのカルチャーに馴染むことができるか否かがポイントになります。</p>

<p>水島：語弊があるかもしれませんが、Javaの視点のまま学んでしまうと途中でつまづくところがあるかもしれないです。</p>

<p>かとじゅん：必ずしもそうではないですが、つまずく傾向にはあるかと思います。</p>

<p>そういう意味では、非同期に処理すると一口にいっても、Promise(Future)、Actor、Reactive Streamsなどの複数の選択肢がありますね。それぞれの目的と向き不向きを実際に試しながら理解することが必要だと思います。</p>

<p>－－ 常にいろんなものを触ってみたり新しいことを身につけていくということが大切ということでしょうか。</p>

<p>かとじゅん：新しいものでも古いものでも、そういうスタンスに違いはないと思います。複数の選択肢があると目的に合わせて選ぶのが難しい側面がありますが、解決方法は解く問題に合わせて選ぶことが大切ですね。エンジニアの基本的なスタンスとして必要じゃないかと。まぁ、これはScalaに限った話ではなく、どの言語でも共通であって、そこで思考停止しない方がよいという意味になると思います。</p>

<h3 id="chatworkakka">ChatWork社では常に新しいことをやらせてもらっていて最近はAkkaと戯れる日々です</h3>

<p>水島：現在の話になりますが、ChatWork社での、かとじゅんさんはどんな感じで日々過ごされているのでしょうか。</p>

<p><img src="https://tech.atware.co.jp/content/images/2016/12/scalainterviewvol8-1-4.jpeg" alt="Scala先駆者インタビュー 最終回 ChatWork かとじゅんさん 〜前編〜"></p>

<p>かとじゅん：まだ、あまり具体的なことは話せないのですが、ChatWork社での役割は次のプロダクトの開発で、現行の開発には関わっていないです。言うまでもなくScalaは使っていますが、そこそこ大きいサービスになってきたこともあって問題解決の手法も変わってきました。なので、メッセージ基盤として、ストレージはHBaseを使いながら、アプリケーションはAkkaのActorベースでやっています。前職ではFinagleを利用していたのですが、他と違ってAkkaの良いところはErlang/OTP由来のSupervisionがあるところです。Actorヒエラルキーの下位層のActorが障害を起こしても、上の監督者としてのActor(Supervisor)がそれらを管理することでリカバリもしやすくなる利点があります。耐障害性という面では魅力的な機構だと思っています。</p>

<p>－－ レジリエンスのような話でしょうか。</p>

<p>かとじゅん： レジリエンスは回復力とか治癒力などという意味ですね。先ほども簡単に説明したように、下位層のActorで起きた障害はSuprvisorに通知され、必要に応じて再起動・停止・さらに親のSupervisorにエスカレートすることができます。例えば、子アクターでネットワークやディスクなどのIO例外が発生した場合は、起きた例外をSupervisorに通知し、Supervisorが子アクターに再起動を命じます。そうすると子アクターは破棄され、再び起動(リトライ)できるようになります。これは、障害が起きた部分を正常な部分から隔離するという可用性に優れた考え方で、let-it-crashとも呼ばれています。</p>

<p>無論、要件に応じて、無限にリトライしないようにもできますし、<a href="http://doc.akka.io/docs/akka/2.4.14/general/supervision.html#Delayed_restarts_with_the_BackoffSupervisor_pattern">BackoffSupervisor</a>を利用することで指数関数的にリトライまでの待ち時間を調整し、タイトなリトライループを回避して、過度な負荷がDBやネットワークなどにかからないようにすることもできます。</p>

<p>蛇足ですが、この際、アクターのインスタンスは入れ替わりますが、その参照であるActorRefは同じ値を示します。これはなかなかすごいことですが、プログラミング言語の標準機能で同様の実装をするのは骨が折れますが、Actor Systemの恩恵にあずかることで僕らエンジニアは本題に集中できるようになります。</p>

<p>今は実戦でやりきるだけのノウハウを溜めているところで、自らフィードバックできれば良いかなと思っています。話が少しそれましたが、僕の役割は次の事業の基盤になるような開発をすることです。</p>

<p>－－ 普段は開発もこなしつつまとめ役のようなポジションでお仕事されているのですか。</p>

<p>かとじゅん：マネージャーやリーダーなど、チームをまとめる立場の人は別にいます。基本的にはチームで作業していて、その中でも僕は毎日Akkaと戯れているという感じです（笑）日々、Actorヒエラルキーをどう設計するかといったような会話をチームメンバーとしています。</p>

<p>ここから話が少し変わってしまいますが、個人的にもAkka Streamsが好きなので、個人活動としてRedisクライアントを題材に「車輪の再発明」をしてます。</p>

<p>Akka Streamsを知らない人に簡単にまず前提をお話すると、Akka Streamsではストリームの上流でデータを提供するSourceと、下流でデータを消費するSinkというAPIが提供されています。例えば、Sourceは、Source#singleで単一の値を取ったり、Source#applyでコレクションを取ったり、Source#fromFutureでFutureのインスタンスを取ったりできます。また、SinkはSink#foreachであったり、Sink#reduceなどがあります。これらを結合すると、ストリームとしての実行可能なRunnableGraphというオブジェクトが手に入ります。そして、RunnableGraph#runメソッドを実行するとストリームを実行できますが、SourceやSinkが実行中に内部で持つマテリアライズド・バリュー(以下 MVと略す)という値を取得することができます。</p>

<p>あまり内部がどのような仕組みで動いているか細かく説明しませんが、たとえば、数列を合計するようなストリーム処理は以下のようになります。</p>

<pre><code class="language-scala">implicit val system = ActorSystem("myActorSystem")  
implicit val actorMaterializer = ActorMaterializer()  
// コレクションとして値を持つSource。MVはNotUsed。つまり使わない。
val source: Source[Int, NotUsed] = Source(1 to 10)  
// ストリームデータをReduceするSink。MVはFuture[Int]
val sink: Sink[Int, Future[Int]] = Sink.reduce[Int](_ + _)  
// 実行可能なグラフを生成。Keep.rightはストリームの右側にあるSinkが実行時に持つMVを取得することを意味する。
// Keep.leftはSourceのMVだがNotUsedなので取得しても意味がない。
val runnableGraph: RunnableGraph[Future[Int]] = source.toMat(sink)(Keep.right)  
// 実行可能なグラフを実行すると指定したMVのインスタンスが取得できる。
val future: Future[Int] = runnableGraph.run()  
// MVからSinkが得た計算結果を得る。
val value = Await.result(future, Duration.Inf)  
println(value)  
</code></pre>

<p>また、以下のようにActorをSourceとして利用するストリームも作れます。少し難しく見えますが、実行すると前述と同じ計算結果になります。ストリームのデータサイズが固定できない場合や、アクターをインターフェイスにしたい場合などに役に立ちます。</p>

<pre><code class="language-scala">// グラフを構築・実行し、Source.actorRefのMVであるActorRefとSinkのMVであるFutureを取得する。
val (actorRef, future) = Source.actorRef[Int](Int.MaxValue, OverflowStrategy.fail)  
  .toMat(Sink.reduce[Int](_ + _))(Keep.both).run()
// SourceとしてのActorRefを使ってストリームにデータを流す
for {n &lt;- 1 to 10} {  
  actorRef ! n
}
// ストリームの完了を通知する。
actorRef ! Status.Success(1)  
// SinkのMVから結果を取得する。
val value = Await.result(future, Duration.Inf)  
println(value)  
</code></pre>

<p>さらに、ちょっとコードが長いですが、以下のように、このグラフをアクター内部で構築・実行することも可能です(サンプルコードなので、Supervisionは考慮していません)。 Akka StreamのTcpにはoutgoingConnectionというFlowを返すAPIがあって、これを使うと非同期・ノンブロッキングI/Oができるので、これを使ってRedisクライアントを作って遊んでいます。</p>

<p>ちなみに、Flowは、Source, Sinkに並ぶコンポーネントで、上流から受け取った値に何かを行って下流に流すことができます。また、FlowをSourceに結合するとSourceに、Sinkに結合するとSinkになる特徴を持っています。なので、Source -> Flow -> Sinkのようなグラフを作ることができます。以下の例では、リクエストとしてByteStringを流すとレスポンスとしてByteStringが返ってくる Source -> Flow -> Sink なグラフを作っています。</p>

<pre><code class="language-scala">class ClientActor(remoteAddress: InetSocketAddress) extends Actor {  
  // requestIdとsenderを紐づける
  private def putSender(requestId: Long, sender: ActorRef): Unit = ???
  // requestIdからsenderを取得する
  private def getSender(requestId: Long): ActorRef = ???
  // Source#actorRef
  private val sourceActorRef: Source[(Long, ByteString), ActorRef] =
    Source.actorRef[(Long, ByteString)](Int.MaxValue, OverflowStrategy.fail)
  // RedisにTCPで接続するフロー
  private val tcpFlow: Flow[ByteString, ByteString, Future[OutgoingConnection]] =
    Tcp().outgoingConnection(remoteAddress)
  // Sink#foreach
  private val sinkForeach: Sink[(ByteString, Long), Future[Done]] =
    Sink.foreach[(ByteString, Long)](responseWithRequestId =&gt; self ! responseWithRequestId)
  // 内部でtcpFlowを使うが、(requestId, request) -&gt; (response, requestId)にするFlow
  private val connectionFlow: Flow[(Long, ByteString), (ByteString, Long), NotUsed] =
    Flow.fromGraph(GraphDSL.create() { implicit b =&gt;
      import GraphDSL.Implicits._
      val requestFlow = b.add(Flow[(Long, ByteString)].map {
        case (requestId, request) =&gt; (request.concat(ByteString("\r\n")), requestId)
      })
      val unzip = b.add(Unzip[ByteString, Long]())
      val zip = b.add(Zip[ByteString, Long]())
      requestFlow.out ~&gt; unzip.in
      unzip.out0 ~&gt; tcpFlow ~&gt; zip.in0 // request -&gt; response
      unzip.out1 ~&gt; zip.in1 // requestId をそのまま引き継ぐ
      FlowShape(requestFlow.in, zip.out)
    })
  // ストリームの構築・実行
  private val internalClientRef: ActorRef = sourceActorRef
    .via(connectionFlow)
    .toMat(sinkForeach)(Keep.left)
    .run()

  override def receive: Receive = {
    case (requestId: Long, request: String) =&gt;
      putSender(requestId, sender())
      internalClientRef ! (requestId, ByteString.fromString(request))
    case (response: ByteString, requestId: Long) =&gt;
      getSender(requestId) ! (requestId, response.toString())
  }
}
</code></pre>

<p>－－ その素振りは面白いですね。</p>

<p>これは、Akka Streamsの勉強をするために作っているので、実用では既に存在するOSSなどを使えば良いと思います。それなりに使い込まないと自分で理解できないので、大事かなと思ってひたすらAkka StreamsとActorを使いこんでいます。あとは、最近あまり参加できていないのですが、、、Akka in Actionの読書会を開いてもらったり、<a href="http://amzn.to/2gvl3Ik">Reactive Messaging Patterns with the Actor Models</a>の読書会に参加したりしています。Akka StreamsのActorMaterializer(RunnableGraphをActor上で実行可能にするオブジェクト)の詳細な説明や、コードを読むときの糸口になるようなヒントが書いてあるので、見ておくとコードも書きやすくなるかなと思います。</p>

<p>というか、ほとんど仕事の話をしていませんね(笑)。詳しくはまた時期をみてということで。ChatWork社では常に新しいことをやっています、って感じです。</p>

<p>－－ ズバリ、楽しいですか。</p>

<p>かとじゅん：これで楽しくないと言ったら怒られてしまいますね（笑）実際楽しくやらせてもらっています。Scala化するという宣言をしてから暫くリリース物が出ていませんが、結果を出すまでは絶対にやらないといけないので最後までやり通したいなと思います。</p>

<h3 id="">出席者</h3>

<ul>
<li>インタビューイー ChatWork株式会社 かとじゅんさん</li>
<li>インタビューワー アットウェア 浅野・三嶋、 株式会社ドワンゴ／一般社団法人Japan Scala Association 水島さん</li>
</ul>

<p><a href="https://tech.atware.co.jp/scalainterview-vol8-2/">後編へ続く...</a></p>

<nav class="navigation post-navigation">  
  <div class="nav-links">
    <div class="nav-next">
      <a href="https://tech.atware.co.jp/scalainterview-vol8-2/">> 最終回 ChatWork かとじゅんさん 後編</a>
    </div>
    <div class="nav-previous">
      <a href="https://tech.atware.co.jp/scalainterview-vol7/">> Vol.7 ドワンゴ 水島さん</a>
    </div>
  </div>
</nav>]]></content:encoded></item><item><title><![CDATA[標準地域メッシュ・システム]]></title><description><![CDATA[<p>地図を扱うシステムにおいて度々登場する地域メッシュ。そのコードや名称に疑問を持つ方も多いのではないでしょうか？ 今回、いろいろと調べてみて分かったことをまとめました。</p>

<h3 id="">標準地域メッシュ・システム</h3>

<p>日本全国を格子状の区画（メッシュ）にわけて、それぞれに一意なコード（メッシュコード）を振って区別する仕組みがあります。</p>

<p><a href="http://www.stat.go.jp/data/mesh/gaiyou.htm">http://www.stat.go.jp/data/mesh/gaiyou.htm</a></p>

<p>元々は国土がどのような用途で使われているかの統計データの単位として使うために作られたもののようです。</p>

<p>政府のデータがこのメッシュの単位で定義されていることが多いため、それらを利用するためには必然的にこれを理解する必要があります。（たとえば「アメダスのメッシュデータ」とか。）
政府そのものが出すデータではなくても、それと親和性の高いデータはやはりこのメッシュが使われていたりします。</p>

<p>基準地域メッシュは3段階で計算されます。</p>

<h3 id="">一次メッシュ</h3>

<p>一次メッシュは4桁のコードで表されます。
先頭2桁が緯度から計算され、残り2桁が経度から計算されます。
ここでいう「緯度/経度」は平成14年を境に測地系自体が変化している（※「補足：測地系について」参照）ので、それ以前の情報と混合する際には変換が必要になります。
（一次メッシュのレベルでは殆ど差異がありませんが、この先もっと細かいメッシュでは差が大きくなります）</p>

<ul>
<li>緯度（北緯）×1.5（小数点以下切り捨て）</li></ul>]]></description><link>https://tech.atware.co.jp/mesh-system/</link><guid isPermaLink="false">ac3c1844-3ee3-4489-9cfe-bf7c1d9c71ca</guid><dc:creator><![CDATA[<§3 ｲﾅｪｹｹ]]></dc:creator><pubDate>Mon, 14 Nov 2016 00:57:10 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2016/10/gmap.png" medium="image"/><content:encoded><![CDATA[<img src="http://tech.atware.co.jp/content/images/2016/10/gmap.png" alt="標準地域メッシュ・システム"><p>地図を扱うシステムにおいて度々登場する地域メッシュ。そのコードや名称に疑問を持つ方も多いのではないでしょうか？ 今回、いろいろと調べてみて分かったことをまとめました。</p>

<h3 id="">標準地域メッシュ・システム</h3>

<p>日本全国を格子状の区画（メッシュ）にわけて、それぞれに一意なコード（メッシュコード）を振って区別する仕組みがあります。</p>

<p><a href="http://www.stat.go.jp/data/mesh/gaiyou.htm">http://www.stat.go.jp/data/mesh/gaiyou.htm</a></p>

<p>元々は国土がどのような用途で使われているかの統計データの単位として使うために作られたもののようです。</p>

<p>政府のデータがこのメッシュの単位で定義されていることが多いため、それらを利用するためには必然的にこれを理解する必要があります。（たとえば「アメダスのメッシュデータ」とか。）
政府そのものが出すデータではなくても、それと親和性の高いデータはやはりこのメッシュが使われていたりします。</p>

<p>基準地域メッシュは3段階で計算されます。</p>

<h3 id="">一次メッシュ</h3>

<p>一次メッシュは4桁のコードで表されます。
先頭2桁が緯度から計算され、残り2桁が経度から計算されます。
ここでいう「緯度/経度」は平成14年を境に測地系自体が変化している（※「補足：測地系について」参照）ので、それ以前の情報と混合する際には変換が必要になります。
（一次メッシュのレベルでは殆ど差異がありませんが、この先もっと細かいメッシュでは差が大きくなります）</p>

<ul>
<li>緯度（北緯）×1.5（小数点以下切り捨て）</li>
<li>経度（東経）－100（小数点以下切り捨て）</li>
</ul>

<p>絵にするとこんな感じです。</p>

<p><img src="https://tech.atware.co.jp/content/images/2016/10/mesh.png" alt="標準地域メッシュ・システム">
<em>（この地図はあくまでイメージで正確ではありません。便宜上、海上にもコードを書いていますが、国土がないところにはコードが（たぶん）割り当たっていません。）</em></p>

<ul>
<li>最南：沖ノ鳥島 → 3036</li>
<li>最北：弁天島 → 6841 または択捉島 6848</li>
<li>最西：与那国島 → 3622</li>
<li>最東：南鳥島 → 3653</li>
</ul>

<p>というわけで、日本の国土が 3022～6853 の範囲に入ります。</p>

<p>北緯を1.5倍するのは、日本の位置する中緯度（40度前後）における東西方向の地球円周が緯度方向の円周と比べて小さくなっているのを、比較的単純な方法で近づけることができるから（そして常に2桁の範囲に収められる）。<br>
コードの算出方法からわかるように、日本の国土を固定長で表せるように特化しているので、外国では使えません。（グローバルなサービスでは使えません）</p>

<p>メッシュの1区画はおおよそ80km四方です。この「おおよそ」というのはかなりアバウトな指標であって、実際には南北方向は1割近く短く、東西方向は1割以上長い、つまり南北と東西では2割以上の差がある長方形です。この比は南方のメッシュほど激しくなります。</p>

<p>たとえば、弊社・横浜本社のある、みなとみらいセンタービルの属する一次メッシュのメッシュコードは「5339」です。これは東京都のほぼ全域（離島及び奥多摩の奥の奥を除く）と神奈川県の大部分（三浦半島や小田原市、相模湾沿岸を除く）が入った、おそらく一番人口の多いメッシュです。</p>

<h3 id="">二次メッシュ</h3>

<p>二次メッシュは、一次メッシュの1区画を、東西南北それぞれ8等分して64分割したものです。
以下の図のように南西の角を始点に00～77の2桁（それぞれの桁は緯度方向/経度方向の0始まりの連番）を、一次メッシュのコードの後ろに続けます。（計6桁）</p>

<p><img src="https://tech.atware.co.jp/content/images/2016/10/mesh-2.png" alt="標準地域メッシュ・システム"></p>

<p>一次メッシュがおおよそ80km四方だったので、二次メッシュはおおよそ10km四方です。</p>

<p>たとえば、みなとみらいセンタービルの属する二次メッシュのメッシュコードは「5339-15」です。
みなとみらい地区全体の他、横浜市中区の大部分、神奈川区の東半分、鶴見区の沿岸地域、川崎区もちょっと、同じメッシュに入ります。
コード中のハイフンは分かりやすさのために入れていますが、ISBNなどと同様、データとしてもらう場合は入ってないことが多いと思います。</p>

<h3 id="">三次メッシュ ＝ 基準地域メッシュ</h3>

<p>三次メッシュは、二次メッシュを更に、今度は東西南北10等分します。00～99の2桁で表せるのでこれをまたコードに追加します。</p>

<p><img src="https://tech.atware.co.jp/content/images/2016/10/mesh-3.png" alt="標準地域メッシュ・システム"></p>

<p>これで、コードは計8桁。各区画はおおよそ1km四方ということになります。
三次メッシュとも言いますが、これが「基準」という扱いになります。</p>

<p>たとえば、みなとみらいセンタービルの属する基準地域メッシュのメッシュコードは「5339-15-40」です。
末尾の0が示すのは、二次メッシュの「5339-15」の中では最も西寄りの部分に属していた、ということです。
北東はインターコンチネンタルホテル（半月形のホテル）から、南西は当社が毎年新年のご祈祷でお世話になる伊勢山皇大神宮あたりまでが同じメッシュです。</p>

<p>分かりやすい地図サイトがあったのでご紹介します。<br>
<a href="http://minorua.github.io/gmaps/mesh/#5339-15-40">http://minorua.github.io/gmaps/mesh/#5339-15-40</a></p>

<h3 id="121418">分割地域メッシュ：1/2地域メッシュ、1/4地域メッシュ、1/8地域メッシュ</h3>

<p>基準地域メッシュを 東西南北2等分して4分割し、以下のように振られた1～4の1桁を追加すると 1/2地域メッシュになります。コードは計9桁になります。</p>

<p><img src="https://tech.atware.co.jp/content/images/2016/10/mesh-4.png" alt="標準地域メッシュ・システム"></p>

<p>せめて 0～3（2進数的に表せば00～11）だったりすると少し幸せだった気がするのですが、こういう振られ方をしてしまいました。</p>

<p>そして、1/2地域メッシュを更に同じ方式で4分割すると 1/4地域メッシュ（コードは10桁）、それを更に4等分で1/8地域メッシュ（コードは11桁）です。
それぞれおおよそ500m四方、おおよそ250m四方、おおよそ125m四方ということになります。</p>

<p>たとえば、みなとみらいセンタービルの属する1/8地域メッシュのメッシュコードは「5339-15-40-4-3-4」あたりです。ちょっと「5339-15-40-4-3-3」にもかかってるかもしれません、特にアットウェアのオフィスは西側の角なので（4が北東、3が北西）。</p>

<h3 id="2510">統合地域メッシュ：2倍地域メッシュ、5倍地域メッシュ、10倍地域メッシュ</h3>

<p>基準地域メッシュから見て、今度は大きくなります。
とは言いつつも、実際には基準地域メッシュからではなく二次メッシュを、三次メッシュに進むときと違う分割サイズで分割することになります。</p>

<p>二次メッシュを東西南北10等分で三次メッシュだったので、2倍は東西南北5等分、5倍は東西南北2等分、10倍は・・・二次メッシュそのものです。（必要性が不明ですが）</p>

<p>2倍メッシュは非常にややこしく、基準地域メッシュ同等の10分割をしたうえで、奇数の場合は1引いて偶数にするという分割です。</p>

<p><img src="https://tech.atware.co.jp/content/images/2016/10/mesh-5.png" alt="標準地域メッシュ・システム">
<em>（5等分して0, 2, 4, 6, 8を振ったと考えることもできます。）</em></p>

<p>しかも、この方法だとそのままでは基準地域メッシュのコード体系と被る（基準地域メッシュでたまたま偶数コードだったのか、2倍メッシュだから偶数なのか区別できない）ということで、さらに末尾に固定で「5」を追加します。
6桁+2桁+1桁の9桁。今度は1/2メッシュと同じ桁数ですが、1/2メッシュの9桁目は1～4しか入らないはずなので区別できます（苦肉の策？）。基準地域メッシュより粗いのに、コードは長くなってます。おおよそ2km四方になります。</p>

<p>5倍メッシュは分割地域と同じルールで二次メッシュを分割して1〜4の1桁を追加するので二次メッシュの6桁+1桁の7桁です。おおよそ5km四方。</p>

<p>2倍メッシュから5倍メッシュに変換しようとすると、真ん中の「44」は5倍メッシュの「1～4」それぞれに分割吸収されるというイレギュラーケースが発生。。。4XやX4も2つに割られます。2倍と5倍は親子関係がありません。</p>

<p>10倍は・・・何も足さない。何も引かない。二次メッシュのコードそのままです。単なる二次メッシュの別名と考えられます。</p>

<h3 id="">細分メッシュ</h3>

<p>標準地域メッシュ・システムには直接は含まれませんが、派生したメッシュです。
「国土交通省　国土数値情報」として出してます。（標準地域メッシュ・システム自体は「国土地理院　基盤地図情報」）
土地利用細分メッシュとか1/10細分区画とかとも言います。おおよそ100m四方なので100mメッシュとも言われます。</p>

<p>1/2地域メッシュ、1/4地域メッシュ、1/8地域メッシュの効率の悪い（※個人的感想です）細分化を無視して、基準地域メッシュを改めて東西南北10等分します。二次メッシュから三次メッシュへの分割と同じです。 <br>
基準地域メッシュの8桁に00～99の2桁を追加するので計10桁です。</p>

<p>1/4地域メッシュと同じ桁数かつ、コード値の範囲も重複しており、ハイフンを入れていれば区別はできますが・・・そうでなければコード値自体からは区別不能です。（下2桁に0や5以上の数字が入っていれば確実に細分メッシュだとわかりますが。） <br>
また、2倍メッシュと5倍メッシュの関係以上に、細分メッシュと1/4・1/8地域メッシュとの変換は醜いものとなるでしょう。。。</p>

<h3 id="">その他のメッシュ</h3>

<p>時代が進んでどんどん精密な分割が必要になったためか、10mメッシュ5mメッシュといったメッシュもあるようです。
コード体系は確認していませんが、たぶん細分メッシュを更に東西南北10等分→さらに東西南北2等分なので、それに沿ったコード体系だろうと思います。</p>

<p>以上、地域メッシュに関する説明でした。複雑なルールの理解の一助になればと思います。</p>

<hr>

<h3 id="">補足：測地系について</h3>

<p>測地系（≒座標系＋楕円体の定義）によって同じ緯度経度でも差が生まれます。
現在地（GPS）の緯度経度⇔地図⇔施設情報の緯度経度 の3者の測位系の互換に注意する必要があります。</p>

<h5 id="">日本測地系</h5>

<p>明治初期から平成14年3月まで使われていた。
地球を「ベッセル楕円体」という回転楕円体に見立てて測定する。
ベッセル楕円体は特にユーラシア大陸において良い精度の出るモデルだったので、ヨーロッパ・アジアで良く採用された。（ユーラシア大陸での精度を優先して実際の地球とのズレがソコソコあることに目をつぶった？）
ゆえにアメリカで発展したGPSによる測地に使われる系（後述）とは差が大きく、相互の利用には補正が必要になる。
英語で呼ぶときは「Tokyo Datum」、コードは「TOKYO」とか「TKY」とか。（日本と名付きながらTOKYO）</p>

<h5 id="">世界測地系</h5>

<p>名前から「世界標準」と勘違いしそうになるが、「世界標準的なものと互換の高い、日本における測地ルール」を日本の法律でそう呼んでいる。
（業界的には、同じく世界標準的なものと互換性の高い諸外国の測地ルールのことも世界測地系と呼んだりする模様だが、ここでは「日本における」ものを指すこととする）
英語では「Japanese Geodetic Datum」と呼ぶ。（世界と名付きながらJapan）
地球の形の扱いが Geodetic Reference System 1980（GRS80）という定義（定数群）の中で定められた楕円体に変更された。
加えて、原点や緯度経度の定義もITRF座標系という定義を使うようになった。</p>

<p>JGD2000とJGD2011があり、JGD2011は東日本大震災における東日本付近の地殻変動を加味したものになる。これは、モデルが変わったのではなく地面のほうが動いたのであって、</p>

<ul>
<li>JGD2000：「大震災 前 に作った地図、大震災 前 に取得した位置情報」</li>
<li>JGD2011：「大震災 後 に作った地図、大震災 後 に取得した位置情報」</li>
</ul>

<p>という意味合いの違いである。
東日本大震災以外の地殻変動も含め、国土地理院の <a href="http://vldb.gsi.go.jp/sokuchi/patchjgd/main.html">PatchJGD</a> で地殻変動前後の位置関係の変換を行うことができる。
ITRF自体も何度か改訂されているがパラメータの細かな調整であり、一般人レベルでは殆ど気にしなくて良さそうだ。</p>

<h5 id="worldgeodeticsystem1984wgs84">World Geodetic System 1984（WGS84）</h5>

<p>アメリカにおける標準、GPSでの測地に用いられる系。
座標系の定義も楕円体の定義も、世界測地系で使われるITRF/GRS80と微妙に違うものの、基本的な構造は同じであり、計算結果もミリやセンチレベルの誤差しかないので一般に利用する地図アプリ程度であれば相互の利用に支障はない。
1984以降に何度か改訂が入っているが名称は変わらない。改訂のたびに ITRF/GRS80 とパラメータが近づいて差が小さくなってきているらしい。</p>

<h5 id="">余談</h5>

<p>昔、地図がらみの機能を作るときにはこの「測地系の違い」でずいぶん面倒なイメージがありましたが、今どきのデータは基本的には世界測地系なので、よほど古いデータを引っ張ってこない限りは気にしなくてよさそうです。
一方で、大震災により測地系ではなく地面そのものが変化してしまったというのが衝撃的ですね。</p>]]></content:encoded></item><item><title><![CDATA[IaCをやって感じた心理的作用が開発チームにあたえる影響]]></title><description><![CDATA[<p>Infrastructure as code（IaC）で、Immutable Infrastructureな構成にした際に、色々と恩恵を受けてよかったことがあったので、「責任」と「心理的負担」という視点で感じたことと、使ったツール群や仕組みを紹介したいと思います。</p>

<h2 id="">責任の所在</h2>

<p>プロジェクトチームの役割や責務とはなんでしょうか。</p>

<p>私たち開発者はプロダクトの出荷時に品質に対して責任を持つ必要があると考えています。
これは自社サービスでも他社へ納品するものでも同じですね。</p>

<p>製品に責任を持っている人（ここではプロダクトオーナーと呼びます）は開発チームを信頼してプロダクト設計から出荷まで任せています。</p>

<p>品質を保証する中の必要な要素として、今回はテストという観点で責任について触れてみたいと思います。</p>

<p>テストでは設計や手順どおりに実現されているか、デグレーションが発生していないかを確認します。プロダクトは1度きりの納品や検証で終わることはありません。プロダクトは継続的に開発され、回帰テストが必要になります。この回帰テストを1回実施することにどれくらいコストがかかるか、どのような範囲をカバーできるかが、プロダクト開発を駆動していくうえで重要なキーとなります。</p>

<p>この、プロダクトを出荷するルーチンワークの中で、プロダクトオーナーに機能や変更点のレビュー説明以外の「言われなくてもやっている」という前提事項が信頼関係の目では見えづらい責任分岐点のひとつではないかと考えています。</p>

<p>信頼関係が良好という状況がベースにあると、やる気も自然にでてきます。</p>

<h2 id="">開発チームの気持ち</h2>

<p>開発チームのメンバーは何度も同じことをやる場合には、スクリプト化や手順化をします。
そして、ミスを見過ごさない為にペアワークや実施後のチェックも行います。</p>

<p>ただ、いくら手順化やスクリプト化してあっても人間はミスするものです。
この「ミスをしてはいけない」という心理的負担はかなりのもので、時間がない時には通常時とは比べられないくらいに心理的な負荷やストレスがかかります。</p>

<p>こういう背景もあって、何度やっても同じ結果になる自動テストやImmutable</p>]]></description><link>https://tech.atware.co.jp/think-immutable-infrastructure/</link><guid isPermaLink="false">253f3717-9bfa-4050-80c9-0fcdc4cee043</guid><category><![CDATA[AWS]]></category><category><![CDATA[Technologies]]></category><dc:creator><![CDATA[asano]]></dc:creator><pubDate>Thu, 10 Nov 2016 01:25:14 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2016/11/IaC.png" medium="image"/><content:encoded><![CDATA[<img src="http://tech.atware.co.jp/content/images/2016/11/IaC.png" alt="IaCをやって感じた心理的作用が開発チームにあたえる影響"><p>Infrastructure as code（IaC）で、Immutable Infrastructureな構成にした際に、色々と恩恵を受けてよかったことがあったので、「責任」と「心理的負担」という視点で感じたことと、使ったツール群や仕組みを紹介したいと思います。</p>

<h2 id="">責任の所在</h2>

<p>プロジェクトチームの役割や責務とはなんでしょうか。</p>

<p>私たち開発者はプロダクトの出荷時に品質に対して責任を持つ必要があると考えています。
これは自社サービスでも他社へ納品するものでも同じですね。</p>

<p>製品に責任を持っている人（ここではプロダクトオーナーと呼びます）は開発チームを信頼してプロダクト設計から出荷まで任せています。</p>

<p>品質を保証する中の必要な要素として、今回はテストという観点で責任について触れてみたいと思います。</p>

<p>テストでは設計や手順どおりに実現されているか、デグレーションが発生していないかを確認します。プロダクトは1度きりの納品や検証で終わることはありません。プロダクトは継続的に開発され、回帰テストが必要になります。この回帰テストを1回実施することにどれくらいコストがかかるか、どのような範囲をカバーできるかが、プロダクト開発を駆動していくうえで重要なキーとなります。</p>

<p>この、プロダクトを出荷するルーチンワークの中で、プロダクトオーナーに機能や変更点のレビュー説明以外の「言われなくてもやっている」という前提事項が信頼関係の目では見えづらい責任分岐点のひとつではないかと考えています。</p>

<p>信頼関係が良好という状況がベースにあると、やる気も自然にでてきます。</p>

<h2 id="">開発チームの気持ち</h2>

<p>開発チームのメンバーは何度も同じことをやる場合には、スクリプト化や手順化をします。
そして、ミスを見過ごさない為にペアワークや実施後のチェックも行います。</p>

<p>ただ、いくら手順化やスクリプト化してあっても人間はミスするものです。
この「ミスをしてはいけない」という心理的負担はかなりのもので、時間がない時には通常時とは比べられないくらいに心理的な負荷やストレスがかかります。</p>

<p>こういう背景もあって、何度やっても同じ結果になる自動テストやImmutable Infrastructureは心配事から解放できる一因になることから、生産性をあげるという以外の理由として実現を望まれます。</p>

<h2 id="">同じノウハウを使い回したい</h2>

<p>技術は日進月歩で新しくなり、導入をしていきたいのですが、同じ仕組みで横展開して複数プロジェクトで使えれば、初動からのリズムを掴みやすかったり、ワークフローを確立しやすくコストにも影響してきます。</p>

<p>また、SIをやっているとお客様によって背景や事情もあり、導入する環境やソリューションが異なることがあります。現在は、クラウド環境を採用するメリットが高くAWSを前提に考えることが多いのですが、時にはAPIを持っているプライベートクラウドや別クラウドベンダーの環境を提案したり、利用することもあります。</p>

<p>その場合には、特定ベンダーに特化しているライブラリより汎用的に使える方が、柔軟性という意味ではうれしいです。
そこで、私が使った、Immutable Infrastructureを実現する為のツールとやりかたを紹介します。</p>

<h2 id="">構成イメージ</h2>

<p><img src="https://tech.atware.co.jp/content/images/2016/10/network-image.png" alt="IaCをやって感じた心理的作用が開発チームにあたえる影響"></p>

<h3 id="">オーケストレーションツール</h3>

<p>Code実行により環境毎の構成を起動・設定します。 <br>
DryRunやPlugabbleな仕組みを持っており、現時点でマルチクラウドに対応している<a href="https://www.terraform.io/">Terraform</a>がお勧めです。</p>

<p>Immutable Infrastructureのように環境を複製して構築するようなケースでは、採用すると時間的にも心理的にも負担が減ります。</p>

<p>また、環境を削除する時にも、構築し際動的に割り当てられたリソース情報をTerraform実行後に生成されるTFファイルで保持しているので、一括削除が可能です。
ロードバランサなど特定のリソースだけ削除し忘れるようなケースも防げるので、説明責任として、事後報告するケース時の後ろめたい気持ちや、お金を無駄にしてしまったことによる「これ防げたらチームにお菓子を配れたのに」というような気持ちを抱かなくてもよくなりますね。</p>

<h3 id="">プロビジョニングツール</h3>

<p>Chef、Puppet、Itamaeなどがあります。 <br>
私は<a href="https://docs.ansible.com/ansible/index.html">Ansbile</a>というAgentレスのプロビジョニングツールを利用しています。</p>

<p>Code実行により環境に対してアプリケーションやOSの設定などが行えます。 <br>
手順書の実行手順ミスや、オペレーション実施者による手順に記載していない事の「暗黙の実行内容」の齟齬が発生することを防げます。</p>

<p>近年のクラウド時代に考慮しないといけない「気にしておいた方がいいこと」があります。Code実行前には動的に変わるリソースIDを明示的に指定できないという点を、プロビジョニングツール実行時にはカバーしておく必要があります。</p>

<p>AnsibleではDynamic Inventoryという機能でスクリプト実行した結果を利用し、動的生成されたリソースをプロビジョングの対象にでき、この機能を利用しました。</p>

<p>この機能を使えば、AWSやプライベートクラウドなどAPIが用意されている環境であれば、ほぼ汎用的に対応が可能です。</p>

<h3 id="">自動テストツール</h3>

<p>次に「責任の所在」にあった回帰テストについてです。
オーケストレーションツールやプロビジョニングツールを実行した結果を保証しなければなりません。</p>

<p>都度、結果を目視で確認していくのはつらいものがあり、回帰テストも自動テストでカバーしたくなります。</p>

<p>そこでつかえるのが、<a href="http://serverspec.org/">Serverspec</a>です。</p>

<p>ここで気をつけたいのが、参照する設定が冗長的にならないように管理することについてです。私の使い方ではAnsibleはTerraformで動的生成されたリソースに対して動的に指定しているので、同じく自動テストツールのServerspecでもAnsibleの設定ファイルの値を利用したくなります。</p>

<p>そういう時に利用できるのが、ServerspecをAnsibleにIntegrateした<a href="https://github.com/volanja/ansible_spec">AnsibleSpec</a>です。
Ansibleで利用したDynamic Inventoryの仕組みをServerspecでもそのまま利用できます。動的に対象指定するスクリプトも共通化できますので、試験でも更新漏れが発生しにくく、ここでも安心を手に入れることができました。</p>

<h2 id="immutableinfrastructure">Immutable Infrastructureを手に入れることの意義</h2>

<p>もう一度、責任の所在に関して話を戻すと「自分たちが安心する」というのは、すなわち「納品への自信」へと繋がるわけです。</p>

<p>そうすればもっと他の事に気を使えるので、良いプロダクトを作れる気運が高まったと感じました。</p>

<p>最初に構築からデプロイまでのパイプラインを作るのは面倒ですが、一度やってしまえばたくさんの恩恵をうけれるので、まだ試したことない方はぜひ導入を検討してみてはいかがでしょうか。</p>]]></content:encoded></item><item><title><![CDATA[AWS WAF（ウェブアプリケーションファイアウォール）を使う時の影響]]></title><description><![CDATA[<p>AWSのWAFというウェブアプリケーションファイアウォールを利用する際の影響やトレードオフについて書きます。</p>

<p><a href="https://aws.amazon.com/jp/waf/">https://aws.amazon.com/jp/waf/</a></p>

<h2 id="waf">なぜWAFを使いたいのか</h2>

<p>アプリケーションを実装する際にはインジェクションやCSRFを始めとする様々な攻撃から守るようにしていますが、アプリに届く前に攻撃を検知・対応ができれば、より運用で安心度が高まります。</p>

<h2 id="waf">WAFがもたらす副作用</h2>

<p>ウェブアプリケーションファイアウォールを通したいということは、間に何かフィルタが入るという形になります。
WAFはCloudFrontを介してフィルタをかけるので、キャッシュ目的でCloudFrontを使いたいわけではない場合に、アーキテクチャや運用が大げさになってしまう可能性もあります。</p>

<h3 id="cloudfront">CloudFront</h3>

<p>WAFではHTTPのヘッダー情報もチェックしてくれるのですが、WAFが依存しているCloudFrontがレスポンスヘッダー情報に値を追記してしまうなど、幾つかのサービス仕様があります。通信データの変更を加えたくない場合には、WAFが邪魔になる場合もあるかもれません。</p>

<p>CloudFrontやWAFの機能でエラーになった場合に表示されるエラーページに「generated by cloudfront (cloudfront) 」の文言が入ってしまいます。正常、異常にかかわらず、レスポンスヘッダに「cloudfront」の文字が入ってしまいます。使用しているミドルウェア情報などをユーザに見せたくない場合に困ってしまいます。</p>

<h4 id="">気をつけたい点</h4>

<ul>
<li>できること
<ul><li>一部のエラーコードのエラーページのカスタマイズ（カスタマイズできるコードは下記参照）
<a href="http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/custom-error-pages.html">http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/</a></li></ul></li></ul>]]></description><link>https://tech.atware.co.jp/aws-waf-intro/</link><guid isPermaLink="false">446df275-c76e-4ed8-a739-299bb0677833</guid><category><![CDATA[AWS]]></category><category><![CDATA[WAF]]></category><category><![CDATA[Technologies]]></category><dc:creator><![CDATA[asano]]></dc:creator><pubDate>Tue, 01 Nov 2016 09:08:00 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2016/11/waf-2.png" medium="image"/><content:encoded><![CDATA[<img src="http://tech.atware.co.jp/content/images/2016/11/waf-2.png" alt="AWS WAF（ウェブアプリケーションファイアウォール）を使う時の影響"><p>AWSのWAFというウェブアプリケーションファイアウォールを利用する際の影響やトレードオフについて書きます。</p>

<p><a href="https://aws.amazon.com/jp/waf/">https://aws.amazon.com/jp/waf/</a></p>

<h2 id="waf">なぜWAFを使いたいのか</h2>

<p>アプリケーションを実装する際にはインジェクションやCSRFを始めとする様々な攻撃から守るようにしていますが、アプリに届く前に攻撃を検知・対応ができれば、より運用で安心度が高まります。</p>

<h2 id="waf">WAFがもたらす副作用</h2>

<p>ウェブアプリケーションファイアウォールを通したいということは、間に何かフィルタが入るという形になります。
WAFはCloudFrontを介してフィルタをかけるので、キャッシュ目的でCloudFrontを使いたいわけではない場合に、アーキテクチャや運用が大げさになってしまう可能性もあります。</p>

<h3 id="cloudfront">CloudFront</h3>

<p>WAFではHTTPのヘッダー情報もチェックしてくれるのですが、WAFが依存しているCloudFrontがレスポンスヘッダー情報に値を追記してしまうなど、幾つかのサービス仕様があります。通信データの変更を加えたくない場合には、WAFが邪魔になる場合もあるかもれません。</p>

<p>CloudFrontやWAFの機能でエラーになった場合に表示されるエラーページに「generated by cloudfront (cloudfront) 」の文言が入ってしまいます。正常、異常にかかわらず、レスポンスヘッダに「cloudfront」の文字が入ってしまいます。使用しているミドルウェア情報などをユーザに見せたくない場合に困ってしまいます。</p>

<h4 id="">気をつけたい点</h4>

<ul>
<li>できること
<ul><li>一部のエラーコードのエラーページのカスタマイズ（カスタマイズできるコードは下記参照）
<a href="http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/custom-error-pages.html">http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/custom-error-pages.html</a></li>
<li>エラーページのカスタマイズでアプリ側のページを指定</li></ul></li>
<li>できないこと
<ul><li>CloudFrontが付与しているレスポンスヘッダを出さないように設定したり、アプリ側でヘッダを上書きして消すことはできない。</li>
<li>URL文字制限を超えた場合のエラーページのカスタマイズができない（8192文字まで、コード413）     <a href="http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html">http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html</a></li>
<li>カスタマイズ対象に入っていないエラーコードのエラーページのカスタマイズができない</li></ul></li>
</ul>

<h3 id="waf">WAF</h3>

<p>作成した制約に違反する場合、403のエラーを返します。
403のエラーページは、CloudFrontでカスタマイズでききます。</p>

<ul>
<li>できること
<ul><li>IPの制限</li>
<li>URLの文字数の制限（URIとURLパラメータそれぞれで設定する）
<a href="http://docs.aws.amazon.com/waf/latest/developerguide/web-acl-size-conditions.html">http://docs.aws.amazon.com/waf/latest/developerguide/web-acl-size-conditions.html</a></li></ul></li>
</ul>

<h3 id="">料金面の影響について</h3>

<ul>
<li>CloudFrontへ設定するSSLについて
<ul><li>独自SSLを使う場合、クライアントがSNIをサポートしている必要があります。未対応のクライアントを使用する場合、専用 IP 独自 SSLオプションを使用する必要があり、毎月 600 USD （日割り）が必要になります。
<a href="https://aws.amazon.com/jp/cloudfront/custom-ssl-domains/">https://aws.amazon.com/jp/cloudfront/custom-ssl-domains/</a></li></ul></li>
</ul>

<h2 id="">性能面の影響について</h2>

<p>間に一つ何かを挟むということは、性能にも影響してきます。
気になるWAFでリクエストBodyをチェックする際のWAFの挙動は現時点では下記の通りです。</p>

<h3 id="">挙動</h3>

<p>Bodyチェック設定をした場合は、リクエストはWAFがリクエストBodyを受け取りながら徐々にチェックをかけつつ、同時進行でELB側にリクエストを送り続けるようなものではなく、クライアントから送られてきたリクエストBodyをWAFの内部で一旦メモリ内に保持して、チェックをし、チェック完了後にELBへデータを送信します。</p>

<p>現状ではWAFは最初の 8KB のみを CloudFront から転送しチェックしており、チェック完了後、許可されたリクエストは継続して CloudFront 動作を続けます。</p>

<p>このサイズは変更不可能なものとなっており、8KB より大きな body データにつきましては現在 WAF でチェックすることができないというのが仕様のようです。</p>

<p>つまり、大きなBodyリクエストを送られてきた場合でも影響を受けず一定の処理時間で捌くことが可能ですが、チェックが完璧だとは言えないということになります。</p>

<h2 id="">最後に</h2>

<p>WAFは非常に便利で強力なサービスですが、うまく付き合わないと逆にデメリット面が大きすぎたり、WAFを入れているから大丈夫だろうという姿勢でいると、思わぬところで穴がでてしまいます。</p>

<p>WAFではできないこともあるので、NginxやウェブアプリケーションでWAFの弱点を補いながら対策しつつ、WAFの費用対効果を考えて導入検討をするとよいと思います。</p>]]></content:encoded></item><item><title><![CDATA[APNコンサルティングパートナー認定を取得しました]]></title><description><![CDATA[<h3 id="amazonwebservicespartnernetworkapn">Amazon Web Services Partner Network (APN) スタンダード コンサルティングパートナーとしての認定を取得しました。</h3>

<p>アットウェアでは、これまで培ってきたWeb基盤を中心としたアプリケーション開発技術と、AWSクラウドインフラ基盤の構築を組み合わせ、クラウドネイティブアプリケーションの開発、クラウドサービスの普及へ向けた活動を行ってまいります。</p>

<ul>
<li>ビッグデータの蓄積、大量トラフィックの収集</li>
<li>機械学習を用いた分析、分散処理によるデータ加工</li>
<li>集中アクセスが予想されるWebサービス、Webアプリケーション</li>
<li>スタートアップサービス</li>
<li>IoTと接続するクラウド基盤</li>
</ul>

<p>クラウドが解決する領域を担うインフラ基盤として、AWSを中心としたソリューションを提供します。
（アットウェアが提供する価値や開発事例は<a href="https://tech.atware.co.jp/aws/">こちら</a>。）</p>

<h3 id="">お問い合わせ</h3>

<p>AWSに関する質問、ご相談は<a href="http://www.atware.co.jp/contact-us/#contact-form">アットウェアお問い合わせフォーム</a>よりお気軽にお問い合わせください。</p>]]></description><link>https://tech.atware.co.jp/apn-consulting/</link><guid isPermaLink="false">c1f50556-eaf7-4196-8135-633f8ec55c38</guid><category><![CDATA[AWS]]></category><dc:creator><![CDATA[Matsudate]]></dc:creator><pubDate>Fri, 28 Oct 2016 13:28:29 GMT</pubDate><media:content url="http://tech.atware.co.jp/content/images/2016/11/apn-logo.png" medium="image"/><content:encoded><![CDATA[<h3 id="amazonwebservicespartnernetworkapn">Amazon Web Services Partner Network (APN) スタンダード コンサルティングパートナーとしての認定を取得しました。</h3>

<img src="http://tech.atware.co.jp/content/images/2016/11/apn-logo.png" alt="APNコンサルティングパートナー認定を取得しました"><p>アットウェアでは、これまで培ってきたWeb基盤を中心としたアプリケーション開発技術と、AWSクラウドインフラ基盤の構築を組み合わせ、クラウドネイティブアプリケーションの開発、クラウドサービスの普及へ向けた活動を行ってまいります。</p>

<ul>
<li>ビッグデータの蓄積、大量トラフィックの収集</li>
<li>機械学習を用いた分析、分散処理によるデータ加工</li>
<li>集中アクセスが予想されるWebサービス、Webアプリケーション</li>
<li>スタートアップサービス</li>
<li>IoTと接続するクラウド基盤</li>
</ul>

<p>クラウドが解決する領域を担うインフラ基盤として、AWSを中心としたソリューションを提供します。
（アットウェアが提供する価値や開発事例は<a href="https://tech.atware.co.jp/aws/">こちら</a>。）</p>

<h3 id="">お問い合わせ</h3>

<p>AWSに関する質問、ご相談は<a href="http://www.atware.co.jp/contact-us/#contact-form">アットウェアお問い合わせフォーム</a>よりお気軽にお問い合わせください。</p>]]></content:encoded></item></channel></rss>