当代核舟记,32MiB内存无swap服务器装php博客

这篇文章介绍下这个网站的搭建过程,就像网站的名字一样,搭建于一台32MIB内存的机器上。为了使网站能够平稳运行,用了很多我能想到的节省内存资源的手段。 也许你在其他地方见到过类似的网站,但是很多机器加了swap内存交换,其实相当于变相添加了内存,有掩耳盗铃之嫌疑。

小鸡配置

市面上出售的32MiB机器实在不多见,因此我自己用kvm机器开了一台LXC小鸡,配置如下:

  • 1核心
  • 32MiB内存
  • 无SWAP
  • 5GB硬盘

方案选择

系统

debian号称宇宙通用系统,在诸多架构与硬件上都能通吃,一般来说小内存机器会选择debian。毕竟,debian比redhat系(如centos)系统节省资源很多,但面对32MiB的内存资源debian并不是一个很合适的选择。Debian系主要的内存占用进程有以下几个:

  • systemd,比较新的debian都内置了systemd作为启动器,负责管理系统启动调用
  • openssh,也就是我们ssh远程连过去用到的服务端,一般也要占用8MB左右
  • bash,是的,想不到吧,我们平时用的比较多的默认shell程序bash其实也要5MB左右的内存占用的,相比sh,ash等还是多了几倍的
  • apt,apt在安装的后处理过程会占用较多内存的,这也是为什么32MIB下连apt install命令都跑不起来

很多人知道我们要选择诸如alpine,coreos等极小的系统。不错,君子不立危墙之下,debian系统是不能符合我们折腾的前提了,为了给后续安装软件腾出资源。我们必须换用另外的更省资源的alpine,不过要选择32位的。这里解释下,虽然LXC的内核由宿主提供,选择32位的alpine还是64位的在客户机上好像没有太多区别。实际上还是有区别的,32位的程序寻址编码会节约一些,可以节省一部分内存占用。具体来说,系统版本为Alpine Linux 3.14 x86,太新的release附带的软件对资源要求会上升,因此这里选一个不上不下的版本吧。

image.png image.png

ram32mb:~# cat /etc/issue
Welcome to Alpine Linux 3.14
Kernel r on an m (l)

初始htop

image.png

初始process

ram32mb:~# ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 /sbin/init
  285 root      0:00 /sbin/syslogd -t
  313 root      0:00 /usr/sbin/crond -c /etc/crontabs
  405 root      0:00 /sbin/udhcpc -b -R -p /var/run/udhcpc.eth0.pid -i eth0 -x hostname:ram32mb
  454 root      0:00 /usr/sbin/dropbear
  459 root      0:00 /sbin/getty 38400 console
  460 root      0:00 /usr/sbin/dropbear
  461 root      0:00 -ash
  471 root      0:00 ps aux

基础软件

配合系统,需要有一系列的基础软件,alpine默认使用SystemV而不是systemd,这很好,就不用手动更换初始化进程了。默认的shell也是更加节省资源的ash,包管理工具apk也更加轻量。选择alpine的确省事很多。为了节省内存,ssh连接工具就用dropbear好了。

apk update
apk add dropbear
service dropbear start
rc-update add dropbear default

web服务器

web服务器选择nginx,当然你可以选择lighttpd。php就用默认的php7了。

这里有个细节,使用apk安装程序其实也是耗费内存的,如果已经有很多程序在运行了,然后再安装资源,很有可能导致apk运行失败,因此最好统一安装后,再启用服务。

apk add nginx
apk add php7-fpm php7-mcrypt php7-soap php7-openssl php7-gmp php7-pdo_odbc php7-json php7-dom php7-pdo php7-zip php7-sqlite3 php7-apcu php7-pdo_pgsql php7-bcmath php7-gd  php7-odbc php7-pdo_mysql php7-pdo_sqlite php7-gettext php7-xmlreader php7-xmlrpc php7-bz2 php7-memcache php7-iconv php7-pdo_dblib php7-curl php7-ctype

rc-update add nginx default
rc-update add php-fpm7 default
service nginx start
service php-fpm7 start

一些简单的配置

nginx

server {
    listen 443 default_server;
    listen [::]:443 default_server;
    index index.html index.htm index.php default.html default.htm default.php;
    root  /home/wwwroot/32mib.eu.org;

    location ~ [^/].php(/|$)
    {
        try_files $uri =404;
        fastcgi_pass  unix:/tmp/php-cgi.sock;
        fastcgi_index index.php;
        include fastcgi.conf;
    }

    # You may need this to prevent return 404 recursion.
    location = /404.html {
            internal;
    }
}

php-fpm7

user = www
group = www
listen = /tmp/php-cgi.sock
listen.owner = www
listen.group = www
listen.mode = 0660
pm = static
pm.max_children = 1
php_admin_value[memory_limit] = 25M

CMS

cms系统本来想选择wordpress + sqlite的,但是试了下如果不加swap,wordpress很难启动。如果把内存设置为72MiB是可以启动的,但也没有必要,内存资源过少会导致体验很一般。因此我们干脆用更加节省资源的极简CMS系统,这里选择了HTMLy,这下连数据库都不用了,HTMLy使用文件储存文章。

image.png

安装很简单,下载文件到web目录,解压,更改拥有者为www,访问你的网站/install.php,即可

一些定制开发

想在网站主页显示CPU、内存、硬盘资源的占用情况,因此魔改了一下主题文件,在网页侧栏增加一个探针组件。 image.png

顺便偷了service status的客户端shell代码,稍作魔改,后台定期更新当前的资源占用。