ssh公開鍵の置き方
本日ssh公開鍵の置き方を教えていただきました!!
いつも他の人に鍵を置いてもらう事ばかりでしたが、これからは自分で誰かの鍵を置いてあげることができるようになりました!!
忘れないように書いておきます!!
手順
sshでログイン
$ ssh hoge-hayashi@hoge-app1 -p 50022
Last login: Wed May 29 14:39:18 2019 from nttkyo898237.tkyo.nt.ngn.ppp.infoweb.ne.jp
__| __|_ )
_| ( / Amazon Linux AMI
___|___|___|
https://aws.amazon.com/amazon-linux-ami/2015.09-release-notes/
117 package(s) needed for security, out of 243 available
Run "sudo yum update" to apply all updates.
Amazon Linux version 2018.03 is available.
rootユーザーになる
[hoge-hayashi@app1 ~]$ sudo -i
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for hoge-hayashi: パスワードうつ
rootユーザーになると最初にいるディレクトリは/root です。
[root@app1 ~]# pwd
/root
/home/deployへ移動
[root@app1 ~]# cd /home/deploy
ls -l -aすると色々みれます。
[root@app1 deploy]# ls -l -a
合計 84
drwx------ 7 deploy 10007 4096 6月 7 12:05 .
drwxr-xr-x 13 root root 4096 5月 28 15:34 ..
drwxr-xr-x 3 deploy 10007 4096 7月 6 2016 .ansible
-rw------- 1 deploy 10007 22517 6月 17 21:17 .bash_history
-rw-r--r-- 1 deploy 10007 18 9月 3 2015 .bash_logout
-rw-r--r-- 1 deploy 10007 193 9月 3 2015 .bash_profile
-rw-r--r-- 1 deploy 10007 124 9月 3 2015 .bashrc
drwxrwxr-x 3 deploy deploy 4096 3月 2 2017 .bundle
drwxrwxr-x 4 deploy 10007 4096 12月 21 2015 .gem
-rw------- 1 deploy 10007 2256 6月 7 11:27 .lesshst
-rw------- 1 deploy deploy 356 3月 2 2017 .mysql_history
drwxrw---- 3 deploy 10007 4096 1月 13 2016 .pki
drwx------ 2 deploy 10007 4096 5月 28 16:33 .ssh
-rw------- 1 deploy deploy 10763 6月 7 12:05 .viminfo
.ssh/authorized_keysファイルを開く
.ssh/authorized_keysの中にssh公開鍵が置いてあるのでviewコマンドやvim等で開くとみれます。
[root@app1 deploy]# view .ssh/authorized_keys
ずらりと公開鍵が置いてあるのがみれます。
Linuxの知識薄すぎるので勉強がんばってゆきます!
「Linuxの仕組み」の輪読会へ行った
今日は「Linuxの仕組み」の輪読会へ行ってまいりました!!
この本を買ったのが昨日のことなので全く予習はできていなかったのですが、予習なしでOKの輪読会だったので有難かったっです!
今日は以下の内容を進めていきました!
・はじめに
・第1章 コンピューターシステムの概要
・第2章 ユーザーモードで実現する機能
この本は実際に手を動かしながら学んでいく形式です。
そこで、企画して下さった方々が作業するための環境をdockerで作ってくださりました!!
以下はそのリポジトリです!!
また、この本のサンプルコードはC言語で書かれているものがたくさんあったのですが、
C言語の解説をしてくださる方もいらっしゃり、とても理解が進みました!!
さらに、Dockerの何が良いのかについてVirtualBoxとの違いについての説明を交えながら教えていただいたり等、今まで理解せずに使ってきてしまった技術について学ぶこともできました!!
本にも書いてありましたが、
「ハードウェアの特性を考慮した、良いソフトウェアを開発できるようになる」、
「どのような指標に基づいてシステムを設計すれば良いか分かるようになる」、
「OSやハードウェアに関するトラブルが起きたときに、冷静に対処できるようになる」、といったことが出来るようになりたいのでしっかり輪読していこうと思います!!
SQL発行されまくるスクリプト
あるデータを取得する必要があり、コンソールでスクリプトを実行しておりました。
すると、AWS RDSのProcessor load が90%を超えているというアラートが何度も鳴ってしまいましたw
OPさんにも心配をさせてしまいたした。
その時のスクリプトが以下です。
idsに調べたいhogeidを代入し、Hogeモデルのレコードと関連するmessageのレコード情報を引っ張っておりました。
messages = []
ids.each do |id|
message = Hoge.find_by(hogeid: id)&.message
messages << "#{message.id}........略"
end
puts messages
これだとレコード1つずつに対してSQLが発行されてしまっており、RDBへの負荷がとても大きくなってしまっていたようです。
さらに期間指定もしていない為、レコード全件見にいってしまっていたようです。。。
修正後のスクリプトが以下です。
いっぺんに100件ずつ処理を行うようにしてあげ、
includesで関連先レコード取得する際SQL発行されないようにし、
期間指定をして全件見にいかないようにしてあげました。
messages = []
ids.each_slice(100) do |new_ids|
pre_messages = Hoge.includes(:message).where(created_at: (DateTime.new(2019,6,6,7,00))..(DateTime.new(2019,6,6,21,00))).where(hogeid: new_ids)
pre_messages.each do |pre_message|
message = pre_message&.message
messages << "#{message.id}........略"
end
end
puts messages
これが正しいやり方なのかは分かりませんが、発行されるSQLがめちゃくちゃ減りました。
データの取得できるスピードも格段にアップしました。
最初のスクリプトだと一度に数百件ずつidsを代入していてもアラートが鳴っていたのが、1万件以上のidを代入してもアラートもならなくなりました。
アクティブレコードのメソッドがどんなSQLに変換されるのか、ログを見て意識していこうと思います!
find_eachで順番を指定したい
pdfの作成される順番を変えたいと思いコードをいじっておりました。
以下はpdfの作成される部分のコードの一部です。
class BatchPrintJob < ApplicationJob
略
def perform(batch_print)
略
invoices.find_each do |invoice|
略
pdf << CombinePDF.load(pdf_object.path)
end
略
end
end
invoicesのレコードを引っ張る際にorderで順番を指定すればうまくいくかと思ったのですが、
find_eachは順番を指定することができないらしく、pdfの作成される順番を指定するにはどうすればいいんだろう、、、と困っておりました。
色々ググっていると以下の記事を発見しました!!
この記事を参考にしてみたら動いてくれました!!
以下のコードは変更後のものです。
class BatchPrintJob < ApplicationJob
略
def perform(batch_print)
略
invoices.order("clients.yayoi_code").find_each_with_order do |invoice|
略
pdf << CombinePDF.load(pdf_object.path)
end
略
end
end
class Invoice < ApplicationRecord
略
def self.find_each_with_order(options={})
page = 1
limit = options[:limit] || 1000
while
offset = (page-1) * limit
batch = limit(limit).offset(offset)
page += 1
batch.each{|x| yield x }
break if batch.size < limit
end
end
略
end
find_each_with_order メソッドの中身が難しくてよくわからなかったのでbinding.pryを挟みながら、変数の値を確認してみました。
limitはいっぺんにブロックの処理を実行するオブジェクトの数、
batchはいっぺんに処理を行うオブジェクトの塊、
offsetは、、、何だろう、、、batchの何番目の塊を引っ張るか判断するためのオブジェクトでしょうか。。。
batch.each{|x| yield x} の部分は do ~ endまでのブロックを実行しているようです。
ネットの情報を参考にするとしても、
理解した上で、きちんと理由を持って、コードを書いていきたいです。。。!!
FactoryBot難しい...
ジョブを実行すると、ある条件の時にレコードが更新されることをテストしたかったのですが、なかなかテストが通らないため、binding.pryを駆使してデバックしておりました。
しかし、binding.pryだときちんと値が更新されているのに、なぜかテストは落ちておりました。
そこで p メソッドでFactoryBotでつくったオブジェクトと、後からfind_byで検索したオブジェクトを出力してみたところ、同じものだと思っていたオブジェクトが別物であることがわかりました!
(テストじゃない場合は同じレコードになる)
以下はそのテストコードです。
require "rails_helper"
RSpec.describe InvoiceCloseJob, :type => :job do
include ActiveJob::TestHelper
略
let!(:contract_auto_before_closing_day) { FactoryBot.create(:contract, :auto_before_closing_day) }
略
describe "契約期間延長処理" do
略
context "自動延長有効の契約書" do
context "契約期間終了日 < 締め期間の最終日" do
it "契約期間が更新されること" do
InvoiceCloseJob.perform_now(invoice_close)
p contract_auto_before_closing_day
p Contract.find_by(display_name: 'auto_before_closing_day')
expect(contract_auto_before_closing_day.to).to_not eq("2019-04-29".to_date)
end
end
略
こちらはターミナルに出力されたオブジェクトです。
idが別物でした。
そして、find_byで検索してきた方のオブジェクトはきちんと値が更新されておりました。
#<Contract id: 511, client_id: 2, from: "2019-04-01", to: "2019-04-29", billing_closing_date_id: 1, contract_type: "従量課金制", status: "actived", display_name: "auto_before_closing_day", created_at: "2019-06-12 05:09:46", updated_at: "2019-06-12 05:09:46", service_id: 2, display_name_service: "", auto_extension: true, extension_months: 6, ceil_digit: nil, had_spot_item: false>
#<Contract id: 467, client_id: 2, from: "2019-04-30", to: "2019-10-29", billing_closing_date_id: 1, contract_type: "従量課金制", status: "actived", display_name: "auto_before_closing_day", created_at: "2019-06-12 04:32:07", updated_at: "2019-06-12 05:09:49", service_id: 2, display_name_service: "", auto_extension: true, extension_months: 6, ceil_digit: nil, had_spot_item: false>
無事、expect( ) の引数をfind_byで引っ張ってきた方のオブジェクトに変更したところ、テストが通ってくれました。
FactoryBot難しい。。。
@sinamon129さんの「システム障害との向き合い方」をもう一度読んだ
@sinamon129さんの「システム障害との向き合い方」をもう一度読んでみました。
このご発表を聞いた当時はシステム障害を経験したことがありませんでしたが、先日まさにシステム障害を経験することがあったからです。
そのスライドが以下です!!
自分の状況と照らし合わせてみる
自分の前提は以下のような感じです
・受託
・プロジェクトに関わる人はインフラエンジニア1名、アプリ側エンジニア3名、PO1名
このスライドの中でシステム障害の種類として、以下の5つを挙げてくださっておりました。
①開発時の実装ミス(バグ)
②手動操作のミス
③ アクセスの急増
④使用しているサービスの不具合
⑤これらの複合
今回自分が経験したのは③のアクセスの急増が原因の障害でした。
そして現在自分の関わっているプロジェクトは、
発生 → 発覚 → 調査 → 一時対応 → 収束 → 振り返りと恒久対応
という順番の「収束」の段階で、これから恒久対応していくという段階です。
心に残った部分と感想その他
ご講演を聞いてもシステム障害を経験したことのなかった自分には理解しきれない所が多かったのですが、今読み返してみると「なるほど!!これは大事だ!!これは気をつけていきたい!!」と思えるようになった部分がありました。
スライドにも書かれておりましたが、戦力にならなくても率先して参加し、発生した障害を学びに変えていきたいと思います!!
そして連絡すべきことは担当の人にしっかり連絡し、一人でできない部分はきちんと周りの人にきく、ということも気をつけていこうと思います。
さらに、障害を起こさないために普段コードを書いたりレビューする段階で、
「条件分岐を意識し、細かい書き方より条件があっているかを確実にする」
「変更が意図しない部分に影響を与える実装になっていないか確認する」
「変更はロールバックできる状態にする」
というのも実行していきたいです!!
ActiveDecoratorを(ごく一部)読んだ
先ほどActiveDecoratorを使って定義したメソッド(を呼んでるモデルに定義したメソッド)をコントローラーで呼んだところ、エラーとなりました。
ActiveDecoratorをView以外で使う時は、ActiveDecorator のデコレーターメソッドをかましてあげる必要があるとのことでした。
以下のように、ActiveDecorator::Decorator.instance.decorate( ) とメソッドを呼ぶインスタンスに処理を加えてあげると無事動いてくれました。
class AmountChecksController < ApplicationController
略
private
def total_amount_sum(invoices)
invoices.map{|invoice| ActiveDecorator::Decorator.instance.decorate(invoice).total_amount_for_read}.sum
end
end
この処理が何をしているのか気になったため、定義元をみてみました。
active_decorator/lib/active_decorator/decorator.rb の中にdecorate( ) メソッドがあり、定義は以下のようになっておりました。
def decorate(obj)
return if defined?(Jbuilder) && (Jbuilder === obj)
return if obj.nil?
if obj.is_a?(Array)
obj.each do |r|
decorate r
end
elsif obj.is_a?(Hash)
obj.each_value do |v|
decorate v
end
elsif defined?(ActiveRecord) && obj.is_a?(ActiveRecord::Relation)
# don't call each nor to_a immediately
if obj.respond_to?(:records)
# Rails 5.0
obj.extend ActiveDecorator::RelationDecorator unless obj.is_a? ActiveDecorator::RelationDecorator
else
# Rails 3.x and 4.x
obj.extend ActiveDecorator::RelationDecoratorLegacy unless obj.is_a? ActiveDecorator::RelationDecoratorLegacy
end
else
if defined?(ActiveRecord) && obj.is_a?(ActiveRecord::Base) && !obj.is_a?(ActiveDecorator::Decorated)
obj.extend ActiveDecorator::Decorated
end
d = decorator_for obj.class
return obj unless d
obj.extend d unless obj.is_a? d
end
obj
end
引数のオブジェクトがArrayならeachで取り出して再度1つずつdecorateメソッドを呼び、
Hashならeach_valueでバリューを取り出して1つずつdecorateメソッドを呼んでおります。
そして必ずオブジェクトを返すように、様々な条件分岐させてモジュールを生やしておりました。
Viewだとdecorate( ) メソッドを呼ばなくてもActiveDecoratorを使えるようになってるのはどうやっているのだろうと思い、そのほかのファイルものぞいてみたのですが、難しかったのでまた後日チャレンジしてみようと思います。。。!!