WordPress 使用 SQLite 数据库

之前写了一半的,如何在轻量级个人 VPS 上搭建各种服务的帖子。一时懒得去把坑填完了。但前几天突然发现自己落入了思维误区:为了配合 Mastodon 或 Pleroma,总想着如何把 WordPress 从 MySQL 迁移到 PostgreSQL。——但是,其实完全可以用 SQLite 啊!对于偶尔才更新一篇的个人 blog 用户,把数据库放在一个 SQLite 文件里,不需要另外安装数据库服务,完全是可行的。

用 Docker 观察内存开销。对于新建的 wordpress 站点,wordpress 本身(包括 php-fpm、nginx)占用内存大约是 40-100M(使用缓存插件后会减少);MySQL 数据库占用内存 200M,随着渐渐使用,有着近千篇文章和评论的 blog 站点,MySQL 占用内存会达到 500M 甚至更多。 ——数据库的这部分内存,使用 SQLite 后,完全是可以省下的。

可以通过 SQLite Integration 插件,安装基于 SQLite 的 WordPress。Wordpress 官网的插件页面,因为作者失联而停更。但隐藏的插件下载链接,一直都还有效:

https://downloads.wordpress.org/plugin/sqlite-integration.1.8.1.zip

最新版本的 WordPress 也仍然可用。Github 上也有这个插件的分支

使用非常简单,就是把 db.php 复制到 wp-content 目录里,同时确保你的系统安装了 php-sqlite3 模块。这里有篇攻略。现有的站点,可以通过 Duplicator 之类的 wordpress 备份插件,或者 wordpress 自身的导入导出功能,进行迁移,不需要进行数据库级别的转换操作。

注意事项:

1. 最重要的,数据库的文件的存放位置,这个一定要改!默认的数据库位置是在 wp-content/database/.ht.sqlite,是会被人通过浏览器从 http://website/wp-content/database/.ht.sqlite 直接下载的!虽然插件在 database 文件里添加了 .htaccess 权限控制,但对于如今大家用的 Nginx,是默认无效的。

在 wp-config.php 里添加设置:

define('DB_DIR', '/absolute/custom/path/to/directory/for/sqlite/database/file/');
define('DB_FILE', 'custom_filename_for_sqlite_database');

可以更改数据库文件的存放位置。强烈建议把数据库文件,放到无法直接用网址从外部访问的目录(记得给那个文件夹授权可写)。

2. SQLite 不适合多线程的高并发使用。如果网站会有多个用户同时在后台编辑,那么网站不适合使用 SQLlite;如果只有一个写作者自己编辑 blog,就很合适。但要避免使用那些,在一般访客浏览网站时,也会导致对数据库进行写入的插件,如:

  • WP Statistics 这样的访客统计插件,会把来访者的每一次点击,都记录到本机数据库里。建议使用 Google Analysis 之类的外置统计软件(Google 给 wordpress 做了个官方插件 Site Kit by Google),通过在页面嵌入 js ,发送访客数据到 Google 服务器,不会写入本地数据库。
  • 官方的防垃圾评论插件 Akismet Anti-Spam,其实也是先把每条评论写入本地数据库,再判断是否垃圾的。如果被机器人大量发送垃圾评论,也会造成数据库写入的压力。建议使用 WP Captcha 之类的验证码插件(可以单独使用或配合 Akismet 一起用),把大多数垃圾评论在写入数据库之前就过滤掉。

3. 使用 WP Super Cache 插件,为网站生成缓存文件,可以极大地减少对数据库的读取操作。个人用户完全可以在插件设置里,关闭默认的 Garbage Collection 功能。


网上搜到的 WordPress + SQLite 的 docker images(12),Wordpress 和 php 的版本都有些过时了,本身也有一些小问题(如数据库文件夹的权限设置),建议修改 Dockerfile 然后自行编译。回头有时间我去改个试试。

WordPress 的 ActivityPub 插件

试用一下 WordPress 的 ActivityPub 插件(官网 / Github)。

主要功能,就是在 wordpress 上,建一个 Fediverse 账号,Mastodon / Pleroma / Misskey / Honk……的用户可以 follow 这个账号。新的 blog 文章发布时,这个账号会发一条嘟文,大家可以转发这条嘟文。followers 对这条嘟文的回复,会自动同步到 blog 文章的评论区。

就像我为这个 blog 建的 fedi 账号:@[email protected]

需要指出的是,并不存在 blog.fivest.one 这样一个 fediverse 实例。陌生人搜索这个账号,看不到任何历史嘟文;这个账号不能去 follow 别人,不能对别人说话,不能回复别人对自己嘟文的回复,也不能看到多少人转发点赞了自己的嘟文。——这些功能也许以后会有,但目前,这个插件所做的,只是在新 blog 发布的那一刻,向所有 follow 这个 id 的账号,push 一条嘟文。这条嘟文,在 blog 服务器上,并没有保存;而只存在于 follow 它的那些实例上,再被人转发到更多实例。

当 blog 的文章被删除时,这个插件也会通知所有的 followers,从他们的实例上删除对应的嘟文。但是就像我说过的,这个机制并不能把那些,被转发到其它实例的嘟文,也一起删除。所以,当你在 blog 按下发布按钮的一刹那,带着你所写的全部内容(或者摘要,可设置)的嘟文,就可能会永远飘在 fediverse 世界里,无从反悔。所以,写完这篇文章后,我还不确定自己是否会继续用这个插件……

所以我只是觉得这个插件运行的机制很有趣,向大家介绍一下而已。它仅仅是通过 ActivityPub 协议,和其它实例通信,而本身并没有创建实例。这个插件在 wordpress 的数据库里,甚至没有新增一个 table,而只是把 followers 的公钥,存到了 wp-options 里(我觉得这么折腾 options 表,有点过犹不及了……)。总而言之,这是个超级轻量化,在 wordpress 基础上,完全不产生多余开销的东西。

我之前吐槽过,目前所有的 Fediverse 引擎,都是用软件工程模块,匆匆拼出来的臃肿怪兽:开销巨大,数据结构不美观,依赖的技术模块未必有长久的生命力,安全性抗冲击性都很差……其实我很期待,一个单用户版的,完全没有 local 功能,支持 ActivityPub 协议的引擎。结构的简洁程度,和资源的开销,要比现在这些要好很多。从这个插件可见一斑(虽然这个插件和完整的个人版 fedi 实例,是完全两回事……


测试了一下。好像只有 follower 的回复(公开 or 私密)才会同步到 blog 的评论区;陌生人的不可以。但目前还没有做 follow 的审核通过机制。所以理论上是可以用这个功能发垃圾评论……

以及目前还没有让用户修改个人简介的功能,图片上那些简介,都是我在插件 templates/author-json.php 里手动改代码的。

关于 fediverse 的删除机制

在当前的很多 fediverse 服务(mastodon、pleroma…)里,当 A 站的用户 a 被另一个实例(譬如:B 站)的用户关注时,他所发的嘟文,会在 B 站的服务器上储存一个副本,B 站的用户,通过访问这个副本,来阅读这条嘟文。当原本的嘟文被删除时,A 站会通知 B 站,删除相应的副本。但这个时候,这条嘟文未必像人们期待的那样,从 fediverse 上彻底消失。

假设存在如下情况:

  • A 站的 a 用户
  • B 站的 b 用户,b 在关注 a
  • C 站的 c 用户,c 在关注 b,但 C 站没有人关注 a
  • a 发了一条公开嘟文,此时 b 可以看到这条嘟文,而 c 是看不到的。
  • b 转发了 a 的这条嘟文,此时 c 可以看到这条嘟文了。C 站的所有人,在查询 a 的时候,也都可以看到 a 的这条嘟文。
  • 如果这个时候,a 再把这条嘟文删除,那么 A 站会通知 B 站这条嘟文已删,而 B 站也会把这条嘟文在 B 站的镜像删除。于是 b 就看不到这条嘟文了。

——然而,似乎并没有一个机制,去通知 C 站,这条嘟文已删?也就是说,这个时候,c 和 C 站的所有人,都仍然可以看到 a 已经删掉的这条嘟文?

如果这个时候 C 站有人再转发这条嘟文,而 B 站甚至 A 站有人关注这个人,那么,B 站和 A 站的人,就又能看到这条嘟文了?甚至连 a 自己,也能看到的?(这个有待验证)


听起来似乎很不靠谱,但也不是不能接受。就像 twitter 还没有官方 retweet 的时代,所有的转发,都是由用户手动复制一个副本。而最初的推文被删除,完全不会影响这些副本继续存在。所以这里只是提醒大家,有这么一个机制。具体的隐私控制,还要由创作者自行把握。你曾发到网上的东西,可能永远不会真正消失。

A simple design of bowstring jig (endless loop)

We know, these jigs are expensive, huge, and not easy for ordering and shipping to many places. There are some DIY solutions online. The hard part of them is, how to make a strong slot or heavy metal fixture to adjust the length smoothly, but it’s not quite necessary. Most of bowstrings are just integer number of inches, so, why not just drill integer inch holes on timber, and fix the poles on these positions?

This is my idea that just needs timber, bolts, drill, and roughly saw cut. A row of holes with 2 inches distance on the base board, and the same 2 inches distance holes on the upper board that can fix the jig in horizonal and vertical direction.

There are two types of radiuses from the string pole to the axis on the upper board. One is 3.5 inches, for any odd number inches of string length (axis distance + 7 inches), the other is 4 inches, for any even number inches of string length (axis distance + 8 inches). If you need more precise length (e.g. 66.5 inches), just make another pair of upper board with the radius of 3.75 inches ( or just twist the string…)

The base board. The shortest hole distance is 46 inches, and the longest is 62 inches. With the upper boards, the system can make bowstring from 54 to 70 inches. Of course, you can make a longer or shorter board as you need.

The upper boards need to be 3 inches wide at least because there are 2 rows of holes. The base board has just 1 row so it could be narrower. I bought a 2.4m long 90mm * 35mm timber (I’m in a metric country…) for the whole system.

I use M8 size drill and hex bolts for all the holes. M6 should be ok as well, but maybe not easy to buy long M6 bolts.

  • Four pieces of 6 inches bolts as string poles, each one needs 2 sets of nuts and rings.
  • Two pieces of 4 inches bolts as the main axis. The length depends on the thickness of the timber. Don’t be too long, so as not to interfere the string serving. One set of nuts and rings for each bolt.
  • Two pieces of 3 inches bolts to fix the upper board on horizonal or vertical direction. The length depends on the thickness of the timber as well. No nuts or rings needed.

There should be around 1/4 inch space between the upper and the base board, thicker than a set of nut and ring, so the upper board can rotate with the nut of the string poles underneath. Use a thin board or several rings.

The Bottom of the base board is not flat as well, because of the head of the axis bolts. So put the rest of the timber under it.

Enjoy.

自制弓弦缠弦架

自己设计制作了一个,缠弓弦(endless loop)的架子。只需要简单的木工钻孔,和不必精确的锯割。

思路

这类做弓弦用的架子,正式的商品要卖 100 – 600 刀,而且体积很大,运费也很夸张。网上有一些 diy 的帖子,但难点都在于,如何做出一个平滑的卡槽,或者能紧紧卡在桌子上的金属件。——但其实不需要任意调节长度啊!常用的弓弦长度,都是英寸的整数值。只需要在木头上的适当位置打孔,然后把缠弦架固定就可以了。

在底板上,钻一排间距 2 英寸的孔,在缠弦板中轴的竖直和水平方向,也钻出距离 2 英寸的孔,无论缠弦板竖直还是水平放置,都可以把螺栓插进旁边的孔里,防止架子转动。

工具和材料

  • 电钻,木工钻头。——钻孔和螺栓,我用的都是 M8 大小。其实 M6 也足够结实了,但 M6 的长螺栓不容易买。
  • 电锯或手锯。长度不需要很精确,随便锯就可以了。
  • 木材。我买的是一根 90mm * 35mm * 2.4m 的木料,足够用了。缠弦板需要打两排孔,所以宽度要超过 3 英寸。底板只需要打一排孔,还可以更窄一些。木材用其它厚度也可以,但中轴和插销的螺栓长度也要相应调整。
  • 螺栓
    • 缠弦杆,4 根 150mm 的 M8 螺栓,每根配两套螺母和垫圈。要上半截不带螺纹的那种,用来缠弓弦。
    • 中轴,2 根 90mm 的 M8 螺栓,每根配一套螺母和垫圈,用蝴蝶螺母更方便(我封城没买到)。
    • 插销,2根 60mm 的 M8 螺栓,不需要螺母和垫圈。
  • 垫板。底板和缠弦板之间,要垫出 1cm 的空隙,给缠弦杆底部的螺栓,留出可以转动的空间。用木板、垫圈、或者木材的下脚料都可以,但太厚的话,需要调整中轴螺栓的长度。

钻孔图纸

底板:长度 > 64 英寸 / 162cm,宽度 > 3 英寸 / 7cm,厚度 > 1 英寸 / 2.5cm。最近孔距 46 英寸,最远孔距 62 英寸,这样可以做出 54 – 70 英寸的弓弦,适用于 56 – 72 英寸的各种弓。

缠弦板:长度 > 9.5 英寸 / 24cm,宽度 > 3.5 英寸 / 9cm,厚度 > 1 英寸 / 2.5cm

缠弦板上的两排孔,对应着缠弦杆到中轴的,两种不同间距:3.5 英寸、4 英寸。

对于奇数长度值的弓弦,使用 3.5 英寸的孔,弦长 = 中轴距离 + 7 英寸。
对于偶数长度值的弓弦,使用 4 英寸的孔,弦长 = 中轴距离 + 8 英寸。

如果需要更精确的弓弦长度(如 66.5 英寸),可以再做一对缠弦板,把孔距设在类似 3.75 英寸的距离。

使用

  • 怎么做弓弦,就不用我说了。自己去搜教程。
  • 因为底板的下面,会露出中轴螺栓,所以底板并不是平的。使用时,用木材的下脚料垫高一下。
  • 中轴尽量拧紧一些。不然弓弦绷的太紧,可能会把缠弦板扯的前后倾斜。也可以把中间的垫板,做的更长一些,但不要妨碍缠弦杆转动。

女司机

拖了好几年,冒着各种被骂的风险,终于写了这一篇。

首先,本人旗帜鲜明地反对嘲讽女司机的行为,认为这种行为非常土鳖,非常歧视,并为自己几十年前无知时也偶尔做过的嘲讽行为表示忏悔。无论是嘲讽女司机的行为,还是「女司机不行」这件事本身(我不认识这是生物上的事实,但在某些文化区域,可能确实存在这种现象),都是长期性别权力不平等造成的后果。我认识很多乐于也擅于飙车的女性朋友,并且真心希望这样的妹子越多越好。

然而,我并不认可,很多人为女司机辩护的方式。他们并不是诉说「嘲讽是不对的」;而是试图证明「男司机更不行」。可能男司机确实更差劲,但是

  • 因为男司机更差,所以不应该嘲讽女司机。这并不是很恰当的思路。
  • 大多数关于「男司机更不行」的阐述,并没有说到点子上。

于是,总给人一种「为了反对而硬找理由」的感觉。


关于「男司机更不行」的阐述,大概有两种方式

  1. 列举统计数据,说明男司机的事故率高于女司机;
  2. 转发男司机肇事的报道和视频,像嘲讽女司机那样嘲讽男司机。

关于第一种方式,用交通局的官方统计数据,说明:

女司机造成的事故数量 < 男司机造成的事故数量

或者,更「科学」一点:

(女司机事故数量 ÷ 女司机数量) < (男司机事故数量 ÷ 男司机数量)

这个数据在绝大多数地区,应该都是正确的。然而,有一个很明显的问题:持有合法驾照的人数性别比例,并不等同于经常开车的人数性别比例,更不等同于总的驾驶时间的性别比例。有多少人拿了驾照但很少开车?这个数据很难准确统计出。但根据(不靠谱的)猜测,男性的人均实际开车时间,应该会更高一些。如果比较

(女司机事故数量 ÷ 女司机总驾驶时长) vs (男司机事故数量 ÷ 男司机总驾驶时长)

那么结果很可能会不一样。

关于第二种方式,转发男司机的事故视频。——其实我很爱看的,任何愚蠢导致的事故,不论性别,我都很爱看的。尤其是现在的新闻报道,确实在性别上有严重歧视:报道经常说,出事的是「一名女司机」,而对于男司机发生的事故,则只是说「一名司机」。大家多 po 一些男司机的事故,指明是「男司机」并加以嘲讽,确实是很公平的事。

问题在于,这些用来嘲讽男司机的事故案例,和嘲讽女司机时的例子,并不是同样的类型。

转发的男司机事故,大多是超速、酒驾、疲劳、玩手机……而造成的惨痛事故。这些司机本来有能力把车开好(——技术上「有能力」;当然了,安全驾驶才叫做真的「有能力」啊),却各种无视规则而作死,最终对社会和他人造成危险。

而嘲讽女司机的视频,更偏向于:在路边很久停不进车位、撞翻停车场的收费杆、前进后退分不清撞进路边店里……她们在那一刻是清醒的,没有任何触犯交规的意图,努力要把车开好,却最终失败。

无疑前者才是真的更危险,也是各种事故的绝对主要原因。然而,惯例上对女性司机的嘲讽,并不是指她们无视规则而造成危险,而是她们操纵机械时努力却显得笨拙。所以,人们列举出来的,男司机危险驾驶的事故,并不能够很好地反驳那些对女司机的嘲笑。


难道不是违规作死才更危险,更应该被谴责吗?

是的,没问题。这句话你指着任何一个男的鼻子质问,他都无法反驳。然而,这更像是一种政治正确意义上的认同,而不一定是每个人都必须放在心中最高优先级的行事准则。人可能因为侥幸心理而违规;可能因为挑战规则而获得心理以及群体中的荣耀;甚至,从人类学意义上讲,人类有没有一个普世准则?人是否应该以维护自己、他人、全人类……的生命为最高目标?都不一定啊。

虽然我并不会做出酒驾超速之类的愚蠢行为,但必须承认,我在日常生活中,会主动警省自己,不应该让「惜命」过于影响自己的行为选择。所以,当女权主义者指责男司机更危险时,我第一时间意识到,大家戳的点,好像并不一致。我开始有意识地,开车时观察周围的车辆。一些车本身并没有违反任何规则,却因为种种「笨拙」行为:绿灯后启动不及时、变线时不果断、驾驶速度过慢……总之,影响了我预想中,大家都「正常」驾驶时的那种流畅度。这样的车主,确实明显超过半数是女性。(——我知道这种观察存在主观误差:抱着偏见去观察时,那些女性车主因为符合了观察者的性别期望,从而印象更深。我努力地让自己不受这种误差影响。)当然了,那些变道过于频繁撒欢,超速甚至从逆行道超车,一看就是作死的,几乎100%是男性。


然而,女性真的操纵机械更笨拙么?

当然不。这一点我绝对不同意。哪怕男女有什么生理上的差别,也完全不至于在开车这种破事儿上显现出来。如果在某些地域,能够统计出,女性确实普遍开车更笨,那也是长期文化上的性别压迫所导致:更少的练习机会、文化语境下的不自信、把不擅机械的刻板印象扭曲为自我认同……

那些嘲笑女司机的习俗,和相关的视频,往往来自于性别权利较差的地区:东亚、南亚、中亚、西亚……而在发达国家,虽然可能同样存在,女司机相对更笨,男司机更彪(我前面说的个人驾驶印象,就是在发达国家得出的),但这种歧视要少很多。也许确实和人数比例有关,这边开车很飒的女性大有人在。然而,女性通过表现得很 man,来获得平等和尊重,这仍然是一种性别压迫。

  • 人类应该更崇尚稳定和安全,还是更崇尚那种无所谓冒险的「男性气质 masculinity」?
  • 或者说,为什么要把冒险定义成「男性」气质?
  • 人们在嘲笑女司机笨拙时,是否在用「男性气质」来压迫女性?当然是。

这些都是未必有结论,但值得深入思考的。我写这些,也是希望大家能跳出那些,为女司机辩护时,过于粗糙的逻辑,多想一些。

Mastodon 的「去中心化」所导致的……?

看到 @[email protected] 写的论文导读。在 Mastodon 的去中心化网络里,用户之间的关联状况,其实比 twitter 更加高度集中。

Raman, Aravindh, Sagar Joglekar, Emiliano De Cristofaro, Nishanth Sastry, and Gareth Tyson. 2019. “Challenges in the Decentralised Web: The Mastodon Case.” Pp. 217–229 in Proceedings of the Internet Measurement Conference, IMC ’19. New York, NY, USA: Association for Computing Machinery.
研究人员爬取了在2017年4月到2018年7月期间的1750个实例,涵盖了23.9万用户和六千七百万条嘟嘟。基于这些数据,构建了用户相互关注的网络,以及实例之间的连接网络。

通过分析这些网络,论文发现了长毛象的中心化趋势。以下结果是基于搜集到的样本,不是全长毛象数据。

1. 用户方面,大约50%的用户都集中在10%的实例里面,因此少数的管理员在长毛象联邦中拥有过量的影响力。开放注册的实例拥有的用户比邀请注册实例里的更多,但是,邀请注册实例的用户平均嘟嘟数量差不多是开放实例用户嘟嘟数量的两倍(187嘟/人 vs. 95嘟/人)。不管哪种实例,都有中心化趋势,服从幂律(power law),前5%的实例容纳了约95%的嘟嘟;

2. 内容方面,只要关掉最大的10个实例,跨站时间轴上62.69%的嘟嘟都会消失。有些实例带有话题标签,研究发现,科技相关实例占据了55.2%的实例,却只容纳20.8%的用户和24.5%的嘟嘟。相比之下,虽然只有12.3%的实例是跟色情相关,但是却吸引了61%的全网用户;

3. 服务器方面,大部分实例都集中在少数的自治系统(Autonomous System, AS)上,主要在日美法德四国。最大的三个AS就有62%的实例。比如亚马逊AS上集中了62%的用户,尽管上面只有6%的实例。关注网络上,92%的用户是连接在一起的,但在极端情况下,只要五个AS崩坏,就会把相互连接的用户数量减到46%。

作者还分析了网络结构的强度。虽然长毛象分成了很多独立的实例,但是用户之间是高度连接的,跟推特相比,长毛象的连接更加脆弱,只要破坏少量的重要节点(高关注用户)就能够极大破坏原本的连接,相比之下,推特的关注网络就比较稳健。

伦理声明:研究通过了大学伦理审查,只收集了公共嘟嘟,并进行了匿名处理,论文结果不包括任何的嘟文内容分析。

实际使用中,也有类似的感觉,Mastodon 用户互相 follow 所形成的网络,比 twiiter 更加纵向化。大家相对更集中关注一些较活跃的用户,而在用户网络的末梢,横向的互相关注相对较少,尤其是不同实例之间的关注,更是如此。

但我觉得这种状况,是和 Mastodon(以及整个 ActivityPub)目前的设计机制有关。最近自己架设实例时,看了一下 Mastodon 和 Pleroma 的后台数据库,架构上有一些莫名其妙的地方:

( btw,我的新帐号: @[email protected]

在当前实例里访问其它实例的文章时,系统要先把其它实例的文章(以及图片附件)复制到当前实例的服务器(而且是和本地用户的文章放在同一个数据表里……),才能被本地用户读取。本地用户所看到的,并不是其它实例的原始数据,而是被保存在本地实例的镜像。

当一个实例的用户 follow 其它实例的用户时,两个实例的数据库把外来实例用户的信息和 public key,保存在各自的数据库里(也是本地用户和外来用户存在同一个数据表里……)。当外来实例的用户发布新文章时,外来实例的服务器会把这条新文章,主动 push 到订阅了它的那些服务器里存起来。

我能看出这样做的一些好处,譬如减少了实例之间的重复通信、避免最终用户和外来实例间的翻墙屏蔽、增强安全性……etc。然而,一切外来实例的文字和图片,都要先保存到本地服务器,才能被阅读,由此导致的,就是用户在随意浏览外面实例的历史文章时,体验非常不友好

界面里显示的外部实例用户的 following 和 followers 数量,也仅仅是当前实例里和这个用户有关联的用户的数量,而不是这个用户在所有实例的真正总关联数。

不仅是外面实例陌生人的信息,不能直接看到;连已经 follow 的用户,在 follow 之前所写的文章,也不能在系统里直接看到。一定要再打开一个浏览器页面,访问对方在其自己实例上的页面,才能浏览。对历史信息的转发和回复也非常不便。

当用户在 Mastodon 界面中,点开一个陌生人的帐号时,有三种情况:

  1. 陌生人也在同一个实例。此时用户可以直接看到陌生人的所有历史文章;
  2. 陌生人在其它实例,但之前曾经被用户实例里的其它用户 follow 过。此时用户可以直接看到,从这个实例里第一次有人 follow 开始,陌生人发过的所有文章。再之前的文章,则必须打开外置浏览器才能查看;
  3. 陌生人在其它实例,之前用户所在实例并没有人 follow 过他。此时用户完全不能直接看到陌生人的任何历史文章,只能通过打开外置浏览器查看。

不能方便地查看一个人以前发过的文章,也就自然没有兴趣去 follow 他。这就导致了两种「集中化」的关联:

  1. 在同一实例内部的人,由于可以互相看到历史文章,所以更方便互相 follow;
  2. 一些已经被实例里其它人 follow 过的「热门用户」,他们的文章更容易被这个实例里的其它用户看到,从而更容易被 follow。

而与之相对的,就是不同实例之间从没 follow 过的陌生人之间,其横向关联度急剧下降。

如果换一种架构模式,每个实例把自己用户的文章都做出静态缓存;然后用户访问外来实例时,直接访问对方服务器的页面,这样的话,情况会不会好很多?

我的技术水平不够,不能再深入分析对比这些机制的优劣了。但这些,其实和「去中心化」本身,并没有直接的联系。「去中心化」和「中心化」的区别,其实仅仅是后台服务器由谁去建,以及随之带来的审查和信息自由度方面的不同。普通用户在使用中,其实是不应该感受到 Mastodon 和 Twitter 的差别的。我们所面对的,并不是「去中心化」带来的问题,而是在做一套新的「去中心化」架构时,所没能解决好的技术问题。那些「中心化」的服务,也有很多因为设计的不如 twitter 理想,而最终倒闭了。目前而言,Mastodon 的架构还远称不上完美,有很多不足,或者让用户觉得不习惯的地方。但这些问题,其实只属于某个产品设计上的问题,而不应该归咎于「去中心化」

个人 VPS 上的服务安装(未完稿)

这篇文章要讨论的是,如何在一台轻量级的 VPS 服务器上,基于自己的域名,同时安装如今各种流行,去中心化的网络服务:

  • 个人博客:Wordpress
  • ActivityPub 社交网络:Pleroma 或 Mastodon
  • Matrix 聊天服务器:Synapse 或 Dendrite
  • 个人网盘和在线办公套件:Nextcloud

然而,原本我一直在用 Linode 每月 5 美元,1C1G(1个CPU,1G内存)的服务器,打算安装的服务,也是基于这个级别的配置。然而弄到一半,突然被乔乔推荐了 Contabo 每月 5 欧元(要一次缴一年,不然有额外费用),4C8G 的服务器。虽然实际速度和网速,并不比 Linode 或 Vultr 好多少,但 8G 内存,选择各种服务的余地可就大多了。所以我整理出来的 1C1G 方案,自己并没有在用……原因我后面会说。

之前也犹豫,既然同样价钱都能 4C8G 了,那为啥还要写 1C1G 的方案?很快大家的配置也都会变高级了吧?但想想也未必,还是整理一下吧。


这篇文章讨论如何在轻量级服务器里塞进各种服务。——前提是这台服务器,假定只会有你一个人在用,最多加上你的闺蜜和男朋友。我并不知道几十个用户的 Mastodon 会有怎样的开销,至少在 1C1G 上这样做非常不靠谱。我所面向的,只是两三个好友自用的私人 VPS 而已。

这篇文章不是写给小白用户的。整个系统还是很复杂的。指望有一个教程,或者一个 docker-compose,能够让完全不懂 Linux 的用户,通过逐行复制命令,就能搞定所有的安装,目前还不现实。你至少要有在完全理解的基础上,用 LNMP 搭出 Wordpress 的能力。所以我也没必要把用过的每一条命令,都放在这篇文章里。——对于每一项服务,我会尽量给出相关靠谱攻略的链接,并且讨论一下里面的坑,和我个人所作的选择。

所以,其实这篇文章本质上就一句话:

是的,这些服务都可以装到一台机器上,不冲突。我弄过了,没问题,你们放心慢慢弄吧。


安装环境:一台 1C1G(或更好的) VPS 服务器,一个你自己的域名。

Continue reading

关于袋鼠肉你们要知道的

袋鼠肉可以吃。

澳大利亚似乎是唯一一个,放到国徽上的动物(袋鼠和鸸鶓)都可以吃的国家。

袋鼠肉历来就是澳洲土著的主食。1980 年,在南澳,最早被允许人类合法食用;在新州、维州、昆州,最初只允许做宠物食品,到 1993 年才允许人类食用。早在 1950s 就出口到欧美。

澳洲最大的超市就有卖袋鼠肉,我见到的最便宜的肉馅 $8/kg,还有肉排、香肠……

个人感觉肉质的粗糙程度,介于牛肉和马肉之间,但味道有点冲,我不会常吃(也不比其它肉便宜)。一些澳洲餐馆也做袋鼠肉的菜,还有袋鼠肉汉堡之类的,肉里加过香料后,也吃不出什么特别了。

袋鼠肉很健康的,脂肪含量小于2%,多种有益的氨基酸。

我确实见过有澳洲白人日常吃袋鼠肉,用袋鼠肉馅炒熟拌pasta酱料做意粉;

我第一次从澳洲回大陆带的手信,就是几包各种袋鼠肉馅和肉排,当晚和小伙伴们用中餐模式炒熟吃了。

并没有关于袋鼠的畜牧业,所有袋鼠肉的来源都是野生袋鼠。

但这不意味着日常杀袋鼠合法,杀袋鼠取肉要在指定的区域里,需要专门的许可证和肉质检测;

有足够的袋鼠可以杀。一般按政府计算,澳洲每年袋鼠总数的 15 – 20% 是可以杀掉的,实际上市场对袋鼠肉的需求远小于这个量。一定区域内,袋鼠繁殖超过一定数量后,也要杀掉保持物种平衡,所以很多只是杀了抛尸。

除了雪梨墨尔本城区实在太大外,其它城市袋鼠在CBD蹦躂,是很常见的事。——啊,这一条和袋鼠肉无关,跑题了,好吧曾经有袋鼠头上插着一支箭逃到 Canberra 市中心,引起轩然大波。

保险公司的车辆理赔数据统计,Canberra 是因为车子撞袋鼠而理赔比例最高的地区;在澳洲车子撞动物的比例:Kangaroo 84%、Wallaby 5%、Wombat 2%、Deer 2%、bird 1%。

最后,最重要的,逗猫秘笈:猫超喜欢吃袋鼠肉!我发现这一点后安利过无数只猫,爱吃率100%,有朋友拿着我送的肉馅回家孝敬猫,猫吃疯了,不停地吃,吃不下跑到一边吐出来,回来继续吃……

hello fediverse

当我说 mastodon 难部署的时候,并不是作为一个建站小白说的。用自己的域名和大约每月5刀的服务器,我可以很轻松地搭建一个 mastodon 实例,用 docker 部署则更简单。——如果我对这个服务器没其它需求的话。

问题在于,对于大多数有建站情操和能力的人来说,建站优先级最高的未必是 mastodon,而是 wordpress 啊。把这两套系统同时塞进一个服务器,理论上是能做到的,但其麻烦程度让我实在没欲望去折腾。而为这两个系统买两个服务器,又总觉得很耻辱,和小白们每个服务交一份钱有啥区别……

另一方面,尽管 mastodon 存在单用户模式,但真的建了实例只有自己一个人用的话,整套 mastodon 程序功能其实是很冗余的。所以对于个人用户而言,要做的可能并不是自建 mastodon 实例,而是寻找其它可以通过 ActivityPub 协议,和 Fediverse 用户进行沟通的程序。——目前似乎还没有太理想的。 write.as 正在做,我去试了试, 用户可以在 Fediverse 上 follow @[email protected] ;wordpress 也有类似的插件(等我先给自己域名申请 SSL ……)。但似乎都只能让 Fediverse 用户「订阅」这个站点,而不能反向和他们回复沟通。

所以还要继续关注 Fediverse 的新进展。据说 nextcloud 已经可以支持 ActivityPub 和 mastodon 沟通了。——网上的免费服务器没这个功能,需要自建 nextcloud 然后挂载相关服务,哪位愿意折腾试试靠谱不?但似乎 nextcloud 还不支持发布 blog??(怒吼:为什么,明明这个更容易啊)。不然 nextcloud 就已经很一站化了。