旧手机小用途:在Android手机上建网站,较完全指南

很多人可能都有些废旧不用的手机,比如像我这只摔得坑坑洼洼连送人都送不出手,二手也卖不了几个钱的。但它们又不是完全不能用,其实功能都正常,性能也还可以。如何才能发挥它们的余热?

image.png

——做个人服务器就是一个不错的用途:功耗低,还自带UPS。做个个人网站,个人云或下载机,7x24小时开机,不担心费电,也不担心停电。

最近在Android手机上利用Linux Deploy搭建了一个LEMP/LNMP网站,本文讲述其中的主要流程和注意事项。有一些坑,也有点小窍门,还有一些测试数据,拿手机做其它框架的网站或其它用途的服务器也可参考。

可行性及方案

先评估下性能。在手机上装了个Linux,用sysbench测试下CPU,以PC和树莓派作为对比。

命令:

sysbench --test=cpu --cpu-max-prime=20000 run

结果是耗时,越短越好。

  • PC: i7 4770K: 21.2s
  • 华为荣耀6 plus: 247s
  • 树莓派3代: 535s
  • 树莓派2代: 1150s

虽然比PC差远了,但比树莓派快不少(多核应该更强)。其实我的网站以前是跑在树莓派2代上的。树莓派的I/O(SD卡)也是很慢的。

至于方案,理论上来说有这么几类:

  1. APK提供http服务器、MySQL服务器、PHP的支持。——功能受限于APK,不能使用标准的工具集。
  2. 用类似于busybox的方式,把Linux下的命令集和需要的服务器都编译到Android上。——累。
  3. 双系统,既可以引导Linux,也可以引导Android。——树莓派可以,以前用过RK3188的Android电视盒也可以,理论上手机也可以做到,就看有哪几个手机厂商愿意提供这种支持了。所以,可遇不可求。
  4. 模拟器:APK是Linux的模拟器。——慢。
  5. Linux和Android共用内核,使用chroot容器的方式。——这几乎是最完美的方案了,既不破坏Android,又有一个几乎完整的Linux。Linux Deploy就是这方面的杰出代表。

手机root及清理

不root会有很多限制,比如不能使用1024以下的端口。而且root也是Linux Deploy要求的。不同的手机型号,请各显神通寻找root攻略。

对于荣耀6和6 plus,大致流程是(国内的各种一键root工具都不行):

  1. 先升级到5.1(可能要申请);
  2. 再升级到6.0(可能要申请);
  3. 申请解锁码;
  4. fastboot下unlock, 刷TRWP recovery;
  5. TRWP recovery下刷root用的zip文件。

root后,SuperSU是必装的(通常会自带),busybox也建议安装。

既然是专用作服务器,其它不用的程序都卸载掉,包括一些系统程序及服务,以减少对系统资源的占用。方法是列出所有进程,在网上搜索其用途,根据自己的需要进行删除。网上一些文章也会说明是否可删除,建议删除还是保留。不能删除的可以尝试禁止启动。

我的荣耀6 plus最后保留了不到一屏的App。不过,系统内的进程数还是很多,但都处于不活动状态。最后,手机设置为飞行模式;休眠状态始终保持WiFi连接。

image.png

SD卡分区

Linux Deploy可以将系统完全安装在内置Flash,或SD卡的image上,也可以装到某个目录或分区。
为了比较,我装了多个系统,并共用home分区。最后的SD卡分区方案是这样的:

  1. 2G, FAT,给android系统使用
  2. 8G, ext2, 安装第二个Debian Linux用(第一个装在内置Flash的/data/local目录里)
  3. 8G, ext2, 玩玩Kali Linux
  4. 16G, ext4, 共用的 /home 分区

这里的小经验是:保留一个小的FAT分区!这是为了让Android系统看上去还是有一个可用的SD卡。否则,系统会提示SD卡不认识,是否要格式化。万一哪天自己忘了SD卡里藏了好几个Linux的系统和数据,或者手快点了一下“是”,就杯具了。

image.png

Linux Deploy的关键设置

建立多个Profile,对应于多个系统。

image.png

然后依次对每个Profile进行配置。

image.png

上图的安装位置设在内部Flash的/data/local目录下。如果想安装在SD卡分区上,则类似于下图。

image.png

ssh服务是必须开启的。挂载点的语法要注意:一行一个条目;用冒号分隔源路径和挂载点。

image.png

然后开始安装(装Debian8时安装忘了截屏,下图用Debian9作为示意)。

image.png

权限问题

这里的坑是在Android手机上安装LAMP/LEMP系统特有的。想不到可能半天也搞不定,想到了只是一行命令。

MySQL启动失败

MySQL在安装的时候报告启动失败,日志上也没有更多信息。

好吧,既然MySQL 5.5失败,那我装MariaDB 10.0吧?——结果还是失败。

会不会是文件系统权限问题?把数据目录从Flash的/var/lib/mysql换到SD卡的/home/mysql吧?——一样失败。

...

其实原因是mysql用户的权限问题。解决办法是把mysql这个用户加到aid_net_raw组。

sudo usermod -a -G aid_net_raw mysql

aid_xxx 这些组其实是Android的用户组(这些组的映射/创建,应该是Linux Deploy做的),容器内的Linux用户要具有Android的相应权限才能做相应的事。而MySQL创建/监听socket,要有aid_net_raw对应的权限。

网上有人把aid_inet也给予mysql用户,其实这个Internet访问权限对于MySQL不是必须的。

PHP下载及发邮件

我安装的这个Web系统(Drupal)有网页上安装/升级模块(插件)的功能。但这个功能用不了:

GuzzleHttp\Exception\ConnectException: cURL error 6: Could not resolve host: updates.drupal.org (see http://curl.haxx.se/libcurl/c/libcurl-errors.html) in GuzzleHttp\Handler\CurlFactory::createRejection() (line 186 of /home/www/drupal-8.3.2/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php).

从字面看,像是DNS或是网络连接的问题。最后的答案和前面MySQL启动不了是类似的:Web server进程需要有Internet访问的权限。

sudo usermod -a -G aid_inet www-data

发邮件也是网站必备的功能。通过PHP发邮件,Web server同样需要Internet的访问权限(比如连接smtp.gmail.com的587端口)。

性能测试及调优

WiFi及网络速度

做服务器肯定是用有线网络好。但无线网络是否堪用呢?下面的测试都是在5G的WiFi下,靠近路由器,小米mini一代。

用 ping 测试有线连接的树莓派和无线连接的手机。

image.png

可以看到,往返时间差了两个数量级。前者平均是0.72ms;后者差不多70ms。

下图是用 iperf 测试网络速度。大约是67Mbps.

image.png

速度属于正常水平,对于自娱自乐的个人站点,也可接受吧。

数据库放在Flash还是SD卡上?

先对文件系统做一简单的测试。用dd读写总共4GB(大于手机内存)的文件,每次读写不同大小的块。

#$count = $totalsize / $blksize
dd if=/dev/zero of=$tmpfile bs=$blksize count=$count && sync
of=/dev/zero if=$tmpfile bs=$blksize count=$count && sync

最后的结果如下图所示。

image.png

可以看到,写的速度差不多,读的速度Flash还是比SD卡快不少。

还可以用sysbench测试MySQL性能,或者用wget/curl直接测试网站的速度。总体上,对于这个手机(荣耀6 plus),后面这两项测试的结果差别不大。最后,我还是把数据库放在了内部Flash上。

屏幕开还是关?

对于做服务器用途,想当然地会认为要把屏幕关掉。控制开关屏幕的有好几个地方:

  • “显示”里面的延时熄屏;
  • “开发者选项”里的插电时保持屏幕活动;
  • Linux Deploy界面里的保持屏幕活动。
image.png

在性能测试中发现,屏幕开着和关着的差别很大。

sysbench --test=cpu --cpu-max-prime=20000 run
image.png
  • 屏幕开:247.5s
  • 屏幕关:441.0s

sysbench进行CPU测试的结果还是很稳定的,包括以前用Linux Deploy 2.0.0-215,现在用的2.0.2-220;开启mysql/nginx等服务或者不开启,分数波动在1%以内。可见,屏幕开和关的差距是非常显著的。

在Android/Linux系统里,还有一个CPU Governor的策略会影响CPU的性能。

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

interactive

可以看到,默认的策略是"interactive". 尝试把它改到性能最高的 "performance",

echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

测试结果也并没有差别。

也许是屏幕关着的时候,CPU被降频使用了?

最后,不得不选择让屏幕常开(当然,亮度调至最低)。

/proc/loadavg的问题

我们通常会用/proc/loadavg查看系统的load

cat /proc/loadavg 
  • 空闲时:5.16 5.14 5.17 1/1290 8877
  • 运行sysbench时:6.02 5.74 5.48 4/1295 9353

作为对比,树莓派的loadavg:

  • 空闲时:0.03 0.07 0.02 2/159 28307
  • 运行sysbench时:1.03 0.72 0.33 3/158 28903

Android系统的loadavg空闲时普遍都很高;而用top命令查看各进程的CPU占用率时,并没有多高。

关于这个问题,网上有一些讨论,但我还没找到权威的说法。总之,并不能用loadavg作为系统load的参考。

自动启动

在启动Android系统时,自动启动容器内的Linux,似乎并不起作用。

image.png

另一个层面的自动启动是自动启动Linux系统内的服务。这需要在Linux Deploy里启用 Init 系统,并选用类型 SysV.

image.png

这样,在Linux系统启动时,runlevel(默认为3)中设置为自动启动的服务就会自动启动,像普通的Linux那样。否则,连cron服务都要手动启动。

image.png

不过在我的手机上有个小问题:在启用了Init后,Stop Linux时会导致Android重启,然后root丢失。但再重启一次会恢复root。

备份

数据库本来是安装在Flash上,可以将其备份到SD卡,这样起到了“两个篮子”的作用。

考虑到Flash和SD卡都有可能突然失效(都曾经碰到过),远程备份也是必须的。

本想用NFS挂载NAS上的目录的,但NFS client的安装有点问题。没有去深究,直接用了ssh密钥登录加rsync。命令示意:

rsync -auvAX --delete $srcdir nas:/$dstdir

升级

升级包括3个层面:

  1. Android系统本身:取决于厂家是否还提供升级支持,升级后可能要重新root。总之是比较麻烦的。由于Linux和Android共用内核,除非出现内核级别的安全漏洞,否则没必要升级。
  2. Linux系统:可以安装unattended-upgrades之类的包来自动更新。
  3. Linux Deploy:根据需要升级。升级前最好保存配置。直接缷载/安装会把原配置数据全部清除;不过只要把Profile重新配置一下,就可以启动原系统 。所以也不是大问题。

功耗

用记录型万用表UT181A对电流进行24小时监测(手机电池始终是满电)。

image.png

每小时的平均电流在140~150mA之间,功耗相当于0.75W。

image.png

小米路由器的USB口实测电流可以超过200mA,所以可以直接用这个路由器的USB口给手机长期供电。

image.png

电源/电池状态

还可以通过读取目录 /sys/class/power_supply/Battery 的文件来监控电源和电池的状态:

  • status:充放电状态;
  • capacity: 电池容量百分比;
  • charge_now:当前充电的容量(mAh);
  • charge_full:电池的总容量(mAh);
  • voltage_now:当前电池电压(V);
  • voltage_max:电池充满电的电压(V);
  • current_now:当前充电电流(mA),充电为正,放电为负;如果系统负载高,电流会是负值;
  • temp:电池温度(有无爆炸隐患早知道)。

可以写几行脚本,直接在网站上显示这些状态。

image.png

结语

在root过的Android手机上通过Linux Deploy安装Linux,可以达到和普通Linux一样的完整度和自由度。能灵活地在上面部署各种LAMP, LEMP/LNMP站点。而且,这样的“服务器”功耗低(小于1W),带“UPS”(电池)。

主要的要注意的方面有:和Android相关的权限问题,如何自动启动服务,熄屏对性能有无影响,等等。手机虽小,但跨越Android, Linux及容器,涉及系统的多方面,对技术爱好者也是一个很好的练习。

本文主要是从平台的角度来谈论“手机服务器”的,并不涉及平台上的应用(即具体如何建一个网站)。至于建网站的其它方面,后续会有文章。敬请关注。

参考

  1. Convert an Android Device to Linux
  2. Linux Deploy官方下载地址
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容