Happy Growth Engineer

成長と幸せな働き方の両立をするために役に立つ

資金調達を実施して、エンジニア組織をさらに拡大する #資金調達 #シリーズA #ホテル番付 #MagicPrice

本日(7/12)、株式会社空の約1.7億円の資金調達を発表しました

f:id:hirontan:20180712101951p:plain

まとまった内容は弊社代表の松村(まっつん)や記事で書いていただいている通りです。

medium.com

私からお伝えしたいことは「エンジニア組織拡大」についてです。

エンジニア組織拡大の前に・・・

弊社は、「世界中の価格を最適化し、売り手も買い手も嬉しい世界を作る」PriceTech Company〜になるために成長を続けています。 大きなことを言っていることは確かですが、プライシングを行なっている企業や個人の方がいらっしゃいます。

個人の方だと・・・

オークションやフリマで出品することが容易に想像できるのではないでしょうか。 出品するときに、売り手は最適な価格を考えて売ります。買い手は最適な価格か(上限価格は個人個人設けていると思います)を考えて買います。

プライシングは無数に存在する

プライシングとしてホテル事業に特化して成長していますが、今回の資金調達を機に新たな業界への展開へもチャレンジします。

f:id:hirontan:20180712101926p:plain

新たな業界への展開へもチャレンジするために

エンジニア組織拡大が必須になってきます。

現在のエンジニア組織

企画・デザイナー・開発エンジニア(フロントエンド、バックエンド)・機械学習エンジニア・データサイエンティストと各職種は揃っている組織ではあります。 企画アイデアは企画という立ち位置で案件を全て作るのではなく、エンジニア組織全体で案件を考えています。 つい先日も、「これからホテル番付・MagicPriceをさらによくするためには」の議論をし、優先順位も全員で考えました。 全員で考えることは生産性が生まれないと思うかもしれません。全員で認識を合わせることで、全員でプロダクトを作っているイメージがしやすく、プロダクトが前進しやすくなります。

これからのエンジニア組織

「企画を考えた人がリーダーとなる」「学習から行動に持っていく」を進めていきたいです。 まだ構想段階ではありますが、アウトプットさせてください。

企画を考えた人がリーダーとなる

プロダクト造りの企画は全員で実施していますが、とりまとめは基本的に企画が行なっています。 そのとりまとめは、企画を考えた人がリーダーとして進めていく方向にしたいです。 なぜなら、プロダクトとエンジニア組織の成長について2つ理由があります。 1つ目、プロダクトは企画を考えた人がリーダーとして実施することで企画に対する想いが入り、120点のプロダクト完成度ができる確率が高まります。 2つ目、エンジニア組織の成長はエンジニアがエンジニアリングだけを突き詰めることも良いことではあるが、リーダーシップを発揮できる機会をより多く作っていき、エンジニアリング以外も成長できる機会を作っていきたいです。企画のポジションが無くなるの?と思う方もいるかもしれませんが、いいえ無くなりません。現在直近でプロダクトをよくすることを考えていますが、中長期的な対策を練る方向にも時間が当てられるようになり、プロダクトとしてはさらに強化されていきます。

副次的ではありますが、職種が完全に別れていると会社内受託っぽくなりえる可能性が高く、全員で前進していきたいと考えています。

学習から行動に持っていく

プロダクトを開発する上での組織構造は現在のまま続けますが、実施していきたいことは、学習から行動に持っていくことをさらに加速していきます。 エンジニア主軸になってしまいますが、エンジニアは日頃から学習をしている方が多いかと思います。ただし、世にインパクトのある環境での学習したことをアウトプットすることは難しいのではないでしょうか。そのアウトプット(行動)をできる環境作りを全員で行なっていきたいです。現在は、新しいモジュールを入れてみて開発してみるなど短期的に効果があり生産性の生まれるものをやっています。これからは生産性の生まれそう?など疑問に思っているものでも、利用してみて問題なければそのまま導入。問題があれば破棄する。意思決定をライトに。また中長期で効果がありそうな技術への投資も実施していきたいです。

Happy Growth を掲げ、HappyとGrowthを両立させるためには、エンジニア組織としては重要になってくる要素です。

www.wantedly.com

最後に

エンジニア組織拡大は必須になってきます。まだまだ各領域の職種が足りていません。 ご応募お待ちしております。

f:id:hirontan:20180712102021j:plain

株式会社空 CPO 田仲紘典

sora.flights

採用募集

Wantedly

www.wantedly.com

www.wantedly.com

www.wantedly.com

Green

Railsエンジニア | 株式会社 空 | IT/Web業界の求人・採用情報に強い転職サイトGreen(グリーン) | 2018/07/19 14:50:28更新 | id:67213

データサイエンティスト | 株式会社 空 | IT/Web業界の求人・採用情報に強い転職サイトGreen(グリーン) | 2018/07/19 09:01:34更新 | id:67212

aliyuncli を使ってみた #Python #Image #サーバ作成

概要

イメージでサーバ作成するために aliyuncli を使ってみました。

やってみたまとめ

  • OpenAPI Explorerがあり、プログラムは相当簡単にかけます。
  • APIへリクエストが叩けない時があるので、リトライ処理入れる方が良い。(お決まり?)
  • OpenAPI Explorer に記されている do_action でリクエスト送るより、ServerException の処理があるdo_action_with_exception をリクエストを送る方が良い。
  • 自分でStatus拾って実行考えたい場合は、do_action_with_exception ではなく get_responseimplementation_of_do_action で実行する。

実行環境

  • CentOS 6.8
  • Python 2.7 → v3あることあとで気づきました

実行準備

$ pip install aliyun-python-sdk-core
$ pip install aliyun-python-sdk-ecs
→必要なライブラリをインストール
$ pip install logging
$ pip install retry
$ pip install argparse

実行

実行内容

事前に Image を作成して、インスタンスを作成する。 ミニマムのサーバリソースで同じセキュリティグループで同じサーバ名で作成していきたかったため、利用しました。 もちろん、UIでインスタンス数指定してもちろん複数構築は可能です。 ただ、また増設するときに必要になるので、書きました。 あと、オートスケーリングすれば。。。との話は置いておきます。

ソースコード

github.com

# -*- coding: utf8 -*-
#!/usr/bin/env python

import json
import argparse
from retry import retry
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkecs.request.v20140526 import CreateInstanceRequest

def acs_client(api_key, api_access_key):
  return AcsClient(
    api_key,
    api_access_key,
    region_id
  );

@retry(tries=4, delay=5, backoff=2)
def request_cli(req):
  status, headers, body = clt.implementation_of_do_action(req)
  print('[ status: ' + str(status) + ' ] [ headers: ' + str(headers) + ' ] [ body: ' + str(body) + ' ]')
  if status != 200:
    raise('[ status: ' + str(status) + ' ] [ headers: ' + str(headers) + ' ] [ body: ' + str(body) + ' ]')
  json_body = json.loads(body)
  return status, json_body

def create_instance():
  req = CreateInstanceRequest.CreateInstanceRequest()
  req.set_accept_format('json')
  req.add_query_param('RegionId', region_id)
  req.add_query_param('ImageId', image_id)
  req.add_query_param('InstanceType', 'ecs.t5-lc2m1.nano')
  req.add_query_param('SecurityGroupId', '[security_group_id]')
  req.add_query_param('InstanceName', '[instance_name]')
  req.add_query_param('InternetMaxBandwidthIn', '50')
  req.add_query_param('InternetMaxBandwidthOut', '50')
  req.add_query_param('VSwitchId', '[vswitch_id]')
  req.add_query_param('SystemDisk.Size', '20')
  req.add_query_param('KeyPairName', '[key_pair_name]')
  status, body = request_cli(req)

def main():
  init_logger()
  create_instance()

def init_args():
  parser = argparse.ArgumentParser(
             prog='aliyun_sample',
             usage='python aliyun_sample.py --region [ap-northeast-1] --key [api key] --access [api access key] --image [image id],
             description='description',
             epilog='end',
             add_help=True
           )
  parser.add_argument("-r", "--region", help="please set region id", type=str, default='ap-northeast-1')
  parser.add_argument("-k", "--key", help="please set api key", type=str, required=True)
  parser.add_argument("-a", "--access", help="please set api access key", type=str, required=True)
  parser.add_argument("-i", "--image", help="please set image id", type=str, required=True)
  return parser.parse_args()

if __name__ == '__main__':
  args = init_args()
  region_id = args.region
  image_id = args.image
  clt = acs_client(args.key, args.access)
  main()
コマンド
$ python aliyun_sample.py --region [ap-northeast-1] --key [api key] --access [api access key] --image [image id]

採用

株式会社空のCPOが目指すテクノロジードリブンな組織 #株式会社空 #MagicPrice #ホテル番付 #SORA #エンジニア #採用 #インタビュー

社内インタビュー記事

www.wantedly.com

内容

以前、「ブラインドタッチもできなかった僕がヤフーと空で成長できた理由」と個人の話をさせていただきました。 個人だけではなく、株式会社空として組織はどうありたいのかを記事にしてもらいました。

サービス

www.hotelbanzuke.com

採用

ブラインドタッチもできなかった僕がヤフーと空で成長できた理由 #株式会社空 #MagicPrice #SORA #エンジニア #採用 #インタビュー #少し補足

社内インタビュー記事

www.wantedly.com

sora.flights

内容

学生、ヤフー、現在(空)としての活動内容などを中心に話しています。 前半部分の補足を若干しておきます。

補足

タイトル「ブラインドタッチもできなかった僕がヤフーと空で成長できた理由」

大学院まで卒業するまで、基本的にコピペエンジニアであったため、完全にブラインドタッチができないまま卒業しました。 その後、ヤフーに入社して、ブラインドタッチがみんなできていることに衝撃を受けました。 研修が終わって、家に帰ってブラインドタッチひたすらやっていました。 今はちゃんとブラインドタッチできています。

ーー立命館大学、大学院を卒業していますが何を学んでいたんですか?ーー

IDSを開発していた時は、研究室に構築しているサーバ群ネットワークのパケットを収集して、パケットをみることが好きでした。 パケットのキャプチャはライブラリ Jpcap を利用して、3ウェイ・ハンドシェイク などを実際に見て理解していました。

大学院の研究室でFreeBSDのOS

実際には FreeBSD だけでなく、CentOS も利用していました。 まだ仮想環境が流行り始めた時に、Windows機の上にVMwareをインストールし、サーバを構築していた経緯もあります。 この時に物理的なネットワーク構築も試みていました。

サーバ利用としては現在クラウド環境として、AWSGCP、Azureなど便利になってきていますね。 研究室時代ではなくヤフーではOpenStackも部の支援もあってJuno、Icehouseあたりの構築も経験しました。

ーーヤフーではどういった業務をやっていたんですか?ーー

基本的に毎年のようにチームが変わり、よく利用する技術・能力が違っていたことで、多様な学びがあった環境ではありました。 ブログには書かれていないですが、広告部門で利用されているツールの保守開発も行なっていました。 広告部門で利用されているツールはヤフーの外側に出ているツールではないため、Chef、Jenkinsなどアグレッシブに新しい技術・ツールを取り入れる機会がありました。

================================

若干ではありますが補足しました。 気がついたらまた補足します。

サービス

www.hotelbanzuke.com

採用

FTP サーバ構築(冗長化にも対応)[vsftp, goofys, s3fs, ec2, s3, elb]

概要

  • ファイルの受け取りをする時、FTP 通信でサーバ利用
  • サーバが潰れても良いよう、S3 にファイル保存する

構築方法

事前準備

  • EC2サーバ準備
  • ELB準備
  • セキュリティグループのポート開放(TCP:21, 60001-60010)
  • S3 のバケット
  • AWS ユーザ作成(SecretKey, SecretAccessKey を利用)

構築手順

$ sudo yum install -y vsftpd
$ sudo cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.orig
$ sudo vi /etc/vsftpd/vsftpd.conf
----- 下記に書き換える -----
anonymous_enable=NO
dirmessage_enable=NO
connect_from_port_20=NO
xferlog_std_format=NO
ascii_upload_enable=YES
ascii_download_enable=YES
chroot_local_user=YES
chroot_list_enable=YES
tcp_wrappers=NO

pasv_enable=YES
pasv_addr_resolve=YES
pasv_address=[ホスト名]
pasv_min_port=60001
pasv_max_port=60010
use_localtime=YES
force_dot_files=YES
user_config_dir=/etc/vsftpd/user_conf
--------------------------

$ sudo touch /etc/vsftpd/chroot_list
$ sudo adduser [ユーザ名]
$ sudo passwd [ユーザ名]
→ ここでパスワードを設定します

$ sudo chkconfig vsftpd on
$ sudo /sbin/service vsftpd start

$ sudo mkdir /home/[ユーザ名]/data
$ sudo chown [ユーザ名]:[ユーザグループ] /home/[ユーザ名]/data

$ sudo yum install -y golang fuse
$ sudo wget https://github.com/kahing/goofys/releases/download/v0.0.5/goofys -P /usr/local/bin/
$ sudo chmod 755 /usr/local/bin/goofys

$ aws configure
AWS Access Key ID [None]: [SecretKey]
AWS Secret Access Key [None]: [SecretAccessKey]
Default region name [None]: [region]
Default output format [None]: text

$ sudo /usr/local/bin/goofys -o allow_other --dir-mode 0700 --file-mode 0600 --region ap-northeast-1 --uid 502 --gid 502 [ユーザ名] /home/[ユーザ名]/data
$ sudo /usr/local/bin/goofys -o allow_other --dir-mode 0700 --file-mode 0600 --region ap-northeast-1 --uid 502 --gid 502 [ユーザ名] /home/[ユーザ名]/data
$ sudo mkdir /etc/vsftpd/user_conf
$ sudo vi /etc/vsftpd/user_conf/[ユーザ名]
-----
local_root=/home/[ユーザ名]/data

$ sudo vim /etc/vsftpd/user_list
----- 追記 -----
ec2-user

$ sudo /sbin/service vsftpd restart

$ sudo vim /etc/fstab
----- 追記 -----
# goofyn
/usr/local/bin/goofys#[ユーザ名] /home/[ユーザ名]/data fuse allow_other,--dir-mode=0700,--file-mode=0600,--uid=502,--gid=502    0       0
----------------

接続確認

$ ftp [ユーザ名]@ホスト名
ftp> put test
→ 「226 Transfer complete.」と出るようにする

Windows で接続できない場合の対処法

再構築

上書き保存ができない

  • vsftpgoofys の相性がどうも悪いようです
状態
ftp> put test
local: test remote: test
229 Entering Extended Passive Mode (|||60007|).
150 Ok to send data.
100% |*********************************************|     5        1.58 KiB/s    00:00 ETA
226 Transfer complete.
5 bytes sent in 00:00 (0.19 KiB/s)
ftp> put test
local: test remote: test
229 Entering Extended Passive Mode (|||60005|).
150 Ok to send data.
100% |*********************************************|     5       19.68 KiB/s    00:00 ETA
451 Failure writing to local file.
5 bytes sent in 00:00 (0.34 KiB/s)

goofys から s3fs に変更してみる

$ sudo su
$ yum -y install git automake gcc-c++ fuse fuse-devel libcurl-devel libxml2-devel openssl-devel
$ wget https://github.com/s3fs-fuse/s3fs-fuse/archive/v1.80.tar.gz
$ tar xzvf v1.80.tar.gz
$ rm -f v1.80.tar.gz
$ cd s3fs-fuse-1.80/
$ ./autogen.sh
$ ./configure prefix=/usr
$ make
$ make install
$ echo '[SecretKey]:[SecretAccessKey]' >> /etc/passwd-s3fs
$ chmod 640 /etc/passwd-s3fs
$ umount /home/[ユーザ名]/data/
$ s3fs [ユーザ名] /home/[ユーザ名]/data -o allow_other,use_cache=/tmp,uid=502,gid=502,passwd_file=/etc/passwd-s3fs
$ vim /etc/fstab
   # もし goofys の追記箇所があれば削除してください
----- 追記 -----
# s3fs
/usr/bin/s3fs#[ユーザ名] /home/[ユーザ名]/data fuse rw,allow_other,uid=502,gid=502    0       0
----------------

営業向けにエンジニアから開発基礎を実施 [資料一部抜粋]

注意事項

内容は営業(セールス)にわかりやすいよう正確に情報を出していないところもあります。
エンジニアからすれば物足りないや他に良い解釈法などはあると思います。

内容

開発基礎

f:id:hirontan:20170214044549p:plain

目的と背景

個人とチームワークの強化のため

f:id:hirontan:20170214044556p:plain

チームワーク = 共通知識の広さ + 専門知識の認め合い

f:id:hirontan:20170214044601p:plain

個人の強化は筋トレと一緒で勉強などをすれば伸びることは簡単です。
チームワークの強化は同じことを知っていると仲良くなって意思疎通が取れやすくなる「共通知識」と知らないことに対して壁を作らないようとする「専門知識を認める」ことを弊社では意識しています。

強化するところはエンジニアの知識

f:id:hirontan:20170214044610p:plain

開発基礎は、エンジニアを理解してもらうためです

クライアント・サーバ

f:id:hirontan:20170214044616p:plain

クライアント・サーバの仕組み

f:id:hirontan:20170214044623p:plain

  • クライアント:要求する側
  • サーバ:応答する側
MagicPrice の Landing Page を見るとき

f:id:hirontan:20170214044629p:plain

Landing Page を見る時、大体の方々は画面が表示されたとしか気にしていないです。
画面が表示されるまでのブラウザ(クライアント)とサーバのやり取りを考えてみます。

Landing Page が表示されるまで

f:id:hirontan:20170214044635p:plain

  1. パソコンのブラウザが「MagicPrice の LandingPage が見たいです。」と要求
  2. Web サーバが HTML を返答
  3. 返答してきた HTML をブラウザが読み取って、見やすい形に変更
パソコンとサーバの違い

f:id:hirontan:20170214044642p:plain

  • サーバは Web やメールなどのソフトウェアが入ったパソコンと認識しておくと良い
ドメインと IP の話

f:id:hirontan:20170214044654p:plain

  • DNS の話はここで
  • 1度に繋がりを話すと、理解しづらくなるため

開発の心得

f:id:hirontan:20170214044659p:plain

開発〜リリースまでのフロー

f:id:hirontan:20170214044705p:plain

  • 考える・作る・確かめる・見てもらうの4点セットで考えている
  • 実際には少し違うかもしれませんが、理解してもらうために言葉を砕いています
エンジニア言葉

f:id:hirontan:20170214044710p:plain

  • エンジニアが話している言葉で変換してもらえるための用語集を揃えました
  • 主に弊社で多い言葉を並べています
  • 参考にしているリンク:不思議の国のSE用語 - Qiita

弊社採用情報

S3 をローカルで擬似的に作成 [minio]

目的

  • S3 をローカルで擬似的に作成し、AWS-SDKをローカルでも利用できるようにする
  • 無駄な通信料の軽減

Vagrant

設定

  • minio にアクセスできるよう、クライアント側も同じネットワークにしてください
$ mkdir locals3
$ cd locals3
$ vi Vagrantfile
-- 以下コピー --
Vagrant.configure(2) do |config|
  config.vm.box = "bento/centos-6.7"
  config.vm.network "private_network", ip: "192.168.33.11"
  config.vm.network :"forwarded_port", guest: 9000, host: 9000
end
------------------------------------------
$ vagrant up
$ vagtant ssh

構築

インストール

$ mkdir /vagrant/s3
$ curl -O -k --tlsv1.2 https://dl.minio.io/server/minio/release/linux-amd64/minio
$ chmod +x minio
$ ./minio server /vagrant/s3
  • /vagrant 配下はデフォルトでホスト側からアクセスできるので、/vagrant 直下を保存先に指定すると便利です

UIアクセス

$ ./minio server s3
Endpoint:  [url]
AccessKey: [accesskey]
SecretKey: [secretkey]
Region:    [region]
SqsARNs:

minio にディレクトリ作成して、ファイルアップロードする方法

  • http://localhost:9000/minio/[bucket名]/[ディレクトリ] のようにURLアクセスして、ファイルをアップロードすれば良い

参考資料