我开发了一个基于 Beancount 的账本托管服务 HostedBeans,欢迎大家来了解纯文本复式记账并试用我的服务。
标签 #技术

RootPanel 2.0 Case Close

我最喜欢的,便是在一个项目完成后,写一篇总结性质的日志,可惜这样的机会并不多。

这一段时间,我心里的压力挺大的,更多的是自己给自己的压力吧——我估计那几十名用户可能不大关心新版本什么的吧。不过这压力似乎并没影响我一天拖一天,看新闻,逛论坛,打游戏。

现在,代码已经全部完成,也完成了大部分的测试,只等上线和微调了,但我心里还是很不安。这一次的更新很大,不亚于重新写一个,但准备工作却远不如RP首次上线时充分,仅预留了几天的测试时间,而且这次要迁移的用户要比上次多很多。这种不安直接导致这几天,经常打开论坛,又关上;打开IDE, 又关上;打开游戏,又退出 ….

一开始我没打算为RP2增加这么多功能,但是写着写着,越来越想一步到位。RP2从3月一直拖到了6月,其实只有五月中下旬我在写RP2的代码我会说么?3-4月一直在反复折腾LightPHP, LightPHP在Web领域,可谓是见证了我成长,从我入门PHP两个月,到现在(两年), 我一直在完善它,虽然它现在仍不完美。

一步到位,我想我做到了,在之后的一段时间,RP面板不会有大的更新了,因为这次的架构设计还算不错,应该可以撑很长时间,小修小补就够了。接下来我将着手宣传工作,同时如果Parthas有时间的话,准备开拓一下海外市场。

我也没想到,我的第一桶金竟然是靠卖虚拟主机,想一年半以前,我还在为寻找一个物美价廉的虚拟主机而发愁。说实话,要不是因为面板是我自己写的,我真的不屑于卖虚拟主机,这离我靠卖代码赚钱的目标还有很大差距,不过也许对于现在的网络环境,卖服务才是更好的选择。

附新版宣传稿:

RP主机:技术宅的Linux虚拟主机

可前往官网了解更多:http://rpvhost.net

我是一名高二学生,出售虚拟主机已经一年多了,RP主机也上线半年了。一直觉得 ____ 是一个高质量的社区,所以我一直在学习和完善,直到现在才敢来这里宣传。

在我还是初中生时,我便涉足Web编程,但那时候零花钱少啊,找不到性价比高又能满足需求的虚拟主机——我一直喜欢追一些新鲜的技术。我深知学生党和业余建站党的需求,于是在我现在有能力时,搞出了RP主机。

RP主机本质上是一个严格划分了用户权限的Linux服务器,你可以在这里通过Shell随意运行进程,(以非root权限)自行安装软件和运行时,当然,也有公用的运行时。需要共享的80端口,MySQL,PPTP等服务,则可以通过我自己编写的面板进行自助管理。

RP主机对PHP,Python,Go,NodeJS,C/C++等语言均有非常好的支持。RP主机的服务器来自Linode,LocVPS等VPS提供商,目前有日本和美国两个节点,稍后会新增香港节点。价格8元/月,19/季度。

笔记: 循环, 递归, 迭代, 遍历

本文首发于SegmentFault, http://segmentfault.com/q/1010000000199577#a-1020000000199630

表示”重复”这个含义的词有很多, 比如循环(loop), 递归(recursion), 遍历(traversal), 迭代(iterate).

循环

循环算是最基础的概念, 凡是重复执行一段代码, 都可以称之为循环. 大部分的递归, 遍历, 迭代, 都是循环.

递归

递归的定义是, 根据一种(几种)基本情况定义的算法, 其他复杂情况都可以被逐步还原为基本情况.

在编程中的特征就是, 在函数定义内重复调用该函数.

例如斐波那契数列, 定义F(0)=1, F(1)=1, 所有其他情况: F(x)=F(x-1)+F(x-2).

所有大于1的整数经过有限次的反推之后都可以转换到两种基本情况. 而在编程中, 算法则是这样的:

int F(x)
{
    if(x==0 || x==1)
        return 1;    //这里是退出递归的条件, 以保证在有限次递归后能够得到结果
    return F(x-1)+F(x-2);    //转化为更为基本的情况, 重复调用自身进行计算
}

迭代(数学)

迭代在数学和编程中有不同的含义.

数学方面是指在循环的基础上, 每一次循环, 都比上一次更为接近结果.

例如下面是一个迭代的例子.

int result = 0;
for(int i=0; i>10; i++)
    result += i;    //每一次循环之后, result都更加接近结果45

有很多数学问题, 都是迭代算法, 如牛顿迭代法(求平方根).

迭代(编程)

按顺序访问一个列表中的每一项, 这在很多编程语言中表现为foreach语句:

$arr = [1, 2, 3, 4];
foreach($arr as $i)
    echo $i;

遍历

按一定规则访问一个非线性的结构中的每一项, 强调非线性结构(树, 图). 而迭代一般适用于线性结构(数组, 队列).

结论

  • 循环(loop) – 最基础的概念, 所有重复的行为
  • 递归(recursion) – 在函数内调用自身, 将复杂情况逐步转化成基本情况
  • (数学)迭代(iterate) – 在多次循环中逐步接近结果
  • (编程)迭代(iterate) – 按顺序访问线性结构中的每一项
  • 遍历(traversal) – 按规则访问非线性结构中的每一项

这些概念都表示“重复”的含义, 彼此互相交叉, 在上下文清晰的情况下, 不必做过于细致的区分.

参考

RP主机如何进行权限控制

折腾虚拟主机一年多了, 除去编写面板,研究的更多的就是权限控制了. 在此我分享一下我在Linux虚拟主机权限控制方面的经验.

阅读本文需要一定的Linux服务器维护基础.

《应用密码学》的前言中讲到:

如果我把一封信锁在保险柜中, 把保险柜藏在纽约的某个地方, 然后告诉你去读这封信, 这并不是安全, 而是隐藏.

相反,如果我把一封信锁在保险柜中, 然后把保险柜及其设计规范和许多同样的保险柜给你, 以便你和世界上最好的开保险柜的专家能够研究锁的装置.

而你还是无法打开保险柜去读这封信, 这才是安全.

我不是说我的安全措施无懈可击, 我只是认为隐藏起来也于事无补, 不如分享出来, 在此我也提示RP主机的用户, 请不要在服务器上做尝试突破限制的操作, 根据协议你可能被封停帐号, 你可以自行架设环境来测试, 或与我交流. 啊, 题外话说了这么多.

我很懒, 我在尽可能地借助Linux本身的功能来进行权限控制, 而且这也是RP主机的宗旨——提供完整的Linux环境.

文件

文件方面, Linux本身已经提供了一套文件权限系统, 我只需要提示用户应当将文件权限设置为770即可: chmod -R 770 ~

为了防止疏忽,我们还可以在.bashrc中加入umask 007这样创建出来的文件默认就是660(注1), 不过这对PHP等脚本生成的文件并不起作用, 因为他们没有通过bash环境.

注1: Linux不允许一个文件创建时就有执行权限, 所以默认是660, 对于目录则是770.

我没有使用单独的FTP软件, 比如有名的vsftp, 因为我觉得配置起来很麻烦, 容易产生新漏洞. sshd自带的SFTP功能完全可以满足文件管理的需求, 这是自带的功能, 方便.

我还使用了quota-tools来限制用户的磁盘占用, 因为磁盘这东西, 占了多少就是多少, 总不能随便删人的文件啊, 所以一定要限制死.

Web

Web部分可谓是重中之重, 因为按照Linux的规则, 端口是被一个进程独占的, 但是大家都需要用80端口来开设Web服务, 这就需要以root运行一个Web服务器, 然后根据用户的在面板中的配置, 分发, 执行Web请求. 其实, 只需要一个反向代理来分发请求就够了, 但是为了降低建站的门槛, 毕竟相当大一部分用户购买RP主机就是为了建站, 所以还要提供公共的常见脚本(PHP)运行环境.

Apache负责运行各种网页脚本, 如PHP, Python, CGI等等. 为了保证自由度, 我没有对PHP加任何的限制, 我希望借助Linux本身的进程安全模型——让脚本以对应的Linux用户来运行.

于是我找到了 mpm_itk_module, 这种工作模式, 可以为每个Virtual Host指定实际运行的用户. 当收到请求时, Apache的工作进程会setuid为相应用户, 然后再执行相应的脚本完成请求.

借助于Linux本身的功能, PHP进程可以按照权限访问文件, 创建新进程(以实际的用户), 而不会干扰到其他用户.

但和标准的 mpm_perfork_module 相比, 因为要频繁地setuid, 创建和销毁进程, 性能相差了几十上百倍之多. 但为了权限控制的灵活性, 只能牺牲性能了. 在新版本中, 我正在把性能低下的Apache边缘化.

目前, 事实上是Nginx在监听80端口, 负责处理静态文件请求, 并把其他请求反向代理到Apache. 为了提供静态文件, Nginx需要能偶访问所有用户的文件.

我选择了以www-data用户来运行Nginx, 同时将www-data加入到每个用户的组当中, 所以需要用户将文件设置为770, 给予同组的Nginx权限.

新版本的Web

新版本中将使用PHP-FPM代替Apache处理PHP脚本, PHP-FPM的功能很强大, 可以建立不同的进程池, 在新版本中, 每个用户都会有一个单独的进程池.

每个进程池表现为一个UNIX socket文件, 用户也可以编译自己的PHP和PHP-FPM来代替默认的PHP-FPM.

新版本中使用了 uWSGI 代替Aapche的 mod_wsgi 来处理Python脚本, 用户需要自行运行uWSGI守护进程, 监听一个UNIX socket, 并配置Nginx的反向代理即可.

事实上这种方式适用于所有的fcgi服务器.

MySQL

MySQL再简单不过了, 装一个phpmyadmin, 默认的安全策略已经相当完善, 每个用户对以自己的用户名为前缀的数据库具有全部权限, 可以随意建立数据库.

流量统计

说实话直到目前我还没找到较可行的方案, 我希望依然以Linux中的用户为单位进行统计. 目前我正在调研iptables的相关功能.

目前还有两个部分的用户相关进程没有以实际用户运行: PPTP, Nginx的worker.

不知不觉写了这么多, 不过好像没啥实际的啊.

精子生于 1995 年,英文 ID jysperm.

订阅推送

通过 Telegram Channel 订阅我的博客日志、产品和项目的动态:

王子亭的博客 @ Telegram


通过邮件订阅订阅我的博客日志、产品和项目的动态(历史邮件):

该博客使用基于  Hexo  的  simpleblock  主题。博客内容使用  CC BY-NC-ND  授权发布。最后生成于 2024-04-08.