LoginSignup
6
2

More than 5 years have passed since last update.

ExpressフレームワークでCSSやJQueryのアクセスでHTTP500が発生する時の対策法

Last updated at Posted at 2017-10-03

Node.jsのアプリケーションで、数回に一回程度、CSSやJQueryのアクセス時にHTTP500 Internal Server Error が発生して、ウェブ画面の表示や動作が壊れる障害があり、対策についての備忘録です。

Expressフレームワークの express-generator でテンプレート・アプリケーションを生成すると、次のディレクトリ構造が作られる。そして、public ディレクトの stylesheets に CSSファイルを置いて、また、javascriptsの下にjquery.js 等を置いて、利用したところ、本問題に直面した。

.
├── app.js
├── bin
│   └── www
├── package.json
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    ├── error.pug
    ├── index.pug
    └── layout.pug

問題判別

調べた結果では、Node.jsのHTTP500の発生原因は解りませんでしたが、CSSファイルやJQueryなどスタティックなコンテンツの要求の応答の課程でHTTP500が発生していることが解ってきました。 また、この障害は3種類 (FireFox, Chrome, Safari)で同様に発生してました。
また、Node.js のバージョンを 6.11 から 8.6へ、バージョンを上げてみましたが、改善しませんでした。

スクリーンショット 2017-10-03 22.26.10.png

対策

回避策として、次の図の様に、public コンテンツ以下は、Nginxのコンテナで応答して、それ以外のNode.jsの処理は、Node.jsのコンテナへ転送する対策を試みました。

スクリーンショット 2017-10-03 22.43.19.png

この結果、CSSやJQuery等の静的ファイルのロードで、HTTP500が発生する事が無くなり、ウェブ画面が壊れる障害が事が無くなりました。

スクリーンショット 2017-10-03 22.53.04.png

nginxリバースプロキシ設定ファイル

Nginxの設定ファイルは次の2つです。 最初、キャッシュ・プロキシーの設定だけを試しましたが改善が見られず、locationの設定を追加してところ、動作が改善して安定しました。

default.conf
proxy_cache_path /var/cache/nginx keys_zone=zone1:1m max_size=1g inactive=24h;
proxy_temp_path  /var/cache/nginx_tmp;
nginx.conf
server {
    listen                                  80;
    server_name                             _;
    root                                    /usr/share/nginx/html;

    proxy_redirect                          off;
    proxy_set_header Host                   $host;
    proxy_set_header X-Real-IP              $remote_addr;
    proxy_set_header X-Forwarded-Host       $host;
    proxy_set_header X-Forwarded-Server     $host;
    proxy_set_header X-Forwarded-For        $proxy_add_x_forwarded_for;
    proxy_cache zone1;
    location / {
    proxy_pass http://node_app:3000/;
    }

    location /javascripts/ {
    alias /usr/share/nginx/html/javascripts/;
    }

    location /stylesheets/ {
    alias /usr/share/nginx/html/stylesheets/;
    }

    location /images/ {
    alias /usr/share/nginx/html/images/;
    }

}

Dockerコンテナのファイル

次の2つが、コンテナを作るためのDockerfileです。

Dockerfile.nginx
FROM nginx:latest
ADD ./nginx_conf/default.conf /etc/nginx/conf.d/default.conf
ADD ./nginx_conf/nginx.conf /etc/nginx/conf.d/nginx.conf
COPY ./webapp1/public /usr/share/nginx/html
Dockerfile.nodejs
FROM ubuntu:latest
RUN apt-get update && apt-get install curl -y
RUN curl -sL https://deb.nodesource.com/setup_6.x | /bin/bash -
RUN apt-get install nodejs -y
ADD /webapp1 /webapp1
ENV NODE_ENV development
EXPOSE 3000
CMD ["node", "/webapp1/bin/www"]

docker-composeのYAMLファイル

NginxコンテナとNode.jsコンテナを連携して起動するためのファイルです。

docker-compose.yaml
version: '3'

services:
    proxy_cache:
        build:
            context: .
            dockerfile: Dockerfile.nginx
        ports:
            - "4040:80"
        depends_on:
            - node_app
    node_app:
        build:
            context: .
            dockerfile: Dockerfile.nodejs
    ports:
            - "3000:3000"

まとめ

Node.js の Express フレームワークで、publicの下に静的コンテンツを置くのは、要注意である。 そして、時々、スタイルシートやJQueryがロードされずウェブ画面の表示や動作が安定しない場合、静的コンテンツの処理をNginxでオフロードすると効果的である。 Dockerコンテナを適用することで、サーバーを増やさず効率良く対処できた。 さらに、この方法は、Kubernetesの利用時にも適用できると見込まれる。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2