年間TOP5 ページビュー編 #vgadvent2017

これは VOYAGE GROUP Advent Canlendar 2017 の5日目のエントリです。

1位

ECナビの環境をもりもり改善している話。17年もの長い期間オンプレミスで稼働してきたシステムもAWS移転してずいぶん良くなったよねー

techlog.voyagegroup.com

2位

VOYAGE GROUPは元SIerのエンジニアも活躍できる環境です!

techlog.voyagegroup.com

3位

未完成なものを共有するのは、慣れてないとちょっと抵抗あるかもしれませんが、結構メリット大きいと思いますよ。

techlog.voyagegroup.com

4位

こんな感じで実際に運用していて出くわした課題を共有していきたいですね。

techlog.voyagegroup.com

5位

プラットフォーム事業ではパートナーとのエンゲージメントが重要です。技術サポートはめっちゃ大事な役割です。

techlog.voyagegroup.com


来年も良いエントリをたくさん発信していきたいと思います!

エンジニアの能力評価制度である技術力評価会を改善し続けています。 #vgadvent2017

これは VOYAGE GROUP Advent Canlendar 2017 の1日目のエントリです。

CTOやってる @makoga です。昨年と同じくトップバッターをゲットしました。通算5回目。

昨年のエントリで技術力評価会の事例を紹介していきたいと書き、いくつか実施できました。

f:id:voyagegroup_tech:20170928143507p:plain

その後も全体ふりかえりを行いながら改善し続けてきましたが、一番の大きな挑戦は社外から評価者を招聘したことだったと思います。このエントリでは詳細は割愛しますが、弊社のエンジニアがやっているPodcast ajito.fmのエピソード5を聴いてもらえると雰囲気がつかめるかもしれません。社外評価者の効果についてはもう1ターン実施後に機会を見つけてどこかで発表したいと思います。

来年はVOYAGE GROUPの中だけではなく、いろいろな企業との交流しながらの改善も考えていますので、ご興味ある方がいればTwitterFacebookでお声がけください。

明日は @katzchang が小ネタを披露してくれるようです。楽しみですね!

冬のインターンSunrise2017 データベースコースふりかえり

こんにちは。システム本部 三浦(@hironomiu)です。

f:id:hironomiu:20171121143923j:plain

このエントリーでは、10月28日(土)、29日(日)に開催した冬のエンジニアインターン「Sunrise2017 データベースコース」をふりかえりたいと思います!

講義

講義はワークショップと座学の2つを行いました。ワークショップではSunrise生一人に対し各2台のサーバを用意し1台を負荷+アプリケーションサーバ、もう1台をデータベースサーバの役割や、1台をマスター、1台をスレーブの役割などとして割り当て、データベースサーバについて様々なトピックを実技形式で学んでいきました。

ワークショップサーバ環境説明 f:id:hironomiu:20171121154632p:plain

ワークショップ前半では各種モニタリングコマンド(dstat,top..etc)やデータベース(MySQL)のモニタリングなどを行い限界性能やパフォーマンスチューニングなどを行っていきました。

ワークショップ Chapter1抜粋 f:id:hironomiu:20171121160210p:plain

ワークショップ Chapter2抜粋 f:id:hironomiu:20171127161832p:plain

ワークショップ後半では実際にレプリケーション、バックアップリストアなどを経験しトラフィックを捌くだけでなく実際のサービスでは必要となる要素についても学んでいきます。ただし実務で耐えられるレベルでの技能習得が目的ではありませんので基礎的なオペレーションを中心に短時間で行っていきます。

ワークショップ レプリケーション(GitHub)

github.com

ワークショップ バックアップリストア(GitHub)

github.com

座学では「第1章 DBサーバの性能計測、サイジング、I/O特性」「2章 DBサーバのシステム要件、運用保守」「第3章 サービスの成長とあわせたDBの拡張戦略」「第4章 DBサーバのI/O戦略」の4章立てでこれまで行ってきたワークショップから実際のサービス運営を踏まえたデータベースの拡張と運用戦略の補強として講義を組み込んでいきました。

座学講義資料(GitHub)

github.com

最終課題

講義後には、ここまで行ってきた講義の内容を用いてアウトプットする「最終課題」を設けました。この最終課題は5人1チーム、チームごとにサポータが1名つく形で行います。お題はこちらで架空のWebサービスを用意し、サービスの概要、アクセス数などサイジングにまつわる情報、SLAとしてクリアしたい情報などを合わせて提示しました。そのお題からSunrise生の皆さんには最終課題でアウトプットする内容はデータベースサーバの「サイジング」と「構成図」、サービス仕様として明示した処理にまつわる「テーブル定義(DDL文)」、「SQL文」と妥当であるアクセスパスであることを「実際のサーバにDDLとSQLを実行しexplainにより検証した結果」などとしました。

最終課題資料抜粋


f:id:hironomiu:20171121155603p:plain


集合写真

最終発表後の集合写真です。二日間のハードなインターンだったと思いますが全員笑顔で終えることができ開催者としてホッとしています!

f:id:hironomiu:20171121144104j:plain

終わりに

非常に短期間のインターンで、どこまでインプットを盛り込みつつアウトプットの時間を取れるか開催者としても苦心したインターンでした。データベース(RDBMS)は長く使われてきた技術のため世の中に情報が溢れていますが、実際に負荷を掛けてみたり、テーブル定義やSQL文の作成、そのSQL文が妥当なアクセスパスの検証などをインターンで経験することは、とても意義があると考えインターンのテーマとしてデータベース(RDBMS)にフォーカスを当てて開催しました。自画自賛となりますが結果としては上手くいったと思っています。インターンに参加されたSunrise生の皆さんには、今後どこかでこの経験と知識が役に立てば幸いです。

Special Thanks

今回の「Sunrise2017 データベースコース」は講師の私だけでなく講義と最終課題の全行程で3名の現場エンジニアのサポータに協力してもらい開催しました。

「りっきー」「ともかつ」「あっきー」ありがとう!

VOYAGE GROUPの企業ブースと登壇資料まとめ #phpcon2017

目次

こんにちは!
ECナビエンジニアのゆきみねです。

日が空いてしまいましたが、10/8(日)に PHPカンファレンス2017 がありました。

今年は弊社エンジニアが 2名登壇 し、企業ブースでは 実コードを交えた改善事例やエンジニア評価の基準や結果レポートの公開 を行いました。

本記事では、PHPカンファレンス2017の 弊社企業ブースの様子登壇資料 をご紹介します。

企業ブースの様子

f:id:yuk4420:20171016171758p:plain

企業ブースでは、事前に告知 した通り、以下のテーマでVOYAGE GROUPの事例を紹介しました。

  • テーマ1. 事業拡大に全振りしてきたwebサービスの実情とこれから
  • テーマ2. チーム全員リファクタリングしかしない日
  • テーマ3. エンジニアによるエンジニアの評価

ブースにお越しいただいた方からは

「評価基準や評価フィードバック、企業ブースで公開しちゃうんですね」

「評価の結果レポートが全社員に公開されるのスゴイですね」

という声から

「テストコードを書いて改善していくと工数が以前より掛かると思いますが
ビジネスサイドにどう説明しましたか?」

「リファクタリングの日はなぜ月1なんですか?
他の日はリファクタリングしないんですか?」

「マネジメント中心のエンジニアの技術力はどうやって評価していますか?」

「評価者の評価スキルを上げる工夫はしてますか?」

といったリアルな質問まで、幅広いコメントをいただきました。

自分も聞いてみたいという方、是非ajitingしましょう!
※ 詳細は記事下部

また、上記テーマの他にも以下の資料をネタに ajitofm の宣伝も行いました。
お越しいただいた方の中にはリスナーの方も!ありがとうございます!
(左半分:来場者に配布したチラシ、右半分:注目を集めていた!?ポスター)

f:id:yuk4420:20171016193405p:plain

登壇資料

発表1. 広告配信管理システムを支えるPHP〜レガシーシステムからの段階的移行戦略〜

登壇者名:鈴木 健太( @suzu_v

speakerdeck.com

www.youtube.com

発表2. 運用、追加開発しづらいPHPアプリケーションに未来を与える方法

登壇者名:田中 改( @ara_ta3

speakerdeck.com

www.youtube.com

ajitingしましょう

今年のPHPカンファレンスも、企業ブース、セッション共にたくさんの方にお越しいただきました。 この場を借りてお礼申し上げます。

カンファレンス当日ブースに行けなかったので話が聞きたい、登壇者と話がしたいという方、是非 ajiting*1 しましょう!
@tech_voyage までお気軽にメンションください。

*1:VOYAGE GROUPでは社内Bar AJITOで飲んで語らうことをajitingと呼んでいます。

#phpcon2017 で2名登壇します!企業ブースでは実コードや評価の仕組みを公開します!

目次


こんにちは!
ECナビエンジニアのゆきみねです。

10/8(日)は何の日かご存知でしょうか?
そうです!PHPカンファレンス2017 ですね!

PHPカンファレンスは今回で22回目となる、国内最大級のPHPイベントです。
VOYAGE GROUPは昨年に引き続きプラチナスポンサーとして協賛しています。

昨年はブースにて実コードを交えた事例紹介を行い、多くの方で賑わいご好評をいただきました。 techlog.voyagegroup.com techlog.voyagegroup.com

今年は弊社エンジニアが 2名登壇 し、企業ブースでは 実コードを交えた改善事例やエンジニア評価の基準や結果レポートの公開 を行います!
昨年好評だった ECナビ 以外のサービスにもスコープを広げ、fluct SSPサポーターズ の改善事例もご紹介します。

セッション発表では老舗Webサービスのレガシーコード改善事例をご紹介

VOYAGE GROUPは以下2セッションで発表を行います。
「広告配信管理システムを支えるPHP」では fluct SSP の、「運用、追加開発しづらいPHPアプリケーションに未来を与える方法」では サポーターズ の改善事例をご紹介します。

発表1. 広告配信管理システムを支えるPHP〜レガシーシステムからの段階的移行戦略〜

発表者:鈴木健太(@suzu_v)

時間・場所:13:35〜14:00 4Fコンベンションホール梅(手前側)

発表資料から抜粋:

f:id:yuk4420:20171005142613p:plain

f:id:yuk4420:20171005142638p:plain

発表2. 運用、追加開発しづらいPHPアプリケーションに未来を与える方法

発表者:田中 改

時間・場所:15:20〜15:45 4Fコンベンションホール梅(手前側)

発表資料から抜粋:

f:id:yuk4420:20171005180811j:plain

f:id:yuk4420:20171005180942j:plain

f:id:yuk4420:20171005180946j:plain

※ 発表資料は変更する場合があります

両タイトルとも、分かる!なるほど!が盛りだくさんのセッションとなっております!

企業ブースでは実コードを交えた改善事例やエンジニア評価の基準や結果レポートを公開します!

具体的には以下のテーマを予定しています。

またセッション発表後は登壇者もブースにいますので、発表に関する質問・相談の場としてもご利用ください。

テーマ1. 事業拡大に全振りしてきたwebサービスの実情とこれから

サポーターズ の改善活動を実コードを交えてご紹介します。

テーマ2. チーム全員リファクタリングしかしない日

ECナビ の改善活動を実コードを交えてご紹介します。

techlog.voyagegroup.com

テーマ3. エンジニアによるエンジニアの評価

VOYAGE GROUPのエンジニア評価制度について、評価基準実際の結果レポート() を用いてご紹介します。
エンジニアによる評価によって、改善活動も評価される仕組みをご紹介できればと思います。

techlog.voyagegroup.com

※ 企業ブースの内容は変更する場合があります

当日会場でお会いしましょう!

VOYAGE GROUPからは CTO 小賀、発表者 鈴木、発表者 田中、若手4名(僕を含む)の計7名で参加します。

参加登録(無料)がお済みでない方、大丈夫です、まだ間に合います。
応募フォーム

当日が楽しみです!

React + RxJSで始める状態管理

こんにちは、fluctの@nekoyaです。

今日は現在開発に携わっている、俗に言う「管理画面」のWebアプリケーションのアーキテクチャをご紹介します。

このアプリケーションはReactRxJSを軸として作られており、コードはTypeScriptを使って書いています。

アプリケーションを流れるデータと状態の管理について、Write StackとRead Stackという考え方を取り入れたところ、いろいろなメリットが得られたので、そのあたりを軸に掘り下げてみます。

全体の大まかな構成

各Stackの前に、まずはアプリケーション全体の構成をざっくりと見ておきます。

Application Stack

流れとしては、DispatcherからWrite Stack, Read Stackを通ってStateが生成され、それをViewが受け取るという構成になっています。

全体の流れとしてはFluxっぽい何かのひとつのあり方なのですが、Stateを生成する部分をWrite StackとRead Stackに分けて考えているところに特徴があります。

また、サンプルとしてURLで指定したidのissueを表示するアプリケーションを用意しました。簡易的なものですが雰囲気はつかめるかと。

cloneして

make

とだけ実行すれば、ビルドからテスト用のnginxコンテナの起動まで一気にやるようにしています。http://localhost:18888/からアクセスできます。

nginxコンテナがそのままコンソールに居続けるので、終了する時はCTRL+Cで止めてください。

Node.jsとyarnが動く環境が必要ですが、そのあたりは各自適当にやってください。

CQRSに基いてデータフローを組み立てる

このWrite Stack, Read Stackという考え方はAlmin.jsからの引用で、その背景にはCQRSの概念があります。

CQRSについては「複雑を増すだけだ」という考えもあるかもしれませんが、少なくとも我々が業務で取り扱っている領域において「データの更新」という副作用を局所化できるメリットは大きいと捉えています。

Alminそのものを採用しなかった理由としては、

  • 当時のAlminがTypeScriptをサポートしていなかった
  • RxJSを組み合わせるには独自に実装した方が都合がよかった

といったところがメインですが、Alminの根本思想として「考えながら作る」ということが掲げられており、アーキテクチャへの理解を深めるためには自身の実装を持つのは悪いことではないと考えた部分もあります。

それぞれのStackについて掘り下げる前に、全体をもう少し把握するために各要素について簡単に解説します。

Dispatcher

Viewの操作などに起因する状態の更新を受け取り、一連のデータフローの起点となるオブジェクトです。

ひとつひとつのドメインイベントをRxJSのSubjectとして切り出すようなイメージです。

それを呼び出す部分は実際にはもう一枚wrapper層を設けたりするのですが、今回のサンプルでは省略しています。

Epic

Dispatcherのイベントを受けて、最終的にRepositoryを更新するための処理を定義するレイヤです。

特徴的な部分としては、EpicはRxJSのデータフローを定義するとこまでを仕事としている点でしょうか。

データが流れてくる度にEpicが仕事をするのではなく、あくまでDispatcherとRepositoryをつなぐだけの役割を持たせています。

Repository

何らかの値を格納する場で、Write StackとRead Stackの橋渡しをする存在となります。Write Stackの終点であり、Read Stackの始点であるとも言えます。

Repositoryは自身が初期値を持つようにBehaviorSubjectを使っています。こうすることでWrite Stackが未実装の段階でもViewの開発を進めることが可能となり、チームでの並行作業なども進めやすくなります。

Store

DispatcherおよびRepositoryを入力として、単一のState Objectを生成するのがStoreです。

Epicと同様、StoreそのものはRxJSのデータフローを定義することを責務とします。

実装としては各種入力をcombineLatestでひとまとめにするだけです。

State

Viewを生成するためのアプリケーションの状態を集約した単一のオブジェクトです。

実装としては単にinterfaceをひとつ置いているだけです。

View

Stateから一連のDOM Treeを生成するReact Component群です。

ここで扱うReact Componentは全てReact0.14から導入されたStateless Functional Component(とは最近は言わなくて単にFunctionalなComponentというっぽい)としています。

そうすることで、React Componentから状態を排除してDOM Treeの生成のみを任せることができ、Viewのレイヤに複雑さを持ち込まないようにしています。

先の図ではViewがDispatcherを直接操作するように見えますが、実際にはここはもう一段抽象化しています(本エントリはWrite StackとRead Stackの解説がメインのため省略)。

全てのComponentが状態を持たないという前提を敷くことで、Componentの分割はその状態を考えることなく、表示の都合だけで切り分けられるため自由度が高くなります。

また、状態をReact Componentに持たせるとRxJSを使ったデータフローとの接合部分が煩雑になりがちなため、切り離すことでView領域の責務を軽くできるというメリットも得られます。

Write StackとRead Stack

さて、本題に戻ってWrite StackとRead Stackの分割について改めて考えてみましょう。

Write Stack

Write Stack

Dispatcherを入力として、Repositoryに何らかの値を保存するところまでをWrite Stackと呼びます。

CQRSで言うところのCommandの系にあたり、アプリケーションの状態を更新するための副作用をこの部分に局所化することで状態を管理しやすくする狙いがあります。

具体的には何らかのWebAPIを通じてデータを取得したり、更新したりといった操作を非同期におこなうなど、外界とのやり取りをWrite Stackに持たせます。

Read Stack

Read Stack

DispatcherおよびRepositoryを入力として、ViewのためのStateを生成する一連の流れをRead Stackと位置付けます。Read StackはCQRSで言うQueryにあたり、Repositoryに変更を加えることはありません。

外界とのやり取りはWrite Stackの段階で全て済んでいるため、Read Stackの実装は全て自身のアプリケーション内で完結できます。

フロントエンドの開発においては、サーバサイドとの連携部分がシステム内に分散していると何かの問題が起きた際の調査が煩雑になったり、機能追加・更新で地雷を踏む場面が増えます。

このアーキテクチャではWrite Stack以外での外界との接触を禁止することで、複雑さを局所化しています。

データフローを単純化するという意味ではDispatcherからStoreへの流れは許可せずに、全てRepositoryを通した方が簡単にはなります。

とは言え、何の操作も伴わないただの値の受け渡し(URLに含まれるパラメータをそのまま描画する場合など)に

  1. その値を格納するRepositoryを用意する
  2. Dispatcherの値をそのままRepositoryに流す経路をEpicに作る

という実装を毎回用意するのは無駄が多いため、DispatcherからStoreへの直結ルートを用意しています。

このアプリケーション構成ではViewに何らかの変更を起こすためには、必ずDispatcherに値を流してデータのフローを回す必要があります。

この直結ルートがあることで「面倒だからViewの中だけで完結させよう」という邪念を封じる効果が得られます。

何がうれしいのか

文中にも書いていますが、改めてこの構成によって得られたメリットをまとめます。

Viewから複雑さを排除できる

React Componentに状態を持たせず、Viewの再描画には常にStateの再生成を要求することでViewの責務を軽くしています。

こうすることでRead Stackをアプリケーション的に参照透明なものとして扱うことができ、Viewの見通しが良くなります。

また、将来的にもしReact以外の何かを使いたくなった場合もViewの責務が軽いので乗り換えやすくなることが期待できます。

副作用あるいは外部への依存を局所化できる

近年のフロントエンド開発においては、外部のリソース(WebAPIなど)との非同期通信とその結果を受けての処理がアプリケーションが複雑化する主な要因であると考えています。

この構成では、その複雑さを受け入れる場所をWrite Stackとして明確に定めることで「あちこちでコールバックが発生して収集がつかない」といった状況を避けることを目指しています。

これが効果を発揮したかが本当の意味で分かるのは数年先のことかもしれませんが、思考の整理のしやすさという恩恵はプロジェクトの初期段階から得られている実感はあります。

懸念される課題

あらゆる状態変化に対してViewが再構築される

React Componentに状態を持たせないということは、何らかの状態の変更に対して常にデータフローを一巡させ、Stateを再生成し、Viewを再構築することを意味します。

高いパフォーマンスが求められるケースでは不利になる場合もありますが、我々の業務ドメインにおいては構成がシンプルになるメリットの方が大きいため、ここには目をつぶっています。

少なくとも現時点ではReactのVirtualDOMに全て任せてしまって問題のないレベルのパフォーマンスが得られています。

初期学習コストが高くなる

例えば公開期間が限定されているようなキャンペーンサイトであれば、このようなStackを分けた構成は必要ないかもしれません。

我々が現在取り組んでいる「管理画面」というものは何年にも渡って使われる(もちろん会社やビジネスが存続するという前提はありますが)ことを念頭に置く必要があるため、初期学習コストを下げることはそこまで重要視していません。

コード量が増える

アプリケーションを構成する要素が増えるため、実際のところコード量は増加する傾向にあります。

この課題については、TypeScriptを採用していることでIDEのサポートも得やすくなっているため、コードの絶対量に対して人間がやるべきことを抑えられているため許容可能であると感じています。

まとめ

フロントエンドの状態管理には様々なアプローチがあり、問題領域によっても適切な手法は違ってくるでしょう。

「状態をどのように扱うか」という問いはアプリケーションの本質的な課題であり、そのあり方については常に向き合い続けるべきであると考えます。

そんなひとつのあり方として、今回ご紹介した手法が何かのきっかけになれば幸いです。