最后更新:2019-03-30 22:02:34 星期六
抽点时间把建设网站的一些心得什么的记录一下吧。也可以作为小白建站参考。

网站建设

服务器

本站已于2019年3月2日迁至Vultr硅谷机房
本站使用的是Vultr日本东京机房。因为众所周知的原因,Vultr日本东京和美国洛杉矶机房被墙得很严重。
因为考虑到速度问题,尽管东京很多IP都被封了,我还是不得不选择东京(当然也有一部分情怀原因……)
一开始我换了5个IP才换到1个能用的……

操作系统

我用的debian 9 x64。这个操作系统网络性能非常好,而且内存占用比较低,最重要的是我用起来比较顺手。如果你想正儿八经做网站,就不要用Windows Server。Windows Server除了有图形界面以外,在任何方面都没法跟Linux比。

安装控制面板

经过这一段时间的折腾,我深刻认识到一个控制面板对小白管理员的重要性。Windows有桌面环境,有什么问题可以直接远程桌面解决,非常简便直观。而对于Linux,虽然你也可以安装桌面环境,但是这样无疑会增加服务器的负担,况且Linux相比于Windows的优势之一就是无桌面环境,纯命令行。在这种情况下,基于网页的控制面板就是图形界面的最好替代品。
之前在三丰云用过一段时间的免费主机,他们的主机使用的是宝塔面板,我用过以后觉得还可以,操作还算简单,功能也很丰富。而且这个面板的文件管理功能很强大,连FTP都省了。我就没装FTP。

(↑大概长这个样)
使用这个命令安装:wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && bash install.sh

LNMP套件安装和配置

刚安装好宝塔面板的时候他会弹出来一个窗口,忽悠引导你安装LNMP/LAMP套件。我不推荐从这里安装,因为这里可选的php和phpMyAdmin都不是最新版本。关掉直接去软件管理中安装。
值得注意的是,我比较推荐以php、MySQL、NGINX的顺序安装。因为在不断折腾调试的过程中,有几次我安装php的时候安装失败了。起初不知道原因,翻了一下日志发现是内存不够被OOM了。所以推荐一开始内存充足的时候安装php。当然,你也可以直接开swap,同样可以解决。
推荐安装好后在php的配置界面安装opcache和memcached。

WordPress的安装和配置

不得不说,宝塔面板的功能还是很强大的。直接左边网站,添加。填好信息以后NGINX和数据库都给你配置好了。
我上面提到宝塔面板的文件管理功能很强大,这里就用到了。使用远程下载功能下载WordPress安装包到服务器上并解压到你网站的根目录。比如我的就是/www/wwwroot/hexis.moe/
解压出来可能是一个文件夹。要注意把index.php那一堆文件拿出来放到网站根目录,不要直接把整个WordPress文件夹放进去。
在控制面板里设置好默认站点,输入IP或者域名(如果你已经提前解析好了),进入WordPress完成配置基本上就可以使用了。不得不说,现在的WordPress比一年前配置起来简单多了。只要填一下数据库、密码什么的。

服务器优化

单核1G512M的服务器配置并不算高,不好好优化一下后期就会很麻烦。

NGINX开启Brotli

Brotli的压缩率比gzip好很多,即便是最低等级的压缩也比gzip最高等级的压缩还要小。整个配置过程不算太复杂。
在SSH中使用下面的指令来安装下载brotli支持库和nginx扩展。

#安装libbrotli
cd /www/server
git clone https://github.com/bagder/libbrotli
cd libbrotli
./autogen.sh
./configure
make && make install
#下载ngx_brotli
cd /www/server
git clone https://github.com/google/ngx_brotli
cd ngx_brotli && git submodule update --init

完成后在宝塔面板中卸载之前安装的NGINX。进入文件管理,编辑/www/server/panel/install/nginx.sh,找到下面几句(在140行以后,不同的版本不太一样)

    if [ "${nginxVersion}" != "1.8.1" ];then
        if [ "${nginx_version}" == "1.14.2" ] || [ "${nginx_version}" == "1.12.2" ];then
        #1.14或1.12
            ./configure --user=www --group=www --prefix=${Setup_Path} --with-openssl=${Setup_Path}/src/openssl --add-module=${Setup_Path}/src/ngx_devel_kit --add-module=${Setup_Path}/src/lua_nginx_module --add-module=${Setup_Path}/src/ngx_cache_purge --add-module=${Setup_Path}/src/nginx-sticky-module --add-module=${Setup_Path}/src/nginx-http-concat --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-stream --with-stream_ssl_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt="-Wl,-E" --with-pcre=pcre-${pcre_version} ${jemallocLD} --with-cc-opt="-Wno-error"
        elif [ "${nginxVersion}" == "1.15.8" ]; then
        #1.15
            ./configure --user=www --group=www --prefix=${Setup_Path} --with-openssl=${Setup_Path}/src/openssl --add-module=${Setup_Path}/src/ngx_devel_kit --add-module=${Setup_Path}/src/lua_nginx_module --add-module=${Setup_Path}/src/ngx_cache_purge --add-module=${Setup_Path}/src/nginx-sticky-module --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-stream --with-stream_ssl_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt="-Wl,-E" --with-openssl-opt="enable-tls1_3 enable-weak-ssl-ciphers" ${jemallocLD} --with-cc-opt="-Wno-error" --add-module=/www/server/ngx_brotli
            else
            if [ "$nginx_version" == "openresty" ];then
            #openresty
                ./configure --user=www --group=www --prefix=${Setup_Path} --with-openssl=${Setup_Path}/src/openssl --with-pcre=pcre-${pcre_version} --add-module=${Setup_Path}/src/ngx_cache_purge --add-module=${Setup_Path}/src/nginx-sticky-module --add-module=${Setup_Path}/src/nginx-http-concat --with-luajit --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-stream --with-stream_ssl_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt="-Wl,-E" ${jemallocLD} --with-cc-opt="-Wno-error"
            else
            #Tengine 2.2
                ./configure --user=www --group=www --prefix=${Setup_Path} --with-openssl=${Setup_Path}/src/openssl --add-module=${Setup_Path}/src/ngx_devel_kit --add-module=${Setup_Path}/src/lua_nginx_module --add-module=${Setup_Path}/src/ngx_cache_purge --add-module=${Setup_Path}/src/nginx-sticky-module --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-http_concat_module --with-ld-opt="-Wl,-E" --without-http_upstream_session_sticky_module --with-pcre=pcre-${pcre_version} --with-cc-opt="-Wno-error"
            fi
        fi
    else
    #1.8
        ./configure --user=www --group=www --prefix=${Setup_Path} --with-openssl=${Setup_Path}/src/openssl --add-module=${Setup_Path}/src/ngx_devel_kit --add-module=${Setup_Path}/src/lua_nginx_module --add-module=${Setup_Path}/src/ngx_cache_purge --add-module=${Setup_Path}/src/nginx-sticky-module --add-module=${Setup_Path}/src/nginx-http-concat --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_spdy_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt="-Wl,-E" --with-pcre=pcre-${pcre_version} ${jemallocLD} --with-cc-opt="-Wno-error"
    fi

这里有所有版本的NGINX编译命令,找到你想编译的版本,在最后加上一句--add-module=/www/server/ngx_brotli。然后在SSH中输入sh /www/server/panel/install/nginx.sh install 1.15
这里的1.15请灵活地替换为你想安装的版本。
在主配置文件中加入相关配置就可以启用Brotli压缩:

http
{
brotli on;
brotli_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml;
brotli_static off;
brotli_comp_level 1;
brotli_buffers 16 8k;
brotli_window 512k;
brotli_min_length 20;
}

注:建议gzip和brotli压缩等级都选1,因为压缩率和压缩等级不成线性反比,但是时间却是指数增长

SSL和TLS 1.3配置

注:在启用CDN的情况下,服务器本身的证书意义不大,配置一次就可以
SSL的配置非常简单。在宝塔面板的网站设置中可以申请Let's Encrypt的免费证书。
重要的是TLS 1.3。TLS 1.3跟1.2相比在速度和安全性上都有了明显提高,但是现阶段兼容性还有待提高。
目前宝塔面板中一键安装的NGINX只有1.15支持TLS 1.3。理论上你可以在编译参数中加上TLS 1.3的支持选项使其他版本支持TLS 1.3。目前已知Tengine 2.2.3不支持。
SSL配置好后在网站的配置文件修改ssl-protocolsssl_ciphers如下。

server
{
#一定要去掉TLSv1,它不符合PCI DSS规范
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:!MD5;
#添加下面这一行可以获得MySSL A+评级(可选)
add_header Strict-Transport-Security "max-age=31536000";
}

内存优化

内存优化是非常困难,需要经验和技术的工作。因为更低的内存占用必然带来性能的牺牲。这里是我用的一些参数,就现阶段而言够用。

MySQL

在配置文件中加入:

[mysqld]
performance_schema = OFF

可以大幅度降低内存占用。

以上是我目前使用的配置,缓存一类的数值你设得比数据库本身还大没多大意思,不如把与线程数有关的数值改得高一点。

php

从宝塔论坛上照搬过来的。

WebP支持

WebP是一种新型的图片格式,在相同质量下可以比jpg小很多(具体小多少懒得找了,总之很小就对了),可以大幅减小服务器负担。
这里操作非常简单,首先你自己需要安装libwebp,直接apt-get。再在你所使用的主题的functions.php中加入:

function bzg_filter_mime_types( $array ) {
    $array['webp'] = 'image/webp';
    return $array; 
}
add_filter( 'mime_types', 'bzg_filter_mime_types', 10, 1 );
function bzg_file_is_displayable_image($result, $path) {
    $info = @getimagesize( $path );
    if($info['mime'] == 'image/webp') {
        $result = true;
    }
    return $result;
}
add_filter( 'file_is_displayable_image', 'bzg_file_is_displayable_image', 10, 2 );

自动备份脚本

宝塔面板虽然有自动备份的功能,但是其备份的格式是zip。这在Linux系统下可能会导致文件权限和所有者出现问题。我自己写了一个脚本,每天深夜执行。

#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

tar -cvf /www/backup/site/hexis.moe-$(date +%Y%m%d).tar /www/wwwroot/hexis.moe/
xz -z -9 /www/backup/site/hexis.moe-$(date +%Y%m%d).tar

tar打包可以避免权限和所有者问题。而且我用了xz压缩,比zip压缩率不知道高到哪里去了。但我这里用的是-9极限压缩,内存占用比较大。如果不开swap不建议开-9,直接默认就好,否则容易导致内存分配错误。
在网上看见有人在Vultr开了服务器,然后遇到了数据丢失,Vultr只是给了2个月的服务器费用。所以备份到服务器本地意义不大,最好可以备份到Google Drive或者Dropbox等网络储存上。


夕暮れの星空も好きですか。