読者です 読者をやめる 読者になる 読者になる

Forkwell Meetup #4 イベントレポート

こんにちは!エンジニア組織推進室の中野です。
3/18(土)のForkwell Meetup #4にスポンサーとして参加してきました! 実は前回もスポンサーとして参加しておりました。

▼前回の様子

Forkwell Press – 発表スライドまとめ − Productivity...

Forkwellさんにはいつも素敵な場をつくっていただき、感謝です!
インタビューもしてもらいました。よかったら見て下さい(^q^)

Forkwell Press – Speee 流『優秀なエンジニアを惹きつけるスカウトの秘訣』 / Forkwell Scout

f:id:kana-nakano:20170322183426j:plain## 雰囲気

今回の会場はメディアドゥさんのオフィス。
お…おしゃすぎる…!広い~!!(走りたくなるぞ)

f:id:kana-nakano:20170320214037j:plain f:id:kana-nakano:20170322190058j:plain

他のスポンサー企業様はこんな感じ。(一部抜粋)
▼ヌーラボさん。ヌーラボラベルの日本酒…美味しそうだった~

f:id:kana-nakano:20170322190135j:plain

▼ネクストさん。ホームズくんのキュートさったら。

f:id:kana-nakano:20170322190156j:plain

Speeeはコーヒーをハンドドリップで提供しました。
“Speee Blend"という社員の嗜好に合わせたしっかりとコクがあり、冷めてくると後味に甘い余韻がある特注の豆でご用意しました!

f:id:kana-nakano:20170320220338j:plain f:id:kana-nakano:20170321230142j:plain

一緒に参加したエンジニアの@hatappi@pataiji(左から)。
Speee Blend、好評だったみたいで嬉しいです。提供追いつかなくて飲んでいただけなかった方、本当にすみません!もくもく会イベントでも提供しているのでぜひご参加ください(๑´ڡ`๑)

ゲストトーク

とにかく登壇者が豪華でした。非エンジニアの私でも知っておくべき大切な内容がたくさんありました。例えば…

  • 振り返りの進め方・雰囲気づくりが大事。KPT以外にも色んな振り返り手法があるし、むしろ同じ手法だと同じ観点からしか意見がでなくなり、みんなツラくなってくる。
    (Effective Retrospective アトラクタ @ryuzeeさんの発表)
  • ペアプロについて。書かれたコードを片っ端からコードレビューしていく。レビューは新鮮なうちにするのが良い、とのことですがこれはどんな仕事も一緒。最速でPDCAを回す劇薬。
    (ペアプログラミングの使いどころ タワーズ・クエスト @t_wadaさんの発表)

などなど。他にも為になる内容がたくさんあり、非常に勉強になりました!

LT&交流会

交流会のなかにLT発表が含まれていました。弊社からは@pataijiが発表しました! 皆さんお酒片手にしっかりLTを聞くという。笑

f:id:kana-nakano:20170322190229j:plain

まとめ

ブースに遊びに来てくださった方、ありがとうございました\(^o^)/
「Speeeさん最近どこにでもいるね~!(笑)」ってよく言われるんですけど、それだけ真剣に一緒に働く仲間の採用活動をしてます!まずはSpeeeのことを知ってほしい、その想いが強いです。本気で技術に向き合っている私たちSpeeeですが、もし興味を持ってくださった方は、ぜひ気軽にラウンジに遊びに来て下さい!お待ちしております♪

f:id:kana-nakano:20170320222914j:plain

HAProxyによるブランチ毎ABテスト基盤

こんにちは、新卒エンジニアの宮地(miyachik)です。
業務ではネイティブアド配信プラットフォーム UZOUの裏周りをやっています。

今回はSpeeeKaigiで発表した(フロントの変更なら)エンジニアの工数を必要とせず、アプリケーションの開発言語を問わない汎用的ABテスト基盤の話をします。 SpeeeKaigiについてはこちら↓

tech.speee.jp

前提

今回のABテスト基盤では

  • ブランチを分けた状態で個別にABテストができる(masterにマージする必要なし)
  • フロントの軽微な修正はエンジニアにはエンジニアの工数は割かない(ディレクターとデザイナーのみで行えるようにする)
  • API側などbackendのロジックに対するABテストも行えるようにする
  • 開発言語にとらわれずABテスト基盤導入をすることが可能

を実現することが出来ます。表側はRailsで裏側にAPIサーバーがいる、みたいなときにも試すことが出来ます。(簡単な変更のみならば既存のgemなどを使えば良いのですが、どうしても要件を満たせないことが出てきてしまうので…)

まずは最上段の振り分けについて話したいと思います。

やったこと

  • HAProxyによるABテスト振り分けと再抽選の防止
  • HAProxyの設定ファイルをRailsアプリケーションから動的に吐き出し、アプリケーションをデプロイとHAproxyの設定を再読込するタスクを作成
    • ABテストサーバをbackendから切り離し
    • 対象のABテストブランチをABテストサーバにデプロイ
    • 生成したHAProxyの設定を再読込
    • フロントのダウンタイムはゼロになるように

HAProxyについて

HAProxy とはプロキシサーバであり、ソフトウェアロードバランサーです。 HAProxyが何であって、何でないかは公式のドキュメントに書いてあります。 ドキュメントにもある通りHAProxyにはロードバランサーとしての機能があり、HAProxy自身がCookieを発行することができます。そしてCookieがセットされているかを判断することもできます。 また、HAProxy単体でABテスト振り分けに関する機能は実現可能なため、Front/backendのアプリケーションの種類は問われません。

インフラ構成図

ざっくりとした構成は以下です。各sideごとのサーバ台数はHAProxyのbackend定義により行えます。 f:id:tigger501st:20170315110949p:plain

ABテストパターンが反映されたブランチはab_sideにのみにデプロイされ、結果が芳しくない場合にはmergeせずに次のABテストに進むことが出来ます。

HAProxyによるABテスト振り分け

振り分けについてはHAProxyのACLとbackendの複数定義により行っています。

ACL(Access Control List)

公式ドキュメント HAProxyのACLは非常に柔軟なアクセスを振り分けることができます。 下記のように書くことでCookieを判断して振り分けるbackendを変更することが可能です。

    acl normal hdr_sub(cookie) ab-test-pattern=0
    acl ab-test-pattern hdr_sub(cookie) ab-test-pattern=1
    use_backend normal_side if normal
    use_backend ab_side if ab-test-pattern
    default_backend first_side

ab-test-patternというCookieが存在していない場合(初回アクセス時)には first_side に振り分けら、Cookieが存在しており && 値が1なら ab_sideへ、値が0なら normal_sideへ振り分けられます。

backendの定義

backendの定義は下記の様に行い、初回アクセス時にはCookieを挿入し、重み付け付きの振り分けに関してはweightで行います。この様にすればweightによってABテストサーバーに振り分けられたユーザはその証拠としてCookieの値として 1が書き込まれます。

下記の例ではnormal:AB = 75:25になっています。normalの確立 = ホスト名末尾が 0に行く確立の総和です。なので、設定を吐き出すときにはnormal_sideのweightは設定されている(normal_sideのホスト数)/(設定したいnormal側のweight)である必要があります。 デプロイされているアプリケーションのブランチが違うので、アプリケーション側で ab_side側かnormal_side側のアクセスなのかは判断する必要はありませんが、事故を防ぐ場合Cookieの値を参照することによりユーザがどちら側に抽選されたのかを判断することができます。 初回アクセス時にはCookieはセットされておらず、X-HOST-NAME を使用しHeaderからホスト名を参照しab_sideかnormal_sideかを判断することが出来ます。

backend first_side
    mode http
    cookie ab-test-pattern insert nocache
    balance roundrobin
    http-send-name-header X-HOST-NAME

    server web1-0 127.0.0.1:80 weight 25% check cookie 0 inter 1000 fall 2
    server web2-0 127.0.0.2:80 weight 25% check cookie 0 inter 1000 fall 2
    server web3-0 127.0.0.3:80 weight 25% check cookie 0 inter 1000 fall 2
    server web4-1 127.0.0.4:80 weight 25% check cookie 1 inter 1000 fall 2

あとはnormal_sideにはnormal側のホストのみを宣言すればnormalにしか行きません。 ただし、ab_sideにはnormal側のホストを含めて宣言しないと、万が一ABテストサーバ(今回の場合web4-1)が落ちていた場合に該当するホストが見つからずアクセスできなくなってしまうので注意が必要です。(check cookieをしている場合でもホストが落ちていると振り分けは行われず別のサーバへ振り分けられる)

以下が実際に吐き出されるファイルです。負荷などを気にする場合は適切にmaxconn等の設定を追記してください。ブランチ名はab-test-patternの想定です。 normal_sideのIPなどはRailsのconfigファイル内に配列で書いています。

global
    log         127.0.0.1 local2 info
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     10000
    user        haproxy
    group       haproxy
    daemon
defaults
    log     global
    timeout connect 60s
    timeout server 1m
    timeout client 1m
    timeout check  5s

# web
listen frontside
    maxconn 4000
    fullconn 4000
    bind 0.0.0.0:80
    mode http
    acl normal hdr_sub(cookie) ab-test-pattern=0
    acl ab-test-pattern hdr_sub(cookie) ab-test-pattern=1
    use_backend normal_side if normal
    use_backend ab_side if ab-test-pattern
    default_backend first_side

backend first_side
    mode http
    cookie ab-test-pattern insert nocache
    balance roundrobin
    http-send-name-header X-HOST-NAME

    server web1-0 127.0.0.1:80 weight 25% check cookie 0 inter 1000 fall 2
    server web2-0 127.0.0.2:80 weight  25% check cookie 0 inter 1000 fall 2
    server web3-0 127.0.0.3:80 weight  25% check cookie 0 inter 1000 fall 2
    server web4-1 127.0.0.4:80 weight  25% check cookie 1 inter 1000 fall 2

backend normal_side
    mode http
    balance roundrobin

    server web1-0 127.0.0.1:80 check inter 1000 fall 2
    server web2-0 127.0.0.2:80 check inter 1000 fall 2
    server web3-0 127.0.0.3:80 check inter 1000 fall 2

backend ab_side
    mode http
    cookie ab-test-pattern insert nocache
    balance roundrobin

    server web1-0 127.0.0.1:80 check cookie 0 inter 1000 fall 2
    server web2-0 127.0.0.2:80 check cookie 0 inter 1000 fall 2
    server web3-0 127.0.0.3:80 check cookie 0 inter 1000 fall 2
    server web4-1 127.0.0.4:80 check cookie 1 inter 1000 fall 2

HAProxyの設定変更はRailsアプリケーションから、指定したブランチのdeployはcapistranoで実現しました。

処理の内容としては

  • HAProxyからab_sideを切り離したconfigをreload
  • 指定したブランチをデプロイ
  • 生成したHAProxyのconfigファイルを再読込

です。HAProxyはgraceful restartが可能なので、デプロイによる表側への影響はありません。

まとめ

実現したこと

  • 既存の構成を崩さない形での振り分け器の導入
  • HAProxyによる、Cookieを使用したアクセス先サーバーへの制限(再抽選防止)
  • HAProxyの設定ファイルを自動書き出し&deploy時読み込み

実現できていないこと

  • オートスケールの考慮
  • deployする毎にインスンタンスのIPが変わる場合の対処
  • 完全なmasterとの同期システム

Q&A

Q.ABテスト用にカラムを追加したいどうする?

A.現状、表側の変更のみを考えているため、考慮していなかった。おそらくdeployフローでmigrationを用意しておくことで対策。

Q.Masterとの同期はどの程度で考えていますか?

A.複数のテストが平行して走る際は、deploy時にmasterとの同期考えているが、それだけではおそらく不整合が出てしまうケースがあるので、考慮が必要。考えきれていなかった。

Speee Loungeで「もくもく会」やってるよ!

こんにちは、広報の生田です。
全社広報とエンジニア採用広報を担当しています。
最近、花粉症にはマスクが効果的という所に行き着いたので四六時中マスクしています。

Speeeでは土曜日の朝から「もくもく会」を開催しています。
今回はその「もくもく会」についてご紹介させていただきたいと思います。
休日も、黙々と作業(コード書く、デザイン考える、仕事など)したいという方には、
電源もコーヒーもあるのでオススメの空間となっています。ぜひ見ていただけると嬉しいです! f:id:mogmog2:20170310162723j:plain

「もくもく会」ってなに?

Speeeが運営する「もくもく会」は、六本木にあるSpeeeのカフェラウンジ
基本隔週土曜に開催しています。色んな会社の開発者の方が来て、
それぞれの作業をもくもくとやっています。

雰囲気は基本的に静かなカフェラウンジを想像していただけると近いです。
回によって参加人数は様々で、あまり少ないと開催を見送ることもあるのですが、
多いときは20人以上参加者がいることもあります。(たまにです)

f:id:mogmog2:20170308203710j:plain

朝ごはんとコーヒーがある♪

朝10時からゆるりと始まり、豆挽きたて・淹れたてのコーヒーをご用意しています。
朝ごはんはコーヒーとパンを用意していますので、まずは目を覚まして集中する準備も万端♪

f:id:mogmog2:20170308203646j:plain

ランチの時間にはせっかく集まったのでみんなで楽しくご飯を食べる時間を取ったりと、
まったり楽しく、でも作業はもくもくとやっています。

もくもくした成果共有もします

最後はその日の成果などを発表して、みんなで幅広い情報共有をしています。

f:id:mogmog2:20170308204700j:plain

中にはマイコンでの開発をして発表してくださった方も!色んな刺激を受けます。

参加したいけど、資格とかいるの?

もくもくと作業したい開発者の方々は誰でも 開発者の方々でしたら、どなたでも参加いただけます!
compassでもくもく会の募集をしていますので、こちらをチェックしてみてください♪
月に1~2回やっています。

speee.connpass.com

スケジュール

10:00~ もくもく作業
13:00頃~昼食タイム
14:00頃~成果発表(今日のやったことなど)
15:00頃 解散

全体的にゆる~くやってます。

まとめ

せっかくの休日だから有意義に過ごしたいよね、という思いではじまった「もくもく会」ですが、
色んな開発者の方が集まっていただける場所になり、
これからもそんな場所でありたいなと思っています。

お気軽にぜひ、お越し下さい♪

DroidKaigi 2017に参加しました

コミュニケーションメディア事業部リードエンジニアのid:eva-hashimotoです。

3/9-3/10に行われたDroidKaigi 2017にスポンサーとして参加してきました。 f:id:eva-hashimoto:20170314124007j:plain

今回は開発部顧問の井原さんが立ち上げたサービスのKibelaを作っているBit Journey, Inc.と合同ブースを設営しました。
try! Swiftのときにはコーヒーを用意していましたが今回は用意していません・・・! f:id:eva-hashimoto:20170314124511j:plain

各種スポンサー枠で出店されている提供品がとても豪華でした! お菓子やコーヒーがとてもうまい f:id:eva-hashimoto:20170314130052j:plainf:id:eva-hashimoto:20170314130103j:plainf:id:eva-hashimoto:20170314130126j:plain

さて、肝心のスピーカーセッションですが全体的にRx、ORM、Kotlinのセッションが人気だった気がします。 個人的にもORMが気になっており、realmgfx氏Ormaの事例紹介はとても楽しめました。 f:id:eva-hashimoto:20170314132842j:plain スピーカーのスケジュールが確認できる公式アプリが用意されておりこれがめっちゃ便利!

まとめ

2週に渡りiOS、Androidの両フォームでカンファレンスが開催されアプリエンジニアは両方参加された方も多かったのではないでしょうか? アプリのカンファレンスは規模拡大が進んでいる印象があり勢いを感じました。

弊社もVICOLLE(ビコレ)をリリースしたばかりで最新のアーキテクチャを使いたく 今回のカンファレンスの内容を聞いていてとても参考になる部分があり来年は弊社からもスピーカーとして参加したいと思いました。

また弊社Twitterアカウントもではエンジニア関連のイベントや勉強会情報を発信していますので是非フォローをよろしくお願いします。

SlackBotを作るSlackBotを作った

こんにちは、Duenoです。 私はデジタルコンサルティング事業部のエンジニアで、普段業務ではMarkeshipというアプリケーションの開発に携わっています。 今回は、SpeeeKaigiで話したSlackBotについて話していきます。

SpeeeKaigiについてはこちら↓

tech.speee.jp

はじめに

Speeeでは現在メインのチャットツールとしてChatWorkが全社的に利用されています。 Slackも利用されており、エンジニアを始めとする一部の社員が利用するチャットツールという位置づけです。 が、 もうすぐSlackがメインになるそうです。

なのでSlackBotを少し使いやすくしてみようと思い、今回私は"Yaya"というアプリケーションを作りました。

動機

Integrationsが痒いところに手が届かなくて困る。

Slackには、他のアプリと連携するIntegrations機能が存在するのですが、あまりカスタマイズ性が高くありません。 そのため、ちょっとデータを加工してBotに発言させたい場合、Botプロセスを何処かで立てる必要が出てきます。 ちょっとしたことなのでわざわざ環境構築からやるのはしんどいので、すでにあるBotに気軽に機能追加出来る環境があると良いなと思いました。

使い方

1.Botキャラクターを作る

f:id:mogmog2:20170314172156p:plain

[キャラ名] キャラ設定 [作りたいキャラ名] [アイコンにしたいURL]

というコマンドを実行すると新しいキャラクターが生成されます。 生成されたキャラクターにコマンドを教えて使います。

2.Botキャラクターにコマンドを教える。

f:id:mogmog2:20170314171920p:plain

[キャラ名] 教える [コマンド名]

でコマンドを教えることが出来ます。 コマンドの内容はRubyのスニペットコードを投稿すると、そのファイルが紐付けられます。 ↑の画像だと、「ぴん」というコマンドに “ぽん!"と発言するRubyプログラムが紐付けられました。

登録したコマンドは

[キャラ名] [コマンド名]! [引数]

で使用することが出来ます。 f:id:mogmog2:20170314171915p:plain

3.状態を読み書きする。

キャラクター毎に状態(key - valueの仕組み)をもたせることが出来ます。 f:id:mogmog2:20170314171916p:plain

これだけだとあまり用途がなさそうですが、プログラムから読み書きすることも出来ます。

4.Webhookのエンドポイントを生成する

f:id:mogmog2:20170314171918p:plain

Botプロセスだけでなく、Webサーバも動いており、Slack上からwebhookのエンドポイントも作成できます。

リクエストを受け取ったときの処理も、コマンドと同様にRubyのスニペットコードとして記述できます。

主な機能は以上です。

構成

f:id:anoChick:20170301005837p:plain

簡単な構成としては↑のようになっています。 f:id:anoChick:20170301013304p:plain

WebhookはRuby on Rails、WorkerはSIdekiqで実装しています。

また、Herokuでの稼働を想定しており、"Deploy to Heroku"ボタンで簡単に環境構築が出来るようになっています。

まだ作りたてなのでそこまで便利につかえてはいないのですが、 基盤としてはとても強力なんじゃないかと思っているので、 機能が増えたらまた記事を書こうと思います。