蘑菇天文馆 https://blog.atr.me How many stars in your bowl? How many sorrows in your soul? Sun, 13 May 2018 16:09:19 +0000 zh-CN hourly 1 https://wordpress.org/?v=4.9.5 28979029 于是我终于也换工作了 https://blog.atr.me/NGC486 https://blog.atr.me/NGC486#respond Sun, 13 May 2018 15:44:35 +0000 https://blog.atr.me/?p=486 阿里内部一直标榜自己是一所大学,同事之间也多以“同学”互称。从2014年4月3日入职实习,到2018年4月9日正式离职,4年了,我算是毕业了吧。 写离职贴向来是阿里内网的一项传统和一道风景(另一道风景是相亲贴),早在决定离职之前的一段时间,就想象过有朝一日我自己的离职贴会写成什么样子,一开始草拟的题目叫《我为什么从阿里离职》,但思来想去我并不像一些遭遇状况离开的同学那样苦大仇深,貌似没有必要玩这种噱头,甚至这篇文章本身也没必要真的发布到内网丢人现眼,就放在这个早已荒草两丈高的博客聊做记录呗。 2014年3月时侯,确定考研无望的我开始找工作,因为早就错过了当年的校招季,其实处境颇有点不尴不尬。先是面试了一两家小公司,互相都没太看上眼,在推上求RT的时候承 @bones7456 抬爱帮忙投了个内推,没两天就接到了阿里的面试电话。经过顺利到我自己都没感觉的面试流程,很快就拿到了 offer, 然后我鸽了在 Google Talk 上聊得很开心的兽兽,无视掉学校里面最后一两个月的课程,买了张卧铺票就跑来杭州了。 除了中间回学校补考高数&办毕业手续,我从14年4月就基本一直住在杭州,必需说,杭州的生活环境真是比北方舒服多了。到6月底我正式毕业,中间不仅没有办离职,甚至还拿着部门特批的笔记本回了学校(正常实习生是只配台式,笔记本是部门工作特性需要经常在工位和值班室来回移动所以特批的)...6月26号早上我直接用实习生工牌刷卡进园区,到4号楼办了第二次入职,主管给我说“这次我就不用来接你了吧”,啊哈哈,当然不用,听完培训我就丢下其他等着各自团队接人的大侠们溜去工位... 然后第二天就跑去千岛湖 Outing 了(乛.乛) 不知不觉过了三年多,中间值了若干个夜班见过了随便几点的西溪园区,亲历了若干次超大型故障并且发了527第一条故障通告,一个人运维了几百台机器的监控系统大半年,徒手写了部署量上百万的监控脚本还搞出来个P2故障至今保持鄙部门记录,带着实习生倒腾出一个跨机房监控被老板拿着截图到故障 Review 上当证据,亲手应急切换过淘宝支付宝交易单元分分钟百万上下,和人邮件撕过逼也被人电话撕过逼,被其他部门主管私聊挖过墙角,拿过3.75A也拿过3.25B, 怎么看都是圆满了( 哦对,唯一的遗憾大概是某个再也看不到某个内部群里面老法师们斗法了( 至于为什么要走,怎么说呢,作为毕业直接进了巨头的我,见识了够多的标准化流程和体系化建设之后,慢慢地也开始对大公司的各种弊端产生了厌倦,总觉得如果再继续在这样的环境待几年,不管是技能树还是整个人的心态都会彻底被固化下来,并且很难有进一步突破的空间了。正好最近一年多以来组织架构数次大幅调整,阿里内部整体技术革新的背景下部门方向转型,工作内容里面非技术的部门越来越多、能关心技术的精力也越来越少,整天都埋没在无尽的会议和故障 Review 中,和各个部门各个团队的人在钉钉上电话上会议室里纠缠不清一个故障甚至一个改进措施的责任归属;偶而停下来看一看的时侯,猛然发现自己的发展路线已经不知不觉指向了技术运营和事件管理:这并不是我喜欢的方向,我也很难在这个领域作出漂亮的成果来。 最后那半年多每天的压力都非常大,并且几度出现了轻微的焦虑症状,再加上工作内容愈发混乱,在这里工作已经不能让我感到有趣,我意识到必需作决定了。 于是么,趁着手上几个主要的事情告一段落,我特意放慢了进一步的工作安排,开始准备另谋出路;大公司干了好些年,不如去小公司长长见识也很好啊。然后非常巧合地,在我简历还没改好的时侯,某 @Tiramisu1993 给我说他实习的公司在招人还发了 JD 过来,我上知乎随手一搜居然好(shui)评(jun)如潮,于是就连夜周末赶了份新简历出来投了过去... 反正中间因为我要压到4月之后离职所以大家都不着急地拖拖拉拉几个月的面试不表,春节后调休完上班第一天我把主管拖到小黑屋讲了离职计划,之后就进入了轻松愉快的工(hun)作(chi)交(deng)接(si)阶段...再然后我就变成了 PingCAP 员工了_(:зゝ∠)_ 由于这篇文章拖了太久,我已经没有刚离职时侯那种沉重的心情了,所以只好写一些新东家一个月来的感受... 首先,作为一家名符其实的小公司,PingCAP 整个公司的规模和我之前所在的阿里 GOC 这么一个小 BU 相当,比起组织严密、流程翔实的大公司明显地要松散灵活很多,嗯,也就是说知乎上的软文基本属实...往好了说,是氛围轻松、迭代迅速、扁平化管理,往坏了说,是野蛮生长、制度残缺和技术沉淀薄弱,这些对于一个小公司来说都是显而易见甚至可以讲理所当然的,我也很庆幸自己有好几年大公司的经历,让我能直观地意识到这些问题,也就给了我进一步产出价值的更多机会与可能性。 嘛,至少目前来说,有两点让我非常满意目前的工作并且乐在其中:1. 可以100%工作时间放在技术领域,用来写代码读文档而非和人撕逼;2. 非工作时间不会被频繁打断,不用一睁眼睛先摸手机看未读消息 你们看我多容易满足(]]> 拖了一个月的博文,再不发就要烂在草稿箱里面了╮( ̄▽ ̄”)╭

阿里内部一直标榜自己是一所大学,同事之间也多以“同学”互称。从2014年4月3日入职实习,到2018年4月9日正式离职,4年了,我算是毕业了吧。

写离职贴向来是阿里内网的一项传统和一道风景(另一道风景是相亲贴),早在决定离职之前的一段时间,就想象过有朝一日我自己的离职贴会写成什么样子,一开始草拟的题目叫《我为什么从阿里离职》,但思来想去我并不像一些遭遇状况离开的同学那样苦大仇深,貌似没有必要玩这种噱头,甚至这篇文章本身也没必要真的发布到内网丢人现眼,就放在这个早已荒草两丈高的博客聊做记录呗。

2014年3月时侯,确定考研无望的我开始找工作,因为早就错过了当年的校招季,其实处境颇有点不尴不尬。先是面试了一两家小公司,互相都没太看上眼,在推上求RT的时候承 @bones7456 抬爱帮忙投了个内推,没两天就接到了阿里的面试电话。经过顺利到我自己都没感觉的面试流程,很快就拿到了 offer, 然后我鸽了在 Google Talk 上聊得很开心的兽兽,无视掉学校里面最后一两个月的课程,买了张卧铺票就跑来杭州了。

除了中间回学校补考高数&办毕业手续,我从14年4月就基本一直住在杭州,必需说,杭州的生活环境真是比北方舒服多了。到6月底我正式毕业,中间不仅没有办离职,甚至还拿着部门特批的笔记本回了学校(正常实习生是只配台式,笔记本是部门工作特性需要经常在工位和值班室来回移动所以特批的)…6月26号早上我直接用实习生工牌刷卡进园区,到4号楼办了第二次入职,主管给我说“这次我就不用来接你了吧”,啊哈哈,当然不用,听完培训我就丢下其他等着各自团队接人的大侠们溜去工位…

然后第二天就跑去千岛湖 Outing 了(乛.乛)

不知不觉过了三年多,中间值了若干个夜班见过了随便几点的西溪园区,亲历了若干次超大型故障并且发了527第一条故障通告,一个人运维了几百台机器的监控系统大半年,徒手写了部署量上百万的监控脚本还搞出来个P2故障至今保持鄙部门记录,带着实习生倒腾出一个跨机房监控被老板拿着截图到故障 Review 上当证据,亲手应急切换过淘宝支付宝交易单元分分钟百万上下,和人邮件撕过逼也被人电话撕过逼,被其他部门主管私聊挖过墙角,拿过3.75A也拿过3.25B, 怎么看都是圆满了(

哦对,唯一的遗憾大概是某个再也看不到某个内部群里面老法师们斗法了(

至于为什么要走,怎么说呢,作为毕业直接进了巨头的我,见识了够多的标准化流程和体系化建设之后,慢慢地也开始对大公司的各种弊端产生了厌倦,总觉得如果再继续在这样的环境待几年,不管是技能树还是整个人的心态都会彻底被固化下来,并且很难有进一步突破的空间了。正好最近一年多以来组织架构数次大幅调整,阿里内部整体技术革新的背景下部门方向转型,工作内容里面非技术的部门越来越多、能关心技术的精力也越来越少,整天都埋没在无尽的会议和故障 Review 中,和各个部门各个团队的人在钉钉上电话上会议室里纠缠不清一个故障甚至一个改进措施的责任归属;偶而停下来看一看的时侯,猛然发现自己的发展路线已经不知不觉指向了技术运营和事件管理:这并不是我喜欢的方向,我也很难在这个领域作出漂亮的成果来。

最后那半年多每天的压力都非常大,并且几度出现了轻微的焦虑症状,再加上工作内容愈发混乱,在这里工作已经不能让我感到有趣,我意识到必需作决定了。

于是么,趁着手上几个主要的事情告一段落,我特意放慢了进一步的工作安排,开始准备另谋出路;大公司干了好些年,不如去小公司长长见识也很好啊。然后非常巧合地,在我简历还没改好的时侯,某 @Tiramisu1993 给我说他实习的公司在招人还发了 JD 过来,我上知乎随手一搜居然好(shui)评(jun)如潮,于是就连夜周末赶了份新简历出来投了过去…

反正中间因为我要压到4月之后离职所以大家都不着急地拖拖拉拉几个月的面试不表,春节后调休完上班第一天我把主管拖到小黑屋讲了离职计划,之后就进入了轻松愉快的工(hun)作(chi)交(deng)接(si)阶段…再然后我就变成了 PingCAP 员工了_(:зゝ∠)_

由于这篇文章拖了太久,我已经没有刚离职时侯那种沉重的心情了,所以只好写一些新东家一个月来的感受…

首先,作为一家名符其实的小公司,PingCAP 整个公司的规模和我之前所在的阿里 GOC 这么一个小 BU 相当,比起组织严密、流程翔实的大公司明显地要松散灵活很多,嗯,也就是说知乎上的软文基本属实…往好了说,是氛围轻松、迭代迅速、扁平化管理,往坏了说,是野蛮生长、制度残缺和技术沉淀薄弱,这些对于一个小公司来说都是显而易见甚至可以讲理所当然的,我也很庆幸自己有好几年大公司的经历,让我能直观地意识到这些问题,也就给了我进一步产出价值的更多机会与可能性。

嘛,至少目前来说,有两点让我非常满意目前的工作并且乐在其中:1. 可以100%工作时间放在技术领域,用来写代码读文档而非和人撕逼;2. 非工作时间不会被频繁打断,不用一睁眼睛先摸手机看未读消息

你们看我多容易满足(

]]>
https://blog.atr.me/NGC486/feed 0 486
使用 Orange Pi One 和 GPS 搭建1级时间源 https://blog.atr.me/NGC437 https://blog.atr.me/NGC437#comments Sat, 21 Jan 2017 15:11:27 +0000 http://blog.atr.me/?p=437 1. 背景知识 整个 NTP 分发网络的结构是一种近似树状的分层结构,每一级叫做一个 "Stratum", 其中 Stratum-0 是可靠的参考时间源,比如原子钟、GPS或无线电授时信号源等,所有0级时间源构成了整个 NTP 网络中的参考时钟;在逻辑上,所有0级时间源作为一个整体提供了全世界的标准时钟。不过因为0级时间源本身实际上只是某种形式的时钟信号发生装置,所以它们并不直接对外提供授时服务,而是连接到一些运行着特定软件的服务器上,这些服务器将0级时间源作为参考时钟并与其同步时间,再把自己的系统时间作为参考时钟提供给其它前来查询时间戳的客户端,以此提供授时服务。这些直接以0级时间源为参考时钟的服务器被称作1级时间源(Stratum-1),它们是 NTP 网络中最可信的时间信号来源。1级时间源之间也可能互相作为上游,作为单个0级时间源不可用时候的备份。 按照标准的 NTPd 实现,每台运行 NTPd 的入网设备都同时充当客户端和服务器的角色(当然是可配置的),从上游同步时间的同时,也可供其他客户端用作参考时钟。设备的 Stratum 为其参考时钟的 Stratum 加一,整个网络中 Stratum 的最大值为16. 因为1级时间源有较高的硬件要求,通常网络上提供授时服务的都是2级时间源,也有一部分3级时间源,1级和大于3级的时间源都相对少见。 NTP的分层组织结构 (图自维基百科) 所以网络中能对外提供服务的最高一级服务器就是 Stratum-1 了,在1级时间源上面需要连接一个0级的参考时钟,这个时钟最简单的来源就是 GPS 信号。然而,一般的民用电子设备(这里特指计算机)在运行中由于节能策略和物理限制等等原因,系统时间的流逝并不是严格匀速的,也就是说系统时间的每一秒对应到现实时间并不严格均匀,这就造成系统在运行时间足够长之后会积累相当可观的误差。运行 NTPd 的系统虽然可以周期性地和上级时间源同步来校正系统时间,但从较长的时间尺度上看依然是一个“抖动”的时间轴,单纯供系统自己使用问题不大,而就1级时间源来说,要对外授时质量就不太够了。 主流的解决方案是在系统上引入一个高可靠的周期性信号,作为基础频率让内核保持稳定的时间流逝速率。比如阿里云的公共 NTP 服务就使用的是 GPS (提供时间戳)加上原子钟(保持时间流逝速率)来维持高精度的授时信号。自家用当然不需要那么夸张,市面上的很多 GPS 模块都能输出 PPS (Pulse Per Second) 信号,其稳定性远远高于一般主板上的晶振,一些型号的 GPS 芯片能提供误差小于 50ns 的信号输出,用作大多数授时场景都绰绰有余。 顺便一提,USB 接口的成型 GPS 模块好像基本都不能输出 PPS.

2. 硬件准备

网上有很多用 Respberry Pi 搭建1级时间源的文章,但树莓派裸机加上一些基础毕竟还是要好几百,作为多数时候只能吃灰的玩具来说还是略贵了点。正好去年年中的时候看到了 Orange Pi 的价格和配置,发现实在是白菜,就顺手入了几只。后来更便宜的 NanoPi M1 和 NanoPi Neo 出现之后也分别入手了一两个。这几个东西都是基于全智 H3 CPU 的 ARM 小板子,性能比树莓派要差一些,社区资源也更有限,好在胜在价格便宜。这篇文档是基于 Orange Pi One 来的,后面会简称为 opi. 至于 GPS 模块,我是在淘宝上找了一款有 PPS 输出的裸模块,自己动手把店家附送的引线转接到杜邦线头上,然后就可以插到 opi 的 GPIO 针脚上了。

3. 软件准备

系统我用的是 Armbian Orange Pi One 的 Debian Jessie 镜像,搭配 Linux 3.4.y 内核(用主线内核 4.9 已经可以正常开机,但配置方法和 3.4 区别比较大所以还没去折腾),系统本身的安装和配置有文档说明略去不提,主要的准备工作是:自己编译内核。 具体编译方法可以看官方的说明,只编译内核的话在完成后把生成的若干个 .deb 包放到 opi 上安装然后重启就行了,当然直接自己编译整个镜像也是可以的。这里需要自己编译的主要原因是为了引入 pps-gpio 支持。 方法也很简单,把这里的 .patch 文件放到编译工程对应的 userpatches 目录([crayon-5b03c55fe6de0037974632-i/])下面就行。 另一项软件准备是编译 NTPd, 因为 Debian 官方源里面的 ntp 包禁用了 PPS 驱动,只能自己重新编译来开启。 [crayon-5b03c55fe6df0087834206/] 然后在 configure 参数中加上 [crayon-5b03c55fe6df4826510065-i/] 选项: [crayon-5b03c55fe6df9620730266/] 可选编辑 [crayon-5b03c55fe6dfd751253042-i/] 更新版本号和说明。 之后使用[crayon-5b03c55fe6e01513168461-i/]命令编译并打包,依赖提示缺什么就装什么就行了。编译过程在 opi 上会非常缓慢而持久,如果有办法在更好的机器上做交叉编译的话值得一试。 编译完成后会在上层目录生成若干个 .deb 文件,使用 [crayon-5b03c55fe6e05878092365-i/] 命令安装之即可。 另外我们还需要 gpsd 来读取和解析 GPS 数据,这个包建议使用 [crayon-5b03c55fe6e09137669743-i/] 源,版本足够新,按官方说明添加源后直接 [crayon-5b03c55fe6e0d518080495-i/] 搞定。

4. Do Magic!

现在假定所有准备工作已经完成:opi 系统安装完成、联网并运行在正确的内核上,ntp 和 gpsd 包安装完毕,GPS 模块连线引出完成并且有良好信号。 首先到[crayon-5b03c55fe6e11112268816-i/]下,编辑 scrit.fex 文件,搜索 uart0 字段,确保所有 uart 端口都是启用状态(opi 一共有4个 uart 接口,其中 uart0 供默认控制终端,剩下3个在 GPIO 上): [crayon-5b03c55fe6e15213038531/] [crayon-5b03c55fe6e19985306145/] 完成后保存退出,执行: [crayon-5b03c55fe6e1e163623448/] 然后编辑[crayon-5b03c55fe6e21747163313-i/]文件,向其中加入一行 pps-gpio 并保存;然后再编辑(新建)[crayon-5b03c55fe6e25279265787-i/]文件,其内容为: [crayon-5b03c55fe6e29383400327/] 关于 GPIO 端口号计算的方法可以参考这篇帖子下面的回复,而具体的引脚定义可以在 Sunxi Wiki 找到。 完成上面两处编辑过后重启系统。如果正常应当有[crayon-5b03c55fe6e2d892870100-i/]几个串口设备出现;另外可以找到[crayon-5b03c55fe6e31055773795-i/]设备并且在 dmesg ([crayon-5b03c55fe6e35281891112-i/]) 里面看到类似下面的日志: [crayon-5b03c55fe6e38015597581/] 然后我们来接线: [crayon-5b03c55fe6e3c267600479/] 其中 PPS 线的接法,按照网上各种版本各异的基于树莓派的文章,有 GPIO 4/5/18 和物理针脚 18/23 等多种说法,但我全部试过一遍都不行...最后照着 GPIO 针脚定义找相关的说明试出来 opi 的物理针脚 5(对应 GPIO 11)和物理针脚 29(对应 GPIO 7)可用,我也有一块 GPS 模块可以使用物理端口 7(对应GPIO 6)但别的型号都不行。 如果买到的 GPS 模块是 5V 的,把 VCC 接到物理针脚 2 上面就行了。如果需要外接 RTC 建议用 PA7, 避免和 PPS 抢针脚。 接线完成后观察 GPS 是否正常工作,然后在系统中进行相关测试: [crayon-5b03c55fe6e41489468487/] 按照我上面的接线方式,GPS 的数据传输对应在[crayon-5b03c55fe6e46954329495-i/]上,设置正确的波特率后直接 cat 就能看到输出;后一个命令是测试 PPS 信号是否获取正确,注意如果 GPS 没有定位成功是没有 PPS 输出的。 测试成功后先配置 gpsd, 编辑[crayon-5b03c55fe6e4a191229300-i/]文件,设置设备为[crayon-5b03c55fe6e4e121477353-i/]并添加 "-n" 参数,具体可参考 AlpineLinux Wiki. 完成后启动 gpsd ([crayon-5b03c55fe6e51850244601-i/]) 并使用 gpsmon 命令观察是否能正确获取数据。

5. 配置 NTP

编辑 /etc/ntp.conf 文件,将其中的 "server xxx" 保留2-3个,其余全部注释掉,然后添加如下内容: [crayon-5b03c55fe6e56301080729/] 这样配置的具体文档可以参考 NTP 文档。 然后启动 ntp ([crayon-5b03c55fe6e5a450936942-i/]) 等待几分钟后使用 ntpq -p 查看工作状态,正常情况下可以看到类似下面的输出: [crayon-5b03c55fe6e5e800104949/] 对于各列的具体含义见这里的说明,总之结论是从这一输出中获取到 GPS 时间戳和准确时间的偏移值(这个偏移值来自线缆传输、gpsd进程处理等地方)。这个步骤最好等10分钟以上,保证系统已经和一个公网服务器同步完成,延迟和 jitter 都足够小的时候再确定偏移值。 之后我们再次编辑配置文件,改成类似下面这样(设置时钟偏移量、去掉 stratum 指定、设置本机0级时间源为首选): [crayon-5b03c55fe6e63102799070/] 重启 ntp ([crayon-5b03c55fe6e67712082399-i/]) 后等待几分钟,再查看和其它服务器的时钟偏移是否正常即可。 [crayon-5b03c55fe6e6b042091724/]]]>
我一直有一种自建基础服务的兴趣,自从当初机缘巧合混到一个开发者邮箱之后,就一直在尝试自建 NTP 服务,海外已经放了好几台 VPS 到 pool.ntp.org 里面了,但国内条件有限,并没有什么好办法。于是就想到了自建一个。

1. 背景知识

整个 NTP 分发网络的结构是一种近似树状的分层结构,每一级叫做一个 “Stratum”, 其中 Stratum-0 是可靠的参考时间源,比如原子钟、GPS或无线电授时信号源等,所有0级时间源构成了整个 NTP 网络中的参考时钟;在逻辑上,所有0级时间源作为一个整体提供了全世界的标准时钟。不过因为0级时间源本身实际上只是某种形式的时钟信号发生装置,所以它们并不直接对外提供授时服务,而是连接到一些运行着特定软件的服务器上,这些服务器将0级时间源作为参考时钟并与其同步时间,再把自己的系统时间作为参考时钟提供给其它前来查询时间戳的客户端,以此提供授时服务。这些直接以0级时间源为参考时钟的服务器被称作1级时间源(Stratum-1),它们是 NTP 网络中最可信的时间信号来源。1级时间源之间也可能互相作为上游,作为单个0级时间源不可用时候的备份。

按照标准的 NTPd 实现,每台运行 NTPd 的入网设备都同时充当客户端和服务器的角色(当然是可配置的),从上游同步时间的同时,也可供其他客户端用作参考时钟。设备的 Stratum 为其参考时钟的 Stratum 加一,整个网络中 Stratum 的最大值为16. 因为1级时间源有较高的硬件要求,通常网络上提供授时服务的都是2级时间源,也有一部分3级时间源,1级和大于3级的时间源都相对少见。
NTP的分层组织结构
(图自维基百科)

所以网络中能对外提供服务的最高一级服务器就是 Stratum-1 了,在1级时间源上面需要连接一个0级的参考时钟,这个时钟最简单的来源就是 GPS 信号。然而,一般的民用电子设备(这里特指计算机)在运行中由于节能策略和物理限制等等原因,系统时间的流逝并不是严格匀速的,也就是说系统时间的每一秒对应到现实时间并不严格均匀,这就造成系统在运行时间足够长之后会积累相当可观的误差。运行 NTPd 的系统虽然可以周期性地和上级时间源同步来校正系统时间,但从较长的时间尺度上看依然是一个“抖动”的时间轴,单纯供系统自己使用问题不大,而就1级时间源来说,要对外授时质量就不太够了。

主流的解决方案是在系统上引入一个高可靠的周期性信号,作为基础频率让内核保持稳定的时间流逝速率。比如阿里云的公共 NTP 服务就使用的是 GPS (提供时间戳)加上原子钟(保持时间流逝速率)来维持高精度的授时信号。自家用当然不需要那么夸张,市面上的很多 GPS 模块都能输出 PPS (Pulse Per Second) 信号,其稳定性远远高于一般主板上的晶振,一些型号的 GPS 芯片能提供误差小于 50ns 的信号输出,用作大多数授时场景都绰绰有余。

顺便一提,USB 接口的成型 GPS 模块好像基本都不能输出 PPS.

2. 硬件准备

网上有很多用 Respberry Pi 搭建1级时间源的文章,但树莓派裸机加上一些基础毕竟还是要好几百,作为多数时候只能吃灰的玩具来说还是略贵了点。正好去年年中的时候看到了 Orange Pi 的价格和配置,发现实在是白菜,就顺手入了几只。后来更便宜的 NanoPi M1 和 NanoPi Neo 出现之后也分别入手了一两个。这几个东西都是基于全智 H3 CPU 的 ARM 小板子,性能比树莓派要差一些,社区资源也更有限,好在胜在价格便宜。这篇文档是基于 Orange Pi One 来的,后面会简称为 opi.

至于 GPS 模块,我是在淘宝上找了一款有 PPS 输出的裸模块,自己动手把店家附送的引线转接到杜邦线头上,然后就可以插到 opi 的 GPIO 针脚上了。

3. 软件准备

系统我用的是 Armbian Orange Pi One 的 Debian Jessie 镜像,搭配 Linux 3.4.y 内核(用主线内核 4.9 已经可以正常开机,但配置方法和 3.4 区别比较大所以还没去折腾),系统本身的安装和配置有文档说明略去不提,主要的准备工作是:自己编译内核。

具体编译方法可以看官方的说明,只编译内核的话在完成后把生成的若干个 .deb 包放到 opi 上安装然后重启就行了,当然直接自己编译整个镜像也是可以的。这里需要自己编译的主要原因是为了引入 pps-gpio 支持。

方法也很简单,把这里的 .patch 文件放到编译工程对应的 userpatches 目录(

userpatches/kernel/sun8i-default/
)下面就行。

另一项软件准备是编译 NTPd, 因为 Debian 官方源里面的 ntp 包禁用了 PPS 驱动,只能自己重新编译来开启。

mkdir -p ~/debs/ntp && cd ~/debs/ntp
sudo apt-get source ntp
cd ntp-4.2.6.p5+dfsg
vim debian/rules

然后在 configure 参数中加上

--enable-linuxcaps
选项:

./configure CFLAGS='$(CFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' \
                --prefix=/usr \
                --enable-all-clocks --enable-parse-clocks --enable-SHM \
                --enable-linuxcaps \
                --disable-debugging --sysconfdir=/var/lib/ntp \
                --with-sntp=no \
                --with-lineeditlibs=edit \
                --without-ntpsnmpd \
                --disable-local-libopts \
                --enable-ntp-signd \
                --disable-dependency-tracking \
                --with-openssl-libdir=/usr/lib/$(DEB_HOST_MULTIARCH)

可选编辑

debian/changelog
更新版本号和说明。

之后使用

export DEB_BUILD_OPTIONS=nocheck; dpkg-buildpackage -rfakeroot -uc -b
命令编译并打包,依赖提示缺什么就装什么就行了。编译过程在 opi 上会非常缓慢而持久,如果有办法在更好的机器上做交叉编译的话值得一试。

编译完成后会在上层目录生成若干个 .deb 文件,使用

dpkg -i
命令安装之即可。

另外我们还需要 gpsd 来读取和解析 GPS 数据,这个包建议使用

jessie-backports
源,版本足够新,按官方说明添加源后直接
sudo apt-get install gpsd gpsd-clients
搞定。

4. Do Magic!

现在假定所有准备工作已经完成:opi 系统安装完成、联网并运行在正确的内核上,ntp 和 gpsd 包安装完毕,GPS 模块连线引出完成并且有良好信号。

首先到

/boot
下,编辑 scrit.fex 文件,搜索 uart0 字段,确保所有 uart 端口都是启用状态(opi 一共有4个 uart 接口,其中 uart0 供默认控制终端,剩下3个在 GPIO 上):

sudo bin2fex /boot/script.bin /boot/script.fex

[uart1]
uart_used = 1
uart_port = 1
uart_type = 4
uart_tx = port:PG06<2><1><default><default>
uart_rx = port:PG07<2><1><default><default>
uart_rts = port:PG08<2><1><default><default>
uart_cts = port:PG09<2><1><default><default>

完成后保存退出,执行:

sudo fex2bin /boot/script.fex /boot/script.bin

然后编辑

/etc/modules
文件,向其中加入一行 pps-gpio 并保存;然后再编辑(新建)
/etc/modprobe.d/pps-gpio.conf
文件,其内容为:

options pps-gpio gpio_pin=11

关于 GPIO 端口号计算的方法可以参考这篇帖子下面的回复,而具体的引脚定义可以在 Sunxi Wiki 找到。

完成上面两处编辑过后重启系统。如果正常应当有

/dev/ttyS[1-3]
几个串口设备出现;另外可以找到
/dev/pps0
设备并且在 dmesg (
/var/log/messages
) 里面看到类似下面的日志:

Feb  2 02:40:21 pallas kernel: [    3.090904] pps pps0: new PPS source pps-gpio.-1
Feb  2 02:40:21 pallas kernel: [    3.091024] pps pps0: Registered IRQ 11 as PPS source

然后我们来接线:

+-----+----------+----------+---------------+
| GPS | Physical |     GPIO |      Pin Name |
+-----+----------+----------+---------------+
| VCC |        1 |          |         +3.3V |
| PPS |     5/29 | PA11/PA7 | SCL.0/SIM_CLK |
| GND |        6 |          |            0V |
|  RX |        8 |     PA13 |      UART3_TX |
|  TX |       10 |     PA14 |      UART3_RX |
+-----+----------+----------+---------------+

其中 PPS 线的接法,按照网上各种版本各异的基于树莓派的文章,有 GPIO 4/5/18 和物理针脚 18/23 等多种说法,但我全部试过一遍都不行…最后照着 GPIO 针脚定义找相关的说明试出来 opi 的物理针脚 5(对应 GPIO 11)和物理针脚 29(对应 GPIO 7)可用,我也有一块 GPS 模块可以使用物理端口 7(对应GPIO 6)但别的型号都不行。

如果买到的 GPS 模块是 5V 的,把 VCC 接到物理针脚 2 上面就行了。如果需要外接 RTC 建议用 PA7, 避免和 PPS 抢针脚。

接线完成后观察 GPS 是否正常工作,然后在系统中进行相关测试:

allen@pallas:~$ sudo cat /dev/ttyS3
$GPGSV,3,1,12,01,42,178,16,07,63,294,29,08,63,007,25,09,15,234,18*7C
$GPGSV,3,2,12,10,02,066,,11,67,198,,16,20,091,,22,03,158,*7B
$GPGSV,3,3,12,23,05,196,14,27,29,044,18,28,09,298,29,30,29,316,23*74

allen@pallas:~$ sudo ppstest /dev/pps0 
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1485009545.999994434, sequence: 13396 - clear  0.000000000, sequence: 0
source 0 - assert 1485009546.999994875, sequence: 13397 - clear  0.000000000, sequence: 0
source 0 - assert 1485009548.000002813, sequence: 13398 - clear  0.000000000, sequence: 0

按照我上面的接线方式,GPS 的数据传输对应在

/dev/ttyS3
上,设置正确的波特率后直接 cat 就能看到输出;后一个命令是测试 PPS 信号是否获取正确,注意如果 GPS 没有定位成功是没有 PPS 输出的。

测试成功后先配置 gpsd, 编辑

/etc/default/gpsd
文件,设置设备为
/dev/ttyS3
并添加 “-n” 参数,具体可参考 AlpineLinux Wiki.

完成后启动 gpsd (

sudo systemctl start gpsd
) 并使用 gpsmon 命令观察是否能正确获取数据。

5. 配置 NTP

编辑 /etc/ntp.conf 文件,将其中的 “server xxx” 保留2-3个,其余全部注释掉,然后添加如下内容:

server 127.127.28.0 #prefer
server 127.127.22.0 #prefer
fudge  127.127.28.0 refid GPS stratum 9
fudge  127.127.22.0 flag3 1 refid PPS stratum 9

这样配置的具体文档可以参考 NTP 文档

然后启动 ntp (

sudo systemctl start ntp
) 等待几分钟后使用 ntpq -p 查看工作状态,正常情况下可以看到类似下面的输出:

remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
+li461-162.membe 10.84.87.146     2 u   10   16  371   72.431  -14.973   5.654
*2400:8900::f03c 10.84.87.146     2 u    1   16  137  249.315   18.702   4.915
+118.143.17.82   .MRS.            1 u    3   64   51   36.991   -0.460   1.800
+61-216-153-105. 118.163.81.63    3 u  161   64  274   72.461    1.635   2.845
xSHM(0)          .GPS.            9 l   13   16  377    0.000  -125.67   2.718
oPPS(0)          .PPS.            9 l   12   16  377    0.000   -0.011   0.012

对于各列的具体含义见这里的说明,总之结论是从这一输出中获取到 GPS 时间戳和准确时间的偏移值(这个偏移值来自线缆传输、gpsd进程处理等地方)。这个步骤最好等10分钟以上,保证系统已经和一个公网服务器同步完成,延迟和 jitter 都足够小的时候再确定偏移值。

之后我们再次编辑配置文件,改成类似下面这样(设置时钟偏移量、去掉 stratum 指定、设置本机0级时间源为首选):

server 127.127.28.0 prefer
server 127.127.22.0 prefer
fudge  127.127.28.0 time1 +0.126 refid GPS #stratum 9
fudge  127.127.22.0 flag3 1 refid PPS #stratum 9

重启 ntp (

sudo systemctl restart ntp
) 后等待几分钟,再查看和其它服务器的时钟偏移是否正常即可。

remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
xli461-162.membe 103.1.106.69     2 u   15   16  345   65.665  -11.538   4.612
+hygiea.home.atr .PPS.            1 u   15   16  376    0.940    0.452   0.802
*SHM(0)          .GPS.            0 l    8   16  377    0.000   -0.209   2.926
oPPS(0)          .PPS.            0 l    7   16  377    0.000    0.773   0.077
 LOCAL(0)        .LOCL.          10 l    -   64    0    0.000    0.000   0.000

]]>
https://blog.atr.me/NGC437/feed 4 437
一年香 https://blog.atr.me/NGC398 https://blog.atr.me/NGC398#comments Sat, 27 Jun 2015 09:05:42 +0000 http://blog.atr.me/?p=398 更何况入职第二天就是跑千岛湖 outing 去了 alibaba-150626 从高考结束到现在,五年过去了,我觉得我做过的最重要的两个决定分别是出省上大学,和翻墙。从此我的眼界大大开阔,世界观也再不似从前,后者甚至在很大程度上保证了我在那个逼仄的学校能保持仅有的一点思考和见解,否则今天我也不会顶着大公司的光环在这里写闲话。 最近一年代码写得不多,但进步还算不小,Google Oriented Develop 和 SlackOverflow Oriented Develop 果然是快速上手开发实践的捷径。干了半年多没有人做备份的运维,也做过类似 rm -rf /* 的事情险些搞出故障,某种意义上的人生完满了呢... 总之,现在的工作能让我把很多以前在学校闹着玩的事情认真做下去并且计入 KPI, 时间也比较灵活,虽然辛苦,但还是很有趣。后面计划要拿业余时间尝试开始一些之前想了很久,但一直力不从心的小项目,凭我现在的水平,起个头应该能办到了。 唯一的遗憾是,像样的天文观测变少了,相关资讯也没有继续跟进了,八月准备去论坛,提前要复习下才行。 Anyway, 给博客除草的任务已经完成 _(:зゝ∠)_]]> 不知不觉,正式入职已经一年了,现在想起来一年前拿到毕业证的第二天就直接坐高铁杀到杭州,第三天直接办理入职的经历,还是觉得挺好玩。更何况入职第二天就是跑千岛湖 outing 去了
alibaba-150626

从高考结束到现在,五年过去了,我觉得我做过的最重要的两个决定分别是出省上大学,和翻墙。从此我的眼界大大开阔,世界观也再不似从前,后者甚至在很大程度上保证了我在那个逼仄的学校能保持仅有的一点思考和见解,否则今天我也不会顶着大公司的光环在这里写闲话。

最近一年代码写得不多,但进步还算不小,Google Oriented Develop 和 SlackOverflow Oriented Develop 果然是快速上手开发实践的捷径。干了半年多没有人做备份的运维,也做过类似 rm -rf /* 的事情险些搞出故障,某种意义上的人生完满了呢…

总之,现在的工作能让我把很多以前在学校闹着玩的事情认真做下去并且计入 KPI, 时间也比较灵活,虽然辛苦,但还是很有趣。后面计划要拿业余时间尝试开始一些之前想了很久,但一直力不从心的小项目,凭我现在的水平,起个头应该能办到了。

唯一的遗憾是,像样的天文观测变少了,相关资讯也没有继续跟进了,八月准备去论坛,提前要复习下才行。

Anyway, 给博客除草的任务已经完成 _(:зゝ∠)_

]]>
https://blog.atr.me/NGC398/feed 1 398
终于解掉 nginx 在 SSL 下 400 的错误,蠢死了 https://blog.atr.me/NGC394 https://blog.atr.me/NGC394#respond Tue, 31 Mar 2015 16:04:49 +0000 http://blog.atr.me/?p=394 假如配置成如下样子,就可以复现出我遇到的这个问题: [crayon-5b03c55fe93e6940311168/] 其中的 [crayon-5b03c55fe93eb732892865-i/] 是 Tengine 的功能,用来自动判断链接是否为 SPDY 协议,原生 nginx 应该是不支持的。 在这个配置下使用 IPv6 访问 80 端口的时候就会出现 400 错误,看 debug 日志里面的报错是说普通 http 流量发到了 https 端口上,但特么的 80 就是 http 端口啊!所以这是服务器解析配置之后的行为有差异造成的。 当把 http 和 https 的监听语句分别写到两个不同的 [crayon-5b03c55fe93f0126401707-i/] 块里面的时候,这两个虚拟主机相互独立,用这样的配置不会有问题。在配置到同一个虚拟主机的情况下,服务器会通过 [crayon-5b03c55fe93f4716819995-i/] 语句后面指定的不同标签判断对应的协议情况,比如加上 [crayon-5b03c55fe93f8895372971-i/] 就意味着这是一个开启 https 的端口,不加就按照默认的 http 来。到这里为止至少在 IPv4 下服务器的行为还是符合预期的。 问题在于对 IPv6 的设置,下面的 [crayon-5b03c55fe93fc150204299-i/] 会覆盖掉监听语句的配置,即将整个虚拟主机都开启 https 协议,所以这个时候在 [::]:80 上面监听的是一个 https 服务器,这特么... 于是解决方法也很简单了,去掉 [crayon-5b03c55fe9400609004049-i/] 这一行就搞定。所以说蠢死了我。 比较奇怪的是这个问题只在 IPv6 下存在,上面的配置放在 IPv4 环境中没有任何问题,当初这个配置也是不知道从哪里抄了一份一直反复修改用到现在的,从来没出过问题所以直觉想不到这里去,直到我尝试在 IPv6 上也配置 ssl 访问... -- UPDATE 2017-09-26 -- 今天看到了这个issue, 里面具体解释了这一现象的原理。]]> 这个问题持续了得有超过一年了,症状很简单,配置了 https 访问之后,使用 IPv6 访问的时候会报 400 Bad Request 错误,强制使用 IPv4 或者强行指定 https 协议都能解决。说到这里应该很明显了对吧,首先就应该想到是不是 80 端口上也开着 ssl 来着。但这个讨厌的地方在于用 IPv4 就一切正常了,我一直没想那么多……就因为这我的博客很长时间都没办法强制 https 访问,不然 IPv6 过来的用户没法看。

前两天搞着搞着调另一个什么反向代理相关的设置的时候,顺手开了 debug 日志,然后就想顺便测一把,结果一不小心就找到了原因_(:зゝ∠)_

长话短说,问题的根本原因是普通 http 协议和加密的 https 协议配置在了一个

server{}
块内。并不是说不支持这样搞,而是这样配置过后服务器的行为会和分开配置成两个有所不同。

假如配置成如下样子,就可以复现出我遇到的这个问题:

server {
        server_name blog.atr;
        index index.html index.htm index.php;
        root /srv/http/blog.atr.me;

        listen 80 spdy_detect;
        listen [::]:80 spdy_detect;
        listen 443 ssl spdy_detect spdy;
        listen [::]:443 ssl spdy_detect spdy;
        ssl    on;
        ssl_certificate     /srv/ssl/atr.me.crt;
        ssl_certificate_key /srv/ssl/atr.me.key;
        ......
    }

其中的

spdy_detect
是 Tengine 的功能,用来自动判断链接是否为 SPDY 协议,原生 nginx 应该是不支持的。

在这个配置下使用 IPv6 访问 80 端口的时候就会出现 400 错误,看 debug 日志里面的报错是说普通 http 流量发到了 https 端口上,但特么的 80 就是 http 端口啊!所以这是服务器解析配置之后的行为有差异造成的。

当把 http 和 https 的监听语句分别写到两个不同的

server{}
块里面的时候,这两个虚拟主机相互独立,用这样的配置不会有问题。在配置到同一个虚拟主机的情况下,服务器会通过
listen
语句后面指定的不同标签判断对应的协议情况,比如加上
ssl
就意味着这是一个开启 https 的端口,不加就按照默认的 http 来。到这里为止至少在 IPv4 下服务器的行为还是符合预期的。

问题在于对 IPv6 的设置,下面的

ssl on;
会覆盖掉监听语句的配置,即将整个虚拟主机都开启 https 协议,所以这个时候在 [::]:80 上面监听的是一个 https 服务器,这特么…

于是解决方法也很简单了,去掉

ssl on;
这一行就搞定。所以说蠢死了我。

比较奇怪的是这个问题只在 IPv6 下存在,上面的配置放在 IPv4 环境中没有任何问题,当初这个配置也是不知道从哪里抄了一份一直反复修改用到现在的,从来没出过问题所以直觉想不到这里去,直到我尝试在 IPv6 上也配置 ssl 访问…

— UPDATE 2017-09-26 —
今天看到了这个issue, 里面具体解释了这一现象的原理。

]]>
https://blog.atr.me/NGC394/feed 0 394
一点点近况 https://blog.atr.me/NGC364 https://blog.atr.me/NGC364#comments Mon, 11 Aug 2014 23:04:29 +0000 http://blog.atr.me/?p=364 ]]> 距离上次更新博客已经一年多了,中间只有从 flicker 同步的贴图在刷着… 这一年多好像没什么好写的,但实际发生了很多,难道说博客写久了不再有耐心?或者更靠谱的说法大概是太现充以至于无暇来慢慢写博客了吧。

去年5月,我还没上大四,申请 GSoC 2013 刚刚提交都不知道结果,转眼一看,现在我已经毕业三个月、艰难地啃着 GSoC 2014 的项目;时间还真是过得快呢。这一年当中我买了单反,考研233,找到了工作,甚至感情状态都修改了两次,居然连13年年终总结都没有写。要说有意义的活动,大概去年暑假参加广州的第四届天文发展论坛算比较典型的了,好歹算是出远门。另外和天南大一起蹭天津天文节的观测去考察了一下第五届论坛的观测地,也是效果拔群的一次经历,话说不知道是不是那时候把人品用完了,第五届论坛的观测日我夜班,正好没法去蹭会。

说回毕业出路这边,之前考研的时候基本上没怎么认真复习,迷迷糊糊就去了,果然是载在数学,最后拿了个超级233的233分,默默滚回开始写简历找工作。中间面试了好几家还算靠谱的公司,也遇到递上简历就被鄙视的情况,最后居然靠着一份内推异常顺利地进了阿里,说实话大大出乎了我自己的意料。结果你看,现在我就用公司的网趁着夜班的最后两个小时写博客了。

如果回顾一下过去的几年,似乎高考是我的一次低谷而大学毕业成了一处高峰,也不知道这个峰和当年通过自主招生以及第一次拿到 GSoC 的参加资格相比高低如何,但似乎它们加起来能够填平高考志愿的大坑了。大学四年待在逼仄的小城廊坊,却因为离家千里习惯了一个人四处奔忙,又碰巧学校有一个刚发展起来不久的天文协会,机缘巧合我成了协会高速发展时期的骨干成员,认识了一大帮专业和非专业的天爱同好,习惯了熬夜学会了流星雨标观,这不,英仙极大期我在通宵值夜班来着_(:зゝ∠)_

于是我该说当初志愿失手去了莫名其妙的学校是幸运还是不幸呢?

哪会有答案的啦,这种事情…

]]>
https://blog.atr.me/NGC364/feed 4 364
To Enrich myLife https://blog.atr.me/NGC266 https://blog.atr.me/NGC266#comments Sun, 26 May 2013 12:59:09 +0000 http://blog.atr.me/?p=266 ]]> 阴天教前天换届了…淋着打伞觉得没必要不打又觉得不爽的毛毛雨,提着湿漉漉的伞回到寝室,磨磨蹭蹭把电脑打开一看,错误691,上网帐号欠费了。
把手机卡卸出来用毕竟只能是应急的,就算是3G也实在用着苦逼,于是哈欠连天地想着干脆写博客消磨时间好了。

周四晚上收到邮件说25号下午组织两场模拟口试,可以去先行体验,然后正好又拿到了普通话考试的准考证,和口试时间一模一样:26号09:00. 于是就没什么好犹豫的了,周五和母上打电话汇报了一声,然后就买了第二天上午去天津的票,接着顺手定了个房间。

坐着普快一路到天津站,出来转地铁,然后走路,然后迷路,然后绕路…然后在终于对股沟地图给的建议路线绝望继而打电话给7天前台问地址的时候,就看到他们的招牌了…给了我个一楼的房间,稍有点不爽,结果进去过后发现整个旅店是一个独院,所以完全没什么问题。
东西放好打开电脑把18封新邮件点掉,随便翻了翻网页,把网站上的口试示例录像下下来看了一下发现考试方式和想象中有比较大的出入,然后就关机出门了。在楼下的兰州拉面随便吃了午饭,再度迷路之后还是提前了半个小时到考场门口,于是就坐着等。
进去过后倒是一切顺利。机房里面的新耳麦话筒音量太小了,后来发现屏幕后面放了个旧耳麦也是可以用的,所以就把旧耳麦的线拉到前面放在面前,变成了两个话筒同时用,效果就好多了。测试的时候和右边隔着走廊那个人分到了一组,一个 Civil 什么什么学校的男生,貌似是青年政治学院?表示不清楚,不过他的口语挺不错,或者说是和我相当的水平把,而且有明显的想要控场的倾向,交流起来倒是不费力。实际上说到一半我们两个分别笑场了…
模拟口试过后更是直接就对着笑出来了。

出来过后顺着南开那条路往外走,还看到树上一直啄木鸟。
门口买了瓶水,然后就在过街天桥下面阴影处站着等顺孃,一不小心把一瓶矿泉水喝完了。然后才发现远处有个开封菜,慢悠悠晃过去刚想蹭个厕所结果一个电话说到了,不过还是上了厕所才出去。说起来那家开封菜就是去年去观测的时候我们一群人吃完饭的地方来着,进去过后突然反应过来的。
唔…顺孃基本上没啥变化的感觉…
于是,天津地陪顺孃带着我去啥文化中心之类的地方转了一圈,到科技馆里面转到闭馆才出来…之后转转转不知道吃什么干脆找了个咖啡店坐下来,结果两个人各点了一大杯茶…然后就是顺孃交代任务什么的了,倒是挺轻松,毕竟六年的老同学了相处还是很自在的…后来随便找了个香锅吃了一顿,把顺孃送上公交就晃晃晃回去了。
回了房已经基本上不想动了,但实在身上难受,进去洗了个澡,出来正准备 osu! 一阵消磨时间母上打电话慰问,简单说了几句,回去 osu! 发现完全没手感,就刷刷网页看了一话炮姐过后直接十点半滚床裸睡了。
想一想很少比二二还睡得早的样子。

今天早上本来定的六点四十的闹钟,结果四点过就醒了一次,五点半又醒了一次,上了个厕所接着回去睡,六点半的时候觉得差不多可以起来了就起来了。醒的时候浑身酸痛,清醒过后反而倒好了。起来过后开电脑稍微刷了下,烧水冲了杯咖啡,然后就收拾东西去考试了。
结果没有迷路,比预想的到得早,就在之前那家开封菜吃了个6块钱的早餐又坐了十多分钟,才慢慢进南开去。

正式考试坐我左边那个女生来的有点晚,然后笨手笨脚不会搞那个考试系统…后来看到身份证号比我大8天,和娄娄是一天的…所以就不能称呼成妹子啦。开始前稍微闲聊了一会,后来并不是很意外地分在一个组,所以考试的时候也还算是有点心理准备地在互相配合了。她说她四级610六级523, 不过后来考试的时候感觉口语上还是口音有点重…淮海大学大二学数学的,地方比我还远,然后学纯理科的女生…真的是…给我很厉害的感觉呢。
至于题目,我们这组一直是围绕的 Enrich Life 的主题在编,所以这篇日志是这个名字了…简单说来我抽到的命题是 Ways to enrich life: Travel More 然后她的是 Read More. 后来 Argue 的时候她先发言,果断选了相对好说一些的 Having a rich life is more important than being rich, 不过反过来也不是就多难就是了,我基本上有点辩论地感觉还是一起把四分半给说完了。
考完过后还互相留了电话什么的。

之后就是回旅馆了,路上就开始有点下雨,所以走得挺快,回去过后用他们的网把 Arch 给顺手更新了一下…这一下就是半个多小时…然后关机收东西退房走人。
去大悦城还是很顺利,到了过后也不是很麻烦就见到了 @SidneyZhang 童鞋,以前一直以为比我小的,结果一看到真人发现应该至少比我大了两三岁的样子…不过炸馒头一直没回短信不接电话不知道怎么回事,于是我们就两个人吃了顿意面然后散伙了。
后来在去南站的路上接到电话,才知道炸馒头同志看球所以睡过了…莫名喜感是怎么回事…嘛,被道歉了反而有点不好意思的感觉…
在南站候车的时候发现北上的高铁全部晚点,推上去问了下得知山东和苏北大暴雨,于是到人人上去 @ 了一下某邪教组织,结果人家没搭理我…

然后就是一路雨兮兮地回来了,然后发现没网,然后就在这里码字了…

总的来说还是挺不错的经历,到处转转虽然累但是很开心,就跟我的口试题目一样的,真是 enrich my life by travel more.

]]>
https://blog.atr.me/NGC266/feed 1 266
三七二十一 https://blog.atr.me/NGC262 https://blog.atr.me/NGC262#comments Sun, 05 May 2013 17:04:06 +0000 http://blog.atr.me/?p=262 ]]> 总觉得还是应该保持每年生日一篇博客的习惯。
二十一岁,突然感觉自己……原来已经长这么大了啊……

嗯,说说近况吧,基本上就是社团这头基本上可以脱手了,另一边GSoC刚交了申请还不知道会是个什么展开。

暂时好像也没什么了,我很好,勿念。
祝我生日快乐

]]>
https://blog.atr.me/NGC262/feed 5 262
Apache + Varnish + nginx 获取正确的客户端IP https://blog.atr.me/NGC257 https://blog.atr.me/NGC257#comments Tue, 16 Apr 2013 15:02:23 +0000 http://blog.atr.me/?p=257 Apache + nginx 的构架。今天折腾一下午 + 一晚上总算是把这个问题(还算)圆满地解决掉了。 首先是参考这篇文章配置好整个服务器构架,后端使用 Apache httpd 来处理 PHP, 中间用 Varnish 做缓存,前端使用 Tengine 作为 web 服务器,所以来自客户端的请求的处理流程是:
Client -> Tengine:80 -> Varnish:8090 ->(Miss)-> httpd:81
然后问题就来了,处在最后面的 httpd 拿不到正确的客户端IP地址,总是显示为127.0.0.1. 这个问题有趣在于,一直以来我都是使用了 mod_rpaf 来获取 X-Forwarded-For 中的客户端IP的,而如果我去掉中间那一层 Varnish 直接让 Tengine/nginx 反向代理给 httpd 的话,IP地址是能够正确获取的,更进一步实验表明,在只有一次代理的情况下一切都是正常的,当代理变成了两层,无论两层代理的顺序如何,都会出现这个问题。 中间各种股沟各种查文档就[此处省略6小时]了... 基本上有两个比较主要的原因。 1. X-Forwarded-For 在经过了多个代理服务器后会变成一个IP列表,形如:X-Forwarded-For: client, proxy1, proxy2; 2. mod_rpaf 只会从 X-Forwarded-For 列表的最右侧取出IP地址,所以代理超过一层的时候就无法取到客户端IP而是把上一层代理的IP当成客户端了。 解决办法也很简单,从 2.3 版开始,Apache 官方提供了一个 mod_remoteip 模块,而且在 2.4 版本中已经默认集成并开启。而对于 2.2 版本,也有第三方自制的兼容版本。 参照说明编译安装好模块: [crayon-5b03c55fe9b66456191371/] 完成过后,在 httpd.conf 中加上: [crayon-5b03c55fe9b6e739108299/] 别忘了把 mod_rpaf 的给去掉避免冲突。 如果你和我一样是拿 ArchLinux 做生产环境的倒霉孩子(呵呵),也可以直接用我打的AUR包: https://aur.archlinux.org/packages/mod_remoteip/ 最后重启 httpd 使模块载入即可。]]>
貌似现在只要我更新博客就说明又在没事瞎折腾了… =.=
很久以前就遇到过这个问题,或者不如说实际上就是因为无法正确获取客户端IP才让我一直用的 Apache + nginx 的构架。今天折腾一下午 + 一晚上总算是把这个问题(还算)圆满地解决掉了。

首先是参考这篇文章配置好整个服务器构架,后端使用 Apache httpd 来处理 PHP, 中间用 Varnish 做缓存,前端使用 Tengine 作为 web 服务器,所以来自客户端的请求的处理流程是:

Client -> Tengine:80 -> Varnish:8090 ->(Miss)-> httpd:81

然后问题就来了,处在最后面的 httpd 拿不到正确的客户端IP地址,总是显示为127.0.0.1. 这个问题有趣在于,一直以来我都是使用了 mod_rpaf 来获取 X-Forwarded-For 中的客户端IP的,而如果我去掉中间那一层 Varnish 直接让 Tengine/nginx 反向代理给 httpd 的话,IP地址是能够正确获取的,更进一步实验表明,在只有一次代理的情况下一切都是正常的,当代理变成了两层,无论两层代理的顺序如何,都会出现这个问题。

中间各种股沟各种查文档就[此处省略6小时]了…

基本上有两个比较主要的原因。

1. X-Forwarded-For 在经过了多个代理服务器后会变成一个IP列表,形如:X-Forwarded-For: client, proxy1, proxy2
2. mod_rpaf 只会从 X-Forwarded-For 列表的最右侧取出IP地址,所以代理超过一层的时候就无法取到客户端IP而是把上一层代理的IP当成客户端了。

解决办法也很简单,从 2.3 版开始,Apache 官方提供了一个 mod_remoteip 模块,而且在 2.4 版本中已经默认集成并开启。而对于 2.2 版本,也有第三方自制的兼容版本

参照说明编译安装好模块:

apxs -i -c -n mod_remoteip.so mod_remoteip.c

完成过后,在 httpd.conf 中加上:

LoadModule remoteip_module modules/mod_remoteip.so
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 127.0.0.1

别忘了把 mod_rpaf 的给去掉避免冲突。

如果你和我一样是拿 ArchLinux 做生产环境的倒霉孩子(呵呵),也可以直接用我打的AUR包: https://aur.archlinux.org/packages/mod_remoteip/

最后重启 httpd 使模块载入即可。

]]>
https://blog.atr.me/NGC257/feed 4 257
写了个简单的 shadowsocks 退出自动重启脚本 https://blog.atr.me/NGC255 https://blog.atr.me/NGC255#comments Sat, 06 Apr 2013 09:26:20 +0000 http://blog.atr.me/?p=255 screen在 VPS 上跑 shadowsocks, 不过时不时会退出然后需要我上去重启,很麻烦,于是就搞了个定时检测 shadowsocks 是否在运行,如果没有就自动重启的脚本。 [crayon-5b03c55feaa3d822391328/] 然后在cron任务里面写上一句 [crayon-5b03c55feaa48458569034-i/] 就可以每分钟自动执行了,而且这样还能变相实现开机自动启动,所以就算服务器意外重启也不怕了。 如果觉得异常退出过后一分钟启动的间隔太长,当然也可以写成死循环: [crayon-5b03c55feaa4f534653124/] 就可以每5秒检查一次了,但这样一来就不是用cron了,可以在/etc/rc.local添加 [crayon-5b03c55feaa55974146332-i/] 来执行启动脚本。 反正我一开始的时候跑死循环跑了两天造成系统负载过高被服务商警告了,想用这个方法的自己慎重。]]> screen在 VPS 上跑 shadowsocks, 不过时不时会退出然后需要我上去重启,很麻烦,于是就搞了个定时检测 shadowsocks 是否在运行,如果没有就自动重启的脚本。

pids="$($_CMD pgrep ss-server)"
if [ ! $pids ]; then
        screen -dmS shadowsocks /some/path/ss-server -p port -k password
fi

然后在cron任务里面写上一句

*/1 * * * * root bash /some/path/autostart.sh
就可以每分钟自动执行了,而且这样还能变相实现开机自动启动,所以就算服务器意外重启也不怕了。

如果觉得异常退出过后一分钟启动的间隔太长,当然也可以写成死循环:

while true:
do
pids="$($_CMD pgrep ss-server)"
if [ ! $pids ]; then
        screen -dmS shadowsocks /some/path/ss-server -p port -k password
fi
wait 5;
done

就可以每5秒检查一次了,但这样一来就不是用cron了,可以在/etc/rc.local添加

bash /some/path/autostart.sh
来执行启动脚本。

反正我一开始的时候跑死循环跑了两天造成系统负载过高被服务商警告了,想用这个方法的自己慎重。

]]>
https://blog.atr.me/NGC255/feed 8 255
从 MySQL 迁移到 MariaDB https://blog.atr.me/NGC251 https://blog.atr.me/NGC251#comments Tue, 26 Mar 2013 15:17:53 +0000 http://blog.atr.me/?p=251 ...)"[?] ArchLinux 昨天宣布将使用 MariaDB 作为 MySQL 的默认提供包,openSUSE 已经在新近发布的12.3版中默认使用 MariaDB, 连 Fedora 也正在考虑更换为 MariaDB. 于是我决定把我的所有服务器从 MySQL 迁移到 MariaDB. 对 Arch 用户来说很简单,照着官方新闻里面的来就是了: [crayon-5b03c55feba21034544211/] 而对于 openSUSE 就更傻瓜式了,毕竟是默认的嘛: [crayon-5b03c55feba2c955361052-i/] 一句就够。 至于 Debian/Ubuntu 用户就要稍微复杂一些,不过整个过程还是很流畅的: 首先到 MariaDB 官方的 Repository Configuration Tool 去选一个合适的源,然后把给出来的地址放到 /etc/apt/sources.list 文件底部: [crayon-5b03c55feba34693441361/] 接下来执行以下命令: [crayon-5b03c55feba3a183074961/] 于是 MySQL(或者 Percona)就自动卸载并且替换成 MariaDB 了,在某些具体环境下,可能还需要执行这些命令: [crayon-5b03c55feba41380910571/] 然后就搞定了!尽情折腾吧 :)]]> “Because Oracle is Oracle is Oracle()”[?]

ArchLinux 昨天宣布将使用 MariaDB 作为 MySQL 的默认提供包,openSUSE 已经在新近发布的12.3版中默认使用 MariaDB, 连 Fedora 也正在考虑更换为 MariaDB.

于是我决定把我的所有服务器从 MySQL 迁移到 MariaDB.

对 Arch 用户来说很简单,照着官方新闻里面的来就是了:

systemctl stop mysqld
pacman -S mariadb libmariadbclient mariadb-clients
systemctl start mysqld
mysql_upgrade -p

而对于 openSUSE 就更傻瓜式了,毕竟是默认的嘛:

zypper in mariadb
一句就够。

至于 Debian/Ubuntu 用户就要稍微复杂一些,不过整个过程还是很流畅的:

首先到 MariaDB 官方的 Repository Configuration Tool 去选一个合适的源,然后把给出来的地址放到 /etc/apt/sources.list 文件底部:

# ...

# MariaDB 5.5 repository list - created 2013-03-26 14:20 UTC
# http://mariadb.org/mariadb/repositories/
deb http://mirror2.hs-esslingen.de/mariadb/repo/5.5/debian squeeze main
deb-src http://mirror2.hs-esslingen.de/mariadb/repo/5.5/debian squeeze main

接下来执行以下命令:

apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db
apt-get update
apt-get install mariadb-server mariadb-client

于是 MySQL(或者 Percona)就自动卸载并且替换成 MariaDB 了,在某些具体环境下,可能还需要执行这些命令:

apt-get autoremove
apt-get upgrade # or apt-get dist-upgrade
mysql_upgrade -p

然后就搞定了!尽情折腾吧 :)

]]>
https://blog.atr.me/NGC251/feed 2 251
解决一个 embrr 不能翻页的 PHP 配置问题 https://blog.atr.me/NGC247 https://blog.atr.me/NGC247#respond Wed, 06 Mar 2013 15:39:41 +0000 http://blog.atr.me/?p=247 把停止更新的 embr 给升级到 Twitter REST API v1.1, 然后今天参考黄飘飘的改动把 fav 相关的两个地方弄上了自动翻页。 因为 api 更新的关系,不能用原来的页码作为参数,只能用推文的 id 来做界定了,不过操作起来倒是比想象的还要简单就是了。修改好过后传到 appfog 上木有任何问题,但放到我自己的服务器上面过后发现翻页不能了... 开始还以为是 nginx 配置不对,但看了半天找不到问题,于是考虑是不是 PHP 的问题... 简单找了一下,发现问题在于生成的翻页链接上,因为推文 id 被作为参数传到链接里面,而生成的链接变成了类似于 [crayon-5b03c55fec599222845287-i/] 这样的形式...科学计数法耶... 不过话说我居然一下就能猜到问题所在还是真不错... 修改 php.ini 文件: [crayon-5b03c55fec5a2619424850/] 只要把设置成超过18的值就可以了(默认是14),twitter 的推文 id 居然都18位了也真是惊人... 然后就好了......]]> 唔…大致说来就是最近在折腾着把停止更新的 embr 给升级到 Twitter REST API v1.1, 然后今天参考黄飘飘的改动把 fav 相关的两个地方弄上了自动翻页。

因为 api 更新的关系,不能用原来的页码作为参数,只能用推文的 id 来做界定了,不过操作起来倒是比想象的还要简单就是了。修改好过后传到 appfog 上木有任何问题,但放到我自己的服务器上面过后发现翻页不能了…
开始还以为是 nginx 配置不对,但看了半天找不到问题,于是考虑是不是 PHP 的问题…

简单找了一下,发现问题在于生成的翻页链接上,因为推文 id 被作为参数传到链接里面,而生成的链接变成了类似于

/favor.php?max_id=2.9972877531744E+13
这样的形式…科学计数法耶…

不过话说我居然一下就能猜到问题所在还是真不错…
修改 php.ini 文件:

; The number of significant digits displayed in floating point numbers.
; http://php.net/precision
precision = 24

只要把设置成超过18的值就可以了(默认是14),twitter 的推文 id 居然都18位了也真是惊人…

然后就好了……

]]>
https://blog.atr.me/NGC247/feed 0 247
新装系统 Win8 与声卡那点纠结的记录 https://blog.atr.me/NGC234 https://blog.atr.me/NGC234#comments Wed, 23 Jan 2013 06:07:47 +0000 http://blog.atr.me/?p=234 ]]> 好吧我换系统了,因为换了个新硬盘神马的。然后就想着干脆装 Win8 吧。

装系统一切都好,什么都很正常很顺利那样,结果完了我想看番的时候发现…耳机没声音……
囧死了好吧。

长话短说,试过了网上提到的多种方法,有些是用了无解,有些是不适用我的情况。

我的声卡是 Reltek ALC 269 机子是华硕 N53Jf.

折腾一整天,重装三次系统之后,问题确定:Reltek 官方驱动与 Win8 不兼容。
是滴你没看错,最新版写着支持 Windows 8 的那个也不行,只有外放有声音耳机不行。

解决方案是装好系统过后静置,等系统自己联网下载微软的驱动。

真疼。

]]>
https://blog.atr.me/NGC234/feed 2 234
慎用 Afraid.org 提供的免费 DNS 服务 https://blog.atr.me/NGC230 https://blog.atr.me/NGC230#comments Wed, 09 Jan 2013 05:22:25 +0000 http://blog.atr.me/?p=230 freedns.afraid.org 是一个非常优秀和好用的免费 DNS 服务商,我自己用了超过两年,现在也还有几个不怎么好的域名在上面。 这家的优点是:界面简单明了、解析记录种类较全、新记录生效极快以及服务稳定。 那我为啥要说慎用呢?因为昨天我终于搞清楚了一个以前一直没在意的功能的含义... 对于所有注册用户,可以免费添加若干域名到 afraid 的解析系统当中,设置解析记录等等。但是,免费用户会被强行开启一个功能叫做 shared:public. 付费用户才可以设置为 shared:private. 因为并不影响使用,我一直都没有在意这个功能到底是啥,直到昨天才发现,将共享设置为公开意味着整个系统中的全部注册用户都可以使用这个域名。 没图我说个丁丁? freedns 那个 litgh 是我,别的么...你认识吗? 可以看到,这是个比较短的域名,所以就比较引人兴趣,所以就有一些别的用户使用了这个域名来设置自己的子域。当然这个域名已经给 @lty1993 了,只是因为我自己的另外几个被很多人使用的域名已经转走了所以只能拿这一个做个示范。 好吧,如果是一般的域名被人拿来弄两个随机串的子域我也不觉得有什么,但是我昨天在我的域名 ntr.la 下面发现了这样一条解析记录: [crayon-5b03c55fecab1192050581/] 解析结果是一个...中!文!垃!圾!站!!! 尼玛这要我怎么忍?我辛辛苦苦找到,自己出钱养着的域名,被人莫名其妙拿来做垃圾站做广告站?呵呵... 顺便说一下,别人已经建好的记录是域名所有人是没办法删除的哦亲~域名所有人的唯一特权就是可以从系统中删除这个域名。 所以,如果有比较好的域名,不希望有别人使用,或者对 SEO 非常敏感的同志们,请慎重考虑是否使用 freedns.afraid.org 的服务。 域名一般并且无所谓一两个奇怪的子域的就没什么了,而且其实不怎么样的域名基本上也不会有别的用户用... 想找免费二级域名的...这是个宝库哦~~ 然后... 免费 DNS 这种东西也不是只有你们家才有嘛: - 大部分域名注册商会提供简单的 DNS 功能; - CloudFlare - ZoneEdit - PointHQ - he.net - 甚至还可以自己架设 DNS 服务器]]> 首先要明确的是 freedns.afraid.org 是一个非常优秀和好用的免费 DNS 服务商,我自己用了超过两年,现在也还有几个不怎么好的域名在上面。
这家的优点是:界面简单明了、解析记录种类较全、新记录生效极快以及服务稳定。

那我为啥要说慎用呢?因为昨天我终于搞清楚了一个以前一直没在意的功能的含义…

对于所有注册用户,可以免费添加若干域名到 afraid 的解析系统当中,设置解析记录等等。但是,免费用户会被强行开启一个功能叫做 shared:public. 付费用户才可以设置为 shared:private.
因为并不影响使用,我一直都没有在意这个功能到底是啥,直到昨天才发现,将共享设置为公开意味着整个系统中的全部注册用户都可以使用这个域名

没图我说个丁丁?
freedns
那个 litgh 是我,别的么…你认识吗?

可以看到,这是个比较短的域名,所以就比较引人兴趣,所以就有一些别的用户使用了这个域名来设置自己的子域。当然这个域名已经给 @lty1993 了,只是因为我自己的另外几个被很多人使用的域名已经转走了所以只能拿这一个做个示范。

好吧,如果是一般的域名被人拿来弄两个随机串的子域我也不觉得有什么,但是我昨天在我的域名 ntr.la 下面发现了这样一条解析记录:

bbs.ntr.la    IN    A    75.126.208.171

解析结果是一个…中!文!垃!圾!站!!!
尼玛这要我怎么忍?我辛辛苦苦找到,自己出钱养着的域名,被人莫名其妙拿来做垃圾站做广告站?呵呵…

顺便说一下,别人已经建好的记录是域名所有人是没办法删除的哦亲~域名所有人的唯一特权就是可以从系统中删除这个域名。

所以,如果有比较好的域名,不希望有别人使用,或者对 SEO 非常敏感的同志们,请慎重考虑是否使用 freedns.afraid.org 的服务。
域名一般并且无所谓一两个奇怪的子域的就没什么了,而且其实不怎么样的域名基本上也不会有别的用户用…
想找免费二级域名的…这是个宝库哦~~

然后…
免费 DNS 这种东西也不是只有你们家才有嘛:
– 大部分域名注册商会提供简单的 DNS 功能;
CloudFlare
ZoneEdit
PointHQ
he.net
– 甚至还可以自己架设 DNS 服务器

]]>
https://blog.atr.me/NGC230/feed 5 230
结束与起始之年 – 2012回览 https://blog.atr.me/NGC228 https://blog.atr.me/NGC228#respond Sat, 29 Dec 2012 18:34:10 +0000 http://blog.atr.me/?p=228 ]]> 惯例的年终总结,惯例的流水总帐。

2012年是结束之年。
结束了我在学生会的工作,也在长长的痛苦过后接受了初恋的失败。当然,世界本身也已经在12月21日终止。
2012年也是起始之年。
我开始了真正和天文圈内的接触,开始了真正的天文观测,也找到了新的牵挂。

2012年,我去过的城市有:
成都、北京、天津、廊坊、沈阳、武汉、威海、青岛、济南、西安

2012年,我参与过的天文观测有:
3月24日天津静海梅西耶马拉松
6月6日沈阳五里河金星凌日
8月13日文登圣经山英仙座流星雨
10月6日密云石塘路天龙座流星雨
11月17日密云石塘路狮子座流星雨

2012年,我开始稳定接触的游戏有:
osu!
Minecraft

2012年,其它值得我罗列的事件有:
4月,GSoC落选
7月2日,特殊的失眠
8月9日,第三届全国天文社团发展论坛
8月15日,中国海洋大学半日游,一段长长的往事和一个难以割舍的心结的结束

总之,2012于我,是罕见的充实的一年,心境的低谷、回复,眼界的扩大、经历的丰富,这一切,必会成为我生命中珍贵的元素。

于是,在这个末世之年,我与新的世界一同,出发了。

]]>
https://blog.atr.me/NGC228/feed 0 228
使用 Trac + git + cherokee 搭建私有版本库 https://blog.atr.me/NGC224 https://blog.atr.me/NGC224#respond Thu, 06 Dec 2012 10:51:05 +0000 http://blog.atr.me/?p=224 Trac 是一个专为软件开发设计的集问题追踪和 wiki 系统于一体的网页软件,git 是一个灵活而强大的版本控制工具,而 cherokee 则是一款简单好用的 web 服务器,当然,三者都是开源的。另外,这里选用 cherokee 而不是 nginx 或者 apache 这一类更为主流的服务器是因为 cherokee 的网站和默认页面比较好看所以想干脆来装逼一下这种事情我是不可能在教程里面说的。 为了搞好这个我折腾了一天,翻看了好多文档和教程,试了多种方法,最后是用的文档上没有提到的一种组合。之所以这样是因为按照文档进行设置一直不成功... 我所用的系统是 Ubuntu 11.10 64bit, 用 12.04 的话 cherokee 的管理面板一直打不开所以用的这个...同时也就意味着这份教程理论上适用于 Debian/Ubuntu 以及所有以此为基础的系统,比如 Mint 等,但是当然,我没办法做任何保证,而且一些细节的配置也可能需要根据具体情况进行修改。 新系统装好过后先卸掉不需要的包以及更新,具体命令可以参考这里,下面直接开始进行版本库的安装和配置。
  • 首先我们要安装 git 并添加用户
  • [crayon-5b03c55fed5ba620262864/] 注意在给 git 用户设置密码或者配置密钥之前这个用户是实际上没办法使用的。
  • 接下来安装 Trac:
  • [crayon-5b03c55fed5c2650810234/] 随后我们需要新建一个 trac 用户并添加到 git 用户组,这样好让 Trac 有管理 git 仓库的权限: [crayon-5b03c55fed5c6704043594/] 接下来就可以初始化我们的第一个 Trac 项目了: [crayon-5b03c55fed5ca651679182/] 这里我们新建了一个名叫 myproject 的项目,这个是 trac 的环境目录名称,命令执行中会要求输入项目名称,输入的这个随后可以修改。 另外本教程以只建立一个 trac 项目为例,如果需要多项目请参照官方文档调整配置。 现在最基本的 trac 配置就已经完成了,可以执行 [crayon-5b03c55fed5ce838304300-i/] 来启动 tracd 进程,访问 http://trac.example.com:8000 就能看到一个 Trac 的默认页面了。 下一步是给 Trac 添加上一个简单的认证,否则是没办法登录进行管理的。 [crayon-5b03c55fed5d2880656471/] 此时再访问 http://trac.example.com:8000 并点击右上角的 login 就可以登录后台了。
  • 接下来安装 cherokee 作为前端:
  • [crayon-5b03c55fed5de848510453/] 此时访问 http://trac.example.com 就可以看到 cherokee 的默认界面了。 需要注意的是,和大多数 web 服务器不同,cherokee 并不需要用户自己编辑配置文件,而是自带了一个管理后台,我们使用下面的方法来进入后台并配置其与 Trac 一同工作。 首先在 console 中执行以下命令: [crayon-5b03c55fed5e2324985616/] 会出现类似这样的提示: [crayon-5b03c55fed5e6442460512/] 使用提供的用户名和密码就可以通过 http://trac.example.com:9090/ 登录后台了,注意只要 console 关闭后台就会关闭,并且每次启动后台的时候密码都是随机生成的。这个也算是一种安全措施。 进入后台过后先到右上角的 Sources 菜单,点击左边的 "+" 图标新建一个信息源,并设置为:
    Type: Remote Host Nick: trac Connection: localhost:8000
    接下来到 vServers 菜单,新建一个虚拟主机,类型为 Manual 并设置为:
    Nick: trac.example.com Document Root: /home/trac/myproject
    接下来选中刚新建好的这个虚拟主机,在 Behavior 中点 Rule Management 并把 Default 以外的规则都删除掉,然后选中 Default 到 Handler 选项卡中,设置为:
    Handler: HTTP Reverse Proxy Balancer: Round Rubin Information Sources: trac
    保存设置并重启 cherokee 服务器,再回到 console 中重新启动一次 trac: [crayon-5b03c55fed5eb604504846/] 此时访问 http://trac.example.com/ 就是 Trac 的首页了。
  • 一点善后工作
  • 要正常使用 Trac 还需要一点额外的配置。编辑 /home/trac/myproject/conf/trac.ini: [crayon-5b03c55fed5f0891858599/] [crayon-5b03c55fed5f4442349812/] 之后从网页登录,点页面右上的 Admin 进入管理面板,在左侧选择 Plugins 并展开 Trac 1.0. 找到 tracopt.versioncontrol.git.git_fs.* 项并将其下三个插件全部勾上,保存即可。 添加 git 项目的时候,在 Trac 后台点击左侧的 Repositories 并像这样设置:
    Name=mygitproj Type=git Directory=/home/git/mygitproj.git
    另外和可以在 cherokee 中添加规则来设置静态文件的位置,把 /chrome/site/ 映射到实际的文件目录就可以了。 当然也可以在 cherokee 后台设置 SSL 一类的,自行发挥想象就好~
  • 参考资料/扩展阅读
  • Running Trac + Git Hosting on a Low End VPS Trac Standalone Simple Cherokee Configuration Cookbook: Setting up Trac]]>
    基本还是弄着玩的…前提显然是有一台vps嗯嗯…

    Trac 是一个专为软件开发设计的集问题追踪和 wiki 系统于一体的网页软件,git 是一个灵活而强大的版本控制工具,而 cherokee 则是一款简单好用的 web 服务器,当然,三者都是开源的。另外,这里选用 cherokee 而不是 nginx 或者 apache 这一类更为主流的服务器是因为 cherokee 的网站和默认页面比较好看所以想干脆来装逼一下这种事情我是不可能在教程里面说的。
    为了搞好这个我折腾了一天,翻看了好多文档和教程,试了多种方法,最后是用的文档上没有提到的一种组合。之所以这样是因为按照文档进行设置一直不成功…

    我所用的系统是 Ubuntu 11.10 64bit, 用 12.04 的话 cherokee 的管理面板一直打不开所以用的这个…同时也就意味着这份教程理论上适用于 Debian/Ubuntu 以及所有以此为基础的系统,比如 Mint 等,但是当然,我没办法做任何保证,而且一些细节的配置也可能需要根据具体情况进行修改。

    新系统装好过后先卸掉不需要的包以及更新,具体命令可以参考这里,下面直接开始进行版本库的安装和配置。

  • 首先我们要安装 git 并添加用户
  • apt-get install -y git-core
    useradd -m -K UMASK=027 git

    注意在给 git 用户设置密码或者配置密钥之前这个用户是实际上没办法使用的。

  • 接下来安装 Trac:
  • apt-get install python python-setuptools python-pygments python-tz subversion
    easy_install Trac

    随后我们需要新建一个 trac 用户并添加到 git 用户组,这样好让 Trac 有管理 git 仓库的权限:

    useradd -m -K UMASK=077 -G git trac

    接下来就可以初始化我们的第一个 Trac 项目了:

    sudo -u trac trac-admin ~trac/myproject initenv

    这里我们新建了一个名叫 myproject 的项目,这个是 trac 的环境目录名称,命令执行中会要求输入项目名称,输入的这个随后可以修改。
    另外本教程以只建立一个 trac 项目为例,如果需要多项目请参照官方文档调整配置。

    现在最基本的 trac 配置就已经完成了,可以执行

    tracd --user=trac -s -p 8000 -d /home/trac/myproject
    来启动 tracd 进程,访问 http://trac.example.com:8000 就能看到一个 Trac 的默认页面了。

    下一步是给 Trac 添加上一个简单的认证,否则是没办法登录进行管理的。

    apt-get install apache2-utils
    # 安装 apache2-utils 以使用 htpasswd
    pkill tracd
    sudo -u trac htpasswd -bc ~trac/myproject/htpasswd tracadmin 12345
    sudo -u trac trac-admin ~trac/myproject permission add tracadmin TRAC_ADMIN
    # 设置用户 tracadmin 及其密码,并添加为管理员
    tracd --user=trac -s -p 8000 -d --basic-auth="*,/home/trac/myproject/htpasswd,Restricted" /home/trac/myproject
    # 重启 trac 并启用认证

    此时再访问 http://trac.example.com:8000 并点击右上角的 login 就可以登录后台了。

  • 接下来安装 cherokee 作为前端:
  • apt-get install cherokee

    此时访问 http://trac.example.com 就可以看到 cherokee 的默认界面了。
    需要注意的是,和大多数 web 服务器不同,cherokee 并不需要用户自己编辑配置文件,而是自带了一个管理后台,我们使用下面的方法来进入后台并配置其与 Trac 一同工作。

    首先在 console 中执行以下命令:

    cherokee-admin -b

    会出现类似这样的提示:

    root@git:~# cherokee-admin -b
    [06/12/2012 13:17:56.456] (warning) rrd_tools.c:120 - Could not find the
        rrdtool binary. | A custom rrdtool binary has not been defined, and the
        server could not find one in the $PATH.
    
    Cherokee Web Server 1.2.2 (Jul 12 2011): Listening on port ALL:9090, TLS
    disabled, IPv6 enabled, using epoll, 4096 fds system limit, max. 2041
    connections, caching I/O, 20 threads, 102 connections per thread, standard
    scheduling policy
    
    Login:
      User:              admin
      One-time Password: lXcCRnfqL1qAgNRE
    
    Web Interface:
      URL:               http://localhost:9090/

    使用提供的用户名和密码就可以通过 http://trac.example.com:9090/ 登录后台了,注意只要 console 关闭后台就会关闭,并且每次启动后台的时候密码都是随机生成的。这个也算是一种安全措施。

    进入后台过后先到右上角的 Sources 菜单,点击左边的 “+” 图标新建一个信息源,并设置为:

    Type: Remote Host
    Nick: trac
    Connection: localhost:8000

    接下来到 vServers 菜单,新建一个虚拟主机,类型为 Manual 并设置为:

    Nick: trac.example.com
    Document Root: /home/trac/myproject

    接下来选中刚新建好的这个虚拟主机,在 Behavior 中点 Rule Management 并把 Default 以外的规则都删除掉,然后选中 Default 到 Handler 选项卡中,设置为:

    Handler: HTTP Reverse Proxy
    Balancer: Round Rubin
    Information Sources: trac

    保存设置并重启 cherokee 服务器,再回到 console 中重新启动一次 trac:

    tracd --user=trac --daemonize --single-env --protocol=http --hostname=localhost --port=8000 --basic-auth="*,/home/trac/myproject/htpasswd,Restricted" /home/trac/myproject

    此时访问 http://trac.example.com/ 就是 Trac 的首页了。

  • 一点善后工作
  • 要正常使用 Trac 还需要一点额外的配置。编辑 /home/trac/myproject/conf/trac.ini:

    base_url = http://trac.example.com

    use_base_url_for_redirect = true

    之后从网页登录,点页面右上的 Admin 进入管理面板,在左侧选择 Plugins 并展开 Trac 1.0. 找到 tracopt.versioncontrol.git.git_fs.* 项并将其下三个插件全部勾上,保存即可。

    添加 git 项目的时候,在 Trac 后台点击左侧的 Repositories 并像这样设置:

    Name=mygitproj
    Type=git
    Directory=/home/git/mygitproj.git

    另外和可以在 cherokee 中添加规则来设置静态文件的位置,把 /chrome/site/ 映射到实际的文件目录就可以了。
    当然也可以在 cherokee 后台设置 SSL 一类的,自行发挥想象就好~

  • 参考资料/扩展阅读
  • Running Trac + Git Hosting on a Low End VPS
    Trac Standalone
    Simple Cherokee Configuration
    Cookbook: Setting up Trac

    ]]>
    https://blog.atr.me/NGC224/feed 0 224
    在两台 VPS 之间实现自动异地备份 https://blog.atr.me/NGC207 https://blog.atr.me/NGC207#comments Mon, 29 Oct 2012 03:14:29 +0000 https://blog.atr.me/?p=207 Wiki 的自动备份,在 Wiki 所在的 VPS 上定时对资料目录打包,然后从备份用 VPS 把打包好的文件传输过去。 之前遭遇过多次 VPS 挂掉而数据灭失的惨剧,最近一次就是幸苦写了十多个页面之后的个人 Wiki... 然后到现在都还木有把那些内容全部给补回来...虽然说现在使用了几乎不用考虑升级(也就大大减少了手贱的几率)的 Slackware 系统,但是以防万一还是做个异地备份的好。 异地备份重于泰山。 为了方便设置备份时间和文件传输的安全性考虑,我把所有参与备份的服务器设置为了同一时区,并且使用 scp 命令来通过 SSH 完成文件传输。至于备份的脚本,设置为使用 cron 任务定期执行。 我的个人 Wiki 放在一台跑着 Slackware 13.37 的低配 VPS 上面,用的是 MoinMoin Wiki 系统,所有数据都保存在文件系统中而不需要数据库,所以只要给 Moin 文件夹打包就可以备份全部内容了。 先是在 Slackware 下面调整时区,我用 tzselect 不知为何木有作用,最后用了这个命令解决: [crayon-5b03c55fedf1f921453823/] 然后 [crayon-5b03c55fedf26258307490-i/] 编写备份脚本: [crayon-5b03c55fedf2a336102603/] 这个脚本会删除前一天的备份并将 Moin 所在目录打包。 然后需要把脚本放到 cron 里并赋予执行权限,让它能够每日自动运行。这里我让它每日备份一次: [crayon-5b03c55fedf2e353831871/] 之后是设置 cron job 的执行时间,执行 [crayon-5b03c55fedf33919218526-i/] 即可编辑: [crayon-5b03c55fedf36010095286/] 修改时间后保存退出。 这个时候可以手动运行一下脚本看能不能正确打包文件。 然后到备份服务器做设置。我的备份服务器运行的是 CentOS 5 32bit. 出于安全考虑,不能把备份文件放在 web 服务器可访问的地方,所以就不能用 wget 来下载到备份机,所以想到了用 SSH 来传输文件。 首先要给两台服务器配置证书认证。先在备份机执行 [crayon-5b03c55fedf3c435323343-i/] , 全部默认设置就行,在本机生成一个 key. 然后到 /root/.ssh/ 目录下,把这个文件传输到生产机: [crayon-5b03c55fedf40641259068/] 按照提示保存密钥并且输入密码过后就可以完成传输了。然后这个时候再尝试用 ssh 命令登录,应该就不再需要密码了。 如果提示 scp 命令找不到,安装 openssh-client 即可。 然后开始配置 cron job. 首先编辑备份用脚本 [crayon-5b03c55fedf44765562852-i/] : [crayon-5b03c55fedf48060515657/] 然后同样地,用 [crayon-5b03c55fedf4c418650179-i/] 赋予其运行权限,之后就要配置 cron 了。 CentOS 5 下不能用 [crayon-5b03c55fedf50437776932-i/] 来编辑配置,因为系统默认的 cron 程序不同。这里要直接编辑 [crayon-5b03c55fedf54484083625-i/] : [crayon-5b03c55fedf58708983436/] 注意这台备份机的时区也是 Asia/Shanghai. 我把每日运行时间设置成生产机的大约40分钟过后,保证生产机已经执行备份打包操作完毕,然后从备份机运行脚本将打包好的每日备份传输到本地并按照日期重命名存放。 以上设置目前已经成功运行。 --- TODO --- 还没有搞清楚自动导出 MySQL 数据库应该怎样操作,下一步是折腾带数据库应用的自动备份。 说不定还可以搞整下 Dropbox 上传w]]> 就是记录一下设置 Wiki 的自动备份,在 Wiki 所在的 VPS 上定时对资料目录打包,然后从备份用 VPS 把打包好的文件传输过去。

    之前遭遇过多次 VPS 挂掉而数据灭失的惨剧,最近一次就是幸苦写了十多个页面之后的个人 Wiki… 然后到现在都还木有把那些内容全部给补回来…虽然说现在使用了几乎不用考虑升级(也就大大减少了手贱的几率)的 Slackware 系统,但是以防万一还是做个异地备份的好。

    异地备份重于泰山

    为了方便设置备份时间和文件传输的安全性考虑,我把所有参与备份的服务器设置为了同一时区,并且使用 scp 命令来通过 SSH 完成文件传输。至于备份的脚本,设置为使用 cron 任务定期执行。

    我的个人 Wiki 放在一台跑着 Slackware 13.37 的低配 VPS 上面,用的是 MoinMoin Wiki 系统,所有数据都保存在文件系统中而不需要数据库,所以只要给 Moin 文件夹打包就可以备份全部内容了。

    先是在 Slackware 下面调整时区,我用 tzselect 不知为何木有作用,最后用了这个命令解决:

    zic -l Asia/Shanghai

    然后

    vi /usr/local/share/moinbackup.sh
    编写备份脚本:

    #!/bin/bash
    
    rm /usr/local/share/moindailyback.zip -Rf
    zip /usr/local/share/moindailyback.zip /usr/local/share/moin -r

    这个脚本会删除前一天的备份并将 Moin 所在目录打包。

    然后需要把脚本放到 cron 里并赋予执行权限,让它能够每日自动运行。这里我让它每日备份一次:

    cp /usr/local/share/moinbackup.sh /etc/cron.daily/moin.sh
    chmod +x /etc/cron.daily/moin.sh

    之后是设置 cron job 的执行时间,执行

    crontab -e
    即可编辑:

    # If you don't want the output of a cron job mailed to you, you have to direct
    # any output to /dev/null.  We'll do this here since these jobs should run
    # properly on a newly installed system, but if they don't the average newbie
    # might get quite perplexed about getting strange mail every 5 minutes. :^)
    #
    # Run the hourly, daily, weekly, and monthly cron jobs.
    # Jobs that need different timing may be entered into the crontab as before,
    # but most really don't need greater granularity than this.  If the exact
    # times of the hourly, daily, weekly, and monthly cron jobs do not suit your
    # needs, feel free to adjust them.
    #
    # Run hourly cron jobs at 47 minutes after the hour:
    47 * * * * /usr/bin/run-parts /etc/cron.hourly 1> /dev/null
    #
    # Run daily cron jobs at 03:40 every day:
    40 3 * * * /usr/bin/run-parts /etc/cron.daily 1> /dev/null
    #
    # Run weekly cron jobs at 4:30 on the first day of the week:
    30 4 * * 0 /usr/bin/run-parts /etc/cron.weekly 1> /dev/null
    #
    # Run monthly cron jobs at 4:20 on the first day of the month:
    20 4 1 * * /usr/bin/run-parts /etc/cron.monthly 1> /dev/null

    修改时间后保存退出。
    这个时候可以手动运行一下脚本看能不能正确打包文件。

    然后到备份服务器做设置。我的备份服务器运行的是 CentOS 5 32bit.

    出于安全考虑,不能把备份文件放在 web 服务器可访问的地方,所以就不能用 wget 来下载到备份机,所以想到了用 SSH 来传输文件。
    首先要给两台服务器配置证书认证。先在备份机执行

    ssh-keygen
    , 全部默认设置就行,在本机生成一个 key. 然后到 /root/.ssh/ 目录下,把这个文件传输到生产机:

    scp /root/.ssh/id_rsa.pub root@wiki.atr.me:/root/.ssh/authorized_keys

    按照提示保存密钥并且输入密码过后就可以完成传输了。然后这个时候再尝试用 ssh 命令登录,应该就不再需要密码了。
    如果提示 scp 命令找不到,安装 openssh-client 即可。

    然后开始配置 cron job.
    首先编辑备份用脚本

    vi /etc/cron.daily/moin.sh

    #!/bin/bash
    
    # Define the time
    NOW=$(date +"%Y-%m-%d")
    
    # Get the file
    scp root@wiki.atr.me:/usr/local/share/moindailyback.zip /home/back/moin-back_$NOW.zip

    然后同样地,用

    chmod +x /etc/cron.daily/moin.sh
    赋予其运行权限,之后就要配置 cron 了。
    CentOS 5 下不能用
    crontab -e
    来编辑配置,因为系统默认的 cron 程序不同。这里要直接编辑
    vi /etc/crontab

    SHELL=/bin/bash
    PATH=/sbin:/bin:/usr/sbin:/usr/bin
    MAILTO=root
    HOME=/
    
    # run-parts
    18 * * * * root run-parts /etc/cron.hourly
    26 4 * * * root run-parts /etc/cron.daily
    19 1 * * 0 root run-parts /etc/cron.weekly
    49 5 23 * * root run-parts /etc/cron.monthly

    注意这台备份机的时区也是 Asia/Shanghai. 我把每日运行时间设置成生产机的大约40分钟过后,保证生产机已经执行备份打包操作完毕,然后从备份机运行脚本将打包好的每日备份传输到本地并按照日期重命名存放。

    以上设置目前已经成功运行。

    --- TODO ---
    还没有搞清楚自动导出 MySQL 数据库应该怎样操作,下一步是折腾带数据库应用的自动备份。
    说不定还可以搞整下 Dropbox 上传w

    ]]>
    https://blog.atr.me/NGC207/feed 4 207