エンジニアにジョブチェンジしてやってきたこと

「君のスキルはウチの新人と同レベルだけど、そんなんでやっていけるの?」と言われて今の会社に入社することを決めたのはもう4年半ほど前のこと。
前職はテスターでコードは全然書けなかったしデータベースとかも触ったことなかったけど好き勝手やらせてもらった結果、それなりのエンジニアに成長することができたと思う。
それも今月いっぱいで退職なのでちょうど良い機会だし自分じゃないとできなかった(やらなかった)ようなことを中心にざっくり振り返ってみる。
※イマイチだったことは全部書いていくとキリがないので省略

Perl(CGI + 生DBI)製Webシステムの改善

Template-toolkitをwrapするPerlモジュールを作った
  • HTMLがscriptタグも含めて1行ずつ丁寧にprintされていたのでメンテナンスが辛かった
  • SQLも文字列連結で組み立てられていたり、無理矢理1行に詰め込まれていたりしたのでメンテナンスが辛かった
  • Perlのバージョンが古くて(たしか5.8)フレームワークの導入も難しい状況だったのでとりあえずTemplate Toolkitで凌ぐことにした
    • HTMLは標準出力に吐き出してテンプレート化
    • SQLVim scriptで.cgiから抽出してテンプレート化
  • Perlモジュールにしたのは各.cgiで統一的なコードが書けるようにしたかったから
DBアクセス用のPerlモジュールを作った
  • DBIの初期化を各.cgiでやっていたのでPerlモジュールに切り出した
  • よく使われていた処理もまとめてPerlモジュールに持っていった
  • 引数でテストモードを指定するとTest::mysqldに繋がるようにした
    • テストコードが一切無かったのでテストを書く布石にしたかった
単体テストを書くようにした
  • ↑の通り、テストが無かったのでTest::Moreでテストを書くようにした
    • その前に.cgiは関数化されていなかったので関数化するところから始めた
    • strictをつけると動かなくなるコードもたくさんあったので合わせて直していった
  • DB関連のテストには↑のモジュールとTest::Fixture::DBIを使った

新しい言語・フレームワークの導入

Python(Flask + SQLAlchemy)
  • Perlで各自が好き勝手にコードを書いているとメンテナンスが辛くなるというのがチームの共通認識だった
    • 当時はコードレビューをするという文化も無かったし…
  • チーム内でPythonに興味を持っている人が多かったので新規システムを作るタイミングで思い切って導入してみた
  • DjangoPyramidを使わなかった理由としては、
    • 今までがcgiオンリーだったので重量級フレームワークに慣れている人がいなかった
    • ロックインされたくなかった
    • といったところ
  • py.testでテストし、pep8pyflakesでコードのチェックをするようにした
  • 今まではテーブルの管理を一切していなかったのでalembicFlask-Migrateで管理するようにした
Go
  • ↑でPythonを導入したはいいけどほとんどがCentOS6上の2.6で動いているのでなんとかしたくなった
    • 最初は2.7や3系への移行を検討したけど、OSのデフォルトではないバージョンを使うのに反対する人が多かった
      • そうこうしているうちに2.7も終わりが見えてきてしまったし…
    • パッケージの管理が不十分でリリース後にImportErrorで落ちることが多々あった
      • pipではなく、yumを推奨しているチームもあったのでバージョン違いでうまくいかなかったりすることも…
    • テストやコードチェックを実施しない人が増えてきた
      • 理由としてはパッケージのインストールができないとかIDEが対応していないとか…
        • リリース後のトラブルは明らかに増えていたけど気にする人は少なかった
  • ということで、ある時期から新規システムを作るときはGoを使うようにしてみた
  • フレームワーク
  • 外部パッケージはgit subtreeでvendoringするようにした

ログ・監視

fluentdでログ収集とアラート検知をするようにした
  • 今まではアプリケーションコード内でアラートの処理を行なっていた
    • アラートの実装が漏れたり後回しにされることがあった
    • アラート処理自体に問題があってシステムが落ちてしまうこともあった
  • アプリケーション側は適切なログレベルでログを出力するだけにし、その後の処理は全てfluentdに任せるようにした

リポジトリ

Trac(svn)からGitHub Enterpriseに移行した
  • 積極的に移行したいという人は自分しかいなかったけど反対意見はあまり気にせず移行することにした
    • 自分にとっては複数人で開発するのにsvnだと厳しかった
    • 反対意見としては
      • Tracでも困らないとか
      • Tracでgitを使えば良いとか
      • gitを覚えたくないとか
        • こういう人にはなんとか覚えてもらうことにした
  • 移行後はPull Requestでコードレビューをする文化も少しずつだけど作っていった
drone.ioの導入
  • GitHub Enterpriseに移行したリポジトリでは以下のようなことをdrone.ioで実行するようにした
    • Lint
    • 単体テスト
      • Goは自作ツールでテストを回した
    • バイナリのビルド
    • ドキュメント(Sphinx)のビルド
    • Pull Requestの自動レビュー

デプロイ

fabricの導入
  • 当初は全てwikiなどに記載された手順書を頼りにコマンドを1つずつ打ち込んでいた
    • 設定ファイルの変更はvi /etc/my.cnfのような手順になっていることもあった
  • 最初に担当したシステムで耐えられなくなったのでfabric + shell scriptでデプロイをするようにした
    • ansibleを使わなかったのは間にPython2.5のホストがあって使えなかったから
    • chefを使わなかったのは
      • 対象ホストにインストールできないと思っていたから
      • ローカルにあるファイルを対象ホストに転送する方法がわからなかったから
chef-soloの導入
  • fabricだと共通処理も含めて毎回コピペして設定を作っていたのでBerkshelfが使いたくなった
  • 実はホストの手配をした際にchefがインストールされているということを知った
  • ファイル転送はfabricを使いつつ、ホストの設定にはchef-soloを使うようにした
自作デプロイツールの導入
  • 最初の頃に比べたらデプロイがだいぶ楽にはなったけどいくつか問題が出てきた
    • 踏み台ホストを経由するのでファイル転送に時間がかかる
    • rootになれる人しか使えないので特定の人に負荷が集中してしまうことがあった
      • 制限していたのはホストの状態を誰も把握できなくなってしまうと困るから
  • そこで対象ホストで実行するタイプのツールを新たに作成し
    • ファイル転送は対象ホストから直接gitで取得するようにした
      • 合わせてビルド済みのバイナリやDockerのイメージもダウンロードする
    • チームのメンバなら誰でも実行できるようにし、オペレーションを全自動で行うようにした
      • 開発時はアプリケーションコードだけでなく、オペレーションも含めてレビューをする
      • タグがついた最新のバージョンのみがデプロイされるようにしたので
        • 同じバージョンは1回しかデプロイされないし巻き戻ることはない
        • バージョンがわかればホストの状態も把握できる

こうしてみると改善系の活動を結構やってきたんだけど、それが偉い人にはあまり評価されなかったのは残念といえば残念。
というか2つ上の職位に要求されることが出来ていないからといって評価を下げられたのは正直根に持ってる。 あとは実際の新人に入社時の自分と同じレベルのことを求めたら何度か怒られてしまったことがあるのも今となっては良い思い出かな?