The paradigm shift

saboyutaka’s diary なんかかく(ブログn回目)

2018年 振り返り

f:id:saboyutaka:20181231211427p:plain

今年の振り返りを今年の内に。沖縄移住4年目、30歳を迎えた2018年の振り返りをやっていきます。

Twitter のダイジェストはこちら

twitter.com

仕事

今年は、Laravel多めで, Railsは1件, Goが2件だった。PlatformはAWSとAzure。フロントエンドはVue。 来年もこのトレンドは変わらなそうでRuby, PHP, Go, JavaScriptを引き続きやっていく。

フロントエンドの苦手意識を少し取りたいので来年はちょっとフロントエンドとアプリも触ってみるつもり。

今年はフリーランスとして色んな会社と付き合うというスタイルから、一緒に仕事したい人と深く付き合う関係性に変わってきた。来年以降はそれを強めていくような仕事の仕方をやっていく。

実績

エンジニアからテックリード

f:id:saboyutaka:20181231200326p:plain
https://www.facebook.com/yutaka.paradigm.shift/posts/2183693195028755

https://amzn.to/2QYGaZx

エンジニアのためのマネジメントキャリアパス ―テックリードからCTOまでマネジメントスキル向上ガイド

エンジニアのためのマネジメントキャリアパス ―テックリードからCTOまでマネジメントスキル向上ガイド

エンジニアのためのマネジメントキャリアパスを読んで、この一年やってきた仕事のスタイルがテックリードだなと気づいた。認識が変わると行動が変わる。来年はマネジメントスキル、ソフトスキルをつけるような方向で仕事をしていきたい。来年から自称の役職はテックリードと名乗ることにする。

仕事以外の活動

ギークハウス沖縄

去年7月にオープンして今年は2年目。仕事やプライベートがバタバタしてたのであまり時間を割けなかったがありがたいことにメディアに取り上げてもらう機会に恵まれたのと、ギークハウス経由で繋がる人とか出来てきたので引き続きやっていきたい。来年は今年以上に時間を割くつもり。 ギークハウスについてはどこかで別に書きたい。

琉球放送

おきなわマグネット

CODEBASE プログラミング講座

www.protosolution.co.jp

講師として関わっているプログラミング講座で、1年通して4期、約60名の方にWebアプリケーションエンジニアになるための講義をしてきました。このスクールで会った方で今一緒に仕事している方が居たり、来年東京にエンジニアとして就職予定の学生が居たりと、ここから出来るつながりもあってやってきてよかったなと☺️

f:id:saboyutaka:20181231202509j:plain

f:id:saboyutaka:20181231202836j:plain

f:id:saboyutaka:20181231202907j:plain

f:id:saboyutaka:20181231203013j:plain

RailsGirls Okinawa

沖縄に移住してきた時の目標がギークハウスを創る事とRailsGirlsを持ってくることだったので、それに今年は関われてよかった☺️

ダイエットと砂糖断ち

今年のライフハックで最大の発見は砂糖を抜いた時のパフォーマンス改善と体質改善、痩せる事に気づいた事。来年以降のパフォーマンスが上がる発見を出来たことはかなり人生の中でも重要な発見に繋がりそう。

note.mu

その他の発信

影響を受けたもの

人生は、運よりも実力よりも「勘違いさせる力」で決まっている

錯覚資産の本。薄々わかっていたけど、心理学からのアプローチで概念に言葉を与えたという意味でこの本の影響はでかい。今年マーケティングを学ぶ機会も多かったので自分自身を商品という自覚が芽生え始めていた頃にこの本を読んだので、人に知ってもらうというのは商品を売り込むチラシ配りのようなものだと考える事ができるようになって、発信の重要性やニーズのある所に自分を売り込むことの重要性に気づいた。

人生は、運よりも実力よりも「勘違いさせる力」で決まっている

人生は、運よりも実力よりも「勘違いさせる力」で決まっている

サウザーラジオ

人生をシュミレーションゲーム、資本主義ゲームにたとえてどうやって勝ち筋を見つけるかという内容のVoicy(ネットラジオみたいなやつ)。元々学生の頃から、金持ち父さん貧乏父さん読んだり、ザ・ゴールを読むのが好きだったのもあって、久しぶりにこういう感覚を思い出して今の心境とだいぶシンクロするものもあってかなり聞いた。来年以降の振る舞いに影響を与えるものになったと思う。人生、金が目的ではないけど色んな事をやるための資金は必ず必要なのと、30歳になるまで打ってきた手が今の状況を導いてるので、もう少しいい打ち方出来るようにする。

voicy.jp

キングダム

ビジネスは現代の戦争そのもの。中国の秦の始皇帝の時代を描いた歴史漫画。経営者と話してると高確率で出てくる話題なのでそろそろ読むかーと思って読んだらめちゃくちゃおもしろかった。そして勉強になる。何かことあるごとにキングダムで例えるとどういうことかなと考えてしまう病にかかった。自分自身そろそろ将軍としての立ち回りを覚えなきゃいけない時期。学ぶことは多い。

群衆の英知もしくは狂気

下のブログで知った人も多いと思う。コミュニティや人間関係や経済や資本主義、全てが言い換えればネットワークだと思うようになった。たぶん僕のライフワークは良質なネットワークの構築と最適化、なんじゃないかなと思う。この分野は人生をかけて深掘りしたいテーマな気がしている。

ncase.me

yunon-phys.hatenadiary.com

やりたかったけどやれなかったこと

  • DJを始める
  • 英語で技術書を読み始める

来年やる。

おわりに

今年前半はメンタル的にめちゃくちゃ落ちててほとんど仕事とメンタル修復だけに時間を使ったので何も出来なかった感じある。後半は持ち直して、かつ色んな偶然も重なってすごい良い年になった。色々あったけど毎年成長を感じるし毎年過去最高の年だなと思う。今年は過去最高に成長した年だった感じがある。やることもだいたい決まってきたし気持ちもだいぶ整ってきたので2019年はがんばりたい。

macOSでの開発環境を全部Docker化したらリストア時間が1時間半になった

f:id:saboyutaka:20180823023857p:plain

どうも、リストア職人のさぼです。みなさんmacOSをどのぐらいの頻度でリストアしてますか?1年に1回はやってますよね?僕は3ヶ月に1回はやるようにしてます。綺麗な状態にしてOSが最大限のパフォーマンスで動いた方がいいし手元に入れたよくわからないアプリがずっと入ってるのって気持ちよくないじゃないですか。なのでMacを定期的にリストア(工場出荷状態に初期化)してます。

前回までは真っ白な状態からだいたい3時間ぐらいで普段開発している環境を構築できるようにしていたのですが今回から開発環境を全部Dockerにしてみようと思ってやってみたところ1時間半で開発環境を終えて作業開始できる状態までの最短記録を更新しました!


おわり(おわらない)






いつもやってる手順を振り返りがてら紹介していきます。

Brewfile

いつもリストア後は brew bundle コマンドでアプリやソフトウェアを入れるようにしていて、今回はその中から言語のRuntimeとMiddlewareを全部取り除きました。 またVagrantも試験的にリストア後には入れずに必要があれば入れる形にします。サブエディタとして使っていたAtomも使うのをやめました、メインはJetBrains系のエディタを使っていますが、サブとしてVisual Studio Codeを使うようにしてます。

少し前まではVagrantでMiddleware, PostgresやRedis を起動してMacのホスト上のRubyのruntimeでRailsを起動して開発したりしてましたが、最近は全部docker-compooseで動かして言語のRuntimeも全部Dockerで行うようになったのでMacに 言語のRuntimeを入れる必要がなくなりました。個人的に rbenvruby-buildMac上に入れなくなったのは時代の転換期を感じます。。

cask_args appdir: '/Applications'
tap 'caskroom/cask'

brew 'ctop'
brew 'curl'
brew 'ghq'
brew 'gist'
brew 'git'
brew 'htop'
brew 'hub'
brew 'jq'
brew 'mackup'
brew 'mas'
brew 'openssl'
brew 'peco'
brew 'rmtrash'
brew 'sshrc'
brew 'telnet'
brew 'tig'
brew 'tree'
brew 'z'
brew 'zsh-completions'
brew 'zsh'

# ココらへんを全部入れないことにした
# tap 'homebrew/php'
# brew 'automake'
# brew 'cmake'
# brew 'ctags'
# brew 'gcc'
# brew 'go'
# brew 'heroku'
# brew 'memcached'
# brew 'mongodb'
# brew 'mysql'
# brew 'node'
# brew 'nodenv'
# brew 'postgresql'
# brew 'pyenv-virtualenv'
# brew 'pyenv'
# brew 'python'
# brew 'rbenv'
# brew 'readline'
# brew 'redis'
# brew 'ruby-build'
# brew 'sqlite'
# brew 'v8'
# brew 'yarn'

cask 'alfred'
cask 'appcleaner'
# cask 'atom'
cask 'bartender'
cask 'bitbar'
cask 'caffeine'
cask 'cyberduck'
cask 'docker'
cask 'fantastical'
cask 'github'
cask 'google-chrome'
cask 'google-japanese-ime'
cask 'grandperspective'
cask 'gyazo'
cask 'iterm2'
cask 'karabiner-elements'
cask 'keycastr'
cask 'ngrok'
cask 'paw'
cask 'postico'
cask 'sequel-pro'
# cask 'vagrant'
# cask 'vagrant-manager'
# cask 'virtualbox'
cask 'visual-studio-code'
cask 'vlc'

mas 'Airmail 3', id: 918858936
mas 'Bandwidth+', id: 490461369
mas 'Be Focused Pro', id: 961632517
mas 'BetterSnapTool', id: 417375580
mas 'LanScan', id: 472226235
mas 'Night Owl', id: 428834068
mas 'Skitch', id: 425955336
mas 'Todoist', id: 585829637
mas 'Wireless Signal', id: 582840059

リストア, 開発環境構築の手順で使うツール

  • DiskMaker X
    • インストールディスク作成
  • Homebrew brew bundle でBrewfileからアプリとツールをダウンロードするのに使います
  • mackup
    • アプリやツールの設定ファイルを指定のフォルダ、デフォルトではDropbox上に作られる、に退避し、それらのファイルが元にあった場所にシンボリックリンクを作ってくれるツール。自分で新たに独自にバックアップするファイルも指定できる。
  • Docker for Mac
    • macOSでDockerを動かす
  • Dropbox
    • mackupで使うフォルダとBrewfileを置く。また基本的にmac上で使うすべてのファイルはDropboxiCloudに置くようにしている。いつMacが動かなくなっても良いようにローカルにしかファイルがない状態は基本的になくす
  • GitHub, または他のGit Repository Hostingサービス
  • 1password
    • パスワードはiCloud keychainと1passwordに両方保持してる。keychainはSafariでは便利。基本的には1passwordを使う。パスワードマネージャー使ってないとリストア後のログインがめちゃくちゃ面倒なので絶対使う。異なるサイトで同じパスワード使うとか絶対にあってはいけない。

リストア手順

  1. リストアして最新OSを入れる。
  2. macOSのシステム環境設定 Dock、トラックパッド、キーボード、言語設定などを好みに変更する。ここはOSが変わっていくと変化する可能性があるので自動化していない
  3. DropboxをインストールしてMacupフォルダとBrewfileを選択同期する。リストア作業に関係ないものは後日時間があるときに同期する。
  4. Homebrew をinstallする
  5. brew bundle でアプリとツールをインストールする
  6. mackup restore でアプリとツールの設定ファイルを復元する
  7. iTerm2を開いてデフォルトのshellをzshに変更する(お好み)
  8. 開発リポジトリgit clone する
  9. docker-compose で開発環境を立ち上げる
  10. JetBrainsのエディタをインストールして立ち上げる

ここまでで所要時間1時間半くらいで構築できるようになりました。

Docker

Dockerの構築を知りたい方は下のリポジトリとかを参考にしてください。Railsのアプリケーションです。最近は開発環境構築を make build とすると終わるようにするのが趣味になってます。

Railsのdocker-composeのサンプル

github.com

Laravelのdocker-composeサンプル

github.com

Dockerを学ぶにはこの本がおすすめです。Dockerやdocker-composeの使い方はこの本を読むことでだいぶ理解が進みました。

Dockerによるアプリケーション開発環境構築ガイド

Dockerによるアプリケーション開発環境構築ガイド

おわりに

リストア環境をちゃんと作っていれば1, 2時間でリストアから開発環境構築完了までいけるようになりました。ここまで来るとOSにほとんど依存しないのでMacである必要ないやんという感じなのですが、ぼく個人としてはApple信者であるためMac使い続けようと思います(今の所は)。LinuxとかWindowsのWSLはDockerサクサク動いていいなぁとは思う。

1時間半でリストアが終わるなら土曜日の午前中に時間があるときにやるか、というぐらい気軽にできるようになるので定期的にリストアをする習慣が作れると思います。新しいOSが1年に1度出るのでそのときにリストアすると良いと思います。リストアせずにOSのメジャーバージョンのアップデートするとだいたい遅くなったり壊れたりします。ツールに愛を持ってメンテンナンスを定期的にしましょう。エンジニアの中でさえOSをアップデートしない人とかがたまにいるんですけど、ほとんどの問題はリストアしたら直るのでやってあげてください。よろしくおねがいします。

Rubyエンジニアはsleep 1で殺せる、をngx_mrubyのAsync.sleepで乗り越える

そろそろ今年のISUCON、ISUCON8まであと1ヶ月ちょっとになったのでひとりリハーサルをそろそろはじめてるさぼです。去年ISUCON7に初挑戦してRubyを選択してsleep 1が乗り越えられず人権を失いました(原因は他にもあるけど...)。

ngx_lua での sleep

去年、予選終わったあとに感想戦で聞いた、Openresty、ngx_luaを使ったsleep方法を試したりしました。Rubyでsleepを行うと処理をブロッキングしてしまうので、nginx側で1秒待った上でRubyに処理を渡すことでRuby側では処理を待つ必要がなくって捌けるリクエストを増やす算段です。

Async.sleepを実装した ngx_mruby v2 がリリースされる

rubykaigi.org

hb.matsumoto-r.jp

今年のRubyKaigi2018での @matsumotory さんの発表で、nginxでのmruby実装である ngx_mruby module のv2をリリースする話をしていて、その中でnon-blockingなsleepが出来る Nginx::Async.sleep が出来るという話でした。今回はこれを次のISUCONまでには使えるようにして sleep 1 に対策出来るようにしておこうと思って実装してみました。

実装

github.com

@matsuu さんが公開しているVagrantfileからアプリケーションを立ち上げて、なんとなくDocker化するのが最近趣味なのでDocker composeで置き換えて実装しました。

dokcer-compose の設定

isucon7q/docker-compose.yml at 201808 · saboyutaka/isucon7q · GitHub

# dokcer-compose.yml 抜粋
version: '3'
services:
  web:
    build: .
    command: "bundle exec rackup -p 8000 -o 0.0.0.0"
    volumes:
      - .:/app
    ports:
      - 8000:8000
  ngx-mruby:
    image: saboyutaka/ngx-mruby
    ports:
      - 80:80
    volumes:
      - ./public:/var/www/public
      - ./config/ngx_mruby/nginx.conf:/usr/local/nginx/conf/nginx.conf
      - ./ngx_mruby/hook:/usr/local/nginx/hook

https://hub.docker.com/r/saboyutaka/ngx-mruby/

@matsumotoryさんもDockerfileを公開しているけど、latestが ngx_mruby 1.19.5 だった(気がする)ので2.1.1で作り直しました。

Ruby app.rb の処理を変更

https://github.com/saboyutaka/isucon7q/blob/0e6cc831d5cf1011d117598ab38536b377c53b34/ruby/app.rb#L154

def fetch
  ...

+  # sleep をコメントアウトする
+  # sleep 1
-  sleep 1

  ...
end

nginx の設定

https://github.com/saboyutaka/isucon7q/blob/0e6cc831d5cf1011d117598ab38536b377c53b34/config/ngx_mruby/nginx.conf

# nginx.confの抜粋
http {
  ...

  upstream app {
    server web:8000;
  }
  
  server {
    ...

  location /fetch {
    mruby_rewrite_handler_code '
      Nginx::Async.sleep 1000
      Nginx.return Nginx::DECLINED
    ';

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://app;
  } 
}

mruby_rewrite_handler_code directive 内でngx_mrubyを実行しています。ここでNginx::Async.sleep 1000を記述することで、nginxでリクエストをnon-blockingで止めて、時間経過後に処理を再開します。ちょっとハマった点は、rewriteを複数回行う場合、今回は proxy_pass も使っているので、明示的にNginx.return Nginx::DECLINED を書く必要があってそれに気づくのに時間がかかりました。nginxもうちょっと勉強して理解したい.. matsumotoryさん本人からリプライ頂いてありがたい🙏

実行結果

Before

f:id:saboyutaka:20180813215213p:plain

realtime: 1.157 apptime: 1.150

After

f:id:saboyutaka:20180813215021p:plain

realtime: 1.150 apptime: 0.140

apptime(Sinatraの処理時間)が1.150から0.140に変わりました!Rubyの処理が約1秒減ったのがわかります。これで/fetchへのリクエストが大量にきてもRubyの代わりにNginxが処理を止めるので、Rubyでリクエストが詰まることがなくなりました。

おわり

今年も去年と同じメンバー(@tompng, @_simanman, @saboyutaka)で挑戦しようという話になっていてRubyと今年はngx_mrubyも持っていけるようにしておきたいなと思ってやってみました。sleep 1 が2年連続は出ないだろーと思いつつも対策は万全で行きたいと思いますー💪