自设带缓存的 Google Fonts 反向代理以实现海内外高速访问

お久しぶり!好久没有写过新东西啦~

最近使用 Internet Explorer 和 Microsoft Edge 访问博客首页的时候发现特别慢。

打开 Developer Tools 对网站做了 Profiler 后发现 Google Fonts 所占用的 Waiting 时间实在是太长,虽然说现在 googleapis 是能够正常解析了,但是速度还是相当的不忍直视。

解决办法有三:

  1. 禁用 Google Fonts
  2. 使用国内镜像
  3. 使用国外 VPS 做反代

第一种办法无疑是得不偿失的,为了速度而牺牲了整个网页的美观性。

第二种办法看起来挺理想,但是

  1. 大多数国内镜像不支持 HTTPS(对于追求小绿锁的我来说这是绝对不能忍的)
  2. 大多国内访问优秀,国外速度堪忧
  3. 反代在别人服务器上,稳定性没有保障

由于最近博客迁移到了 Azure 上,响应时间和速度还是比较有保证的,最终我选择了第三种方案。


特此声明,本文仅适用于带宽充裕,响应时间较短,速度较快的国外 VPS ,国内机基本免谈

设立反向代理的条件如下:

  1. nginx-extra(Ubuntu 里 apt-get install nginx 出来的 Nginx 并不支持 SSL)
  2. 域名(其实没有域名的话随意弄个免费的 tk 域名也可以)
  3. (可选)SSL 证书(假如你不需要 HTTPS,可以不要)

  • 关于 Nginx 如何安装,点击这里有传送门直达
  • 接下来我要暴力贴出配置,并在必要的地方加上注释,跟着修改即可使用

第一步,创建让 Nginx 存放反代缓存的目录

sudo mkdir -p /var/cache/nginx/cache
sudo mkdir -p /var/cache/nginx/temp

第二步,暴力复制、修改配置文件

正常情况下 Nginx 会在配置文件中 include /etc/nginx/sites-enabled/* 和 include /etc/nginx/conf.d/*.conf

(评论中的 dant 菊苣指出,Debian 系的 Nginx 才有 sites-{enabled,available},RH 系是没有的)

我们选择在 sites-enabled 里头创建配置

sudo vim /etc/nginx/sites-enabled/fonts-proxy.conf

复制粘贴并且根据注释修改以下内容

proxy_temp_file_write_size 128k;
proxy_cache_path  /var/cache/nginx/cache levels=1:2 keys_zone=fonts:300m inactive=7d max_size=10g;
proxy_temp_path   /var/cache/nginx/temp;

upstream google {
    server fonts.googleapis.com:443;
}

upstream gstatic {
    server fonts.gstatic.com:443;
}

server {
    listen 80;
    #将下面的 font.lawrencexs.xyz 替换成你要做反代用的域名
    server_name font.lawrencexs.xyz;
    #限制引用的域名。按需改成自己要用到字体库的域名。做公益服务需要去掉下面的一行以及if
    valid_referers server_name *.lawrencexs.xyz *.winooxx.tk;
    if ($invalid_referer) {
        return 404;
    }

    resolver 8.8.8.8;

    location /css {
    #将下面的 font.lawrencexs.xyz 替换成你要做反代用的域名
        sub_filter 'fonts.gstatic.com' 'font.lawrencexs.xyz';
        sub_filter_once off;
        sub_filter_types text/css;
        proxy_pass_header Server;
        proxy_set_header Host fonts.googleapis.com;
        proxy_set_header Accept-Encoding '';
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_pass https://google;
        proxy_cache fonts;
        proxy_cache_valid  200 304 365d;
        proxy_cache_key $host$uri$is_args$args;
        expires max;
    }

    location /icon {
    #将下面的 font.lawrencexs.xyz 替换成你要做反代用的域名
        sub_filter 'fonts.gstatic.com' 'font.lawrencexs.xyz';
        sub_filter_once off;
        sub_filter_types text/css;
        proxy_pass_header Server;
        proxy_set_header Host fonts.googleapis.com;
        proxy_set_header Accept-Encoding '';
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_pass https://google;
        proxy_cache fonts;
        proxy_cache_valid  200 304 365d;
        proxy_cache_key $host$uri$is_args$args;
        expires max;
    }

    location / {
        proxy_pass_header Server;
        proxy_set_header Host fonts.gstatic.com;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_pass http://gstatic;
        proxy_cache fonts;
        proxy_cache_valid  200 304 365d;
        proxy_cache_key $host$uri$is_args$args;
        expires max;
    }
}

#如果你没有证书或者不需要 HTTPS 访问,那么下面这部分你不需要再看了

server {
    #监听 443 端口
    listen 443 ssl spdy;

    #打开 HTTPS
    ssl on;

    #替换下面的证书
    ssl_certificate /etc/ssl/certs/lawrencexs.xyz.crt;
    ssl_certificate_key /etc/ssl/private/lawrencexs.xyz.key;

    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
    keepalive_timeout 70;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    #将下面的 font.lawrencexs.xyz 替换成你要做反代用的域名
    server_name font.lawrencexs.xyz;

    #限制引用的域名。按需改成自己要用到字体库的域名。公益服务需要去掉下面的一行以及if
    valid_referers server_name *.lawrencexs.xyz *.winooxx.tk;
    if ($invalid_referer) {
        return 404;
    }

    resolver 8.8.8.8;

    location /css {
    #将下面的 font.lawrencexs.xyz 替换成你要做反代用的域名
        sub_filter 'fonts.gstatic.com' 'font.lawrencexs.xyz';
        sub_filter_once off;
        sub_filter_types text/css;
        proxy_pass_header Server;
        proxy_set_header Host fonts.googleapis.com;
        proxy_set_header Accept-Encoding '';
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_pass https://google;
        proxy_cache fonts;
        proxy_cache_valid  200 304 365d;
        proxy_cache_key $host$uri$is_args$args;
        expires max;
    }

    location /icon {
    #将下面的 font.lawrencexs.xyz 替换成你要做反代用的域名
        sub_filter 'fonts.gstatic.com' 'font.lawrencexs.xyz';
        sub_filter_once off;
        sub_filter_types text/css;
        proxy_pass_header Server;
        proxy_set_header Host fonts.googleapis.com;
        proxy_set_header Accept-Encoding '';
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_pass https://google;
        proxy_cache fonts;
        proxy_cache_valid  200 304 365d;
        proxy_cache_key $host$uri$is_args$args;
        expires max;
    }

    location / {
        proxy_pass_header Server;
        proxy_set_header Host fonts.gstatic.com;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_pass https://gstatic;
        proxy_cache fonts;
        proxy_cache_valid  200 304 365d;
        proxy_cache_key $host$uri$is_args$args;
        expires max;
    }
}

最后一步,让 Nginx 重载配置文件

sudo nginx -s reload

如果中间不出差错,那么你就可以使用你新设的反代地址去替换 fonts.googleapis.com 了。

Enjoy! お楽しみください!

一些坑爹的事 = =

前段时间嘛一直在折腾 WordPress

有天看到某舰娘群里萌萌的 KB 说要上 PHP 7 ,方才想起我的 PHP 5.5.9 了 = =。在提及了我的版本号以后, KB 聚聚推荐我升级到 PHP 5.6。

升级 PHP


关于这事,本来我都打算去 clone 源码自编译了,这时候群里的 HJC 聚聚提醒说 Ubuntu 下应该优先找找 PPA。

Google 了一番过后,发现这玩意可以免去自编译的痛苦。于是在此记录一下加入 PHP 5.6 PPA 的步骤。

sudo apt-get purge php* //卸载原有的 PHP

sudo apt-get update

sudo apt-get install python-software-properties //必要依赖

sudo add-apt-repository ppa:ondrej/php5-5.6

sudo apt-get update && sudo apt-get upgrade

sudo apt-get install php5

好了,经过以上步骤过后, PHP 就升级到 5.6 了。

重新配置 uWSGI


升级完 PHP 过来,紧接着我发现另一个更加重要的问题,那就是我的神奇 PHP 后端 uWSGI 启动失败了 = = Orz

一直以来都是用 supervisor 启动的我决定手动debug。

在看到error log以后,发现是 php-plugin.ini 调用的依赖没了 = =

Ubuntu 源自带的东西比较旧了,这插件也是基于 PHP 5.5.9 编译的 = = Orz

好吧,找到问题所在,接下来就要想办法解决了 = =

我们先来升级一下 uWSGI ,步骤如下

sudo apt-get purge uwsgi*
sudo apt-get install build-essential python
sudo apt-get install python-dev
sudo apt-get install python-pip
sudo pip install uwsgi

这样我们就会在萌萌的 /usr/local/bin/ 里头看到一个 uwsgi(隐患)

接下来是编译并且安装 PHP 处理插件

uwsgi --build-plugin https://github.com/unbit/uwsgi-phpsgi

没错就这么简单,然而我当时却绕了不少的弯子 – –

配置 Supervisor 启动 uWSGI


这玩意可是坑了我好久好久,但是我不打算把思考过程发出来了 = =

直接上配置方法

写入 /etc/supervisor/conf.d/uwsgi.conf:

[program:uwsgi-php]
directory = /usr/local/bin/
command=uwsgi
--plugin php
--master
--socket :3030
--processes 6
--php-allowed-ext .php
--php-allowed-ext .inc
stopsignal=QUIT
user=www-data
autostart=true
autorestart=true
stdout_logfile=/home/XXX/error.log  //XXX代表你的用户名
redirect_stderr=true

最后依次运行

sudo service nginx restart
sudo service supervisor restart

 

替换 WordPress 默认的 Gravatar 服务器地址

今天在尝试优化 WordPress 打开速度的时候,发现总是有图片是没法加载的。后来才发现 WordPress 默认使用 Gravatar 头像,而 Gravatar 在国内的情况是大家都懂的,经常出现无法加载的情况。Google 一番过后终于找到解决方法,同时也有了此文。

解决思路


Gravatar 无法访问的原因不在于 Gravatar 服务器,是你国功夫网和谐了人家,查证后发现只是污染了 HTTP ,而 HTTPS 仍是存活的,所以解决思路是使用 Gravatar 的 HTTPS 线路,或者使用其他 Gravatar 反代 CDN。

实现方法


源代码来自 http://www.dmeng.net/wordpress-replace-gravatar-host.html ,感谢原作者的无私奉献。

此处我将源代码中的 secure.gravatar.com 替换成由通天塔提供的 Gravatar 反代 CDN

把代码添加到主题目录下的 functions.php 文件最后即可

function lawrence_get_https_avatar($avatar){
$avatar = str_replace(array("www.gravatar.com", "0.gravatar.com", "1.gravatar.com", "2.gravatar.com", "secure.gravatar.com"), "gravatar.loli.net", $avatar);
return $avatar;
}
add_filter('get_avatar', 'lawrence_get_https_avatar');