yamachan.log

紫陽花

Rubyで小さなツールを作る時のtips

メインファイルの作成

main.rbを用意し処理を1ファイルにまとめます。 実行する同一処理の増加などによってはオブジェクト指向の考え方に則って構造化していきます。 走り出しから構造化を意識してコードを書くのではなく、とりあえず処理を実行できるところまで作ることを意識します。

別ファイルの読み込む

ファイル毎に処理を分けた場合には実行ファイルにファイルを読み込む必要がある 基本的はrequireで読み込む。 同一ディレクトリ階層の場合は、requireでカレントディレクトリを示すドットを打つ

optparseでパラメータ管理

CLIで実行する際にオプションを渡したい時あります。 そんな時は optparse を使うと便利です。 ARGVの機能を簡単に導入できます

require 'optparse'
opt = OptionParser.new
opt.on('-a') { |v| p v }
opt.on('-b') { |v| p v }

opt.parse!(ARGV)

ARGVはコマンドライン引数のこと argument vector (引数の配列)

手軽な構造体

OpenStruct

ruby-progressbarで進捗表示

実行時間が長い処理を行っている時進捗状況が目に見える形でわかると便利ですよね。 ruby-progressbarを使うことで進捗状況を可視化することができます。 利用方法は簡単です。下記を参考に使ってみましょう

インストール

gem install ruby-progressbar

実行処理

require 'ruby-progressbar'
pb = ProgressBar.create
10.times do
    pb.increment
    sleep 0.1
end
pb.finish   

SEO 学習 memo

SEO memo

SEO

「Search Engine Optimization」 検索エンジン最適化

検索結果でWebサイトがより多く露出されるために行う一連の取り組みのことを指す

Googleが掲げる10の事実

  • ユーザーに焦点を絞れば、他のものはみな後からついてくる。
  • 1つのことをとことん極めてうまくやるのが一番。
  • 遅いより速い方がいい。
  • ウェブでも民主主義は機能する。
  • 情報を探したくなるのはパソコンの前にいるときだけではない。
  • 悪事を働かなくてもお金は稼げる。
  • 世の中にはまだまだ情報があふれている。
  • 情報のニーズはすべての国境を越える。
  • スーツがなくても真剣に仕事はできる。
  • 「すばらしい」では足りない

SERP

SERP (Seach Engine Result Page) サープ Googleは1ページ目の情報でユーザーのニーズを全て満たそうと考えている なのでSERPには多様性を持たせようとしている

ゲームタイトルの検索結果では - 公式ページ - wiki - playstore - news - 公式youtube - twitter - 攻略サイト

など網羅的なページが表示される

ユーザーの満足度と数字

ユーザーの満足度を数字を通して見る際に見るべき指標

情報の細分化はユーザーの満足度に影響する

検索ボリューム

キーワードの検索回数 Adwordsで確認することができる 検索ボリュームの大きいキーワードは検索上位をとるのが難しい 単一キーワード、「モンスト」のほうがボリュームが大きい 複合キーワード、「モンスト アニメ 最新話」の方がボリュームが小さい

複合キーワードと単一キーワード

単一キーワード 「モンスト」

複合キーワード 「モンスト アニメ 最新話」

ロングテール

特定の狙ったキーワードだけでなく、関連する様々なキーワードで検索にヒットさせ、幅広く流入を増やすこと

検索順位とセッション

検索順位とセッションは相関性はないがニアイコールではある

コンテンツマーケティング

最終的に勝負を決めるのはコンテンツ

ドメインオーソリティ

mozが定めるサイトの評価スコア

ページオーソリティ

mozが定めるページの評価スコア

  • 被リンク
  • 信頼性
  • キーワード網羅性

パンダアップデート

「低品質なコンテンツが検索結果上位に表示されにくくするため」のGoogle検索アルゴリズムアップデートの総称

ペンギンアップデート

「スパム行為や、ウェブマスター向けガイドラインに著しく違反しているwebページ」の検索順位を下げる

Ginzametrics

検索順位をdayで追うことができる Ginzametrics

namaz

検索順位の変動を確認できる namaz

インフラ 学習 memo

インフラ で学んだことを雑にmemoしていく

サーバー

サーバーとは、「Linux」や「Windows Server」など、サーバー用のOSインストールしたコンピュータ

「サーバーにどのようなミドルウェアをインストールするか」によってサーバーの用途が変わる。

サーバーに複数のミドルウェアをインストールすることも可能。 この場合「Webサーバー 兼 データベースサーバ」となる

ネットワーク

TCP/IP

IPアドレス

32ビットで構成 8ビットずつ10進数に変換したものをピリオドで区切って表現 例:「192.168.100.200」 「0」~ 「255」 「0.0.0.0」から「255.255.255.255」まで IPアドレスは、ネットワーク上で互いに重複しない唯一無二の番号で、いわゆる「住所」に相当 IPアドレスには「パブリックIPアドレス」と「プライベートIPアドレス」がある。

パブリックIPアドレス

IPアドレスは重複が許されないため勝手に設定できない、 インターネットで利用するIPアドレスは「ICANN」という団体が一括管理 インターネットに接続する際に用いるIPアドレスのことを「パブリックIPアドレス」もしくは、 「グローバルIPアドレス」と呼ぶ

プライベートIPアドレス

プライベートIPアドレスは誰にも申請することなく自由に使える

ポート番号

ポート番号の利用で1IPアドレスに対して複数のアプリケーションが通信可能になる 「web」「DNS」「SMTP」にはあらかじめポート番号が決まってたりする。それを「ウェルノウンポート」と呼ぶ

HTTP

webサーバーとwebブラウザでやりとりする通信規約

TCP/IPモデル

OSI参照モデル

ドメイン

DNSサーバー

ドメイン名」と「IPアドレス」を結びつける

ホスト

ホスト「host」とは、コンピュータやルーターなどのネットワーク機器など、 IPアドレスを持つ通信機器の総称

VPC

VPCを「パブリック」と「プライベート」に分けて利用

パブリックサブネット

Webサーバーなどを置く インターネットに接続し、「公開」されている。

プライベートサブネット

DBサーバなどを置く インターネットには直接接続していないため、「非公開」とされている。

NAT

Network Address Translation 内部だけで通用するアドレスを外部とも通信できるアドレスに変換する技術

サブネットマスク

サブネットマスク表記」

表記方法の違い

CIDR

「CIDR表記 (サイダー表記)」

表記方法の違い

ルーティング

ネットワークにデータを流すために必要な設定「ルーティング情報」 「ルーティングテーブル」や「ルートテーブル」と呼ばれる AWSでは「ルートテーブル」

インターネットゲートウェイ

インターネットに接続する間口 EC2からインターネットへ、インターネットからEC2へアクセスできるようにするためにアタッチする必要がある

ネットワーク関連コマンド

AWS

2004年11月からサービス開始

AWSの特徴 - 豊富なサービス - 柔軟なリソース - 従量課金

リージョン

世界中の地域に存在するデータセンター群 「オレゴンリージョン」「東京リージョン」「バージニアリージョン」

アベイラビリティゾーン

リージョンのさらに分割されたデータセンター群 大阪と東京的な

エッジロケーション

東京に2つ、大阪に1つある CDNサービスのcloudFrontやRoute53のDNSサーバなどで用いられている

Amazon VPC

Amazon Virtual Private Cloud」

AWS上に論理的な仮想ネットワークを構築するサービス 元々AWSパブリッククラウドサービス

Amazon EC2

Amazon Elastic Compute Cloud」 「EC2インスタンス」と呼ぶ インスタンスとは、仮想的なサーバーのこと

AMI (Amazon Machine Image)

Amazon Route53

WebベースのDNSサービス 権威DNSサーバー

  • Hosted Zone

Hosted ZoneはDNSレコード (Resource Record) の集合

  • Record Set Record Setは、各DNSレコード

  • Routing Policy Routing Poricyは、Route53がRecord Setに対してどのようにルーティングを行うのかを決定する

レコードタイプ

A (Address Record)

ホスト名とIPV4IPアドレスマッピングを行う ドメイン名とIPアドレスドメイン名:IPアドレス = 1:n

CNAME (Canonical Name Record)

他のDNS名の別名を設定する Aレコードで定義されているドメイン名と別名を定義する。 IPアドレス:ドメイン名 = 1:n を定義する

AレコードとCNAMEレコードの違い

Aレコードはドメイン名とIPアドレスの関係性を定義、CNAMEはそれの別名を定義する

DNSフェイルオーバー

利用の前提としてヘルスチェックを設定する必要がある

Amazon S3 (Simple Storage Service)

シンプルでとても使い易いインターネットストレージサービス

CloudFront

CloudFrontはAWSが提供するCDNサービス CDNサービス (Content Delivery Network) 画像などの性的コンテンツをS3から配信している時に、S3の前段にCloudFrontを挟むことで静的コンテンツをエッジサーバーがキャッシュし、速度を早くすることができる

S3とCloudFrontを連携して用いる

サーバー移設

road_workerのファイルを変更しmasterブランチへマージ circleciが変更を確認しAWSのRoute53の設定を変更 変更が反映されたタイミングでDNSサーバーからのレスポンスに応じて飛び先を変える DNSフェイルオーバーをサーバーの向き先変更には利用しない 重み付けはサーバーで失敗した時のリスクを最小限に抑えたい場合などで利用する レイテンシーは大規模サービスで主に利用する

アプリケーション管理ツール

  • ElasticBeanstalk
  • Opsworks
  • CloudFormation

unicorn-worker-killerを導入

Railsのプロダクトでサーバーのメモリが足りなくなる問題が頻発しました。

構成はnginx + unicorn

unicornのワーカープロセスは、起動後ユーザーからのリクエストを処理し、再起動されることがありません。 長期間の運用を続けるとメモリが徐々に食いつぶされ次第に枯渇していきます。 結果、リクエストが集中していない時間帯でもdatadogのアラートな鳴りまくる事態に陥っていました。

この状況を「unicorn-worker-killer」を導入し、解決しました。

f:id:Yamakichi:20170710225857p:plain

下記ブログを参考にさせていただきました。

Unicorn-worker-killerが便利だった件

unicorn-worker-killerを使うことで、ワーカプロセスが以下の条件の場合に、自動的に再起動してくれます。 - ワーカプロセスが指定回数のリクエストを処理した場合 - ワーカプロセスが指定量のメモリを使用している場合

Gemの導入

gem 'unicorn-worker-killer'

config.ruに設定を記述 [参考]

unless ENV['RAILS_ENV'] == 'development'
  require 'unicorn/worker_killer'
  CHECK_CYCLE = 16
  use Unicorn::WorkerKiller::Oom, (400*(1024**2)), (500*(1024**2)), CHECK_CYCLE
end
  • graceful restartとは?

graceful restart (緩やかな再起動)

グレースフル・リスタート

Apacheのrestartやgraceful、stopなどの違い

AmazonCloudFrontでRailsのAssets周りにある静的ファイルをCDN配信する

AmazonCloudFrontでRailsのAssets周りにある静的ファイルをCDN配信する

RailsでアプリのassetsをCloudFront経由で配信した時の話

問題と解決

Railsのアクションキャッシュ導入時、Webサーバ内からassetsの配信を行っていた。 その場合、Deploy時にassets precompileを実行しmanifestの更新を行うと、 キャッシュしていたviewのCSSがmanifest更新に伴って参照できなくなり、表示が崩れてしまうという問題が発生した。 この問題を解決するために、Deploy時にassets以下のファイルをS3に置いてCloudFront経由で配信する形式に変更することにした。

CDN

CDN (コンテンツデリバリーネットワーク) Akamaiが1990年代に提唱したコンテンツを配信するネットワーク

参考: 第1回 CDN の 仕組み (CDNはどんな技術で何が出来るのか)

Amazon CloudFront

AWSが提供するCDNサービス 今回はCloudFrontを使いました

CloundFront

Amazon S3

SimpleStrageService Sが3つでS3 「超便利ファイル置き場」

今回は静的ファイルをS3に置いてCloudFrontが参照する

S3

CDNを導入すると何が良いの?

パフォーマンスが良くなる。(高速化) 世界中のどこからアクセスされてもある程度一定のレスポンス速度を担保できる。

やること

  • S3バケットを用意
  • CloudFront側の設定
  • Rails側の設定
  • sprocketsのmanifestファイル
  • S3でクロスオリジンの設定

S3バケットを用意

assetsファイルはS3バケットに置くので、バケットを用意します

ドメイン

assets.service-domain.com

CloudFrontの設定

CIでprecompileを行いS3にファイルを置く

DeployフローでCIを通す前提の話です。普段はCircleCIを利用しています

  • 1.テスト実行
  • 2.テスト成功
  • 3.assets precompile を実行
  • 4.compileファイルをs3にupload
  • 5.デプロイ
machine:
  environments:
  timezone:
    Japan
  ruby:
    version: 2.2.3
  services:
    - redis

deployment:
  production:
    branch: master
    commands:
     - ./deploy/circleci/upload_assets.sh
     - ./deploy/circleci/deployment.sh
#!/bin/sh
EXPIRE=`ruby -e "puts (Time.now + (60*60*24*30)).strftime('%Y-%m-%d')"`

bundle exec rake assets:precompile RAILS_ENV=production
mv ./public/assets/.sprockets-manifest-* ./public/assets/.sprockets-manifest-8jednoecyllbeucnvekdwhbqlkjwhhdq.json
aws s3 sync ./public/assets s3://assets.service-domain.com/assets --region ap-northeast-1 --expires $EXPIRE

shellファイルの先頭に #!/bin/sh (シバン))を記述することはマナー (一応記述がなくても動く)

EXPIREでS3内のファイル有効期限を指定 (今回は30日間にセット)

mv コマンドで生成したmanifestの32文字の乱数部分を同一のものに変更 (今回は決めの値を記述しましたが、32文字であれば何でも大丈夫)

Rails側の設定

Rails側でassetsの配信設定を行います

config/environments/production.rb

config.action_controller.asset_host = ""

デフォルトではコメントアウトになっています、asset_hostに配信のURLを指定します。

config.acrion_controller.asset_host = "https://assets.service-domain.com"

precompile後のファイルはS3に置きますが、manifestファイルはWebサーバーのpublic/assets以下に置かなければうまく参照できず正しく表示されません。 Deployのタスク内でmanifestファイルのみをs3から取ってくる処理を書きます。

execute "aws s3 cp assets manifest" do
  cwd release_path
  command "aws s3 cp s3://assets.service-domain.com/assets/.sprockets-manifest-8jednoecyllbeucnvekdwhbqlkjwhhdq.json ./public/assets/"
  environment "RAILS_ENV" => rails_env
end

今回はaws s3 cpコマンドで設置方法

sprocketsのmanifestファイル

  1. そもそもmanifestファイルってなんのために存在するの?
  2. manifestファイルではコンパイルされたassetsファイルのルートを指示する
.sprockets-manifest-8jednoecyllbeucnvekdwhbqlkjwhhdq.json

S3でクロスオリジンの設定

RailsでFontawsomeなどを利用している場合、上記の手順でDeployし表示できるが、Fontawsomeのアイコンが豆腐になってしまう問題が発生する。 この問題はクロスオリジンの設定をすることで解決できる。

うまく設定できるまで幾つか地雷を踏みましたがうまく設定できました。

Rails Routing Constraints

Constraintsとは

  • Railsのroutingに存在する機能
  • routingに制限を設けることができる
  • デフォルトで定義されている
  • カスタムで制約を作成することも可能

セグメントの制限

get "books/:id" => "photos#show", constraints: { id: /[A-Z]\d{5} }

上記はconstraintsでidに制約を追加している。 /books/A12345 のようなパスにはマッチするが、 /books/12345にはマッチしない。

リクエストに応じた制限

get "books", constraints: { subdomain: "admin" }

サブドメインadminが含まれていることを制限している。

ブロックでも表現できる。

namespace :admin do
  constraints subdomain: 'admin' do
    resources :photos
  end
end

カスタムconstraints

制約用のクラスを設けて対応する lib/constraint以下にクラスを置く self.matches?メソッド内に制約を定義する 下記ではrequestを引数で取り、その中に、admin が含まれているかどうかを判定する

module Constraint::Subdomain
  class Admin
    def self.matches?(request)
      request.subdomains.include?("admin")
    end
  end
end

ルーティング側には下記のように定義することで制約を加える

Rails.application.routes.draw do
  constraints Constraint::Subdomain::Admin do
    get "dashboard" => "homes#dashboard"
  end
end

dashboardへのリクエストパスのサブドメインにadminが含まれているかを判定する

社会人1年目

無事3月に大学を卒業し、今日から社会人になりました。 都内のWeb系の企業でRailsアプリの企画と開発をやっていきます。 まだまだひよっこエンジニアなので日々精進していきたいです。 今年の目標は、去年よりもブログ記事を多く書くことなので、日々の開発で得た気づきや、学びを記事に落とし込んで書いていきたいと思います。

日付変わる前に更新できてよかった。w

がんばります!