ちょっと厨二っぽいSEのブログ

プログラミングとかのシステム備忘録など

AWS移行の全記録

■概要

以前、オンプレで動いていた古い予約システムをAWSへ移行したのでその内容です。
AWS環境は存在しなかったため、アカウント作成からはじめました。
コンサル会社と契約し、なるべく良い形で進めました。

11サービスを一気に移行しました。

※サイト規模として、PVは75000/1h。DBのデータ量は100GB。

変更項目 移行前 移行後
環境 オンプレミス AWS
php php5.2 php5.3
DB mysql 5.1, PostgreSQL9.1.11 mysql 5.5, PostgreSQL9.5.18
APサーバー Apache 2.2 Apache 2.2
sessionサーバー tokyo tyrant ElastiCahe(Redis)
CDNサーバー Akamai Akamai
webサーバー オンプレ x 13 ec2 x 10

サーバー代は150万円/月から、AWS移行後は60万/月まで下がりました。
hiritu.PNG

やったこと

クラウドの選定。コンサル会社選定
・環境構築<EC2、RDS、ElastiCache、S3、ELB、VPC・SG・NSネットワークまわり>
・開発環境整備<デプロイの自動化など、開発効率UP施策>
・RDSデータ移行
・アプリ設置
・負荷テスト
・リリース
・運用監視

クラウドの選定、コンサル会社選定

AWS、GCM、Azureの中から、コンサル会社複数社に対して見積もりを取り検討。
結果、AWS + クラスメソッドに選定。
Q, C, Dで比較をしましたが、他の企業に比べ全体的に優れていました。

◆インフラ環境構築

EC2、RDS、ALB、NatGatewayなどなどを使う、普通の構成
今までバラバラだったネットワーク関連をルール化して管理
またソースにたどり着くまでにALB、Akamaiを経由することで、ソース側の改修が必要になります。

詳細はこちらの記事にまとめています:
https://qiita.com/ryokwkm/items/cd885d8ef72176587466

DNSをお名前.comから、Route53に移行

 route53のゾーンをあらかじめ作っておき、本番移行時にそちら切り替えました。

◆開発環境整備

自動化できるものを以下のように自動化&ルール化。

デプロイを手動から自動へ

Jenkins + deployerを使ってボタン1つでデプロイできるようにした。

ソースの管理をGitLabからGitHub

GitHubGitHub-Flowを採用して開発、Masterマージにはプルリク承認後でないとマージできない制限をかけた。
GitLabは当時の開発ベンダーが用意したものを使用していましたが、動作が重くなり通常使用に耐えなかった。

◆データ移行

Postgresは、dump&リストア
Mysqlは、レプリケーションでデータを移行
その他のファイルは rsyncコマンドで持っていき、その後aws s3 sync コマンドでS3へ移動させました。
rsyncは差分だけを持っていきますので、事前に一度実行しておくことで当日は短時間で移動できます。

詳細はこちらの記事にまとめています:
https://qiita.com/ryokwkm/items/0230f547a666b2441d51

◆アプリ設置

ここが一番苦労しました。
・今までサーバーごとにバラバラだったシステムのドキュメントルートを統一(ルール化)
・ソース内の環境依存部分の修正
ロードバランサーが挟まったことによる修正
・DBの接続先をprivateドメインへ変更

詳細はこちらの記事にまとめています:
https://qiita.com/ryokwkm/items/c6e35d28f8fec72ad3ce

◆負荷テスト

loadRoidというSaasツールを採用
Sonyが作ったという、手軽に負荷試験が行えるツールです。
現在はアルファ版で、なんと無料で使用できます。
負荷試験といえばJMeterという無料ツールがありますが、EC2から実行すると結局実行する側のEC2代がかかってしまいます。

◆運用監視

これまで障害が発生した場合は、
Mackerel -> Twilioで電話 & Slackへ通知 -> リモートデスクトップで作業
という運用だった(DB負荷などで障害がよく起きていた)
AWS移行したことで障害はほとんどなくなったが、運用監視の会社に入ってもらった。
障害発生時のフローを決めておくことで、障害が起きても復旧まで行ってもらえます。

あのサービス・アプリのアーキテクチャ・プログラミング言語・フレームワークまとめ〔2019年始版〕

概要

他所様の言語・F/W・DB・ツール等の使用数まとめ

以下の記事の集計の軸を変えて、各カテゴリ&ジャンルごとにカウントしたまとめ あのサービス・アプリのアーキテクチャプログラミング言語フレームワークを大調査!〔2019年始版〕 employment.en-japan.com

プログラミング言語

サーバーサイドKotlinが伸びてる。

バックエンド系

Python機械学習系の利用も含まれている様子 ※ Java, Node.jsの集計はF/Wなどのツールを見てバックエンドと判断。Node.jsがBFFかは判別できず。 ※ Kotlinはサービスごとにググった結果からサーバーサイドKotlinと判断

フロントエンド系

ネイティブ系

※ Kotlin, Javaの集計はサービスやF/Wなどを見てネイティブと判断

フレームワーク

Golangは言語の使用数多いけどF/Wの数が少ない。Rails減ってる。

バックエンド系

フロントエンド系

  • Vue.js: 12
  • React: 12
  • Angular: 4
  • Riot.js: 2
  • Backbone.js: 1
  • Knockout.js: 1
  • Next.js: 1

その他

  • gRPC: 2

DB・データ

Elasticsearchが伸びてる。

  • MySQL: 32(AuroraのMySQLが6つ&RDSのMySQL1つ含む)
  • Elasticsearch: 18(内2つがAmazon Elasticsearch Service)
  • Redis: 18(内2つがRedis Cluster)
  • PostgreSQL: 12
  • Memcached: 10
  • MongoDB: 6
  • BigQuery: 5
  • DynamoDB: 5
  • Cassandra: 3
  • Redshift: 3
  • Bigtable: 3
  • Presto/Hive: 2
  • Solr: 1
  • CloudSearch: 1
  • Kafka: 1
  • RabbitMQ: 1
  • Couchbase: 1
  • HBase: 1
  • Hadoop: 1
  • Athena: 1
  • Oracle Exadata: 1
  • Realm: 1
  • SQLite: 1
  • PipelineDB: 1
  • Druid: 1
  • Firestore: 1

CI/CDツール

  • CircleCI: 26
  • Jenkins: 24
  • Bitrise: 4
  • Sider: 3
  • Travis CI: 3
  • Drone: 2
  • Codecov: 2
  • GitLab CI: 2
  • AWS CodeBuild: 2
  • AWS CloudFormation: 1
  • Terraform: 1
  • Screwdriver: 1
  • Azure Dev Ops: 1
  • fastlane: 1
  • AWS CodeDeploy: 1
  • DeployGate: 1
  • Codeship: 1
  • Cloud Build: 1
  • Concourse: 1
  • Chef: 1
  • AppVeyor: 1

各種ツール・その他

構成・サービス管理系

  • Ansible: 11
  • Terraform: 9
  • Chef: 5
  • Capistrano: 3
  • Packer: 2
  • Consul: 1

監視・BI・モニタリング系

  • New Relic: 11
  • Mackerel: 9
  • Redash: 8
  • Datadog: 6
  • Sentry: 5
  • Kibana: 5
  • Fabric: 4
  • PagerDuty: 3
  • Prometheus: 2
  • Grafana: 2
  • BugSnag: 2
  • Crashlytics: 1
  • Tableau: 1
  • Munin: 1
  • Nagios: 1
  • AppDynamics: 1
  • Zabbix: 1
  • Metabase: 1
  • New Reric: 1

デザイン的なコミニュケーションツール

  • Zeplin: 7
  • Abstract: 3
  • Figma: 2

その他

  • Docker: 14(この内5つがKubernetesを利用)
  • Fluentd: 11

React + Reduxのシンプルな雛形

概要

私はサーバーサイドのエンジニアですが、片手間にフロントもやってます。 業務でReact+Reduxを使っているので、構成を参考にしつつシンプルな雛形を作りました。

https://github.com/ryokwkm/react-redux-sample.git

このサンプルはテキストフォームに入力した内容を console.log で出力するシンプルな内容です。 React-Routerを使っている、2ページ構成です。

スクリーンショット 2018-12-25 18.33.05.png

以下の手順で動作します

1.git clone 2.npm install (もしくは yarn install ) 3.npm run start (もしくは yarn run start ) 4.webpackサーバーが起動するので、コンソール出力されたURLにアクセスする 例: http://localhost:8083/

ディレクトリ構造

├── public
│   └── index.html
├── src
│   ├── Handler.jsx
│   ├── actions
│   │   └── index.js
│   ├── compornents
│   │   ├── About.jsx
│   │   └── App.jsx
│   ├── reducers
│   │   └── index.js
│   └── store
│       └── configurte-store.js
├── stylesheets
│   └── index.scss
├── .eslintrc.js
├── README.md
├── package-lock.json
├── package.json

各ファイルの解説

Action, Reducer, Compornentsの各階層ごとにディレクトリを切ってある。

src/actions/*.js src/compornents/*.jsx src/reducers/*.js

src/Handler.jsx 一番最初に読まれるJS React-RouterによるRouting、 その他の初期処理を読み込んでいる。

src/store/configurte-store.js Storeの設定を行っている。 Middlewareの読み込みや、Reducerとの紐付け、Redux-Devtoolの設定など。 Middlewareは、redux-thunkのみ使用している。

使用パッケージ

使用しているパッケージは以下のとおり es2015など若干古いパッケージを使っているので、適宜最新のものを使うと良いでしょう。

{
  "name": "react-redux-sample",
  "version": "1.0.0",
  "main": "index.js",
  "author": "ryokwkm <ryokwkm@gmail.com>",
  "license": "MIT",
  "description": "react redux simple code",
  "dependencies": {
    "babel-core": "6.25.0",
    "babel-loader": "7.1.1",
    "babel-preset-es2015": "6.24.1",
    "babel-preset-react": "6.24.1",
    "css-loader": "0.28.4",
    "extract-text-webpack-plugin": "^3.0.2",
    "import-glob-loader": "1.1.0",
    "node-sass": "4.5.3",
    "prop-types": "15.5.10",
    "query-string": "5.0.0",
    "react": "15.6.1",
    "react-dom": "15.6.1",
    "react-redux": "5.0.6",
    "react-router-dom": "4.1.2",
    "redux": "3.7.2",
    "redux-devtools": "3.4.0",
    "redux-devtools-extension": "2.13.2",
    "redux-thunk": "2.2.0",
    "sass-loader": "6.0.6",
    "style-loader": "0.18.2",
    "webpack": "3.3.0",
    "webpack-dev-server": "2.11.3"
  },
  "devDependencies": {
    "eslint": "^3.19.0",
    "eslint-config-airbnb": "^15.0.2",
    "eslint-plugin-import": "^2.14.0",
    "eslint-plugin-jsx-a11y": "^5.1.1",
    "eslint-plugin-react": "^7.1.0"
  },
  "scripts": {
    "start": "./node_modules/.bin/webpack-dev-server"
  }
}

reduxを使った感想

結論としては、大規模なアプリでない場合、Reactだけで十分だと感じました。 Reactは比較的簡単ですが、Reduxは難易度が高いことが主な理由です。

学習も必要な上に、コード量、複雑性が増します。 開発コストは増大するでしょう。

ソースをキレイに分割できるので、管理のしやすさは上がります。 ですが、そこまで大規模でないアプリでしたらReactのみで十分な印象です。

以下の記事ではReduxの開発者のコメントを紹介をしていますが、無理して導入する必要はない旨が書いてあります。 https://techracho.bpsinc.jp/hachi8833/2018_03_13/53183

【Git】特定のフォルダのみを操作対象にする

同じシステムの改修が何年も続くと、Gitリポジトリが重くなっていきます。
さらに同一のリポジトリに複数のシステムが乗っておりPullするだけでヒドイ状態・・なんてことがプロジェクトによってはありえますよね。(最近経験した話)

そんな時は特定フォルダのみを操作対象にして動作を軽くしましょう。
sparsecheckout という機能を使うことで、対象フォルダ以外の存在を隠し、動作を高速にすることが出来ます。

git config core.sparsecheckout true
echo 対象フォルダのPATH/ > .git/info/sparse-checkout
git read-tree -m -u HEAD

対象リポジトリに対して行います。
まず、sparsecheckoutを有効にします。
その後、以下のファイルに、必要なフォルダを相対Pathで記述します。
.git/info/sparse-checkout 
Windowsだとしても / 区切りで記述してください。

これで準備は完了です。以下のコマンドを実行すると、不要なファイルはいなくなります。

git read-tree -m -u HEAD

.git/info/sparse-checkoutには改行区切りで複数のフォルダを記載できます。

echo 追加で表示させるPATH/ >> .git/info/sparse-checkout

【Git】Gitプロンプトを便利にする方法

以下のことを実現します。


・Gitコマンドの自動補完
・Gitのプロンプトの表示を変更

Gitの自動補完

コマンドの途中でTabを押すことで入力を行う、自動補完
下記URLから「git-completion.bash」をコピーし読み込み。
git bashの場合は追加ずみ(C:\Program Files (x86)\Git\etc\git-completion.bash)
https://github.com/git/git/tree/master/contrib/completion/git-completion.bash
設定の読み込みには.bashrcを使います(後述)

Gitのプロンプトの表示を変更

ブランチ名を表示

同じく以下のファイルをコピー、読み込み。(同じくgit bashには追加されている)
https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh

オプション

gitプロンプトにもオプションがあり、以下の変数の変更することでプロンプトの表示を変えるることができます。

GIT_PS1_SHOWDIRTYSTATE
addされてない変更(unstaged)があったとき"*"を表示する、addされているがcommitされていない変更(staged)があったとき"+"を表示する

GIT_PS1_SHOWSTASHSTATE
stashになにか入っている(stashed)とき"$"を表示する

GIT_PS1_SHOWUNTRACKEDFILES
addされてない新規ファイルがある(untracked)とき"%"を表示する

GIT_PS1_SHOWUPSTREAM
現在のブランチが追跡ブランチより進んでいるとき">"を、遅れているとき"<"を、遅れてるけど独自の変更もあるとき"<>"を表示する。

PS1の設定方法

コンソールの表示
色の変更や、2行を1行に変更ができます。
http://qiita.com/caad1229/items/6d71d84933c8a87af0c4
f:id:ryokwkm:20170921125254p:plain 

f:id:ryokwkm:20170921125506p:plain

・設定

.bashrcで設定を行う

Push通知の証明書、p12 -> pem変換について

Push通知の証明書をP12からPEMに変換する方法、Push通知のテストをする方法、Push通知の証明書の種類などをまとめました。
範囲としては、キーチェーンからp12を作るところから、pemに変換するところまでになります。

証明書(PEM、P12)の種類

push通知の証明書はその役割によって4パターンのファイルにわけることができます。
push通知はサーバーに置いて使いますが、送信実行するにあたりパスワードや秘密鍵を設定することができます。
ここではわかりやすいように、以下のファイル名を使用します。
拡張子はp12とありますが、システムによりpemに変換する必要があります。

xxx_push_production.p12 : パスありの証明書
xxx_push_production_secret.p12 : 証明書の秘密鍵
xxx_push_production_secret_noenc.p12 : 証明書の公開鍵(秘密鍵のパスワードを解除したもの)
xxx_push_production_test.p12 or xxx_push_production_all.p12 : パス無しの証明書(=証明書と公開鍵をあわせたもの)

p12 書き出し方法

一番簡単なものはパスワード無しの証明書を作成する方法です。
push通知を送る際パスワードを使用しませんので、テストに使用するのには良いと思います。
キーチェーンからp12を書き出す際は、以下のように証明書を選択(鍵ごと選択します)
xxx_push_production_test.p12 という名前で保存します。
f:id:ryokwkm:20170627194939p:plain


サービスを運用するにあたり、証明書とキーは分けて管理するのが一般的です。
やり方はそれぞれ以下のとおりで、
書き出し後にパスワードを求められますので、設定してください。

証明書の書き出し

xxx_push_production.p12 として保存
f:id:ryokwkm:20170627200317p:plain

秘密鍵の書き出し

xxx_push_production_secret.p12 として保存
f:id:ryokwkm:20170627200344p:plain




P12ファイルからPEMファイルへの変換方法

pemの種類によってコマンドが異なります。
コマンド実行時にパスワードを求められますが、これは出力時に設定したパスワードを入力してください。

・証明書(パス無し)

openssl pkcs12 -clcerts -nodes -out xxx_push_production_test.pem -in xxx_push_production_test.p12

・証明書(パス付き)

openssl pkcs12 -clcerts -nokeys -out xxx_push_production.pem -in xxx_push_production.p12

秘密鍵

openssl pkcs12 -nocerts -out xxx_push_production_secret.pem -in xxx_push_production_secret.p12

秘密鍵パスフレーズを解除し、公開鍵へ変換

openssl rsa -in xxx_push_production_secret.pem -out xxx_push_production_secret_noenc.pem

パスレーズを解除する目的や使い方

鍵ありの状態ですと、apache等のサーバーでは起動のたびにPEMフレーズ (PEM phrase) の入力を求められます。そのため、暗号化された秘密鍵は復号化して使うのが一般的です。
復号化した秘密鍵はroot以外は読めない状態で保存すべきです。

証明書と公開鍵をあわせる

cat xxx_push_production.pem xxx_push_production_secret_noenc.pem > xxx_push_production_all.pem



証明書のパスワードを確認する方法

古い証明書や自分以外が作成した証明書など、パスワードを確認したい場合があると思います。
方法はいくつかあると思いますが、以下のコマンドを実行するとパスワードが求められますので、
それが想定したものとあっているか確認する方法が最も簡単な方法です。
openssl rsa -in xxxx_push_production.pem




疎通テスト方法

証明書が正しいか、ターミナルからお手軽にテストすることができます。
注意すべきなのは、Xcodeから実機インストールした場合、テストできるのはdevelopのpush通知のみだということです。

・疎通テスト(パス無し)

openssl s_client -connect gateway.push.apple.com:2195 -cert xxx_push_production_all.pem

・疎通テスト(パスあり)

openssl s_client -connect gateway.push.apple.com:2195 -cert xxx_push_production.pem -key xxx_push_production_secret.pem

Push通知を送ってみる

アプリと証明書、両方のテストがしたい場合、実際にPush通知を送ってテストします。
PHPとは違い、Rubyでしたら数行書くだけで簡単に送れますので、そのサンプルを載せておきます。

gist.github.com

Tech Crunch Tokyo 2016 レポート 一日目

f:id:ryokwkm:20161120111711j:plain

2016/11/17(木)、2016/11/18(金)の二日間、Tech Crunch Tokyo 2016に参加してきました。


まずこのイベントがなんなのか

Tech Crunchは、スタートアップ企業の紹介やインターネットの新しいプロダクトのレビュー、そして業界の重要なニュースを扱うテクノロジーメディアです。

Tech Crunch Tokyoは年に一回開催される上記サービスのイベントで、日本最大のスタートアップ祭典と呼ばれます。

名前からはテクニカル系の情報がメインと感じますが、
メインの内容としてはサービスのプロダクトや、スタートアップに関する情報でした。

もちろんテクノロジーに関するプロダクトのイベントなので話題は出てきますが、
VCやアクセラレータに関すること、スタートアップ企業の事業計画の説明やプレゼンなどがほとんどを占めます。

イベントステージ以外の通路にも企業の出店があり、プロモーションや参加者との交流が盛んにおこなわれていました。

内容としては、もう軌道に乗りはじめている企業から、
「今年新しいSNSを立ち上げましたー」というような企業まで様々です。

様々な催しがありましたが、
特に興味深かったのは、「スタートアップバトル」です。
これは今年プロダクトをローンチしたスタートアップ企業がプレゼンで競い合うイベントで、
「市場性」「独自性」「将来性」の3点で審査を行い、最優秀プロダクトを決めるものです。

約5分間を2000名の来場者全員の前で話します。

優秀者はこのイベントで資金調達をできたり、その他にも様々なメリットを享受できます。

今回はスタートアップバトルの中で気になった一つを紹介します。

出張のための計画を自動で作ってくれるサービス「AI Travel」です。
AI Travel:世界一シンプルな国内出張・海外出張の予約手配サービス


旅行のプランをざっくり伝えると計画してくれるサービスで、
出張する場所はどこで、ホテルはこんな感じ、交通手段はこれ などと入力すると
新幹線や泊まるホテルの案をいくつか出してくれます。

また最寄り駅に近いかなどの他に、ホテルがコンビニや繁華街に近いかなど、人が実際にホテルを予約する時の判断基準も考慮されています。
私も旅行するときに一番苦労するのがホテル選びになるので、個人的に使ってみたいと感じました。

またこの「プランを立ててくれる機能」は今後色々な企業が行ってくるのではと思います。

例えば居酒屋なんかは特にこだわりはなく、場所や値段、雰囲気がマッチすればそれでいいと思いますので
それらを設定するとマッチしたものの候補を出してくれるようなものは使ってみたいです。

このプランの選出には機械学習や独自のアルゴリズムを使っているらしく
テクノロジーとしてはそこも将来性を感じました。