$30 off During Our Annual Pro Sale. View Details »

JavaでWebサービスを作り続けるための戦略と戦術

 JavaでWebサービスを作り続けるための戦略と戦術

Japan Java ユーザーグループ クロスコミュニティ カンファレンス 2018 Spring 登壇資料

Yu Watanabe

May 29, 2018
Tweet

More Decks by Yu Watanabe

Other Decks in Technology

Transcript

  1. #ccc_g1
    published
    JavaでWebサービスを作り続けるための
    戦略と戦術
    JJUG-CCC 2018 Spring
    ベルサール新宿 2018-05-26
    Y. Watanabe

    View Slide

  2. #ccc_g1
    published
    ストップウォッチスタート確認
    2

    View Slide

  3. #ccc_g1
    published
    3

    View Slide

  4. #ccc_g1
    published
    Webサービスを止めずに
    Webサービスを進化させ続けるには?
    4

    View Slide

  5. #ccc_g1
    published
    Who?
    ● 渡辺 祐
    ● (株)ビズリーチ
    ● SREグループ
    ○ Site Reliability
    Engeneering
    ● twitter: @nabedge
    5

    View Slide

  6. #ccc_g1
    published
    ビズリーチシステムとは
    ● 創業事業かつ主力事業 2009〜
    ● 社内でもっとも古くから稼働している
    Javaアプリケーション群
    6

    View Slide

  7. #ccc_g1
    published
    1. 開発環境とCI戦略
    2. 老朽化した技術からの脱却
    3. フロントエンドと仲良くする
    4. 手動テストも、自動テストも。
    5. セキュリティ
    6. バージョンアップする
    7

    View Slide

  8. #ccc_g1
    published
    1. 開発環境とCI戦略
    2. 老朽化した技術からの脱却
    3. フロントエンドと仲良くする
    4. 手動テストも、自動テストも。
    5. セキュリティ
    6. バージョンアップする
    8

    View Slide

  9. #ccc_g1
    published
    Q. 開発環境とは?
    A. そこでアプリケーションが動く
    けど、それは本番用ではないモノ
    すべてを指す
    PCだけ?エンジニアだけ?
    9

    View Slide

  10. #ccc_g1
    published
    「動くソフトウェアこそが
    進捗の最も重要な尺度」
    アジャイルソフトウェア開発宣言より
    10

    View Slide

  11. #ccc_g1
    published
    ● あるエンジニアのPCでなら動く
    ● 他のエンジニアのPCでも動くけど
    準備に時間がかかる
    ● 検証環境でも動くけど、いま別のチームが
    テストのために検証環境にデプロイしているのは
    別ブランチのコードなのでやっぱり動かない
    逆に、なぜ ”動かない” のか?
    11

    View Slide

  12. #ccc_g1
    published
    あるべき姿(ローカル開発環境編)
    1. sh ./setup.sh でミドルウェアは全部入る
    2. データ層へのテストデータ投入も
    1に含まれている
    3. システムAのローカル開発環境は
    システムBのそれと干渉しない
    12

    View Slide

  13. #ccc_g1
    published
    仮想OS on 仮想OS
    13
    OracleVirtualBox
    CentOS
    Docker
    (MySQL)
    Docker
    (Redis)
    CentOS
    Docker
    (PgSQL)
    Docker
    (fakes3)
    Aサービス
    のコード
    Bサービス
    のコード
    172.16.1.1 172.16.2.2
    setup.sh setup.sh
    Mac OS

    View Slide

  14. #ccc_g1
    published
    あえて生dockerを使わなかった理由
    ● “その当時は”、Docker for Macが不安定だった
    ● mysqlはlocalhost:3306だと他の環境とバッティング
    ○ ex. 新人君が本を写経しようとして...
    14

    View Slide

  15. #ccc_g1
    published
    setup.shがやってること
    1. vagrant up
    1.1. 仮想OS(CentOS)起動
    1.2. yum install docker-ce
    2. vagrant ssh -c “docker-compose up -d”
    2.1. mysql, solr, localstack, etc...
    3. DBにテストデータをINSERTするスクリプト
    15

    View Slide

  16. #ccc_g1
    published
    ● あるエンジニアのPCでなら動く
    ● 他のエンジニアのPCでも動くけど
    準備に時間がかかる
    ● 検証環境でも動くけど、いま別のチームが
    テストのために検証環境にデプロイしているのは
    別ブランチのコードなのでやっぱり動かない
    逆に、なぜ動かないのか?(再掲)
    16

    View Slide

  17. #ccc_g1
    published
    ● いま、ローカル開発環境用に作っている
    Dockerfileをそのまま検証環境、本番環境で
    使えれば使いたい。使えるように書きたい。
    ● 少なくともDockerに関する知見を
    エンジニアが蓄積できる
    ● Dockerfileのメンテナはアプリケーションエンジニア。
    17
    Docker利用は将来構想に向けての布石でもある

    View Slide

  18. #ccc_g1
    published
    Eclipse -> IntelliJ IDEA
    1. ライブラリプロジェクト、アプリケーションプロジェクトの絶対数
    が増
    a. フラットなプロジェクトレイアウトが前提のEclipseだと何かと不都合
    2. Python, TypeScript, Android Java...
    3. Scalaのチームもいる
    4. 全社の全エンジニアまとめてIntelliJ
    18

    View Slide

  19. #ccc_g1
    published
    Maven -> Gradle
    ● ライブラリプロジェクト、アプリケーションプロジェクトの絶対数
    の増加
    ● CPUのコア数に合わせて並列ビルドできるほうが有利
    ● フロントエンドのビルドツールもろともgradleから制御したい
    ● pom.xmlよりもbuild.gradleのほうが自由度が高いわりに読み
    やすい
    19

    View Slide

  20. #ccc_g1
    published
    Jenkins1から2へ。そしてJenkinsfileへ
    20
    ● Maven -> Gradle移行の過程でjenkinsジョブの
    調整コストが増
    ● 全ソース, build.gradle, Jenkinsfile まで含め
    git管理するだけで楽勝。
    ● っていうのを見越してまず先にJenkins2に
    バージョンアップしていた

    View Slide

  21. #ccc_g1
    published
    次に目指しているところ(構想)
    1. プルリクエストひとつに対して
    それ専用の検証環境がひとつ自動構築される
    2. pushされる都度mergedな状態のコードで
    1の環境にビルド&デプロイされる
    3. 非エンジニアが会議室のプロジェクタで
    動くソフトウェアをいつでも確認できる
    21

    View Slide

  22. #ccc_g1
    published
    ● あるエンジニアのPCでなら動く
    ● 他のエンジニアのPCでも動くけど
    準備に時間がかかる
    ● 検証環境でも動くけど、いま別のチームが
    テストのために検証環境にデプロイしているのは
    別ブランチのコードなのでやっぱり動かない
    逆に、なぜ動かないのか?(再掲)
    22

    View Slide

  23. #ccc_g1
    published
    以下は、その実現方法論にすぎない
    ● イミュータブルインフラストラクチャ
    ● Blue/Greenデプロイメント
    ● 12-Factor App
    23

    View Slide

  24. #ccc_g1
    published
    1. 開発環境とCI戦略
    2. 老朽化した技術からの脱却
    3. フロントエンドと仲良くする
    4. 手動テストも、自動テストも。
    5. セキュリティ
    6. バージョンアップする
    24

    View Slide

  25. #ccc_g1
    published
    インストール型Tomcatはオワコン
    25

    View Slide

  26. #ccc_g1
    published
    ● tomcat(インストール前提)をどうやって
    起動してますか?
    ○ maven-tomcat-plugin ?
    ○ WTP?
    ○ sysdeo plugin?
    26

    View Slide

  27. #ccc_g1
    published
    ● “public static void main”ならIDEだろうと
    サーバ上のCLIだろうと、どうにでも動かせる
    27
    public class AppStarter {
    public static void main(String args[] argv) {
    Tomcat tomcat = new Tomcat();
    tomcat.start();

    View Slide

  28. #ccc_g1
    published
    Tomcatとは、インストールするものではなく、
    new するもの。
    参照:JJUG-CCC-2014 Fall 「JavaでやってみるThe Twelve Factor App」
    28

    View Slide

  29. #ccc_g1
    published
    JasperReportsはオワコン
    29

    View Slide

  30. #ccc_g1
    published
    JasperReportはオワコン
    ● PDF出力ライブラリ
    ● Java8だとデザインツールが事実上動かない
    ○ (2016年当時です。今は知らない)
    ● 全体のJava8化を阻害する意外なボトルネックだった
    ● flying-soucer-pdf でPDF関連機能を全部作り直し
    30

    View Slide

  31. #ccc_g1
    published
    ポイントはJasperReportの話ではなくて...
    31

    View Slide

  32. #ccc_g1
    published
    “JSESSIONID”はオワコン
    32

    View Slide

  33. #ccc_g1
    published
    “JSESSIONID”はオワコン
    ● サブシステムAは http://localhost:8001/
    ● サブシステムBは http://localhost:8002/
    ● 両方ともセッションCookie名が
    ”JSESSIONID”
    ● ローカル開発環境でA, B同時に起動すると
    片方でしかログイン状態を保てない
    ● エンジニアの生産性低下
    33

    View Slide

  34. #ccc_g1
    published
    意外と知らない人がいるから念のため
    Tomcatで言えば6.0.28 (2010年)から実装済み



    MY_HOGE_SESSIONID


    34

    View Slide

  35. #ccc_g1
    published
    // JavaConfigの場合
    @WebListener
    public class SessionTrackingListener implements
    ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent event) {
    SessionCookieConfig config =
    event.getServletContext().getSessionCookieConfig();
    config.setName("MY_HOGE_SESSIONID");
    config.setHttpOnly(true);
    35

    View Slide

  36. #ccc_g1
    published
    でもなあ、セッションクッキー名が
    ”JSESSIONID”ではなくなります!って言うと、
    L7ロードバランサのスティッキーセッションcookieも
    設定変更しなきゃいけなくなって、
    インフラ担当チームと調整しなきゃなんだよなあ。
    36

    View Slide

  37. #ccc_g1
    published
    sticky-session-cookieもオワコン
    37
    1号機JVM
    2号機JVM
    セッション
    ALB
    JSESSIONID=abc123.1

    View Slide

  38. #ccc_g1
    published
    sticky-session-cookieもオワコン
    ● APサーバ2台の冗長構成だとして
    ● リリースのときは1台ずつ止めてデプロイ
    ● リリース中は片系統にアクセス集中
    ● リリース後も片系統にアクセス集中したまま
    (sticky-session-cookieとはそういうもの)
    ● 同時利用ユーザー数が増えると... !!
    38

    View Slide

  39. #ccc_g1
    published
    sticky-session-cookieもオワコン
    ● spring-session-redis のフィルタをかぶせるだけで、
    javax.servlet.http.HttpSessionの取り回しをラッピング
    39
    1号機JVM
    2号機JVM
    ALB Redis
    セッション

    View Slide

  40. #ccc_g1
    published
    ● L7ロードバランサ、お払い箱説。
    ● WAF的な機能は残るかもですが。
    40

    View Slide

  41. #ccc_g1
    published
    セッションストアが
    JVMヒープでは無いということは?
    SerializationFailedExceptionを起こしやすくなる
    41

    View Slide

  42. #ccc_g1
    published
    “設定ファイル.xml”はオワコン
    42

    View Slide

  43. #ccc_g1
    published
    “設定ファイル.xml”はオワコン
    ● xmlは修正ポイントがわかりにくい
    ● JavaConfigならIDEで補完が効くのでミスりにくい
    ● JavaConfigはif文、switch文なんでもOKで小回りが利く
    ○ 環境差分に対処しやすくなる
    ■ 環境が無数にある場合に便利
    ■ さっき、プルリクエスト毎に専用環境が...って話
    43

    View Slide

  44. #ccc_g1
    published
    おすすめの「JavaConfigはじめかた」



    44
    package jp.bizreach.foo
    @Configuration
    public BarConfig {
    @Bean
    public HogeService hogeService() {...}
    }
    xmlファイルにほんの数行だけ残しておく

    View Slide

  45. #ccc_g1
    published
    jspはオワコン
    45

    View Slide

  46. #ccc_g1
    published
    jspはオワコン
    ● 今さら自作カスタムタグのメンテだるい。
    ● リファクタリングしづらくてゴミになりがち
    ● メールのテンプレートには使えない
    ● jspの単体テストはJUnitすら使えない
    ○ apache cactus?そんなものもありましたね
    46

    View Slide

  47. #ccc_g1
    published
    断捨離、大切。
    47

    View Slide

  48. #ccc_g1
    published
    そもそも”src/main/webapp”がオワコン
    48

    View Slide

  49. #ccc_g1
    published
    src/main/webappの存在がオワコン
    ● クラスパスではないからJUnitから読み込めない
    ○ 単体テスト自動化を妨げる元凶
    ● MVCフレームワークの機能が中途半端だった時代の遺跡
    ○ ほとんどのMVC-FWは、”src/main/resources/static” に置
    いた静的リソースをそのままレスポンスする機能が既にあ
    る。
    ○ TomcatのDefaultServletの出番はもはや無いのに、それ
    を使うためのディレクトリ構造を残すの?
    49

    View Slide

  50. #ccc_g1
    published
    ├ build.gradle
    └ src/
    ├ main/
    │ ├ java/
    │ ├ resources/
    │ └ webapp/
    │ └ WEB-INF/
    └ test/
    ├ java/
    └ resources/
    普通のクラスパス
    テストのクラスパス
    ロストテクノロジー置き場
    50

    View Slide

  51. #ccc_g1
    published
    普及する前にオワコン化しそうな
    “META-INF配下のjsp”
    ● Servlet3.0仕様的には
    jspをここに置くこともで
    きる。
    ● Tomcatなら7.0以降で
    実装済み
    src/
    ├ main/
    │ ├ java/
    │ └ resources/
    │ └ META-INF/
    │ └ foo.jsp
    51

    View Slide

  52. #ccc_g1
    published
    1. 開発環境とCI戦略
    2. 老朽化した技術からの脱却
    3. フロントエンドと仲良くする
    4. 手動テストも、自動テストも。
    5. セキュリティ
    6. バージョンアップする
    52

    View Slide

  53. #ccc_g1
    published
    ちょっと休憩
    53
    1. 水を飲む
    2. 時間を確認
    20分?

    View Slide

  54. #ccc_g1
    published
    1. 開発環境とCI戦略
    2. 老朽化した技術からの脱却
    3. フロントエンドと仲良くする
    4. 手動テストも、自動テストも。
    5. セキュリティ
    6. バージョンアップする
    54

    View Slide

  55. #ccc_g1
    published
    フロントエンド ”技術” と仲良くする
    55

    View Slide

  56. #ccc_g1
    published
    ● IDEはもちろんIntelliJ IDEA
    ○ Java, Scala, TypeScript, JavaScript, Python 全部対応
    ● npm + gulp/webpack から yarn + gradle へ
    56

    View Slide

  57. #ccc_g1
    published
    ● わざわざgradleからyarnを呼ぶ理由
    ○ gradleのほうがなんでも書ける(groovy)わりに、bashより
    も読みやすい
    ○ mavenではまず無理
    ○ 並列実行ですばやくビルドできる
    ○ 並列実行対象タスクを任意に設定しやすい
    ○ Jenkinsfileが短くなる
    57

    View Slide

  58. #ccc_g1
    published
    フロントエンド ”エンジニア” と仲良くする
    58

    View Slide

  59. #ccc_g1
    published
    Swagger + SpringMVC 大好評
    59

    View Slide

  60. #ccc_g1
    published
    1. 開発環境とCI戦略
    2. 老朽化した技術からの脱却
    3. フロントエンドと仲良くする
    4. 手動テストも、自動テストも。
    5. セキュリティ
    6. バージョンアップする
    60

    View Slide

  61. #ccc_g1
    published
    お約束
    61

    View Slide

  62. #ccc_g1
    published
    テストコードに価値はなく、
    その実行結果を見たあとの行動に価値がある。
    ● 基本
    ○ プルリク作る前に手元でテストを実行
    ○ プルリクごとにJenkinsが自動テスト
    ● 理想
    ○ 自動テストが失敗したらプルリクの
    マージボタンが押せない
    62

    View Slide

  63. #ccc_g1
    published
    テストの理想と現実
    ● 自動化に倒すべきなのは確か
    ○ JUnit, spring-test, Selenium...
    ● 「テスト項目表を書いての手動テスト」も
    結局は存在し続けるだろう
    ○ その良し悪しはともかく
    63

    View Slide

  64. #ccc_g1
    published
    「組織にテストを書く文化を根付かせる
    には年単位の取り組みが必要だ」
    ○ これは本当に本当!
    ○ ゼロから初めて既に2年半が経過
    ○ テストコードを根気よく、少しずつ、皆で書く。
    64

    View Slide

  65. #ccc_g1
    published
    65

    View Slide

  66. #ccc_g1
    published
    ● 良い兆候=ビズリーチシステムの現状
    ○ 若手のエンジニアが増、ソースコードの絶対量も増。
    ○ にも関わらずテストカバレッジ率は下がってない。
    むしろジリジリと上がってる。
    ○ “@Test”メソッドの数は明らかに増えている
    ● よくある悪い兆候
    ○ テストが書いてあるのに実行されてない。
    ○ ソース規模やカバレッジ率が
    毎日測定&周知されてない or 不正確。
    66

    View Slide

  67. #ccc_g1
    published
    当面の目標 誰かがコードレビューするとマージ
    ボタンが活性化
    Jenkinsでのテストが一部失
    敗している
    SonarQubeのコーディング
    ルールチェックはOK
    テストコードの有無、カバレ
    ジの低下傾向チェックもやり
    たい
    どれか一つでもXならマージボタンを押
    せなくしたい!
    67

    View Slide

  68. #ccc_g1
    published
    手動テスト
    68

    View Slide

  69. #ccc_g1
    published
    ● あるエンジニアのPC上でなら動く
    ● 他のエンジニアのPCでも動くけど
    準備に時間がかかる
    ● 検証環境でも動くけど、いま別のチームが
    テストのために検証環境にデプロイしているのは
    別ブランチのコードなのでやっぱり動かない
    「動くソフトウェアで進捗を確認せよ」
    しかし、なぜ動かないのか?(再掲)
    69

    View Slide

  70. #ccc_g1
    published
    ● あるエンジニアのPC上でなら動く
    ● 他のエンジニアのPCでも動くけど
    準備に時間がかかる
    ● 検証環境でも動くけど、いま別のチームが
    テストのために検証環境にデプロイしているのは
    別ブランチのコードなのでやっぱり動かない
    「動くソフトウェアで進捗を確認せよ」
    しかし、なぜ動かないのか?(再掲)
    だから手動テストが面倒くさくなる
    70

    View Slide

  71. #ccc_g1
    published
    歴史を紐解いてみる
    ● 2001年: アジャイルソフトウェア宣言
    ○ 「動くソフトウェアこそが最重要な進捗の尺度だ」
    ● 2004年: レガシーコード改善ガイド
    ○ 「レガシーコードとはテストが無いコードのことだ」
    ● 2005年: JUnit4
    71

    View Slide

  72. #ccc_g1
    published
    歴史を紐解いてみる
    ● 2001年: アジャイルソフトウェア宣言
    ○ 「動くソフトウェアこそが最重要な進捗の尺度だ」
    ● 2004年: レガシーコード改善ガイド
    ○ 「レガシーコードとはテストが無いコードのことだ」
    ● 2005年: JUnit4
    ● この頃無かったもの
    ○ 分散VCS(git), AWS-EC2, IaaC, Docker
    72

    View Slide

  73. #ccc_g1
    published
    2000年代前半に書かれたバイブルを片手に
    2018年の”Cloud Native”の世界を生きる?
    73

    View Slide

  74. #ccc_g1
    published
    分散VCS, コンテナ, IaaC時代の手動テスト(案)
    1. プルリクエスト毎にそれ専用の検証環境が
    自動構築される
    2. pushされる都度mergedな状態のコードで
    1の環境にビルド&デプロイされる
    3. そのプルリクに対するテストをいつでも誰でもできる
    a. エンジニア、デザイナー
    b. 社内の手すきの人員?
    c. クラウドソーシング?
    まだ出来てませんが、
    目指すところです。
    74

    View Slide

  75. #ccc_g1
    published
    ちょっと休憩
    75
    1. 水を飲む
    2. 時間を確認
    35-40分?

    View Slide

  76. #ccc_g1
    published
    1. 開発環境とCI戦略
    2. 老朽化した技術からの脱却
    3. フロントエンドと仲良くする
    4. 手動テストも、自動テストも。
    5. セキュリティ
    6. バージョンアップする
    76

    View Slide

  77. #ccc_g1
    published
    ● AWS-S3のバケットがうっかりpublic設定
    ● パスワードを平文でログ出力
    ● 割賦販売法改正, PCI-DSS…?
    ● AWSのシークレットキーを
    ソースコードに埋め込んだままn年変えてない
    ● JRE/ライブラリ/フレームワークで
    脆弱性報告からのバージョンアップ祭り
    77

    View Slide

  78. #ccc_g1
    published
    AWSのシークレットキーをソースコードに
    埋め込んだままn年変えてない問題
    ※ビズリーチではこれから説明する内容で解決済みです
    78

    View Slide

  79. #ccc_g1
    published
    ● シークレットキーをローテーションするというより、
    ローテーションしやすくするのがポイント
    ● AWSに限らない。Twilioのアクセスキー, OAuth2
    プロバイダのclient-secretも。
    79

    View Slide

  80. #ccc_g1
    published
    ● ベストなのはOS環境変数
    ● キーを変えたくなってもソースコードを変更する必
    要をなくす。
    ● OS環境変数を変更してアプリケーションを再起動
    するだけ。
    ● OS環境変数をどう管理するかは別途
    ○ Hashicorp Vault, AWSパラメータストア
    アプリケーションの外から差し替え可能にする
    80

    View Slide

  81. #ccc_g1
    published
    それ、Spring3.1 (2011年)から普通にできるよ!
    $ export FOO_KEY=HOGE
    $ java -jar application.jar
    @Component
    public class FooBean {
    @Value("${foo.key}")
    private String key;
    1. FOO_KEY は
    foo.key プロパティに
    当てられる
    2. 変数 “key” に
    “HOGE” が入る
    See: SystemEnvironmentPropertySource.java
    81

    View Slide

  82. #ccc_g1
    published
    考え方
    ● 設定値の外部化は、セキュリティ確保とテスト容易性の両方に
    関係する
    ○ 「プルリクエストの数と同じだけの開発環境がある」をお忘
    れなく
    ● デプロイ先の環境に合わせてビルドしなおしたら負け
    82

    View Slide

  83. #ccc_g1
    published
    JRE/ライブラリ/フレームワークで
    脆弱性報告からのバージョンアップ祭り
    83

    View Slide

  84. #ccc_g1
    published
    xxxxxというJavaライブラリに脆弱性が発見されました
    深刻度: important
    CVE-2018-xxx…..
    84

    View Slide

  85. #ccc_g1
    published
    たとえばlogbackの脆弱性
    ● logback1.2.0未満にはシリアライゼーション機構に脆弱性が
    ある
    ● SocketServer と ServerSocketReciever 要するにソケット通
    信でログを中継する機能を使ってる場合は危険
    ● 逆にいうとそれを使っていなければ大丈夫そうだね
    85

    View Slide

  86. #ccc_g1
    published
    たとえばJREの脆弱性
    ● JavaWebStartのサンドボックス機構が破られる脆弱性
    ● JavaWebStart使ってるのJenkinsしか見たことないよ
    86

    View Slide

  87. #ccc_g1
    published
    たとえばTomcatの脆弱性
    @WebServlet (name = "Root", urlPatterns = { "/" })
    @ServletSecurity(
    value=@HttpConstraint(rolesAllowed={"admin"})
    )
    public class HelloServlet extends HttpServlet {
    最後に自前でサーブレットクラスを書いたのは
    いつだっけ?(遠い目)
    87

    View Slide

  88. #ccc_g1
    published
    ● ウチでは使ってない機能の脆弱性だから
    今のバージョンのままでいい
    ● そんな対応を続けると、どうなるか?
    88

    View Slide

  89. #ccc_g1
    published
    1.0.1 いま使っているバージョン
    1.0.2 自分は使ってない機能での脆弱性Aに
    対応したバージョン
    1.1.0 便利な機能が増えましたバージョン
    1.1.1 バグを直したバージョン
    ここで危険な脆弱性Bが発見される
    1.1.2 脆弱性Bに対応したバージョン
    89

    View Slide

  90. #ccc_g1
    published
    1. 脆弱性Bはやばい!xxxライブラリを1.1.2まで
    バージョンアップしよう!
    2. あれ?アプリケーションが
    動かなくなった...だと?!
    3. 1.1.0 の段階で自分たちが使っている
    メソッドの仕様が変更されてました。
    「リリースノートやChangeLogに
    全てが書いてあるなんて誰が言った?」
    4. 詰んだ!\(^o^)/
    90

    View Slide

  91. #ccc_g1
    published
    1. xxxライブラリのAという機能に脆弱性が
    発見されたけど自分たちは使ってないから
    問題ない
    2. (半年後)新しい画面の開発のために
    xxxライブラリのAを活用しました(ドヤ顔)
    91

    View Slide

  92. #ccc_g1
    published
    ❏ セキュリティに100%は無い。
    ❏ サービス/開発の利便性とセキュリティを
    両立させる有効な手段?
    ❏ 自分のプロダクトでの影響範囲を見極める
    ❏ 一発で大きくバージョンアップ
    ❏ 複数回に分けて小さくバージョンアップ
    92

    View Slide

  93. #ccc_g1
    published
    1. 開発環境とCI戦略
    2. 老朽化した技術からの脱却
    3. フロントエンドと仲良くする
    4. 手動テストも、自動テストも。
    5. セキュリティ
    6. バージョンアップする
    93

    View Slide

  94. #ccc_g1
    published
    ライブラリ/フレームワークを
    バージョンアップする理由
    1. セキュリティ的な理由で上げることになる。
    Webサービスを開発している場合は特に。
    2. そもそも、新しいバージョンの方が便利なんだから
    ありがたく乗って、作り続ける。
    94

    View Slide

  95. #ccc_g1
    published
    ビズリーチシステムでは
    ● Java6 -> Java8
    ● Spring 3.0 -> 3.2 -> 4.0 -> 4.1 -> 4.2 -> 4.3 -> 5.0
    ● Tomcat6(インストール方式) -> tomcat-embed-8.5
    ● Maven -> Gradle
    ○ Mavenの基本は「先勝ち」でjarが入ってくるため
    意図せず古いor新しいjarが使われることがある
    ○ Gradleではデフォルト”Newest”
    95

    View Slide

  96. #ccc_g1
    published
    ❏ サービス/開発の利便性とセキュリティを
    両立させる有効な手段?
    ❏ 自分のプロダクトでの脆弱性の影響範囲を見
    極める
    ❏ 一発で大きくバージョンアップ
    ❏ 複数回に分けて小さくバージョンアップ
    96

    View Slide

  97. #ccc_g1
    published
    絶え間ないバージョンアップを支えてくれたもの
    少しずつ書き溜めた自動テスト
    ● ビジネスロジックに対するJUnit
    ● Model, View, Controller の各レイヤー毎に
    わざとバラして書いたJUnit
    ● Seleniumテスト
    ○ メンテ工数大なので最小限
    97

    View Slide

  98. #ccc_g1
    published
    1. 開発環境とCI戦略
    2. 老朽化した技術からの脱却
    3. フロントエンドと仲良くする
    4. 手動テストも、自動テストも。
    5. セキュリティ
    6. バージョンアップする
    98
    おっ、すべて語りきれたかな?
    1. 水を飲む
    2. 時間を確認
    あと何分?

    View Slide

  99. #ccc_g1
    published
    99
    開発環境、CI、テスト、フロントエンド、
    セキュリティ、絶え間ないバージョンアップ...
    これらすべてを支える最後の一手とは?

    View Slide

  100. #ccc_g1
    published
    ソフトウェアプロジェクトの世界では、その技術においても管理手
    法においても、生産性、信頼性、容易性の飛躍的な改善を約束す
    る特効薬のような、
    銀の弾丸など無い。
    “No Silver Bullet”
    フレデリック・ブルックス 1987
    “The Computer” IEEE
    100

    View Slide

  101. #ccc_g1
    published
    金の弾丸は実在する。
    匿名エンジニア 2018
    “The Twitter”
    101

    View Slide

  102. #ccc_g1
    published
    102
    Mac Book Pro
    3GHz Core i7
    16GB memory
    250GB SSD
    Jet Brains
    All Products Pack
    ビズリーチのエンジニアとデザイナーの基本装備

    View Slide

  103. #ccc_g1
    published
    「マシンパワーがエンジニアの能力を
    最大限に引き出せてない事象が
    発生している」
    by CTO
    103

    View Slide

  104. #ccc_g1
    published
    104
    iMac Pro 136台
    Xeon 8コア
    メモリ 32G

    View Slide

  105. #ccc_g1
    published
    ノートパソコンじゃないと、
    会議室に持っていけないから
    不便じゃね?
    (とあるツイートより)
    105

    View Slide

  106. #ccc_g1
    published
    A. MacBook Pro + 外付けディスプレイ
    B. iMac Pro + MacBook (Proじゃないやつ)
    106
    好きなほうを選べ。ってことになってます

    View Slide

  107. #ccc_g1
    published
    107

    View Slide

  108. #ccc_g1
    published
    エンジニアの感想
    ● IntelliJ が vim のようにスムーズに...動くぞ!
    ● sbt(scalaのビルド), webpack, XCodeビルドを同時に動かし
    てもへっちゃら!
    108

    View Slide

  109. #ccc_g1
    published
    まとめ
    109
    1. 時間を確認

    View Slide

  110. #ccc_g1
    published
    作るのではなく、作り続けるために
    ● ビッグリライト
    ● リファクタリング
    110

    View Slide

  111. #ccc_g1
    published
    リファクタリングとは(若干のこじつけあり)
    ● オワコンは乗り換えるしかない
    ● ゴミは断捨離するしかない
    ● 新しい息吹を吹き込む
    ○ フロントエンド技術、Python...
    ● 遅くなってしまったものを速くする
    ○ Maven -> Gradle
    ● CIまで含めて管理しやすくする
    ○ Jenkins2 と Jenkinsfile
    111

    View Slide

  112. #ccc_g1
    published
    リファクタリングを支えるもの
    ● setup.sh 一発で準備できるローカル開発環境
    ● 基本FW/ライブラリのこまめなバージョンアップ
    ● 自動テストコード
    ● いつでも誰でも確実に手動テストできる環境
    ○ プルリクエストひとつに対して
    検証環境ひとつ(を目指してます)
    112

    View Slide

  113. #ccc_g1
    published
    簡単かつ確実にセキュリティを維持する基本は
    ● 「シークレット」「キー」と名のつく設定値を
    OS環境変数で書き換えられるようにしておく
    ○ 検証環境がn個ある状態に耐えられるように
    なる副次効果あり
    ● こまめなバージョンアップ
    ○ 巷の脆弱性情報の影響範囲を見極めたところで
    ちょっとした時間稼ぎにしかならない
    113

    View Slide

  114. #ccc_g1
    published
    こまめなバージョンアップを支えるものは
    ● 自動テストコード
    ● 多種類の技術を束ねて並列高速ビルドするGradle
    ● 自動テストを確実に実行するCIサーバ群
    114

    View Slide

  115. #ccc_g1
    published
    目指す世界線は?
    ● プルリクエストひとつに対してその動作検証環境が
    ひとつ、自動的に構築される世界。
    ○ 誰でも、いつでも、安定的に、再現性高めに、
    テスト=要求と実際の動作を比較する=を
    可能にする世界。
    115

    View Slide

  116. #ccc_g1
    published
    目指す世界線のための布石は?
    ● IaaCとコンテナ技術の知見を身につけておく
    ○ ローカル開発環境でDockerを使ってみる
    ○ vagrant, docker, setup.shの存在理由が
    “ローカル開発環境構築手順書” (A4 15枚)
    の代替だけだと思ってると、もったいない。
    116

    View Slide

  117. #ccc_g1
    published
    JJUG-CCC-2014 Fall
    「JavaでやってみるThe Twelve Factor App」 Y.Watanabe
    JJUG-CCC-2015 Fall
    「Java8移行から始まる技術的負債との戦い」 Daisuke.Sei
    JJUG-CCC-2016 Spring
    「テストゼロからイチに進むための戦略と戦術」 Y.Watanabe
    JJUG-CCC-2018 Spring
    「JavaでWebサービスを作り続けるための戦略と戦術」 Y.Watanabe
    117

    View Slide

  118. #ccc_g1
    published
    118

    View Slide

  119. #ccc_g1
    published
    この講演で語ったことのうち、自分一人だけで
    思いついたことも成せたことも、何ひとつありません。
    チームの同僚が助けてくれてこそのことです。
    あらためて、同僚に感謝します。
    助けてくれて、ありがとう。
    119

    View Slide

  120. #ccc_g1
    published
    120
    ビズリーチでは
    エンジニアを募集しています

    View Slide