新着記事

Viewing posts from March, 2023

サイトページの修正確認はスーパーリロード/ハードリロードで行いましょう

keyboard

こんにちは、品質管理係の渡辺です。
品質管理係は、発見した不具合箇所が改修されたかの再検証もお仕事のひとつとして行っています。
修正の連絡を受けてから、ページにアクセスして確認をしますが、不具合箇所が変わっていない時があります。

そんな時は「キャッシュ」が残っている可能性を考えて「キャッシュクリア」を行います。
大抵は、この操作で、古いデータが削除されるので、改修箇所の再検証が行えます。

さてここで「キャッシュ」とは何か疑問に思いますよね。
簡単に伝えると、アクセスしたサイトページのデータを一時的に保管することで次回同じページにアクセスした時にブラウザが保管データを用いて表示する仕組みのことです。この仕組みにより、ページ表示が高速化され快適に閲覧することが出来るのです。
ブラウザに「キャッシュ」が残った状態の場合は、保管している『キャッシュ』を優先的に表示するため、反映されないことがあるのです。
解決するには再読み込み(リロード)をしてWebページの最新データを取りに行く作業が必要になります。

「通常の再読み込み」
閲覧しているページで、最後までページが表示されない、画像が表示されない等のトラブルの対処法として、ブラウザの更新ボタンやキーボードのF5、ショートカットキーを押して、リロード(再読み込み)させる、という対処は一般的だと思います。
ただし、この通常の再読み込み方法では、更新された画像やキャッシュクリアはされません。


「スーパーリロード」「ハードリロード」
こちらの2つのリロードは同じ作用であり他にも 「強制再読み込み」「フルリロード」「強制リロード」などとも呼ばれます。
スーパーリロードという呼び方は日本の用語のようです。
ある程度のキャッシュを削除して最新データを反映するので、更新の画像やレイアウトなら、こちらの機能で対処ができます。
操作方法は、ショートカットキーで Ctrl+Shift+R または Shift+F5を同時に押すと起動します。

「キャッシュクリア」
しかし最近は、キャッシュの強化が増えています。またcookieにより個人データを保持しているサイトも増えてます。
このようなキャッシュや個人情報データを削除したい場合は、キャッシュ自体を削除する「キャッシュクリア」をすると良いでしょう。
ただし、キャッシュクリアを行うとサイトが初期化されたようになるので、ログイン中のサイトからはログアウトされる、クリック済みのリンクが未クリック状態に戻るなど起こりますので、ご注意ください。
ブラウザの履歴データから削除する方法と、開発ツールを開いて更新ボタンから選択して押す方法があります。後者の方は私も最近その存在を知りました。また、macのsafariでは、メニューバーに開発メニューを表示すれば、ボタンがあるので一度設定してしまえば、使いやすいと思います。

【リロード(再読み込み)の操作方法】

Windows版

通常リロード chrome、edge、firefox 更新ボタン、ctrl+R or F5
スーパーリロード
ハードリロード
chrome、edge、firefox shift +更新ボタン、shift+ctrl+R

chrome、edge ctrl+更新ボタン

画面上で右クリックして開発ツールを開く→更新ボタン上で右クリック→「ハード再読み込み」を押す
キャッシュクリア chrome、edge、firefox ブラウザメニューの履歴データからキャッシュを削除
キャッシュクリア
        +
ハードリロード
chrome、edge 画面上で右クリックして開発ツールを開く→更新ボタン上で右クリック→「キャッシュの消去とハード再読み込み」を押す

mac版
safariは、開発者ツールを有効化すれば、メニューバーにキャッシュクリア、履歴データ削除のボタンが表示されます。

  1. デスクトップ開発マシンで、Safari を開きます。
  2. [Safari] | [環境設定] を選択します。
  3. [詳細] を選択します。
  4. [メニューバーに “開発” メニューを表示] ボックスをオンにします。

通常リロード chrome、edge、firefox 更新ボタン、command+R or F5
スーパーリロード
ハードリロード
chrome、safari shift + command + Rもしくはshift + 更新ボタン

firefox shift + command + R
キャッシュクリア chrom、safari、firefox ブラウザメニューの履歴データからキャッシュを削除
キャッシュクリア
        +
ハードリロード
chrome 画面上で右クリックして開発ツールを開く→更新ボタン上で右クリック→「キャッシュの消去とハード再読み込み」を押す

nginx+FPMの環境のタイムアウトの解決法の備忘録

前回、記事を書いたPHPをnginx+FPMの環境で、実際にwebアプリを作成。
ページが重くなる場合にタイムアウトが発生、その原因が複数の理由のため解決に時間がかかったのでその備忘録。

さきに原因を書くと
  1. phpの実行時間によるタイムアウト
  2. ブラウザとnginxのタイムアウト
  3. nginxとphp-fpmのタイムアウト
と3つの箇所でタイムアウトが発生していた。

まずは最初に表示された
504 Gateway Timeout
を解消する。
phpのタイムアウト時間max_execution_timeを設定して確認。
まだ504エラーが表示されるので、つぎにnginxのsend_timeoutkeepalive_timeoutを設定。
この設定の追加で504エラーは表示されなくなったが、別のエラーがnginxから表示されるようになった。
An error occurrerd. Sorry, the page you are looking for is currently unavailable. Please try again later.

このエラーメッセージがnginxとphp-fpmのタイムアウトだと気づくのに時間がかかった。
これの対応はnginxの設定にfastcgi_connect_timeoutfastcgi_read_timeoutfastcgi_read_timeoutを追加することで解消できた。

最終的にnginx.confphp.iniに下記の設定を追加しています。
nginx.conf
http {
send_timeout 300; # クライアントへの応答のタイムアウト時間
keepalive_timeout 300; # クライアントとの接続をキープする時間

fastcgi_connect_timeout 300; # nginxとphp-fpmの接続を確立するためのタイムアウト時間
fastcgi_send_timeout 300; # nginxからphp-fpmへのリクエスト送信のタイムアウト時間
fastcgi_read_timeout 300; # php-fpmからの応答のタイムアウト時間
}
php.ini
max_execution_time = 600 # phpのスクリプトの実行時間

webサーバーとアプリケーション・サーバーを分けた場合、その間のタイムアウトも気にしなければいけなかった。

PHPをnginx+FPMの環境で動作させる

古いPHPのWebアプリの改修を行うことになりました。
まずはメンテナンス性の確保のためにオレオレフレームワークからLaravelに載せ替える。
また、1台サーバーを使用して動かしていたが、あまり大きなアプリではないので、kubernetesで動作させることにします。
そして合わせて将来的な技術投資としてWebサーバーをApacheからnginx + FastCGI Process Manager(FPM)を試してみることにしました。
その際のdokcerとkubernetesの設定の備忘録になります。

nginxのconfファイルの作成

まずはLaravelとphp-fpm用にしたnginxのconfファイルを作成。
default.conf
server {
    listen       80;
    listen  [::]:80;
    server_name  example.com;

    access_log  /var/log/nginx/host.access.log;
    error_log  /var/log/nginx/host.error.log;

    location / {
        root   /usr/share/nginx/html;
        index  index.php index.html index.htm;
        # リクエストされたファイルが存在しなければ、Laravelのフロントコントローラーに内部リダイレクトさせる
        try_files $uri /index.php?$query_string;
    }

    # 400番台のエラーページの設定
    error_page  404              /404.html;

    # 500番台のエラーページの設定
    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # Apacheの設定なので今回はコメントアウトのまま
    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # FastCGIの設定
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        # Laravelのルートディレクトリ
        root           /var/www/html/public;
        # nginxからphp-fpmに受け渡すIPアドレスとポート番号の設定
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        # 全てのリクエストをLaravelのフロントコントローラーで実行させる
        fastcgi_param  SCRIPT_FILENAME  $document_root/index.php;
        include        fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}
ここでの注意点はnginxからphp-fpmに受け渡すIPアドレスとポート番号の設定
ローカル環境で動作させる場合はdokcerのphp-fpmのコンテナを指定してください。
fastcgi_pass   php-fpm:9000;
kubernetesで動作させる場合は1pod内でnginxのコンテナとphp-fpmのコンテナを動作させるため127.0.0.1:9000で受け取ることができます

nginxのDockerfileの作成

Docker Hubから最新のものを使用。
Dockerfile
FROM nginx:1.23.3

COPY docker/nginx/default.conf /etc/nginx/conf.d/default.conf

EXPOSE 80 443

STOPSIGNAL SIGQUIT

CMD ["nginx", "-g", "daemon off;"]

php-fpmのDockerfileの作成

こちらもDocker Hubから最新のものを使用。
注意点はnginxがアクセスできるようにLaravelのプロジェクトを配置しているディレクトリの所有ユーザーを変更すること。
アクセスしてくるのはnginxなので所有ユーザーをwww-dataに変更しておかないと404エラーになります。
Dockerfile
FROM php:8.1.16-fpm

#PHPの拡張機能のインストール
RUN apt update \
    && apt install -y libonig-dev libxml2-dev libcurl4-openssl-dev libssl-dev libzip-dev \
    && docker-php-ext-install pdo pdo_mysql mysqli simplexml curl phar zip ftp \
    && pecl install xdebug redis \
    && docker-php-ext-enable xdebug redis

# nginxがアクセスできるように所有ユーザーを変更
COPY project /var/www/html
RUN chown -R www-data:www-data /var/www/html

EXPOSE 9000

ENTRYPOINT ["docker-php-entrypoint"]

CMD ["php-fpm"]

kubernetesの設定の作成

kubernetesに反映させるdeployment、service、ingressを作成します。
deployment.yaml
1pod内で動作させるためcontainersにnginxとphp-fpmのコンテナを記載します。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-deployment
  labels:
    app: example
spec:
  replicas: 1
  selector:
    matchLabels:
      app: example
  template:
    metadata:
      labels:
        app: example
    spec:
      containers:
        - image: php-fpm:latest
          name: example-php-fpm
          ports:
            - containerPort: 9000
              protocol: TCP
        - image: nginx:latest
          name: example-nginx
          ports:
            - containerPort: 80
              protocol: TCP
service.yaml
外からのアクセスはnginxが受けるのでポートは80番。
kind: Service
apiVersion: v1
metadata:
  name: example-service
spec:
  type: NodePort
  selector:
    app: example
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: example-service
                port:
                  number: 80

kubernetesに反映を実行。 これで動作できました。
Search