配置 nginx 来提升 Ghost 博客性能

前言

Ghost 博客应用是用 Node.js 作为平台创建的,但让 Node.js 的 http 模块来服务静态资源的请求,性能不是很好,因此我们要用 nginx 来提升 Node.js 应用的整体性能。

通过本文你将会了解到如何用 nginx:

  • 实现反向代理服务 √
  • 缓存静态文件 √

5 个提升 Node.js 应用性能的提示

  1. 实现反向代理服务
  2. 缓存静态文件
  3. 在多个服务端前做负载均衡
  4. 代理 WebSocket 连接
  5. 实现 SSL/TLS 和 HTTP/2

为 CentOS 7 安装 nginx

# 我这里得到的最新版 nginx 是 v1.6.3-8.el7
$ yum list nginx
# 安装 nginx
$ yum install nginx
# 如果需要升级 nginx 运行 yum update nginx 即可

是啊,安装完了,可配置文件在哪啊?
在 Linux 系统中,我们可以使用 RPM (RedHat Package Manager),一种数据记录的方式来将你所需要的软件安装到你的Linux系统的一套管理机制,来查找安装的软件包所在位置。

# 查询 nginx 包名称
$ rpm -qa nginx
nginx-1.6.3-9.el7.x86_64  
# 查询 nginx-1.6.3-9.el7.x86_64 包文件路径
$ rpm -ql nginx-1.6.3-9.el7.x86_64
...
/etc/nginx/mime.types.default
/etc/nginx/nginx.conf
/etc/nginx/nginx.conf.default
...

可以看出 nginx.conf 在这个位置 /etc/nginx/nginx.conf

nginx 全局配置 & http 服务器配置

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

# main 全局配置
user root;  
# worker_processes 表示「工作进程个数」,设为 CPU 核数
# 可以为 auto,即 `grep ^processor /proc/cpuinfo | wc -l`
worker_processes auto;  
error_log /var/log/nginx/error.log;  
pid /run/nginx.pid;

events {  
    # epoll 高效事件模型
    use epoll;
    # 并发处理最大连接数 = worker_processes * worker_connections/4
    worker_connections 1024;
}

# main server config
# http 服务器配置
http {  
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    # 高效文件传输模式
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    # 客户端连接的超时时间
    keepalive_timeout   65;
    # types_hash_max_size 影响散列表的冲突率。types_hash_max_size 越大,就会消耗更多的内存,但散列key的冲突率会降低,检索速度就更快。types_hash_max_size 越小,消耗的内存就越小,但散列 key 的冲突率可能上升。
    types_hash_max_size 2048;
    # 允许客户端请求的最大单文件字节数。如果有上传较大文件,请设置它的限制值。
    client_max_body_size        10m;
    client_body_buffer_size     128k;

    # gzip 压缩功能设置
    gzip on;
    # 设置允许压缩的页面最小字节数,页面字节数从 Content-Length 中进行获取。默认值是 0,不管页面多大都压缩。建议设置成大于 1k 的字节数,小于 1k 可能会越压越大。
    gzip_min_length     1k;
    gzip_buffers        4 16k;
    gzip_http_version   1.0;
    # gzip 压缩比,1 压缩比最小处理速度最快,9 压缩比最大但处理速度最慢(传输快但比较消耗 CPU)
    gzip_comp_level     6;
    # 和 http 头有关系,加个 vary 头,给代理服务器用的,有的浏览器支持压缩,有的不支持,所以避免浪费不支持的也压缩,所以根据客户端的 HTTP 头来判断,是否需要压缩
    gzip_vary           on;
    gzip_types text/plain text/css text/javascript application/javascript application/json application/x-javascript application/xml application/font-woff image/svg+xml;
    # gzip_types 默认有 text/html 所以不用添加
    # css  text/css
    # js   text/javascript application/javascript application/x-javascript
    # xml  application/xml
    # woff application/font-woff
    # svg  image/svg+xml

    # http_proxy 设置
    # 代理后端服务连接超时时间
    proxy_connect_timeout       75;
    proxy_send_timeout          75;
    # 代理后端服务接收超时时间
    proxy_read_timeout          75;
    proxy_buffer_size           4k;
    proxy_buffers               4 32k;
    # 高负荷下缓冲大小(proxy_buffers * 2)
    proxy_busy_buffers_size     64k;
    proxy_temp_file_write_size  64k;
    proxy_temp_path             /etc/nginx/proxy_temp 1 2;

    # server 虚拟主机
    # default server
    server {
        listen         80;
        server_name     _;
        access_log      /var/log/nginx/server.log main;
        server_name_in_redirect  off;
        location / {
            root  /usr/share/nginx/html;
            index index.html;
        }
    }

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
    # nginx 会在启动时应用 /etc/nginx/conf.d/ 下所有的 conf 配置。

}

注意:如果反向代理出现 403/503,尝试修改 user root 为你的用户

配置 Ghost 服务

/etc/nginx/conf.d/ 下创建一个 ghost.conf

# cache config
# levels 设置目录层次
# keys_zone 设置缓存名字和共享内存大小
# inactive 在指定时间内没人访问则被删除在这里是 1 天
# max_size 最大缓存空间
proxy_cache_path /cache levels=1:2 keys_zone=ghostcache:100m inactive=24h;  
proxy_cache_key "$scheme$request_method$host$request_uri";

server {  
    listen          80 default_server;
    listen          [::]:80 default_server;
    root            /path/to/ghost/;
    server_name     myhost.com www.myhost.com;
    access_log      /var/log/nginx/myhost.log;
    charset         utf-8;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    # 拦截请求,直接返回上传的静态图片资源,缓存时间 1 个月
    location ^~ /content/images {
        alias /path/to/ghost/content/images;
        expires 1M;
        access_log off;
        add_header Cache-Control "public";
    }

    # 拦截请求,直接返回 JS、CSS、imgs、WebFonts 等资源,缓存时间 1 个月
    location ^~ /assets {
        alias /path/to/ghost/content/themes/casper-custom/assets;
        expires 1M;
        access_log off;
        add_header Cache-Control "public";
    }

    # 不缓存 ghost 核心文件(反向代理后台管理)
    location ^~ /ghost/ {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;
    }

    # favicon
    location = /favicon.ico {
        root /path/to/ghost/core/shared;
        access_log off;
        log_not_found off;
        expires 30d;
    }

    # cache urls
    # 反向代理博客请求到服务端
    location / {
        proxy_cache ghostcache;
        proxy_cache_valid 200 60m;
        proxy_cache_bypass  $http_cache_control;
        add_header X-Proxy-Cache $upstream_cache_status;
        proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
        # 后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass http://127.0.0.1:2368;
        proxy_redirect off;
    }

    error_page 404 /404.html;
    location = /404.html {
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    }
}

注意:上面的配置中你需要将 /path/to/ghostmyhost 替换成你的「项目路径」和「域名」。

启动 nginx 服务

# 提示:Linux 系统中,开启 1024 及以下端口的服务时,需要 root 权限。
$ systemctl start nginx
# 如果做了 conf 修改,需要重启,直接运行:
$ systemctl restart nginx

启动后打开你的域名查看网页运行情况,可以利用 Chrome DevTools (F12) 来查看请求情况:

未缓存的请求
未缓存的请求
缓存后的请求
缓存后的请求

最后

要了解更多的 nginx 配置,Node.js 应用优化 和 HTTP 协议相关的内容:

开启 nginx 后,可以用 PageSpeed Insights 来查看网站速度的评分,以及可优化的项目。

正在加载 Disqus 评论组件...