Web 自托管平台评测 Cloudron vs YunoHost vs Sandstorm

作为一个爱折腾的人,我的服务器上有几个自己写的 web 服务在跑,也有部署的开源软件。时间长了七八个服务分散在三四个平台上,经常需要到处续费,还要偶尔备份数据,部署的开源软件还要记得升级,可以说是挺烦的了。前两天偶然接触到 Cloudron 和 YunoHost,才知道有专门服务我这种需求的自托管平台,可以一键安装应用并通过面板管理。

我为了选到最适合自己的,不但安装了这两个平台,还又找到了一个竞品 Sandstorm。在选择的过程中我发现不但中文网络上没有比较它们的文章,英文网络上也没有写的很详细的,所以选择完了顺便写篇博客,也给大家介绍一下我的发现。

  • 本文不是广告。
  • 本文中的 Cloudron 链接是带 Ref 的,使用 Ref Code 059fff403129974a 付费你我均可获得 30 美元优惠。

自托管平台不是什么

自托管平台不是 ownCloud, Nextcloud 之类的私有云,尽管他们也提供文件存储,文档表格之类的应用,但是不能安装外来应用(比如 WordPress)。反而,在自托管平台上,我们可以安装一个私有云(例如在 Cloudron 提供了 Nextcloud).

需求

在开始比较几个平台之前,我先列一下我的需求:

  1. 尽量多的提供我正在使用的应用(Wordpress, Monica, FreshRSS, Confluence)
  2. 自动备份到外部存储
  3. 应用之间相互隔离,提高安全性
  4. 可以自动升级应用
  5. 可以使用自己写的应用

继续阅读

从面试官的角度分享一些后端校招经验

1. 写在前面

我从去年年初开始在美团当校招面试官,参加了 17 届春招和 18 届秋招两届面试,总共就面试了五十多个人。本来我也就是刚开始学着当面试官,不该妄谈经验,但是因为最近换了一份工作,未来几年都不会再有国内互联网公司的校招经验了,所以不如趁热分享一下,省得知识过期。本文是个人体会,而且经验不多,读者姑妄听之就好,不必太认真。

这篇文章主要针对的是徘徊在 offer 线上下的同学,因为作为面试中的初试官,也在这部分同学上花心思比较多,如何保证通过的质量、如何保证面试的公平性等等,明显能通过的同学反而不用花太多心思,offer 的定级交给复试官就好。文章中会用校招圈子的通用标准来描述 offer 等级:批发价、SP、SSP。更高的等级(例如阿里星)就不讨论了,拿到 SSP 的候选人我都没见过几个。

继续阅读

ElasticSearch: Index 和 Type 的区别

原文: Index vs. Type By Adrien Grand
译者: fengchang

对于 ES 的新用户来说,有一个常见的问题:要存储一批新的数据时,应该在已有 index 里新建一个 type,还是给它新建一个 index?要想回答这个问题,我们必须先理解这两者是怎么实现的。

过去,我们为了让 ES 更容易理解,经常用关系型数据库做一个比喻: index 就像关系型数据库里的 database, type 就像 database 里的 table。但是这并不正确。由于两种数据库存储数据的方式是如此不同,任何比喻都是没有意义的。这种比喻往往会导致对 type 的滥用。

继续阅读

API自动化测试利器——Postman

自从开始做API开发之后,我就在寻找合适的API测试工具。一开始不是很想用Chrome扩展,用的WizTools的工具,后来试过一次Postman之后就停不下来了,还买了付费的Jetpacks。推出Team Sync Beta之后我又把这个工具推广给团队,作为API文档使用。看到中文网络上关于这个工具的文章并不多,于是决定写一篇小文介绍一下。

一、基本功能

Postman的功能在文档中有介绍。不过文档略啰嗦,这里简单介绍一下主界面,入门功能就都提到了。

继续阅读

PHP:设置Location导致状态码被修改为302

最近在试着做RESTful API,学了很多平时用不到的HTTP知识。在一个API上,我想用409 Conflict表示要创建的资源已经存在。这是一个挺冷门的状态码,在B/S结构中基本上用不到。RFC 2616对它的解释是:

409 Conflict

The request could not be completed due to a conflict with the current
state of the resource. This code is only allowed in situations where
it is expected that the user might be able to resolve the conflict and
resubmit the request. The response body SHOULD include enough
information for the user to recognize the source of the conflict.
Ideally, the response entity would include enough information for the
user or user agent to fix the problem; however, that might not be
possible and is not required.

《RESTful Web APIs》这本书在409 Conflict的解释中写到:

响应报头:如果该冲突是由于某些其他资源的存在(比如,客户端尝试创建的某个特定的资源已经存在了)而造成的话,那么Location报头应该链接到该资源的URL:也就是说,冲突的来源。

继续阅读

微信内Web App自动登录

最初是在Tower.im的公众号里见到了WebApp自动登录,想做一个同样效果的。那时候对公众号开发不熟悉,问了一些人也说的稀里糊涂的,文档又乱,最后花了好长时间才实现。这个功能需要的接口是「网页授权获取用户基本信息」,需要认证企业号才能使用。如果没有权限的话可以试一下微信之门,我也只是知道这个东西,从来没试过。

基本的思路是通过公众号OAuth API获取用户微信的openid。第一次使用的时候让用户登录,然后在数据库里把openid和自己应用的userid对应起来。以后获得用户的openid之后就可以自动登录到对应的用户上。

我的Web App是用AngularJS实现的SPA,登录之后获取一个token放在localStorage,给后端发请求的时候,把token写在Header的Authorization里。

这个过程中不需要使用Cookie,但是为了减少跳转次数,还是用了Cookie。我把和微信登录相关的功能写在了几个PHP单页里,用一个redirect.php做入口,把要跳转的页面放在参数里,由redirect.php检查用户是否已经获得了token,在获取到token之后跳转到目标页面。

登录流程图如下:

继续阅读

从一行JavaScript代码生成随机字符串说起

今天在写JS的时候,要生成一个随机字符串,JavaScript中没有PHP的uniqid()方法,我Google了一下,在Stack Overflow上看到了一个很漂亮的函数,只有一行:

function generateUIDNotMoreThan1million() {
    return ("0000" + (Math.random()*Math.pow(36,4) << 0).toString(36)).slice(-4)
}

这种代码以前都copy来直接用,不过今天读到一篇《从一行CSS调试代码中学到的JavaScript知识》,觉得还蛮有意思的,我也试着来解读一下这行代码。

继续阅读

Pomelo中一次RPC调用被多次执行

每次遇到很久调试不出来的bug,都觉得这个bug只要解决了,以后的「你调过的最难调的bug是哪个?」这个问题就有答案了。但是最后找到的原因都是很弱智的错误。

这个bug由来已久,大约两个月之前出现的。在新玩家加入游戏的时候,会给场景内的玩家推送一条onJoin消息。告诉其他玩家这个新人的信息。

后来为了方便做假用户,就另外写了一个入口,供机器人登录,登录后会给所有场景的玩家广播一条onJoin,也去掉了一些玩家需要的信息和游戏逻辑,机器人只是出现在游戏场景里,并不会留下游戏记录。

继续阅读

PHP中三元运算符的结合性

春节之后上了两门Coursera课程,又跟集智俱乐部研究了一个多月神经网络,一篇博客都没写完。今天先从一篇短文开始,再慢慢完成之前的一些草稿。

昨天鸟哥在PHP Conference讲到PHP7的AST时,说起PHP的一个历史遗留问题:三元运算符的结合性。PHP的语法是类似于C的,但是在这里却不一样。

继续阅读