nginx编译添加brotli模块对wasm压缩的支持

Posted 郑子明

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nginx编译添加brotli模块对wasm压缩的支持相关的知识,希望对你有一定的参考价值。

需求描述:
公司的在线系统前端页面上了CDN,但是无法对 wasm 文件进行压缩优化,这种文件很大加载慢影响用户体验
需要对 wasm 进行压缩后访问,但是需要nginx支持 ngx_brotli  模块才行
模块的github地址
https://github.com/google/ngx_brotli
# -q 是压缩级别
brotli -q 5 -f FicModule.wasm
准备工作:
# 编译安装 ngx_brotli,需要重新编译nginx,此处我们使用的是tengine2.3.2版本,具体的源码修改需要参考 https://www.cnblogs.com/reblue520/p/12186442.html,否则会有一些坑
1.安装依赖

yum -y install git

mkdir /usr/local/ngx_module
cd /usr/local/ngx_module/
git clone https://github.com/google/ngx_brotli.git

cd ngx_brotli/
# 国内因为网络问题,无法正常下载deps里面的文件,需要FQ下载后拷贝过来
git submodule update --init

2.重新编译tengine2.3.2

cd /usr/local/src/tengine-2.3.2
# 更换编译目标路径为 /usr/local/tengine-2.3.2_with_brotli,避免和现有的nginx冲突

# 编译过程

./configure --prefix=/usr/local/tengine-2.3.2_with_brotli --with-ld-opt="-Wl,-rpath,/usr/local/include/luajit2.1/lib" --user=daemon --group=daemon --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_sub_module --with-http_stub_status_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_geoip_module --with-http_secure_link_module --with-http_degradation_module --with-mail_ssl_module --with-pcre=/usr/local/lab/pcre-8.34 --with-zlib=/usr/local/lab/zlib-1.2.11 --add-module=/usr/local/lab/ngx_cache_purge-2.3 --with-jemalloc --with-http_lua_module --with-luajit-lib=/usr/local/include/luajit2.1/lib --with-luajit-inc=/usr/local/include/luajit2.1/include/luajit-2.1/ --with-lua-inc=/usr/local/include/luajit2.1/include/luajit-2.1/ --with-lua-lib=/usr/local/include/luajit2.1/lib --with-openssl=/usr/local/lab/openssl-1.1.0l --add-module=/usr/local/ngx_http_geoip2_module-3.2 --with-stream --add-module=/usr/local/lab/nginx_upstream_check_module-master --add-module=/usr/local/ngx_module/ngx_brotli

make -j 4 && make install

# nginx 的http段添加如下配置

brotli on;
brotli_comp_level 3;
brotli_static on;
brotli_types application/atom+xml application/javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml;

3.配置文件示例
nginx 主配置文件参考
# more /usr/local/nginx/conf/nginx.conf

user  apache;
worker_processes  8;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;
pid        /data/www/logs/nginx.pid;

worker_rlimit_nofile  65535;

events {
    use epoll;    
    worker_connections  10240;
    accept_mutex    off;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    #set_real_ip_from   0.0.0.0/0;
    #real_ip_header     X-Forwarded-For;

    #proxy_set_header   Host    $host;  
    #proxy_set_header   X-Real-IP       $remote_addr;  
    #proxy_set_header   X-Forwarded-For $http_x_forwarded_for;  
    #proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for; 

    proxy_headers_hash_max_size 51200;
    proxy_headers_hash_bucket_size      6400;

    ssl_session_cache    shared:SSL:200m;
    ssl_session_timeout  15m;

    geoip2 conf/GeoIP2/GeoIP2-Country.mmdb {
        auto_reload 5m;
        $geoip2_metadata_country_build metadata build_epoch;
        $geoip2_data_country_code source=$remote_addr country iso_code;
        $geoip2_data_country_name country names en;
    }

    geoip2 conf/GeoIP2/GeoIP2-City.mmdb {
        $geoip2_data_city_name  city names en;
    }
    fastcgi_param COUNTRY_CODE $geoip2_data_country_code;
    fastcgi_param COUNTRY_NAME $geoip2_data_country_name;
    fastcgi_param CITY_NAME    $geoip2_data_city_name;

    #lua_package_path "/usr/local/nginx/conf/ngx_lua_waf/?.lua";
    #lua_shared_dict limit 10m;
    #init_by_lua_file  /usr/local/nginx/conf/ngx_lua_waf/init.lua; 
    #access_by_lua_file /usr/local/nginx/conf/ngx_lua_waf/waf.lua; 

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    #log_format main '[$time_local] $remote_addr $status $request_time $body_bytes_sent "$request" "$http_referer" $upstream_addr $http_x_real_ip $http_x_forwarded_for $http_user_agent  $request_filename';
    log_format main  '$remote_addr - - [$time_local] - - "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_cookie" "$request_body" "$http_user_agent" $request_time '; 
    #log_format test '[$fastcgi_script_name] [$time_local] $remote_addr $status $request_time $body_bytes_sent "$request" "$http_referer" $upstream_addr $http_x_real_ip $http_x_forwarded_for $http_user_agent ';
    log_format error  '$remote_addr - - [$time_local] - - "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time '; 
    log_format  json_log '{"time_local":"$time_local",'
        '"remote_addr":"$remote_addr",'
        '"host":"$host",'
        '"body_bytes_sent":$body_bytes_sent,'
        '"request":"$request",'
        '"request_time":$request_time,'
        '"status":"$status",'
        '"http_referer":"$http_referer",'
        '"http_x_forwarded_for":"$http_x_forwarded_for",'
        '"http_user_agent":"$http_user_agent",'
        '"http_cookie":"$http_cookie",'
        '"request_body":"$request_body",'
        '"upstream_response_time":"$upstream_response_time"'
    '}';
    #access_log  logs/access.log  main;

    sendfile        on;
    tcp_nodelay    on;

    keepalive_timeout  300;
    #----for upload file
    client_max_body_size    512M;
    client_body_buffer_size 8M;
    #--- for resolve 400 error
    client_header_buffer_size 64k;
    large_client_header_buffers 4 64k;
    proxy_connect_timeout 300s;
    proxy_read_timeout 300s;
    #60s内后端服务器需要返回成功
    proxy_send_timeout 300s; 
    proxy_buffer_size 16k;
    proxy_buffers 4 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;
    proxy_ignore_client_abort on;    
    proxy_intercept_errors on;
    gzip  on;
    gzip_vary off;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.0;
    gzip_comp_level  5;
    gzip_disable     "MSIE [1-6]\\.";
    gzip_types text/plain text/css text/javascript application/javascript application/x-javascript text/xml application/xml application/wasm;

    brotli on;
    brotli_comp_level 3;
    brotli_static on;
    brotli_types application/atom+xml application/javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml
    application/xml font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml;

    ssi on;
    ssi_silent_errors on;
    #ssi_types text/shtml;
    #expires 60d;
    server_names_hash_bucket_size 20480;
    #if_modified_since before;
    #limit_req_zone $binary_remote_addr zone=all_zone:10m rate=3r/s;
    #limit_req zone=all_zone burst=2 nodelay;
    upstream convert_servers{
        ip_hash;
        server 172.18.1.143:8900 max_fails=0 fail_timeout=30s weight=1;
        server 172.18.1.144:8900 max_fails=0 fail_timeout=30s weight=1;

        check interval=3000 rise=2 fall=5 timeout=1000 type=tcp port=8900;
        check_keepalive_requests 100;
    }

    include vhost.d/*.conf;


    server {
        listen       80  default_server;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
        root   /data/www/html;
        index  index.html index.htm;
        }


        #20201013增加如下配置,主要用于监控本机的php网页是否异常

        location ~ ^/php {
            root   /data/www/html;
            location ~ php(.+\\.php)(.*)$ {
                fastcgi_pass  unix:/tmp/php-cgi.sock;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
                include fastcgi_params;
                expires -1;
                if ($request_uri ~ "^(.*)(\\?.*)$") {
                set $path_info $1;
            }

            include proxy_params;
            fastcgi_param PATH_INFO $path_info;set $path_info $request_uri;
            }
            index  watchphp.php;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
        root   html;
        }

        location /ws_status {
            stub_status on;
            access_log off;
        }

        location ~ ^/(status|ping)$ {
            include fastcgi_params;
            fastcgi_pass unix:/tmp/php-cgi.sock;
            fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
            access_log   off;
            allow 127.0.0.1;
            deny all;
        }

        location /status {
            check_status html;
            access_log   off;
            allow 127.0.0.1;
            deny all;
        }

    }
}

# more nginx/conf/vhost.d/chinasoft.com.conf

server {
        listen 80;
        server_name     www.chinasoft.com chinasoft.com ori-www.chinasoft.com;

        access_log      /data/www/logs/nginx_log/access/chinasoft.com_access.log json_log;
        error_log       /data/www/logs/nginx_log/error/chinasoft.com_error.log ;
        root            /data/www/vhosts/ps.chinasoft.com/httpdocs;
        index           home.html index.html index.htm index.php default.php default.html default.htm;
        include         rewrite.d/chinasoft.com.conf ;
        error_page  404 403              /404.html;

        if ($http_user_agent ~ Ezooms) {
                return 403;
        }

        location ~ ^.*\\.(htaccess|htpasswd|ini|sh|git|svn|project|LICENSE|log|env|env\\.[\\w]+|env\\.[\\w]+\\.[\\w]+)$ {
                deny all;
        }

        #rewrite ^/(.*)$ https://chinasoft.com/$1 permanent;    #跳转到Https

        location ^~ /app {
                root /data/www/vhosts/ps.chinasoft.com/httpdocs;
                try_files $uri $uri/ /app/index.html;

                location ~ .*\\FicModule.js$ {
                        expires -1;
                        etag on;
                }

                location ~ .*\\.(gif|jpg|png|bmp|swf|mapl|js|css)$ #静态页面缓存时间
                {
                        expires 30d; #expires缓存模块,缓存到客户端30天
                }

                etag on;
                expires -1;

        }

        location  /feedback {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Real-Port $remote_port;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header    Host                $http_host;
                proxy_set_header    X-NginX-Proxy       true;
                proxy_connect_timeout 10; 
                proxy_send_timeout 180;
                proxy_read_timeout 180;
                proxy_http_version 1.1;
                proxy_pass http://node_feedback_servers;
        }

        location  /help {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Real-Port $remote_port;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header    Host                $http_host;
                proxy_set_header    X-NginX-Proxy       true;
                proxy_connect_timeout 10; 
                proxy_send_timeout 180;
                proxy_read_timeout 180;
                proxy_http_version 1.1;
                proxy_pass http://node_help_servers;
        }

        location /static {
                alias /data/www/vhosts/ps.chinasoft.com/httpdocs/static;
                location ~ .*\\.(html)$ #静态页面缓存时间
                {       
                        expires -1;
                
                }
                etag on;
                expires 365d;
        
        }

        location ^~ /community {

                try_files $uri $uri/ /community/index.html;
                root /data/www/vhosts/ps.chinasoft.com/httpdocs;
                location ~ .*\\.(gif|jpg|png|bmp|swf|mapl|js|css)$ #静态页面缓存时间
                {
                        expires 30d; #expires缓存模块,缓存到客户端30天
                }

                etag on;
                expires -1;

        }

        location ^~ /community-admin {
                try_files $uri $uri/ /community-admin/index.html;
                root /data/www/vhosts/ps.chinasoft.com/httpdocs;

                location ~ .*\\.(gif|jpg|png|bmp|swf|mapl|js|css)$ #静态页面缓存时间
                {
                        expires 30d; #expires缓存模块,缓存到客户端30天
                }

                etag on;
                expires -1;
        }

        location / {
                try_files $uri $uri/ /index.html;
                root /data/www/vhosts/ps.chinasoft.com/httpdocs/static/index/;
                index index.html;

                location ~ .*\\.(gif|jpg|png|bmp|swf|mapl|js|css)$ #静态页面缓存时间
                {
                        expires 30d; #expires缓存模块,缓存到客户端30天
                }

                etag on;
                expires -1;

        }
}

server {
        listen 443 ssl http2;
        server_name     www.chinasoft.com chinasoft.com ori-www.chinasoft.com;
        access_log      /data/www/logs/nginx_log/access/chinasoft.com_access.log json_log;
        error_log       /data/www/logs/nginx_log/error/chinasoft.com_error.log ;
        root            /data/www/vhosts/ps.chinasoft.com/httpdocs;
        index           home.html index.html index.htm index.php default.php default.html default.htm;
        include         rewrite.d/chinasoft.com.conf ;
        error_page  404 403              /404.html;

        ssl_certificate         cert2016/pixso_design.crt;
        ssl_certificate_key     cert2016/pixso_design.key;
        ssl_dhparam             cert2016/dh_2048.pem;

        ssl_session_timeout     15m;
        ssl_protocols  TLSv1.1 TLSv1.2;

        ssl_ciphers     "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!AES128-GCM-SHA256:!AES256-GCM-SHA384:!AES128-SHA256:!AES256-SHA256:!AES128-SHA:!AES256-SHA:AES:!CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";

        #include route.sz_office.conf;
        #deny all;

        if ($http_user_agent ~ Ezooms) {
                return 403;
        }

        location ~ ^.*\\.(htaccess|htpasswd|ini|sh|git|svn|project|LICENSE|log|env|env\\.[\\w]+|env\\.[\\w]+\\.[\\w]+)$ {
                deny all;
        }

        location ^~ /app {
                root /data/www/vhosts/ps.chinasoft.com/httpdocs;
                try_files $uri $uri/ /app/index.html;
                location ~ .*\\FicModule.js$ {
                        expires -1;
                        etag on;
                }

                location ~ .*\\.(gif|jpg|png|bmp|swf|mapl|js|css)$ #静态页面缓存时间
                {
                        expires 30d; #expires缓存模块,缓存到客户端30天
                }

                etag on;
                expires -1;

        }

        location  /feedback {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Real-Port $remote_port;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header    Host                $http_host;
                proxy_set_header    X-NginX-Proxy       true;
                proxy_connect_timeout 10; 
                proxy_send_timeout 180;
                proxy_read_timeout 180;
                proxy_http_version 1.1;
                proxy_pass http://node_feedback_servers;
        }

        location  /help {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Real-Port $remote_port;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header    Host                $http_host;
                proxy_set_header    X-NginX-Proxy       true;
                proxy_connect_timeout 10; 
                proxy_send_timeout 180;
                proxy_read_timeout 180;
                proxy_http_version 1.1;
                proxy_pass http://node_help_servers;
        }

        location /static {
                alias /data/www/vhosts/ps.chinasoft.com/httpdocs/static;
                location ~ .*\\.(html)$ #静态页面缓存时间
                {       
                        expires -1;
                
                }
                etag on;
                expires 365d;
        
        }

        location ^~ /community {

                try_files $uri $uri/ /community/index.html;
                root /data/www/vhosts/ps.chinasoft.com/httpdocs;
                location ~ .*\\.(gif|jpg|png|bmp|swf|mapl|js|css)$ #静态页面缓存时间
                {
                        expires 30d; #expires缓存模块,缓存到客户端30天
                }

                etag on;
                expires -1;

        }

        location ^~ /community-admin {
                try_files $uri $uri/ /community-admin/index.html;
                root /data/www/vhosts/ps.chinasoft.com/httpdocs;

                location ~ .*\\.(gif|jpg|png|bmp|swf|mapl|js|css)$ #静态页面缓存时间
                {
                        expires 30d; #expires缓存模块,缓存到客户端30天
                }

                etag on;
                expires -1;
        }

        location / {
                try_files $uri $uri/ /index.html;
                root /data/www/vhosts/ps.chinasoft.com/httpdocs/static/index/;
                index index.html;

                location ~ .*\\.(gif|jpg|png|bmp|swf|mapl|js|css)$ #静态页面缓存时间
                {
                        expires 30d; #expires缓存模块,缓存到客户端30天
                }

                etag on;
                expires -1;

        }

}

# 跳转的设置

# cat /usr/local/nginx/conf/rewrite.d/chinasoft.com.conf

if ($host ~* ^www.chinasoft.com$){ rewrite ^(.*)$ https://chinasoft.com$1 permanent;}
if ($request_uri ~ ^/(.*)/(index|indice).(html)) { rewrite ^/(.*)/(index|indice).(html) /$1/   permanent;}
if ($request_uri ~ ^/(index|indice).html) { rewrite    ^       / permanent;}

 通过命令行工具进行验证

# 没有压缩过的文件
# curl  -I  -H "Accept-Encoding: br,deflate"  "https://chinasoft.com/FicModule.wasm"

HTTP/1.1 200 OK
Server: Tengine
Content-Type: application/octet-stream
Content-Length: 11902336
Connection: keep-alive
Date: Fri, 27 Aug 2021 06:25:00 GMT
Last-Modified: Thu, 26 Aug 2021 03:16:05 GMT
ETag: "61270775-b59d80"
Expires: Fri, 27 Aug 2021 06:24:59 GMT
Cache-Control: no-cache
Accept-Ranges: bytes
Ali-Swift-Global-Savetime: 1630045500
Via: cache48.l2cn1833[210,210,200-0,M], cache14.l2cn1833[211,0], vcache2.cn1963[225,224,200-0,M], vcache14.cn1963[227,0]
X-Cache: MISS TCP_MISS dirn:-2:-2
X-Swift-SaveTime: Fri, 27 Aug 2021 06:25:00 GMT
X-Swift-CacheTime: 0
Timing-Allow-Origin: *
EagleId: 7b605da416300455

# 通过压缩后的文件
# curl  -I  -H "Accept-Encoding: br,deflate"  "https://pre.chinasoft.com/FicModule.wasm"

HTTP/1.1 200 OK
Server: Tengine
Content-Type: application/octet-stream
Content-Length: 3566284
Connection: keep-alive
Date: Fri, 27 Aug 2021 06:25:10 GMT
Last-Modified: Thu, 26 Aug 2021 03:16:05 GMT
ETag: "61270775-366acc"
Content-Encoding: br
Expires: Fri, 27 Aug 2021 06:25:09 GMT
Cache-Control: no-cache
Ali-Swift-Global-Savetime: 1630045510
Via: cache48.l2cn1833[220,219,200-0,M], cache20.l2cn1833[222,0], vcache8.cn2038[259,259,200-0,M], vcache47.cn2038[263,0]
X-Cache: MISS TCP_MISS dirn:-2:-2
X-Swift-SaveTime: Fri, 27 Aug 2021 06:25:10 GMT
X-Swift-CacheTime: 0
Timing-Allow-Origin: *
EagleId: 73eec0c316300455100

以上是关于nginx编译添加brotli模块对wasm压缩的支持的主要内容,如果未能解决你的问题,请参考以下文章

Nginx 开启 BR 压缩

一种优于gzip的压缩方式Brotli

CentOS一键编译安装nginx,带http2/brotli/zlib/pcre/ssl,非root监听80端口

性能优化Brotli使用Brotli压缩算法来压缩静态文件

brotli压缩

使用 brotli 压缩文件和目录列表