1 of 83

入社してから運用している

サービスの運用改善奮闘記

JJUG CCC 2017 FALL 2017/11/18

#jjug_ccc #ccc_e5

フリュー株式会社

佐藤慧太 @SatohJohn

2 of 83

自己紹介

  • 佐藤慧太@SatohJohn
  • フリュー株式会社(京都):入社6年目
  • ピクトリンクというサービスで�サーバサイド開発とフロントエンド開発やってます

2

3 of 83

本日の目的

  • 今回の発表が皆さんの業務に役立つ!
  • フリューを知ってもらって仲間になって�もらう!

3

4 of 83

JJUG CCCとフリュー

4

5 of 83

今回も

「改善」について話します

5

6 of 83

目次

  • リソースの一元管理
    • Spring Cloud Config
  • JavaScriptの依存解決
    • webpack + frontend maven plugin
  • UIテストの自動化
    • Gauge
  • まとめ

6

7 of 83

ピクトリンク

  • 若年女性がターゲット
  • 2011年にSPサイトをリリース
  • Android、iOSアプリもリリース

7

8 of 83

ピクトリンク

  • 会員数:1300万人
  • クリスマスとか世間が�浮かれているとき�イベントのときに負荷が�上がります
  • クリスマスを支える俺たちと�Java

8

9 of 83

ピクトリンク

  • プリントシール機から�送られてきた画像を扱う
  • シール画像を利用したSNS
  • 課金システム
  • 商品クチコミ

 などなどたくさんの機能がある

9

10 of 83

目次

  • リソースの一元管理
    • Spring Cloud Config
  • JavaScriptの依存解決
    • webpack + frontend maven plugin
  • UIテストの自動化
    • Gauge
  • まとめ

10

11 of 83

課題

  • 様々なプロジェクトやツールがそれぞれDBの接続URLを記述したファイルを持っている
  • DBのリプレース時に、全プロジェクトのファイルを�修正することになった

11

12 of 83

The Twelve-Factor App

  • セットアップ自動化のために 宣言的なフォーマットを使い、�プロジェクトに新しく加わった開発者が要する時間とコストを�最小化する
  • 下層のOSへの依存関係を明確化し、実行環境間での�移植性を最大化する
  • モダンなクラウドプラットフォーム上へのデプロイに適しており、�サーバー管理やシステム管理を不要なものにする
  • 開発環境と本番環境の差異を最小限 にし、アジリティを最大化する�継続的デプロイ を可能にする
  • ツール、アーキテクチャ、開発プラクティスを大幅に変更することなく�スケールアップ できる

12

13 of 83

The Twelve-Factor App

  • セットアップ自動化のために 宣言的なフォーマットを使い、�プロジェクトに新しく加わった開発者が要する時間とコストを�最小化する
  • 下層のOSへの依存関係を明確化し、実行環境間での�移植性を最大化する
  • モダンなクラウドプラットフォーム上へのデプロイに適しており、�サーバー管理やシステム管理を不要なものにする
  • 開発環境と本番環境の差異を最小限 にし、アジリティを最大化する�継続的デプロイ を可能にする
  • ツール、アーキテクチャ、開発プラクティスを大幅に変更することなく�スケールアップ できる

13

14 of 83

The Twelve-Factor App - III. 設定

  • 環境変数に設定値をいれて、アプリケーションで�参照する
    • データベース、Amazon S3やTwitterなどの�外部サービスの認証情報

14

15 of 83

一元管理の考慮点

  • ファイルをデプロイして配置するのではなく�アクセスできるような形式にしたい

15

16 of 83

Spring Cloud Config

16

17 of 83

Spring Cloud Config

  • アクセスするとGitHubや自前Repositoryから�設定を取得してJSONとして返却する
    • /ファイル名
  • Spring Boot プロジェクトとしてサーバに�デプロイすることで使える

17

18 of 83

Spring Cloud Config

18

19 of 83

configサーバの場所が

変わると設定変えなきゃ�いけない

19

20 of 83

Service Discovery

(Netflix Eureka)

20

21 of 83

Service Discovery

21

22 of 83

Service Discovery

22

23 of 83

Service Discovery を使った�Spring Cloud Config の メリット

  • リソースサーバの移行に対して接続先を�変更する必要がない
  • 複数Eurekaに登録すると適当にルーティングされる

23

24 of 83

Service Discovery を使った�Spring Cloud Config の デメリット

  • Eurekaの分、設定が多くなる
  • 監視するアプリケーションが増える

24

25 of 83

configサーバ(bootstrap.yml)

25

spring:

application:

name: アプリケーション名(clientが指定する

spring.cloud.config.server:

git:

uri: configのレポジトリ

username: githubのusername

password: githubのpassword

eureka.client.serviceUrl.defaultZone: eurekaサーバの場所

26 of 83

client側(bootstrap.yml) Spring Bootから繋ぐ場合

26

spring:

cloud:

config:

name: oracle-rdbms(取得してくる情報)

profile: prod

label: master

discovery:

enabled: true

serviceId: configサーバの名前

eureka.client.serviceUrl.defaultZone: eurekaサーバの場所

27 of 83

client側(bootstrap.yml) Spring Bootから繋ぐ場合

27

spring:

cloud:

config:

name: oracle-rdbms(取得してくる情報)

profile: prod

label: master

discovery:

enabled: true

serviceId: configサーバの名前

eureka.client.serviceUrl.defaultZone: eurekaサーバの場所

28 of 83

github上のリソースファイル

28

29 of 83

リソースの一元管理が

できるようになった

29

30 of 83

今後

  • 現状利用しているのがSpringBootプロジェクト�だけなので、それ以外のプロジェクトで�利用できるようにする

30

31 of 83

目次

  • リソースの一元管理
    • Spring Cloud Config
  • JavaScriptの依存解決
    • webpack + frontend maven plugin
  • UIテストの自動化
    • Gauge
  • まとめ

31

32 of 83

課題

  • フロントエンドの処理が増えて、ファイル間の�依存関係ができた
  • どのスクリプトがどこから参照されているのかが�分かりにくく機能の削除がしにくい

32

33 of 83

Require.js

  • config.jsに記述することで動的に関係ファイルを�取得することができる

33

34 of 83

Require.js - 問題点

  • 関係するJavaScriptの実行が遅い
  • config.jsをロードして依存するファイルを�持ってくる

34

35 of 83

webpack

  • 依存するファイルを一つのJavaScriptファイルに�まとめ配布することができる

35

36 of 83

webpack - 問題点

  • Node.jsなど開発環境を整える必要がある
  • トランスパイルする必要が出てくる

36

37 of 83

webpack実行環境の作成

  • Node.jsを各自インストールする
  • Package.jsonを記述する
  • webpack.config.jsを記述する

37

38 of 83

非エンジニアの作業を

考えると

Node.jsのインストールは

敷居が高い

38

39 of 83

運用スタイル

  • コーダは基本的な画面の作成のみを担当しており、�開発の知識があるわけではない
  • コーダが一番リリースをしている

39

40 of 83

環境構築の考慮点

  • 環境構築をしなくて良いようにする
  • Mavenでのpackagingをしているので�その過程にwebpackの処理を入れたい

40

41 of 83

frontend maven plugin

  • compile処理中に自動的にNodeをインストールできる
  • goalにwebpackを指定することができる

41

42 of 83

frontend maven pluginのメリット

  • Windows、Mac OS、Linuxで使える
  • バージョンを合わせられる
  • Nodeの存在を意識しなくて良い

42

43 of 83

frontend maven pluginのデメリット

  • 個人のNode環境が使えない

43

44 of 83

frontend maven pluginを使う際のpom.xmlの設定

44

<plugin>

<executions>

<execution>

<id>install node</id>

<goals><goal>install-node-and-npm</goal></goals>

</execution>

<execution>

<id>npm install</id>

<goals><goal>npm</goal></goals>

</execution>

<execution>

<id>webpack build</id>

<goals><goal>webpack</goal></goals>

</execution>

</executions>

</plugin>

45 of 83

frontend maven pluginのTips

  • Node.jsやnpmのProxyはsettings.xmlに書く
  • 実行したくない場合はskipを書く
  • 実行時のパラメータはargumentsタグに書く

45

46 of 83

JavaScriptの依存解決が�できた

46

47 of 83

webpackによる改善点

  • 依存関係が解消できたので修正が楽になった
  • Node.js(npm)を使うことでライブラリの管理も�楽になった

47

48 of 83

frontend maven pluginのデモ

48

https://github.com/furyu-john/frontend-maven

49 of 83

今後

  • 開発環境でJavaScriptやSCSSを毎回トランスパイル�してdeployするのが面倒

49

50 of 83

gulp.js

  • リソースファイルの処理に得意なライブラリが多い
  • 変更をwatchしてdeployするタスクなどが簡単にかける
  • es2015で書きたければgulp.babel.jsという名前にする

50

51 of 83

目次

  • リソースの一元管理
    • Spring Cloud Config
  • JavaScriptの依存解決
    • webpack + maven frontend plugin
  • UIテストの自動化
    • Gauge
  • まとめ

51

52 of 83

課題

  • 手動でUIテストを実施している
  • 単純な移行作業をやりたくても、テスト項目が�多すぎて再実施工数が馬鹿にならない

52

53 of 83

スプレッドシートの内容

53

  • テストの概要
  • 事前状態
  • テスト内容(方法)
  • 確認内容

54 of 83

UIテストを自動化したい

54

55 of 83

自動化の考慮点

  • UIテストは日本語でレビュワーに読みやすいように�書かれていてほしい
  • Seleniumだけだとコードベースになりがち

55

56 of 83

Gauge

  • 現在ベータ版 ( 0.9.4 )
  • Windows、Mac OS、Linux対応

56

57 of 83

Gauge

  • 実施内容はJava、C#、Rubyで書くことができる
  • IntelliJやVisual Studio Code、Visual Studioの�プラグインがある

57

58 of 83

Gaugeのメリット

  • 日本語でテスト内容を記述できる
  • ある程度実装していくと組み合わせて�非エンジニアの人でもかけるようになる

58

59 of 83

Gaugeのデメリット

  • ベータなのでバージョンアップすると�全く動かないとかあるある
  • テストが多くなってくるとステップの定義が�ごちゃごちゃになりやすい

59

60 of 83

Gaugeのプロジェクト構成

  • Gauge-Java
    • Stepの定義をJavaで記述する
  • DbUnit
    • DBの初期化や状態のチェックなどに利用する
  • Selenide
    • ブラウザを操作する、画面の状態のチェックに利用する

60

61 of 83

Gaugeのプロジェクト構成

61

Gauge

Gauge

Java

DbUnit

Selenide

62 of 83

Gaugeの用語

62

Gauge

説明

ユニテ

シナリオ

テスト単位

@Testの�メソッド

ステップ

実施内容

コード一行

コンセプト

ステップの

集合

メソッド

63 of 83

specファイルの記述方法

63

# ログイン

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

## 非会員がトップページにアクセスした場合、ログイン画面に遷移する

* "/top/menu"にアクセスする

* URLが"/login/top"か検証する

* ログイン画面が表示されているか検証する

64 of 83

stepの定義

64

@Step("<url>にアクセスする")

public void openUrl(String url) {

Selenide.open(url);

}

@Step("URLが<url>か検証する")

public void verifyUrl(String url) {

String actualUrl = Selenide.url();

assertThat(actualUrl, is(url));

}

@Step("ログイン画面が表示されているか検証する")

public void verifyPageIsLogin() {

$("input[type='email']").should(exist);

$("input[type='password']").should(exist);

$("input[value='ログイン']").should(exist);

}

65 of 83

specファイルの記述方法(ファイル)

65

* 初期データとして<file:specs/ログイン/init01.xml>を登録する

specファイル

定義

@Step("初期データとして<file>を登録する")

public void addRecords(String records) throws Exception {

IDataSet dataSet = getDataSet(records);

DbunitManager.insertRecords(dataSet);

}

66 of 83

specファイルの記述方法(テーブル)

66

* 以下のテーブルをクリアする

|name |

|---------------------------|

|HOGE |

|FUGA |

|PIYO |

specファイル

定義

@Step("以下のテーブルをクリアする <table>")

public void truncateTable(Table table) {

List<String> tableNames = table.getTableRows()

.stream().map(r -> r.getCell("name")).collect(Collectors.toList());

DbunitManager.truncateTables(tableNames);

}

67 of 83

SetupとTear down

67

# 通常有料会員化

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

* ピクトリンクにログインする

…..ほにゃらら......

___

* "9000000000000"のアカウント情報を以下のテーブルから削除する

|table |

|---------|

| ACCOUNT |

| SESSION |

| COOKIE_LOGIN |

* キャリアサイトをログアウトする

68 of 83

大きくなってきたらコンセプトにまとめる

68

* Topページが表示されていること

specファイル

# Topページが表示されていること

* ページタイトルが"ピクトリンク"であるか検証する

* URLが"/top/menu"か検証する

cptファイル

69 of 83

詰まったこと

  • Headlessのために使っていたHtmlUnitが�JavaScriptのPromiseでエラーになって�SPAで作ってた画面のテストができなくなった
  • polyfillを入れてもうまく動かない

69

70 of 83

Chrome Driver

  • 定期的にバージョンアップされている
    • 別途Driverは入れなきゃいけない
  • headless optionを利用する

70

71 of 83

mavenから実行する

  • gauge-maven-pluginを追加する
  • Maven pluginを入れて mvn testを実施する

71

72 of 83

UIテストの自動化が�できた

72

73 of 83

Gaugeのデモ

73

https://github.com/furyu-john/gauge-sample

74 of 83

今後

  • UIテストの実施タイミングを考える
    • 初めての自動テスト-Webシステムのための自動テスト基礎
    • マージタイミングでUIのテストを走らせると�リリースが遅くなる
    • フィードバックタイミングを考え、ユニテや結合テストを�組み合わせる

74

75 of 83

目次

  • リソースの一元管理
    • Spring Cloud Config
  • JavaScriptの依存解決
    • webpack + frontend maven plugin
  • UIテストの自動化
    • Gauge
  • まとめ

75

76 of 83

まとめ

  • リソースの一元管理
    • Spring Cloud Configをつかって解消した
  • JavaScriptの依存解決
    • webpack + frontend maven pluginをつかって解消した
  • UIテストの自動化
    • Gaugeをつかって解消した

76

77 of 83

まとめ

  • 改善はこつこつと積み重ねていくことが大事
  • 関係各位のスキルセットに合わせて、�前準備と設計をする

77

78 of 83

最後に

78

79 of 83

フリューでは

エンジニアを募集してます

79

80 of 83

80

81 of 83

81

82 of 83

一緒に働きませんか!?

82

83 of 83

Fin

83