rhanda | 元銀行員Web系エンジニアの日記

実務未経験からWeb系受託開発企業に転職したひよっこエンジニアが覚えたことや日々の感情を残すブログ

デプロイしていたRailsアプリケーションでThe change you wanted was rejected.が出た

当該エラー

The change you wanted was rejected. Maybe you tried to change something you didn't have access to. If you are the application owner check the logs for more information.スクリーンショット 2021-03-08 11.20.07.png



解決プロセス

CSRF対策説

とりあえずエラー文でググって、複数タブ・端末でのログインが原因との記事をいくつか発見。 確かにPCとiPhoneの両方からアクセスしていたので、共にタブやクッキーまで削除してリトライしましたが変わらず。

ここでログを見ましたスクリーンショット 2021-03-08 11.16.24.png

②バージョン相違説

最終行のblock in spawn_threadに目が行き、ググってみるとrack・rails・pumaのバージョンを合わせたところ解決したとの事例を発見。しかし調べると全て合っていました。🤔


③ルーティング間違い説

同時にルーティングでの解決事例を発見。しかし開発環境では問題なく動作していることから、そこは関係ないと考えました。



④nginx設定説 ←ここで解決

このタイミングで、エラー文をを見られていないことにやっと気づきました。スクリーンショット 2021-03-08 14.04.04.png

HTTP Origin header didn't match request.base_url そもそものヘッダーはhttpなのにhttpsが来ちゃってると言われているのかなと考えました。 (最近にHTTPS設定をしたのでほぼそうだろうと思いました。) ググってみると、nginxで追記する必要のある設定を発見。

/etc/nginx/conf.d/default.confで以下のように設定を追加。

 location / {
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header Client-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto $scheme;  #この設定を追加
        proxy_redirect  off;
        proxy_pass http://puma;
    }

※X-Forwarded-Proto:https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-Forwarded-Proto

sudo systemctl restart nginx.serviceでnginxを再起動し解決しました。


(ついでに)vimファイルがread onlyだった

また/etc/nginx/conf.d/default.confの内容をvimで書き換えたときに、read onlyが出たのですが、 :w !sudo tee % で反映させて :q! で強制脱出し、変更できました。

(参考記事) https://qiita.com/Catshollic/items/2334f63845d8b0d85bdd http://tm.root-n.com/unix:command:vim:readlonly_write



まとめ

エラーが出た時に直近で自分がいじっていた物も考えると、良い仮説が立てられるのではないかと思いました。 ログを見て事実情報を集め、仮説を立てて検証というステップが踏むことが大切だと感じました。

VSCodeでファイルを開くとき、常に新しいタブでエディタを開く方C

VSCodeを使っていると、ファイルを開く時に現在のタブに上書きされて表示される時があり、ちょっと不便に思うことが多いと感じたので設定してみました。

ファイルに設定を追記する方法ではなく、メニューバーから入っていって設定したメモ。 参考記事:https://masizime.com/blog/vscode-enablepreview



やり方

①メニューバーから、「code」→「基本設定」→「設定」と入っていく スクリーンショット 2021-02-25 16.15.01.png

workbench.editor.enablePreviewを検索して、入っているチェックを外します。

スクリーンショット 2021-02-25 16.16.18.png

↓↓↓

スクリーンショット 2021-02-25 16.19.16.png

以上でエディタが上書きされることなく開けるようになりました。 ご覧いただきありがとうございます。



参考記事:https://masizime.com/blog/vscode-enablepreview

Ajax通信を実装しようとしたら、Uncaught ReferenceError: $ is not definedが出た

Uncaught ReferenceError:~~is not defined

調べたところ「〜〜の変数や関数が定義されていないから使えmasenn」というエラーのようです。 また今回の$ is not definedは、「jQueryが読み込まれていない段階でjQueryの関数は使えないよ!」と言われていることがわかりました。

しっかり</body>直前でCDNを読み込んでいるのに何故と詰まってしまいました。

# layouts/application.html.erb

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>

結論

早速ですが結論は、記述していた組み込みコードのjquery-3.3.1.slim.min.jsjQueryのスリムビルドと呼ばれるバージョンで、非推奨の機能やAjax機能が削除された軽量版だったからでした。

ずっとjQueryが読み込めていない線のみで調べていたので非常に紆余曲折を経たのですが、組み込みコードを取ってきたBootstrapのサイトを再度見た時に、「jQueryはスリム版」という気になる文言に気づきました。 スクリーンショット 2021-02-17 18.39.42.png


リンク先はjQuery公式ページで全て英語だったので、あまりよくわからなかったのですが、 『BootstrapでAjaxを使うときの注意点』https://www.inet-solutions.jp/technology/jquery-ajax-bootstrap/ を読み、jQuery公式サイトからスリムではない組み込みコードを取ってきたところ、無事動くようになりました。

まとめ

一番最初の、CDN読み込み段階でつまづいていたとは疑いもしていませんでした。 解決策までの紆余曲折の間では、 gemfileからの読み込みを試みたり、レイアウトファイルいじってみたり、webpackの設定が何か間違っているのではないかetc考えたりして、非常に多くの時間を使ってしまいました。 とはいえ大きくわかりやすく書いてあった訳だしと反省しました。 特にこの初心者のうちからちゃんと読んで、わからなければ調べるようにして行けば、何かが起こった時にスムーズに検証を進められるのではないかと思いました。

Webpackとは?

何度も調べまわっているような気がしたので、関連の用語をまとめてメモしてみました。 修正点・誤っている箇所等あれば、アドバイスを頂けると幸いです。

Webpackとは

JavaScriptのモジュールバンドラー。 ややこしいと思ったのはWebpackerとは別物だということ。 (Webpackerは、モダンなフロントエンド開発を強力にサポートするWebpackをRailsで使うためのgemパッケージ。)



モジュールとは

ひとつのファイル。 関数やコンポーネント等、機能ごとに分割したファイルのこと。

※パッケージとは

複数のモジュールをグループ化したもののこと。

※ライブラリとは

いくつかのパッケージをまとめて、ひとつのライブラリとしてインストールできるようにしたもの。

モジュールバンドラー(module bundler)とは

モジュールをひとまとめにするツール。 まとめることによってHTTPリクエストの数を減らし、表示速度の高速化に繋げるというのが主な理由のよう。 それならば、初めから一つのファイルに記述すれば良いのでは。とつい自分も考えてしまったのですが、

①コード量が増えてきたら、どこに何を書いたのか探すのが大変であること ②名前空間の汚染が起こる可能性(誤って同じ変数を使用して上書きしてしまったり) ③以上よりメンテナンスがしづらい

などの理由から、基本はひとつの処理や機能(関数、コンポーネント)をひとつのファイルに書き、他のファイルでそのモジュールが必要になったら、都度読みこんで利用する。



おわりに

Webpackerが難解に思われるのは、モジュールのバンドル以外の処理の代替を行っていることが大きな理由のひとつとしてあるようです。一歩ずつ理解していきたいと思っています。

参考記事

『Webpackってどんなもの?』 https://qiita.com/kamykn/items/45fb4690ace32216ca25 『webpackとは?』 https://qiita.com/minato-naka/items/0db285f4a3ba5adb6498 『最新版で学ぶwebpack 5入門JavaScriptのモジュールバンドラ』 https://ics.media/entry/12140/ 『【基本】webpackerとは何か学ぼう』 https://it-kyujin.jp/article/detail/1661/ 『はじめてのモジュールバンドラー』 https://blog.mach3.jp/2016/10/01/module-bundler.htmlJavaScriptにおけるモジュールとimport/exportの使い方』 https://analogic.jp/module-summary/ 『モジュールバンドラーはなぜモダンなフロントエンドの開発に必要なのか?』 https://note.com/billion_dollars/n/n596fecfdeb2e

【インフラ】冗長化して稼働率を高くするとは

AWSインフラ構築学習で、稼働率向上のための具体的な冗長化に初めて取り組んだので、そこで学んだ用語等をメモしておきます。修正点やアドバイス等ございましたら教えていただければ幸いです。

参考講座:AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得

そもそも稼働率とは

トラブルなく無事に使えている期間を示すもの。 インフラ設計観点の大切な項目である可用性(サービスを継続的に利用できるか)を表す指標のひとつ。 稼働率の計算には、平均故障間隔MTBF)や平均修理時間MTTR)が用いられる。

平均故障間隔(Mean Time Between Failure)

故障と故障の間隔を表すもの。

○平均修理間隔(Mean Time To Repair)

修理に必要な時間を表すもの。 7F00FE8E-DA47-4BCE-9412-5C4B49BA50EA_1_105_c.jpeg こんな稼働状況があったら、 平均故障間隔は→ (80時間+120時間+40時間)÷3 = 80時間 平均修理時間は→ (2時間+6時間+4時間)÷3 = 4時間

つまり「平均80時間くらいの間隔で故障する」ということと、「だいたい平均すると4時間が復旧時間として必要」ということが言える。

稼働率の求め方

稼働率は、システムが正常稼働していた割合なので稼働時間(MTBF)÷全運転時間(MTBF+MTTR)で求められる。 今回の場合は、稼働時間240時間÷全運転時間252時間 = 約95%となる

稼働率を上げるための基本的な考え方

そこで、稼働率を高くするためには

①障害発生間隔を長くする or ②平均復旧時間を短くする

の2つが考えられる。そのための手法の一つに冗長化がある。

冗長化

システムの構成要素を多重化すること。 ある構成要素で障害が発生しても、処理を引き継げるようにすることで稼働率を高める。

「冗長」という言葉は、通常「無駄が多い」のようなネガティブなニュアンスが伴うことがありますが、システムの世界では、冗長であることは「より耐久性が高く、堅牢である」という良い意味を持っている。

○単一障害点(Single Poing Of Failure)

冗長化で重要なのがSPOFの考え方。 SPOFとは、システム構成要素のうち、多重化されておらずそこが停止すると全体が停止してしまう部分のこと。 このSPOFを無くすために、二重化まではやることが多いが、それ以上どの程度コストをかけて冗長化するかは、予算制約と、求める信頼性水準とのせめぎ合い次第らしい。

稼働率を上げる具体的な方法

AWSで取り組める主な方法は2つ

①要素を組み合わせて、全体の稼働率を高める
②負荷を適切なプロビジョニングで回避する

①要素を組み合わせて、全体の稼働率を高める

06668983-7745-4035-A05F-B420A7F022AB_1_105_c.jpeg サーバが2台ある構成。 Active-Active:構成要素が同時に稼働する Active-Stanby:稼働するのはActiveのみで残りは待機している

Active-Active構成のメリットはダウンタイム時間の短さで、この構成は複数のサーバが同時に動いているため、そのうち一つが動作不能に陥ったとしても、残りのサーバが処理を継続することで、システム全体の停止を防ぐことができる。

それだけ聞いて、全てActive-Activeにしておけば良いのではないかと考えてしまったが、 Webサーバはそれで良くても、DB等のデータを持つものはデータの生合成を保つために同期が必要で、動作が遅くなる等の事象が発生する。そういう時にはActive-Stanbyにしたりするようだ。

②負荷を適切なプロビジョニングで回避する

アクセス数等を予測し、適切にリソースを準備(プロビジョニング)することで、負荷を捌けるようにする方法。ここでは、スケールアップ・スケールアウトが用いられる。

○スケールアップ

・個々の要素の性能を向上させること。  ある程度の規模まではスケールアップがコスパ良いが、一定範囲を超えると悪化する。

○スケールアウト

・個々の要素の数を増やすこと  ある程度の規模を超えそうであれば、スケールアウトで対応する。  基本用意するのがN+1構成。安心なのはN=2構成。  (サービス提供に必要な最低限のサーバ台数をNとする)



まとめ

最近アプリケーション制作でも、SQL発行数を減らせるようなコード作りを意識し始めました。 初心者ながら少しでも負荷を下げたり、スムーズな稼働のためにできることはやっていきたいなと思いました。  

rails newをしたらPG::ConnectionBad: could not connect to server: No such file or directoryとエラーが出た

PostgreSQLが起動していないよ」というエラーのようです。 PCの再起動によるものと思われますが、以下の方法で解決できました。 何度も遭遇している割には、復旧手順を毎回調べていると感じたので記録しておきます。



手順

PostgreSQLが出力するログファイルの前まで行く

$ cd /usr/local/var/log

②ファイルの内容を確認

$ cat postgres.log

   ↓↓↓ スクリーンショット 2020-12-27 16.19.25.png lock file "postmaster.pid" already existsとたくさん表示されました。 postmaster.pidファイルが既にあるとのことなので削除しました。

④rmコマンドで当該ファイルを削除

$ rm /usr/local/var/postgres/postmaster.pid

削除後、無事にrails newを実行することができました。



結果

postmaster.pidは、サーバーが複数起動されるのを防止するための仕組みで、サーバーの起動と共に作成され、停止と同時に削除されるようです。 サーバーが正常に停止されないとファイルが残ってしまうことがあり、今回のようなエラーに繋がるという事ですね。