需求描述:
公司的在线系统前端页面上了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