今日はこのへんで

Webエンジニア。プログラミング、スタートアップについて。もしくはただの雑記。

エンジニアリングとプロダクト、その役割の違い

今の職場に移ってから何度か組織の変更があって、少し思うところもあったので、自分の中でのエンジニアリングとプロダクトの違いについて少し整理をしておこうと思う。

さて、ITを生業とする組織では、VP of Engineeringとか、VP of Productとか、はたまたCTOとかいう役職の人がいる。それなりの組織でも3つとも役職がある場合は少なくて、CTOだけだったり、各VPを兼務していたりする場合が多いような気もするのは、それぞれの役割が各組織で定義され、共通認識が曖昧だからなのかもしれない。

自分の中では、端的にいうと、「正しいプロダクトを正しくエンジニアリングする」という分担がしっくりきている。顧客が何を価値をとしているのかを掴み、どういった機能を作るかを考える、つまりWhatの部分はプロダクトの仕事であり、それをどうやって実装して顧客に届けるかのHowの部分はエンジニアリングの仕事である、と思う。

プロダクトのリーダーにとって、最も大切な指標はユーザの継続率だろう。継続率こそ、ユーザがそのプロダクトにお金を払うだけの価値を見出しているかどうかの判断基準であり、この数値が企業の黒字化、はては存続を左右するからだ。

対して、エンジニアリングのリーダーにとって最も大切な指標は、おそらくチームの生産性だろう。どれだけ早く新しい機能をユーザに提供し、どれだけ早く学びを得られるかによって、企業の生死が決まる。エンジニアリングにおいては、その原動力となる生産性を最大化することが至上命題といえる。

そうした役割の違いがあるなかで、組織のメンバーとしてのエンジニアは、プロダクトとエンジニアリングの両方の役目を担うことになる。新規の機能を実装し届けるにあたって、デザイナーやプロダクトマネージャーも含めたチームを構成するのは当然の判断だが、エンジニアはプロダクトチームに属して機能開発をしながら、同時にリファクタリングや様々なフローのシステム化のようなエンジニアリングを行う。組織が大きくなってくると、QAエンジニアのチームや何かしらの基盤チームなど、エンジニアリングを専門とするチームも必要になってくるのが自然な組織の成長のように思う。

組織全体としては、プロダクトとエンジニアリングに書ける時間比率は半々くらいが健全だと思う。とはいえ、これは企業のフェーズによって変わってくるもので、ユーザへの提供価値が薄い初期のプロダクトでは、多少効率が悪くても(例えば手の温もりのあふれるデプロイフローを使ってでも)プロダクトの機能開発を優先させなければならないかもしれないし、ユーザを大量に抱えるプロダクトでは、SREチームなど先に述べたようなエンジニアリングを専門に行うチームが必要になるかもしれない。

自分の組織に最適な比率を知ることは難しいかもしれないが、組織が健全かどうかを知るのはそれほど難しくない。メンバーの声を聞けば、たいてい何かしらのアラートが出ているはずだからだ。例えばプロダクトマネージャーが、エンジニアが何をやっているのかさっぱりわからないと言えば、それはおそらくそのエンジニアのエンジニアリング比率が高いことを表す。その上で、継続率やそれに結びつく指標が伸びていないとすれば、その組織はおそらく早すぎる最適化によって、時間を無駄にしている。逆に、エンジニアがバグの修正に時間を取られ、日々のベロシティも上がらないようなら、おそらくリファクタリングが必要な状態なのだと言える。

時として、エンジニアリングに時間を割くのは無駄ではないかと、プロダクトチームにおけるエンジニアリングの比率が軽視されることがある。これはおそらくエンジニアリングの専門性が理解されないことが原因だと思うのだが、例えそれが理解されなくても、大事なのはプロダクトとエンジニアリングにかける比率をお互いに最大限尊重しあい、領域を侵犯しないことだろう。エンジニアリングのリーダーは、次々と新しい言語やライブラリに挑戦したがるエンジニアの手綱をひき、常に早すぎる最適化に注意を払いつつ、必要な技術投資をして競争力を維持しなければならない。プロダクトのリーダー・メンバーは、エンジニアリングの内容がブラックボックスだったとしても、それに時間を割かないことが際限のないバグを生み、ユーザの信頼を損ねる結果となることを理解しなければならない。エンジニアリングを怠れば、最悪プロダクトの作り直しを迫られることになる。年季の入ったプロダクトの作り直しには長い時間がかかるし、その間、ユーザへの新しい価値提供は止まる。

さて、それではCTOの役割はなんだろう。個人的には、プロダクトとエンジニアリング両方の組織を、メンバーの強みに合わせて上手く組成し、育てることが一番の役割のように思う。各エンジニアの強み、志向を理解し、力のあるものをリーダーに任命するのがCTOの役割だ。技術に明るいリーダーがいるのであれば、プロダクトのリーダーはマーケティング出身の者やデザイナー出身の者でも良いかもしれない。プロダクトマネージャーが足りなければ、プロダクト志向の強いエンジニアの役割を転換させるのも手かもしれない。事業の価値をさらに強化するために、機械学習の専門チームが必要かもしれない。経営の方向性と照らして、そうした組織の組成における意思決定を行い、メンバーを監督するのがCTOの役割のように思う。とは言いつつも、エンジニアの少ない初期のチームではCTO自らががりがりコードを書くことで周りを鼓舞し、事業を前に進めていくことが求められるし、フェーズが変わってもそういうスタイルの人もいる。どこかのタイミングで創業者とプロ経営者が交代するように、技術に強いが人には興味がないような人から、組織作りに強い人に、CTOという肩書きや役割が移譲されることもよくあるようだ。

というのが、今のところの自分なりの理解だった。なんにせよ、メンバーの強みに合わせて、組織は変わっていくものであり、また持てるものを最大限活かすために変わっていくべきものでもあると思うし、「正しいプロダクトを正しくエンジニアリングする」ということが組織としてできていれば、役職やラベルはどうでも良いのだけど。


ピープルウエア 第3版

ピープルウエア 第3版

最近の仕事ぶり

最近はもっぱらRailsを書いていて、ここ数ヶ月で自分がメインで書いた機能がプロダクションにもデプロイされるようになってきた。

そんななかで、自分はもう少しまともなコードが書けると思っていたが、全然そうじゃなかったな、と思うことも多い。つい先日は、N+1クエリを直したつもりでいたのに一部のデータで上手く動かなくて、結局変更を元に戻す、なんて馬鹿みたいなことをやったりした。

一緒に原因を調査してくれた同僚に「 Ruby のプロファイラって使ったことあります?」と聞かれ、使ったことないどころかライブラリの一つも頭に浮かんでこなかったときの情けなさといったらなかった。盲目的にクエリの数を減らせばまぁ早くなるだろ、と思っていた自分が恥ずかしい。

ちょうどその週末の Ginza.rb で Rails のパフォーマンス改善について k0kubun さんが発表していて、身につまされる思いだった。

Railsアプリケーションのパフォーマンス改善手法 / #ginzarb // Speaker Deck

会社では、Ruby 以外の言語も使えるようにしていきたいね、という話が少しく盛り上がっているけれど、個人的には自分は Ruby や Rails のことを知らなさすぎるのではという気がしていて、それどころではない。Go や Rust も良いけれど、それよりも、良い Ruby のコードに触れる機会を増やしたいと感じることが多い。

例えば上記のプロファイラの例で言えば、メジャーな Ruby プロファイラであるところの tmm1/rblineprof は RubyKaigi 2014 で紹介されたもので、もう3年も前の情報なのに、コミュニティの外にいるからなのか少しばかりエンジニア業から離れていたからなのか、そういう常識が抜け落ちている。

そう思ってRubyKaigiのYoutubeを見返したりしており、ちょうど松江Ruby会議での amatsuda さんの公演が良い指針になりそうだった。基本的に amatsuda/gem-src でいつでも gem を手元に置いておいて読める状態にしたうえで、yak shaving 駆動で gem を読んだりあわよくば直したりする、と。なるほど。

実際に gem-src を ghq と一緒に使ってみつつ、bundler では path を指定して手元のソースを読むようにすると、gem のブラックボックス感が薄れて良い。さらにエディタで定義ジャンプをするようにすれば、自然と gem のソースコードも読む習慣ができると思う。

話は逸れるけれど、技術情報をYoutubeで観るのは結構良いと思っていて、なぜなら最新の情報はたいていカンファレンスで発表されるし、メジャーなカンファレンスであれば最近はYoutubeに動画がアップロードされるのは普通だからだ。ブログのように「やってみた」レベルの話ではなく、本のように古くもなっていない、知見のつまったスピーチが聴けるのはYoutubeの良いところだと思う。(とは言え自分が観ているのは1年〜数ヶ月前のものばかりだけど)

(ということをPOSTDを運営していたときにもちらっと思って、そういう動画のまとめサイトみたいなのほしいなぁと思ったけれど思ったままだった)

Ruby/Rails 以外のレイヤーも、いくらでも学び直す必要性を感じていて、ちょうど Real World HTTP が出版されたので読みたいなと思っていた。これについては会社で読書会をすることになり、良い機会だと思ったので参加している。読書会というのに参加するのは初めてで、まだ一度しかやっていないけれど、参加者の知見が集まることで、自分の知識のヌケモレがなくなっていく感覚があり、とても満足度の高いものだった。引き続きやっていきたい。

と、仕事ぶりとしてはバリューも出せておらず、いまだに自己啓発や開発環境の整備といった領域から抜け出せていないけれど、いつまでもそんなことをやっていてもしょうがないので、ちゃんと技術と向き合っていきたい。

最近のシェル環境

最近周りの開発者に刺激されたこともあって、シェル/macの環境をちょこちょこ整備したので、道半ばではあるものの現状をメモがてら残しておく。

Githubの差分

シェル環境

Fishにした

ZshからFishにした。Zshのときは sorin-ionescu/prezto を使っていたので、デフォルトで使い物になる、というFishの謳い文句も響いてはいなかったのだけど、友人にそそのかされた。補完が少し重かったり、configの記法がbash/zshと違いすぎたりと、使えはするもののあまり気に入りはしなかったのでそのうちきっとzshに戻すと思う。

ちなみにプラグインマネージャーは fisherman/fisherman を使ったが、特に問題はなかった。oh-my-fishのプラグインも使えて便利だった。

ショートカットエイリアス

今さら馬鹿みたいなんだけど git ** のエイリアスを登録したら捗った。これまで gitg だったし各種サブコマンドはgitconfigで省略形をエイリアスにしていたのだけれど、結局スペースを押すのがボトルネックになっていることに気づいた。

あまり固有のコマンドをエイリアス化するの好きではなかったんだけれど、ポリシーを変えて積極的に登録したいという気分になった。

エイリアス一例

alias ga  'git add'
alias gb  'git branch'
alias gba 'git branch -a'
alias gbl 'git blame'
alias gc  'git commit -v'
alias gca 'git commit -v --amend --no-edit'
alias gco 'git checkout'
alias gcl 'git clone --recursive'
alias gd  'git diff'
alias gdc 'git diff --cached'
alias gdh 'git diff "@{u}..HEAD"'

alias rs  'bundle exec rails s'
alias rc  'bundle exec rails c'
alias rg  'bundle exec rails g'
alias rd  'bundle exec rails d'
alias rr  'bundle exec rails r'
alias rk  'bundle exec rake'

Tmuxを復活させた

Tmuxは、スクロールやコピペもマウスのほうがスムーズだし、画面分割もなくてもそれほど困らないし、他人とのセッション共有もしないし、と思ってしばらく使用をやめていた。

最近他の開発者の画面を見せてもらったら、一番懸念だったスクロール/コピペの問題は nhdaly/tmux-better-mouse-mode で解決できることを知ったので、改めて使うことにした。そもそも以前は tmux-plugins/tpm でプラグイン管理さえしていなかったので、Tmuxが悪かったのではなく単に自分の tmux.conf が弱いだけだった。

手が昔の動きを覚えていたので、リハビリに時間がかからなかったことは幸い。

その他便利コマンド系ツール

  • Ctrl-r の履歴検索を junegunn/fzf でやることにした。が、ヒットがちょっとfizzyすぎて若干使いづらい
  • リポジトリ管理は motemen/ghq でやることにした。自分なりに構成していたプロジェクトディレクトリを崩すので躊躇していたが、使ってみると便利だった
  • direnv/direnv は以前から知っていたが、今のプロジェクトではローカルの開発環境で環境変数をいくつも設定するので、やっと真価を発揮してきたという感じがある
  • github/hub はPull Requestをコマンドラインでやるツールだと思っていてスルーしていたけど、 hub browse を引数なしで実行するとリポジトリのページをすぐ開けるということに気付き、今ではこれだけ多用している
  • peco/peco でブランチ切り替えとSSH Hostの指定をできるようにしたいと思いつつ設定書いたけど気に入らなかったのでちゃんと設定したい
  • PhrozenByte/rmtrash (または dankogai/osx-mv2trash)、結構便利だと思うんだけど意外と使っている人少ないということに気づいた
  • Unarchiverの unar がWindowsの圧縮ファイルを文字化けせずにコマンドラインから解凍できてOSXでは便利だった

Atomエディタ

パッケージ関連

  • atom-alignment をいれつつなんか上手く動かないな、と思っていたけど、複数カーソルを揃えたい場所の先頭に持ってこればちゃんと動くことに今さら気づいた

bの行頭にカーソルを合わせてalignする例 f:id:Kechol:20170618144112g:plain

  • Vimバインディングにvim-modeの改良版の vim-mode-plus を使うことにした。良い感じ
  • 家と会社のPCで、Atomの設定を共有することにしたが、 sync-settings が便利だった。Atomだけなら dotfiles いらない
  • 複数のリポジトリを行き来することが増えたので project-manager を導入した。cson は自分で編集しないとだけどとても便利
  • open-on-github というコアパッケージが存在することを知らなかったのだけど、編集中のファイルをGithubでパッと開けるのでめちゃ便利だということに気づいた。SSH configとか使っているとRemote URLの引当がうまくされず、動かないことがあるので注意
  • Atom 1.18.0 から使える GitHub Integration 、まだそんなにちゃんと使ってないけど特にGit Viewが便利っぽかった

keymap関連

大した設定はしていないけど捗ったもの。ちなみにkeymapいじるときは keybinding-resolver を使って競合しているショートカットを確認するのが良い。

  • Tab / Shift-Tab でウィンドウ(Pane)を行き来する
'body':
  'ctrl-tab ^ctrl': 'unset!'
  'ctrl-tab': 'pane:show-next-item'
  'ctrl-shift-tab ^ctrl': 'unset!'
  'ctrl-shift-tab': 'pane:show-previous-item'
  • 検索結果/Paretteで Ctrl-j/k で移動する
'body':
  'ctrl-j': 'core:move-down'
  'ctrl-k': 'core:move-up'
'atom-text-editor':
  'ctrl-j': 'core:move-down'
  'ctrl-k': 'core:move-up'

find-and-replace

Atomにはバッファ(ファイル)内の文字列を検索し、複数カーソルで置換する便利機能(デフォルトのショートカットは Ctrl-d)があるのだけど、vim bindingで潰れていることに先日気づいた。

僕程度のvim力だとやりにくい操作がシンプルにできて便利なので改めてショートカットを設定し直した。便利。

一部のctrlを除いてctrlをshiftに置換する例

f:id:Kechol:20170618144124g:plain

アプリ関連

改めてiTerm2にした

なんとなく前のアイコンが古臭くて好きではなく、Terminal.appを使っていた時期があったけれど、アップデートされてアイコンがシュッとしたのと、Terminal.appの描画は遅いんじゃないかという記事をどこかで見た気がしたのでiTerm2にもう一度チャレンジした。

正直iTerm2の機能はほとんど使っていないけれど、Dropbox経由でカラースキーム設定を共有できるのは役立っている。カラースキームは mbadolato/iTerm2-Color-Schemes から選んだ。

ショートカットでターミナルを起動するのは誰しもやるものだと思うけれど、iTerm2のショートカット機能使うよりもTerminal.appの時から使っているAlfred PowerpackのWorkflowで設定するほうがマシだったのでそちらをいまだに使っている。Workflowはターミナルが起動していなくてもショートカットが効く点で優れている。

f:id:Kechol:20170618144213p:plain

こんな感じで、Launch Appsの設定に Toggle Visibility for Apps のチェックをいれておけばターミナルの表示もよしなに切り替わる。

その他のツール系アプリ

  • Magnet :職場の先輩に教えてもらい、いれてみたらウィンドウの整頓や最大化にとても便利だった
  • Gifox :実装した機能やデモをGifで見せることがよくあり、Gifアニメツールのなかでも出来がよさそうだった
  • Amphetamine :アイコンやカスタマイズ性が Caffeine より良かったので乗り換えた
  • Gyazo :サクッとスクショを共有するのに使い始めた
  • Airmail 3 :職場のメールがGoogle Appsになったので、Officeの代わりのメーラーに採用した。複数アカウントをまとめられるし、Gmailのブラウザと同じショートカットが使えて便利だけど実はメール自体をあまり使っていない
  • Wunderlist が開発終了するらしいけど手に馴染みすぎているのでいまだに使っている。悩ましい

これからもちゃんと道具は整備していきたい。

QuipperにJoinして2ヶ月が経った

2017年の4月1日から、リクルート子会社のQuipperでWebエンジニアとして働いている。

なぜJoinすることにしたか

もともと新卒でリクルートホールディングスに入社し、新規事業開発の部署や海外投資を担当する部署でエンジニアとして4年ほど働いてきた。

会社では貴重な経験をたくさんさせてもらえたけれど、小さなチームを転々としたり、社外の組織にコンサル的に関わることが多かったので、もう少し成熟した組織・プロダクトに腰を据えて関わるということをしてみたかった。

そうしたなかでちょうど組織の再編があり、よいタイミングだと思ったので社内の転籍制度を利用してQuipperに応募をした。実際にはリクルートのなかだけでなく、転職エージェントに会ったりして外の会社も少し探ったりしたけれど、結局以下の3つを大事にした結果Quipperだった。

  1. 精神的にスタートアップである組織である
  2. グローバルで意義のある事業を展開している
  3. エンジニアとしてプロダクトを育てることのできる文化・裁量がある

Quipperについては会社のHandbookや、CTOの中野さんのブログを読むと少し前の状況がよくわかると思う。

短期連載Quipper CTOより 第1回: Quipperの今 - Masatomo Nakano Blog

入社のプロセス

社内の転籍制度を利用したけれど、レジュメは一応書いた。たぶんあんまり参考にされていないと思う。他にコードテストがあって、簡単なRailsアプリをシュッと書いた。

転籍の時期が悪く、コードテストの提出を急かされたので大変だったけど、フィードバックではそれなりの評価をもらえて通過できていたようなので良かった。あとそれは0から書いたけど、GitHubで検索すると過去の受験者のコードが見つかることは後から気づいた。まぁコピペはどうせバレる。

それとは別にWebエンジニアチームのマネージャー+リーダー、CTO、CEOと3度の面接をし、転籍となった。

入社してみた感想

グローバルなチーム?

知っている人は知っているが、リクルートの出しているスタディサプリの裏側はQuipperのメンバーが作っており、コードベースの大半もQuipperがグローバルで提供しているQuipper VideoやQuipper Schoolといった製品と共通になっている。

グローバルチーム、といいつつ、僕を含め東京の開発メンバーはほとんどがスタディサプリを作っているので、グローバルに向けたプロダクトを作っている、という感じは期待していたよりも少なかった。

といってもそれは主観的な話であって、全体としてはSlack上でのミーティングやGithubのPull Requestは英語が当然だし、タイムゾーンを意識した非同期なコミュニケーションが多い気がする。Quipperはそのへんのバランスがちょうどよくて、外資のように英語が話せないと死ぬというわけではない(むしろエンジニアで英語話すのは苦手、という人は多い)が、コミュニケーションに英語が混ざるのは当たり前だよね、という雰囲気がある。メンバーも外国人の開発者が増えつつあるので、今後、より英語での会話は増えそうな予感はする。

エンジニアリングと組織

QuipperはGithubの使い方が上手くて勉強になる。全ての開発タスクはGithubのIssueとして一つのリポジトリにまとめられていて、各プロジェクトごとにラベル付けされている。Github Projectsのカンバンで開発ステータスが管理されていて、プロジェクトごとにだいたい2~4人程度がアサインされる。Pull Requestは開発者同士でレビューしてからマージする。リリースはIssueについたマイルストーンをもとに週次で行われていて、リリースノートもGithub上でIssueとして公開される。全ての情報をGithub上にまとめることで、上手く回っているように見える。

これまで自分が開発するなかで、あまり”チームでやる”ということを意識したことはなかったけれど、Pull Requestをレビューしてもらえるのはとても勉強になるし、ポエムを書く場所や折々のKPTがあり、組織として振り返りをして改善していくという文化が根付いていると思う。個人としても、エンジニアリングマネージャーとの1on1でキャリアや直近の仕事の仕方について相談に乗ってもらえるのは非常にありがたい機会になっている。

Webのチームの周りを見ても、インフラを管理するSREチームはなにかあってもすぐ対応してくれるし、ネイティブエンジニアもすごい人ばかりで強いプロダクトを作るための基盤がしっかりしている印象を受ける。ビジネスとしても勢いを感じる。一方で、そうやってビジネスが伸びているからこそ、いわゆるProduct Managerと呼ばれる役割の人はまだ足りていないかもしれない。

個人的に良いな、と感じたのは、エンジニアがユーザの近くにいるということだ。この間は自分もユーザインタビューに同席させてもらった。自分が開発調査の必要なCS対応をすることもあるし、CSのチームから機能改善のフィードバックもされる。学校向けの開発をしているチームでは、エンジニアも希望すれば営業同行が可能で、実際の使われ方を見る機会がある。個人的に、過去こんな風にフィードバックを得られる機会はそれほど多くなかったし、エンジニアとして、ビジネスサイドと一緒にになってユーザにとっての正解を考えられるような文化・組織を求めてきたところがあったので、これについては満足だし、ひと安心といったところ。

プロダクトと技術的負債の辛さ

Wantedlyにもあるように、テクノロジースタックとしては以下のような言語・ツールを使っている。

  • 言語: Ruby, JavaScript, etc.
  • フレームワーク: Ruby on Rails, Backbone.js, Marionette.js, React.js etc.
  • データベース: MongoDB, Redis, PostgreSQL
  • インフラ: AWS, Heroku, GCP

QuipperもStudySapuriも、大きく分けて学校向けのプロダクトと学習者向けのプロダクトの2種類があるけれど、どちらもWebはサーバとフロントで分かれたSPAの構成になっている。

ある程度覚悟はしていたけれど、予想していたよりも歴史の詰まったプロダクト、という第一印象だった。もちろんテストはきちんと書かれているし、それなりにモジュール化されていて変更しやすいようにはなっているけれど、要求される仕様の複雑さに由来する辛さがあり、そこに時代的な背景で古くなったライブラリなどが乗っかった結果負債化している感じがする。

顧客への価値のデリバリーを止めて負債を一括返済しよう、と言うほど子供ではないし、言ったところで一人ではどうしようもないけれど、いずれはどうにかしないといけない。実はQuipperで見てみたかったことの一つが、こうした一人では全体を把握することも難しくなった大きなプロダクトの技術的負債に、組織としてどうやって立ち向かっていくのかということだった。(あともう一つはグローバルなプロダクト開発をどうやって進めているか、だった。)なので、自分としてはちょうどよいケーススタディくらいに思うし、メンバーの一人として、こうした負債の返済にも貢献していけたらと思う。組織としては、20%ルールではないけれど、こうしたエンジニアリングをリードするチームを作っても良いフェーズなのかもしれない。

あと、もう一つ苦労していることの一つに複雑な仕様の把握がある。とはいえまだ入社してたった2ヶ月なのでなんとも言えないけれど、周りを見てもそこに苦労して生産性が下がっている感じが否めないので、なんとかしていきたい。

個人的な生活の変化

Quipperはフレックスでとても働きやすい環境だと思う。MTGも多くないし、一日中コードを書く生活を送ることができている。

仕事でコードを書く生活をしていると、家に帰ってからもコードが書きやすいことに気づいた。たぶん使う脳のコンテキストをスイッチしなくて良くなったからだと思う。自分としては、Quipperにいるうちにきちんとエンジニアリングの素地を身に着けておきたいという思いがあるので、しばらくはがっつりコードを書く生活を楽しんでいたいと思う。

一方で、触れている技術については狭まった感がある。Railsも各種JavaScriptフレームワークもそれぞれ過去にそれなりに経験してきた技術で、それだけを生業とする生活に限界があるのではないかという漠然とした不安がある。巨大なコードベースや他の優秀なメンバーの書いたコードで勉強させてもらいつつ、個人としては技術の幅を広げるようなバランスをとっていきたい。


少し長くなったけど、世界中に教育を届けるためにがんばりたいという所存です。やっていくぞ。

f:id:Kechol:20170603130427p:plain

HerokuをRailsアプリの本番環境として使う

Herokuというのは今さらだけれども、最近、本番環境をHerokuでセットアップする機会があったのでメモを残しておく。前提としてはRailsで作られたWebアプリケーションで、まだほとんどユーザがいないけど本番環境としてある程度まともにセットアップできているレベルを目指したもの。

Herokuインスタンスの無料の範囲

Herokuのインスタンスは、毎月少なくとも550時間は無料で使える。なんだけど、この無料インスタンスは30分間トラフィックがない場合自動的にシャットダウン(スリープ)してしまうため、本番環境としては使えない。なので基本的には $7/month の Hobby Dyno 以上のプランを利用して運用する必要がある。

If an app has a web dyno, and that web dyno receives no traffic in a 30 minute period, the web dyno will sleep. In addition to the web dyno sleeping, the worker dyno (if present) will also sleep.

https://devcenter.heroku.com/articles/free-dyno-hours

Herokuインスタンス(Dyno)で気をつけるべき仕様

有料プランであっても、Herokuのインスタンスは約1日のサイクルで勝手に再起動する。開発者側ではこのタイミングをどうにかすることはできない。特にアプリ側で長い処理を行う場合には、トランザクションに気をつける必要がある。

Dynos are also restarted (cycled) at least once per day to help maintain the health of applications running on Heroku. Any changes to the local filesystem will be deleted. The cycling happens once every 24 hours (plus up to 216 random minutes, to prevent every dyno for an application from restarting at the same time).

https://devcenter.heroku.com/articles/dynos

また、Herokuインスタンスでは、インスタンス内にファイルを保持しておく方法がない。Restart の度に全てのファイルは削除されるので、ファイルのアップロードなどで永続化するファイルはS3かどこかに保存する必要がある。

Each dyno gets its own ephemeral filesystem, with a fresh copy of the most recently deployed code. During the dyno’s lifetime its running processes can use the filesystem as a temporary scratchpad, but no files that are written are visible to processes in any other dyno and any files written will be discarded the moment the dyno is stopped or restarted.

https://devcenter.heroku.com/articles/dynos#ephemeral-filesystem

Heroku のインスタンスはDB用のインスタンスも含めて、基本的にプライベートなネットワーク内に置くことができない。( Heroku Private Spaces) という機能があるが、Heroku Enterpriseのみにしか提供されていない。)

なので、個人情報保護の問題で、DBなどをネットワーク的に隔離したい場合には、気軽に Heroku を使うことができない。そうしたい場合は素直にAWSでVPCを構成しましょう。

あと、現在Herokuインスタンスを立ち上げる際にサポートされるRegionはUSとEUの2つしかなく、インスタンスをTokyoに立ち上げることはできない。レイテンシは気にしないようにしましょう。

Two regions are available, US and EU. Each dyno is secured with strong firewall rules so even though all dynos run in a single, flat network, they are strongly isolated from each other.

https://devcenter.heroku.com/articles/dyno-runtime#common-runtime

各種モニタリングツールの活用

Heroku の良いところの一つに、色々な有料モニタリングツールがアドオンとして無料で使えるところがある。

有名どころとしては以下のようなものがあるので設定しておくと良い。

個人的なおすすめはAirbrakeとPapertrail。他にもDeploy HooksでSlackに通知したりするのも便利だし、Herokuダッシュボードのメトリクスツールもよくできている。

HTTPS化とLet’s Encrypt

今ではHerokuで運用しているサービスも自動でrenewされるLet’s EncryptでHTTPS化できる。もちろんLet’s Encryptでなくても自分で買った証明書を設定することも可能。

HerokuでのLet’s Encryptの設定は以下に詳しい。

https://devcenter.heroku.com/articles/automated-certificate-management

なんだけど、Heorkuで設定されるドメイン(*.herokussl.com)をCNAMEでトップレベルドメインに割り当てることができないので注意が必要。

Configuring your DNS provider for a root domain is similar to configuring a DNS provider for a subdomain. However, whereas with subdomains the type of record to configure is always a CNAME, with root domains the type of record depends on the DNS provider:

https://devcenter.heroku.com/articles/custom-domains#add-a-custom-root-domain

これはRFC1912で規定されているのでしょうがない。DNSプロバイダによってはALIASやANAMEといった代替手法が使える場合もある。個人的には結局AWSのCloudFrontをかませてAWS側でHTTPS化した。

CI を使ってデプロイする

Herokuへのデプロイは、Gitを利用してHeroku上のリポジトリにpushすることで簡単に行うことができる。もう少しまともにやろうと思ったら、CIなどでテストが通ったときにデプロイしたいけど、これも難しくない。

Circle CIでは、Herokuとインテグレーションがされていて、HerokuのAPI Keyを登録して circle.yml に以下のように追記するとCIからデプロイできるようになる。便利。

deployment:
  production:
    branch: master
    heroku:
      appname: heroku-appname

デプロイ時のコマンドをカスタマイズするなど詳しくは以下。

https://circleci.com/docs/1.0/continuous-deployment-with-heroku/

Worker を動かす

Herokuでは、WorkerのプロセスをWeb用のインスタンスとは別に動かす必要がある。今回はActiveJobのプロバイダとして mperham/sidekiq を利用した。

基本は以下の設定のとおりにやった。 https://github.com/mperham/sidekiq/wiki/Active-Job

各種ファイルの設定は以下のような感じ。

Procfile

web: bundle exec puma -C config/puma.rb
worker: bundle exec sidekiq -C config/sidekiq.yml

environments/production.rb

config.active_job.queue_adapter     = :sidekiq
config.active_job.queue_name_prefix = "myapp_#{Rails.env}"

config/sidekiq.yml

:verbose: false
:concurrency: 5
:queues:
  - myapp_production_default
  - myapp_production_mailers

yamlに処理するqueueのkey名を列挙しておかないと処理されない。またconcurencyの数とRedisの同時接続上限に気をつける。

そして、バックエンドにRedisを使う場合はもう少し設定が必要。(最初やってなくてQueueが処理されず困った)

https://github.com/mperham/sidekiq/wiki/Using-Redis

REDIS_PROVIDER環境変数をセットする必要がある。値はRedisのURLがセットされている環境変数のkey名(url自体ではない)。

heroku config:set REDIS_PROVIDER=REDISCLOUD_URL
# config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
  config.redis = { url: ENV['REDISCLOUD_URL' }
end

Sidekiq.configure_client do |config|
  config.redis = { url: ENV['REDISCLOUD_URL'] }
end

Redis プロバイダとその活用

Herokuでは、様々なRedisホスティングのプロバイダがいるのでサービスを選ぶと良い。無料枠でメモリが一番多いのが Redis Cloud っぽいので、自分はそれを使っている。

また、Heroku には Memcached のプロバイダがいないので、RailsではSessionやCacheにもRedisを使うのが楽で良い。以下のようにすれば設定可能。

# config/environments/production.rb
  config.cache_store = :redis_store, ENV['REDISCLOUD_URL'], { expires_in: 2.hours }
  config.session_store :redis_store, servers: [ENV['REDISCLOUD_URL']]

cron ではなく Heroku Scheduler

定期的なタスクを実行したい場合は、cronではなくHeroku Scheduler というアドオンを使うのが一般的。実行頻度は Daily/Hourly/Every 10min から選択することができる。

Heroku Schedulerで起動されたインスタンスはその起動時間に応じて請求が発生する(もしくは無料範囲の時間が消費される)。

また注意点として、2分以上かかるような長いJobはHeroku Schedulerのインスタンス内では実行できないので、WorkerにJobを登録するなどといった対策が必要。

Scheduled jobs are meant to execute short running tasks or enqueue longer running tasks into a background job queue. Anything that takes longer than a couple of minutes to complete should use a worker dyno to run.

https://devcenter.heroku.com/articles/scheduler


Heroku は頑張らないインフラにおすすめです。

f:id:Kechol:20170524223347p:plain

メルカリでうまく売る - 配送・トラブル対応編 -

公開するの忘れていたけど、メルカリで上手く売る -出品編- の続き。配送対応から。

配送の対応

配送の方法と料金

配送は基本的に、らくらくメルカリ便(ヤマト運輸)か、郵便局を利用するのが楽だと思う。小さくて封筒に入るようなもの(化粧品、アクセサリーや単行本など)は郵便局で送るのが安く済む。ある程度モノが大きかったり、匿名で配送したいということであればメルカリ便のヤマトで配送する。

郵便局では、定形郵便物の範囲であれば、100円以内で送ることができる。定形外でも、三辺が90cm(1辺最大60cm)かつ250g以内に収まるものであれば、250円以内で送ることができる。

ヤマトでは、3編計60cm、重量2kgまでの60サイズの品物は、関東の範囲であっても送料は756円かかる。すこし大きくなって100サイズを超えると送料も1000円を超えてきてしまうので馬鹿にできない。また、宅急便コンパクトという専用ボックスで送るサービスだと、400円程度で品物を送ることができる。

ヤマトでの配送は、コンビニに持ち込むこともできるけど、もし近くにヤマトの営業所があれば営業所に行くことをおすすめしたい。梱包が甘い場合は一緒に梱包をしてくれるし、配送票を印刷するネコピットの扱いも丁寧に教えてくれる。

梱包材の値段

今回は、梱包材についてはヤマトの営業所で売っているものを利用した。また、封筒やプチプチは近くの文具店で買うことができた。

ヤマトの営業所で売っている資材は、配送料別にサイズが最適化されている。

f:id:Kechol:20170323185127j:plain

段ボール箱だと100円以上するが、袋だと数十円で済むので、衣類などは袋で、ワレモノは箱で送るようにすると良いと思う。

自分は、送るものの大きさがよくわからないことが多かったので、箱に詰めるだけの状態の品物を営業所まで持っていき、その場で段ボールを比べて購入する、という事をしていた。ヤマトの人が毎回親切に対応してくださってありがたかった。(忙しい午前中などに行くのは迷惑だったかもしれないけど。。)

梱包時の注意点

個人の配送なのでそこまで気を遣わなくてよいが、梱包時には以下のことに注意すると良い。

  • 品物の汚れなどはアルコールなどで綺麗にしておく
  • 配送中に雨が降る場合はビニール袋にいれ、濡れるのを防ぐ
  • 精密機器やワレモノはプチプチで包んでおく
  • 余った梱包材や新聞紙などをいれて品物が段ボール内で動かないように固定する

今回は利用しなかったが、ハコBOONやクリックポストで安く配送できるケースもあるみたいだった。

配送のことを考えると、小物や衣服よりも精密機器やワレモノのほうが梱包材や配送料にかかるコストが大きいので、売値をつけるときには考慮すると良い。

トラブルの対応

取引のキャンセル・返品

今回、配送をしてしまってから取引がキャンセルになり、返品されたことがあった。

そうした場合には、お互いにキャンセルに合意し、購入者から品物を返品してもらった上で事務局に連絡すれば、取引がキャンセルになる。

なお、返品時のやり取りについて事務局に問い合わせた際には以下のような返答だった。

1.購入者は、出品者に商品を返送後、出品者のお手元に届くまでお待ちください。
※返品の際の送料については双方でご相談ください。
※返品を行うにあたり取引相手の住所等の情報が必要な場合は、取引メッセージでご確認をお願いいたします。

2.出品者は、お手元に返品商品が届きましたら、取引メッセージで報告のうえ、事務局までお問い合わせください。

3.事務局で取引状況を確認後、キャンセル(返金)手続きを行います。

返品の際には、メッセージでこちらの住所氏名を伝える必要がある。また、送料については、こちらに非があれば着払いで、先方の都合であれば先方の負担で送ってもらえば良いと思う。

取引がキャンセルされると、アプリ上では品物が「出品停止中」のステータスに変更される。

購入者が受取評価をしてくれない

取引しているときに、購入者が商品を受け取っても受取評価をしてくれないことがあった。幸いこのときには、数日待つとしてくれたので問題なかったが、たまに受取評価をしてくれない人もいるようだ。

メルカリのヘルプによると、そうした場合には、一定の期間が経つと事務局に評価依頼をするためのフォームが出るようになっているらしい。なので、一旦待ってみて、解決しないのであれば事務局に評価を依頼するのがよさそうだ。

 万一、購入者からの応答がない場合、以下の条件を満たすことで取引画面上に事務局に評価を依頼するためのフォームが表示されますので、そちらからご連絡ください。

・発送通知をした8日後13時以降
・購入者の最後の取引メッセージから3日後13時以降

※話し合いが継続している場合や商品に問題がある場合、事務局での評価はできません。あらかじめご了承ください。

よくある質問と答え - Mercari


メルカリなどのフリマアプリは、今後もうまく活用していきたい。

メルカリでうまく売る - 出品編 -

せっかくなので、初めてメルカリを利用したときに気づいたことをメモしておこうと思う。まずは出品時のお話。

プロフィールの設定

いろいろな人のプロフィールを見ていると、以下のような事柄が書いてある。安心感を与えることができるので真似すると良い。

  • 年代/都道府県
    • 少なくとも未成年かどうか判別できるとよい
    • 都道府県から発送にかかる日数が推測できる
  • 出品している物の出処
    • 「買ったけど使わなくなったものを出品しています」等
  • 喫煙・ペットの有無
    • 匂いやアレルギーを気にする人が多いっぽい
  • 発送にかかる期間
    • 「土日に発送しています」「お急ぎの方はご遠慮ください」等
  • 免責事項
    • 「中古のため返品不可でお願いします」等
    • もちろん柔軟に対応するけど建前という感じ
  • 独自ルールへのポリシー
    • 名前欄に「@プロフ必読」とする
    • 「即購入(コメントせずに購入する行為)不可です」
    • 「少しでしたらお値下げ可能です」等

また、プロフィール画像は初心者感が消えるので必ず設定すると良い。

出品に適している商品

ゴミでも売れる、という神話もあるらしいメルカリだけれど、そもそも売れるか、そして利益が出るか、という観点から出品するかどうかを考えると良い。

  • 小さいものの送料は一番安くて120円(郵便局の定形外サイズ)、大きいものは700円(ヤマトの80cmサイズ)以上になることもある
  • 配送のためのダンボールや袋、梱包材を買うと数百円かかる
  • あまりに古いものは購入者からの返品リスクがある
    • 返品時の配送料はユーザ間で協議して負担することになる
  • メルカリでの販売手数料は10%かかる

サイズにもよるけれど、最低でも2000円程度で売れるものでないと、残る利益が1000円を割ると思う。購入時の半額が相場だと考えると、だいたい4000円以上で購入したものであれば売るに足る。

出品タイトルのつけかた

出品するときには、一度出品前に自分の思いつくキーワードで検索して見ると、検索サジェストから良く検索されるキーワードが出てくるので参考になる。

例えば3DSを出品する場合だと、「3DS」というキーワードだけでなく「本体」というキーワードも一緒に入れたほうが良さそうなことがわかる。

f:id:Kechol:20170409144917p:plain:w320

写真の活用のしかた

メルカリの写真は4枚までしか出せないので、悩ましいけれど以下のような写真を撮る。

  • 全体像(付属品も含む)
  • メインのアップ(メインのモノだけ)
  • バック、サイドの別角度
  • キズ、スレの一番ひどい部分のアップ
  • (服であれば)サイズ表のスクショ

中古であれば多少のキズがあるはずで、そういう部分を先に開示しておくことで安心して取引してもらえるし、返品リスクも減る。サイズ表はAmazonやZOZOなどの商品ページをスクショして載せた。

他にも写真のアップの際には以下のようなテクニックが使える。

  • モノが明るい色の場合は背景は暗い色、逆なら背景は明るい色
    • モノの色味が正確に出やすくなる
  • 編集機能で色味とシャープネスを修正する
    • 色味が変化しすぎるフィルタは多用しない
  • サイズのあるもの(靴、服)は一枚目の画像にテキストでサイズを表記すると一覧画面でもわかりやすい

最初の値付け

出品の際には、タイトルとカテゴリ、ブランド、商品の状態を入力するとメルカリが売れやすい価格をサジェストしてくれる。

f:id:Kechol:20170409144938p:plain:w320

また、公式のガイドには以下のような値付けのガイドラインがある。

  • 新品/未使用品: 60-80%
  • 未使用に近い/汚れがない: 30-60%
  • 使用感がある: 20-40%

自分はすぐ売りたかったこともあり、サジェストされた価格の中央値+500円(送料分)くらいで値を付けていた。また、似たような過去の出品を検索してみるのも最近のトレンドがわかって良い気がする。

出品の時間帯

メルカリは出品された品物が時系列に並んでいるっぽいので、買ってくれそうな層が見ている時間に出品の時間帯を調整すると良い。

例えば以下のような考え方がある。

  • 婦人服: 主婦層が買うのでお昼過ぎ
  • ゲーム: 中高生が買うので夕方
  • ガジェット: 会社員男性が買うので夜7時以降

逆に言うと、出品して3日とか経ってしまった場合には検索で引っ掛からない限り閲覧される機会がないので、一度出品を取り消して再出品するのが良いかもしれない(利用規約確認してないけどNGなのかな・・・)。

値下げのタイミング

大抵の商品が値下げされるからなのか、メルカリのユーザはすぐに購入せずにまずいいねをつけて様子を伺うきらいがある気がする。

大体、1日経って売れなかったら10%程度値下げするのが良い気がする。

また、たまに「値下げ可能ですか?」的なコメントをもらうことがあるが、特に出品して数時間のときは「もう少し考えさせてください」などと言って流しつつ、時間が経った時点で改めてコメントで連絡したら良いと思う。


売れた後の配送などについては次回。

メルカリ公式ガイドBOOK

メルカリ公式ガイドBOOK

はじめてメルカリで出品した

部屋の整理の一環で、家にある使っていないものを整理しようと思い、初めてメルカリを利用した。せっかくなので感想をメモしておこうと思う。

出品したもの

f:id:Kechol:20170416113041p:plain:w320

使わなくなったデバイスや、来ていない服・鞄・靴を主に出品した。

デバイスでいくとiPadは第三世代、Kindleは第五世代で、どちらも数年前に購入したものだったけど、数千円で売れたので、下手にアキバの買い取りなんかに持っていくよりも良いお金になる気がした。

戴き物のインドの木像が家にあり、ちょっとキャラが強すぎたので出品することにした。こうしたニッチなノンブランドの雑貨が売れるとは全く期待していなかったけど、実際に売れたのでびっくりした。メルカリの懐の深さを感じたし、良い検証になった。

逆に数年前に青山かどこかで購入して結局着なかった新品のフォーマルなシャツは売れなかった。ユーザ層的に実は男性が少なかったりするのかもしれないし、単に需要がなかったのかも。

売れるもの売ったら数万円にはなったので、部屋も片付いてお小遣いも手に入ってよい体験だった。

トラブルで返品対応

一度、実際の商品とは違う説明を誤って記載してしまい、商品を送った後に先方が気付いて返品を希望されたことがあった。

これについては自分に非があったので、送料着払いで送り返してもらい、正しい情報で再出品して別の人に購入してもらった。

よく確認せずにAmazonの情報をコピペしてしまったのが原因だったけど、幸い購入者の方も慣れている方で助かった。ごめんなさい。

返品や取引のキャンセルの際には、一度こちらからサポートに問い合わせる必要があり、問い合わせると、事務局からお知らせ欄に個別メッセージが来る。返品の対応が完了した後に事務局が取引メッセージを確認たうえで初めてキャンセルとなる。

f:id:Kechol:20170416113113p:plain:w320

キャンセルに至るまでには少なくとも2回問い合わせが必要であり、また、取引キャンセルの場合はメルカリ便の送料負担が実質メルカリ側になる(売上が発生せず送料を差し引くことができないため)ので、運営側にも負担が大きい。こうしたサポートはサービスの運営者としても大変だなと思う。ごめんなさい。

フリルとメルカリ

フリマアプリと言えば、メルカリの他に楽天に買収されたフリルがあって、現在は販売手数料が無料なので、本当はフリルで売ったほうがお金になる。(売ってみて改めて感じたけど10%の手数料はなかなか大きい。)

なんだけど、フリルはインストールしたときの初回画面で、メンズかウィメンズか選ぶような画面遷移になっていて、この時点で「あ、デバイスとか売っちゃいけない雰囲気なのかな・・・」と思って離脱してしまった。(実際にはなんでも売られているけど)

f:id:Kechol:20170416113128p:plain:w320

元々女性向けだったこともあり、フリルは服やコスメが充実している印象なので、そういう出品/購入が多い人には良いと思う。

また、フリマアプリを使ってみた印象として、ふたつのアプリに同時出品する、というのは管理が大変で難しいように感じた。上記の通りキャンセルには手間がかかるし、わりと短時間で突然買われてしまうので。それよりはどちらかで売れなかったらもう一方に出品する、という風にしたほうが良さそう。手数料を考えると先にフリルで出品し、売れなかったらユーザの多いメルカリで試す、という流れが一番良い気がする。

メルカリという会社

メルカリは会社としても、Offer Up や Let go といったすごく伸びてる競合がいるUSの市場に挑戦していたり、メルカリ アッテでまだ日本に圧倒的な成功者がいない(と言っていいと思う)クラシファイドに挑戦していたりと、会社としても面白い。

ちょっと前のRebuildでもCTOの sotarok さんがグローバルなプロダクトの開発について話していて面白かったのを覚えている。

企業ブログである メルカン でも会社のことがたくさん広報されており、勉強になる話がたくさんある。人事・広報主導でここまでやっている企業は少ないんじゃないだろうか。メルカンではポッドキャストもやっていて、最近だとアッテのコミュニティマネージャーの回が勉強になった。聴くとやっぱり草の根活動は必要なんだな、と思う。


使ってみてやっぱり良くできたプロダクトだと思う。アメリカでも競合に負けず頑張って欲しい。出品のTipsなどはまた次回。