项目是运行在Ubuntu上,基于Django 1.4开发。我想用gunicorn
作为生产服务器,并用nginx
作为web服务器,以此提高性能。
考虑django已经可以正常工作,现在安装gunicorn和nginx
1 | $ sudo apt-get install gunicorn nginx |
Native Client 是Google支持的开源技术,用来在浏览器中像桌面程序一样运行编译过的代码,满足人们对web应用程序的可移植性和安全性的期望,提供更好的富客户端用户体验,允许开发者编写更强大的移动Web应用程序。
JavaScript创始人Brendan Eich上个月在旧金山召开的O’Reilly Fluent ConfereNative Cliente大会上解释说JavaScript足以满足Google对Native Client的设计目的,并怀疑Native Client是否能够像JavaScript一样,得到浏览器厂商的广泛支持。
软件自动化测试,作为手工测试的替代,越来越受到关注。Pekka Klärck,作为Robot Framework的创建者和核心开发者,按照系统级别,介绍了几种不同的自动化测试方法的区别。
记录回放的方式流行于商业工具之中,无需编程技能即可快速上手。然而这种方法相对脆弱,一旦UI变化测试就会受到影响,分散的脚本不可重用且难以维护,而且系统在测试前必须可用(也就意味着无法使用A-TDD方法)。因此这种方法并不适合大型自动化测试。
线性脚本允许使用各种语言来编写非结构化脚本,脚本直接与被测系统交互。能够快速上手,灵活性强。但是编写脚本需要编程技能,系统中一个改动会影响所有脚本,没有经过模块化或重用的大量脚本难以维护。因此这种方法适合简单任务,不适合大型自动化。
模块化脚本由两部分组成:驱动脚本执行测试,测试库函数完成与被测系统交互。驱动脚本编写起来非常简单,这样可以更快地建立新测试,容易维护。然而需要花时间和编程技能建立测试库,并将测试数据嵌入脚本,建立新测试就需要新的测试脚本。因此,只要拥有编程技能,这种方法还是适合大型项目,但不适合非编程人员。
数据驱动方法,将数据与测试脚本分离,基于模块化的测试库,一个驱动脚本可以执行多个相似测试,这样非常容易建立新测试。维护工作可以分离,测试人员负责数据,程序员负责写测试库。然而,不同类型测试仍需要新的驱动脚本,初始建立数据解析器和重用组件需要花人力。这种方法适合大型项目,只需要较少的编程技能。
关键字驱动,将数据与关键字结合来描述如何使用数据执行测试。这种方法具备数据驱动的优势,同时非编程人员也能建立新类型测试。所有测试由同一个框架来执行,无需不同的驱动脚本。然而初始成本很大,但是可以使用开源方案!因此非常适合大型项目。
Pekka对以上五种方法的介绍其实也是对自动化测试发展史的介绍,同时也体现了RobotFramework背后的设计思想。
自动化测试需要关注可测性。自动化最难的部分是与被测系统交互,特别是GUI层。确保系统容易被测试,比如给GUI元素增加标识、输出易于解析的文本、提供自动化接口等。
系统一般可以分为GUI层以及GUI之下的业务层。GUI层测试需要调用与普通用户同样的接口,但是某些GUI技术缺乏好的工具支持,会使测试变得脆弱,而且执行相对较慢。从业务层开始测试相对容易,执行快。但GUI层仍然需要被测试,以保证GUI正确连接到了业务层,甚至有时GUI层也具有业务功能。Pekka建议考虑对业务层进行完全测试,而部分地对GUI层实行端到端测试。 不是所有系统都具有GUI层,却可能具有API、数据库、服务器、命令行等。自动化测试框架可以调用不同驱动来进行测试。这些非GUI层相对容易测试,只要把测试用例看作另一个客户端而已。
那么自动化测试应该在什么阶段进行?如果开发完成后单独做自动化,这是典型的瀑布式过程,不同团队之间存在沟通障碍,反馈周期慢,产品在后期难以获得可测性,从而导致复杂和脆弱的测试方案。相反,典型敏捷式过程中,程序员和测试人员协同完成自动化。把自动化看作团队开发的一部分,可测性不再是问题,团队做技术决定时就可以考虑可测性和工具选择,程序员可以提前加入提供可测性的钩子特性。
自动化测试需要版本控制和持续集成来支持。将测试和代码放在一起,像管理代码一样管理测试脚本,那么多可用工具,SVN、GIT、Mercurial,没道理不用。持续集成是全方位自动化的关键,当测试或代码有所改动立即执行测试。如果测试运行时间比较长,也可以定期运行。使用Jenkins、Hudson、Cruise Control、 BuildBot吧,自己写定时脚本或Cron Job可以休矣。
好东西肯定贵,但是贵的不见得好,再便宜的许可证也会阻止整个团队的协作。而且商业化工具难以和其他自动化工具(特别是其他厂商的)或版本控制、持续集成进行整合和定制化。另外,产品终止或公司关门是潜在的风险。开源工具可供选择余地很大,当然也是良莠不齐。开源工具通常容易与其他工具整合,关键是免费,谁都可以随意使用和定制化,还永远不会消失。至于免费软件,越来越少了,很多自由软件都已经开源。免费软件同样不能定制化,且存在中止的风险。
一般来说,包括Python、Ruby、Perl、JavaScript、正则表达式、XPath和CSS定位、SQL语句、版本控制等。
当然需要!! 不过,要避免手工执行脚本来测试,还是将其完全自动化吧,测试人员可以更多关注于探索性测试。 记住,机器擅长回归测试,人类善于寻找Bug。
本文作者 @申导 自2007年开始在诺基亚西门子内部接触到RobotFramework工具,在团队管理和一线开发的时候,一直坚持和推荐RF工具至今,尤其是基于RF的ATDD/BDD团队协作实践,在敏捷团队中取得良好收益,并形成了一套完成的培训体系。欢迎交流经验。
最近Uncle Bob发表了新的博客 Why is estimating so hard?。
Bob大叔首先抛出一个问题,如何将著名的葛底斯堡演说的237个单词以固定字体和固定行宽写在一张书签上。如果人工执行这个任务,假设每秒钟处理一个单词来寻找合适的断句点,估计5分钟内就可以完成,而且实际花费时间也和估计的差不多。然而,如果要编写程序来做,要花多久?而且是在知晓算法、没有意外情况、没有绊脚石、无需备份和恢复功能的情况下,编写程序要花多久时间?
Esther Derby发表了文章 What do middle managers do?。
关于敏捷转型,存在两种现象。有时候高层管理者要求“使用敏捷”,但中层经理“抵抗”;另外有些中层经理在高层并不关心敏捷的情况下,做到了转型。
作者观察到,高级和中层管理者都看到了转向团队为基础的组织和迭代增量式开发的好处。据她的经验,中层经理往往对现有模式不愿放手。为什么?如果他们在敏捷组织中没有看到自己的位置,他们不会拥抱敏捷。而敏捷方法对中层经理的角色所言甚少。泛泛的说消除对经理的需要没有帮助。
组织向敏捷转型仍然需要管理层,而且经常需要管理角色的人,特别是在大型复杂的组织中。在传统层级中,中层经理从高层确认未来的方向,并将工作重点放在一线人员,让他们完成。当团队从队列中拉取任务并自我管理来完成目标,中层经理们真正的机遇是跨越部门边界来观察组织,以改进系统和培养人员及团队。 所以当中层经理不再指挥日常工作,他们做什么?作者认为有很多,特别是帮助同事,上司和团队:
不同读者在评论中指出以下几点:
原文:
http://www.infoq.com/cn/news/2012/05/what-do-middle-managers-do
iPhone OS 3.0一个引入注目的新特性是Push Notifications(推送通知),它允许向已安装相关应用程序的各设备直接发送消息。苹果在新闻提示或IM应用中展示了此特性,它也十分完美地适合于我们的服务器监视服务程序Server Density。
我们的程序提供一个选项,当你设定的某个服务器事件发生时,通知会直接发送到你的iPhone上。这是非常有用的因为它提醒用户立即打开我们的程序查看引起此警示的服务器详情。
Apple提供了有关实现和处理设备上提示消息的 iPhone OS 的详细代码文档 ,但它只包括消息提供者服务器端编程指南。
作为消息提供者,我们需要与 Apple推送通知服务 (APNS)连接以发送消息到iPhone。为减少电池使用,一个设备仅需维持与APNS的一个连接。
本教程将从代码的层面介绍关于怎样建立一个推送通知服务器以连接APNS并使用推送通知到我们的服务器监视iPhone程序上。我们是使用PHP进行开发的,我们的示例都是PHP 5兼容的。
使用唯一的SSL许可证连接到APNS
循环通过你需要发送到消息
为各消息构建有效载荷
断开与 APNS的连接
远程通知数据的流程是单向的。提供者将包括客户程序设备令牌和有效载荷的数据打包,发送到APNS,然后APNS再将通知发送给最终设备。
有效载荷限制为256字节 – 它包括了消息主体以及你希望传送带其他属性。推送通知并不适于传送大量的数据。例如,我们仅仅传送一条短消息通知服务器监视的事件已经被触发了。
APNS并不提供消息发送成功与否的回馈状态。一个原因是如果一个设备无法联系那么发送给它的消息将被存于队列中,然而只有最新发送的消息被存于队列中 – 覆盖了先前发送但不成功的消息。
推送通知不适合用于发送紧急通知,因为消息仅在设备具有wifi或手机服务连接的情况下才能被发送,这也是为什么我们推荐与其它方法如email或SMS一起使用的原因。
用来与APNS通讯的SSL许可证(下面将讨论)是在程序层生成的。本教程涉及到实现方法仅适于单个iPhone程序,所以如果你有多个程序,那么你需要修改代码使之适合于使用多个许可证。
每条推送消息都必须针对某特定设备。这是通过使用在你的iPhone程序中由APNS产生的唯一deviceToken(设备令牌)来实现的。一旦获取了此令牌,你需要将其存储于服务器而不是你的iPhone程序内。它看上去像这样:
c9d4c07c fbbc26d6 ef87a44d 53e16983 1096a5d5 fd825475 56659ddd f715defc
在我们的 Server Density iPhone 程序中,我们在程序启动时调用相应的令牌生成方法,然后通过 HTTP API 调用 传回给我们的服务器 。这将使得deviceToken存储于服务器的有关用户的数据库中,从而我们可以使用它与持有此设备的用户进行通讯。
Apple 还提供了一个 反馈服务 ,你应该定期查询。它提供了一个以前使用过但不再有效的(例如用户卸载了你的iPhone程序)设备令牌列表。你可以从你的数据库中删除这些设备令牌。
本教程不涉及反馈服务的使用。
要进行推送服务的第一件事就是获取推送许可证。它用来对你通过SSL与APNS通讯进行识别。
在Mac上生成 Apple推送通知SSL许可证:
1 | 9. 如果你想要移除密码,要么在导出/转换时不要设定或者执行:``` [sh] |
显示 $payload 的内容可以看到传送到APNS 的 JSON字符串:
{
“aps” : { “alert” : “This is the alert text”, “badge” : 1, “sound” : “default” }
}
这将使消息显示于设备上,触发提升声音并将“1”置于程序图标上。默认按钮“Close”和“View”同时会显示于弹出窗口上。
对于 Server Density iPhone程序而言,让用户按下“View”直接进入产生此提示的服务器是很重要的,所以我们增加了额外的自定义值:
1 | $payload['aps'] = array('alert' => 'This is the alert text', 'badge' => 1, 'sound' => 'default'); |
当用户按下“View”后,自定义server值将被传递到设备中的程序。JSON 值如下:
{
“aps” : { “alert” : “This is the alert text”, “badge” : 1, “sound” : “default” },
“server” : { “serverId” : 1, “name” : “Server name”)
}
256字节的限制适用于整个载荷,包括自定义字典集。
在Server Density中,一旦产生了一条提示,将建立一个载荷并插入队列中。因此有必要时我们可以同时发送多个载荷。
Apple推荐使用这种方法,因为如果你在发送各载荷时频繁连接和断开,APNS有可能会封锁你的IP。
如Apple 描述:原生接口使用原生socket,具有二进制内容,采用数据流技术,不产生回馈。
打开连接的 PHP 5代码如下:
1 | $apnsHost = 'gateway.sandbox.push.apple.com'; |
如果发送错误,你可以参考$errorString。它也包括了SSL许可证不正确时的详细信息。
许可证文件处于执行的PHP代码的当前工作目录下,如果需要你可指定其绝对路径。
注意测试时应该使用开发许可证及sandbox。成品主机名为 gateway.push.apple.com ,而且你必须使用不同的产品许可证。
在此,我们循环整个载荷队列进行发送。构建发送到APNS的二进制内容简单示例如下:
1 | $apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . |
注意 $deviceToken 是从数据库中提取并去除空格得到的。我们还应该检查是否$payload超过256个字节。
$apnsMessage 包括了正确的二进制载荷,而fwrite 将载荷写入当前活动的数据流连接中。
完成后,应关闭连接:
1 | socket_close($apns); |
有一个开源服务器库php-apns实现了以上所有功能,它依赖于 memcached。我们不想使用任何第三方代码,所以完全自己编写了自己的服务器。我们使用自定义cron系统,几秒钟运行一次。
原文见:
How to build an Apple Push Notification provider server (tutorial)
参考:
Apple 文档
Jenkins是著名的开源CI工具,也很易用。其前身是Hudson,自从Hudson被Oracle收购就被迫改名了。
(关于iPhone开发的CI,参见: 命令行运行iphone模拟器以及运行Unit test)
我的Jenkins安装在Linux上,但是iphone app却只能在Mac机上进行编译和运行单元测试,所以需要给Jenkins建立带tag 的Node,并且把iphone工程也打上相同的tag,这样就可以强制该工程在Mac环境上编译,而不是在本机Linux上。
由于需要搭建持续集成CI平台,因此需要利用命令行进行编译和单元测试。
命令行编译倒是容易,xcodebuild即可。但是如果运行Unit test甚至启动模拟器运行应用程序,成了国内外同行的大问题,苹果还没有来得及开放或者根本不愿意开放命令行,所以只好自己摸索。环境为XCode4.2。工程名为Krowdit.
参考:
https://github.com/hborders/iphonesim/commit/27acdfdf6c900b0e9bbd061f45c904c1d18fd21d#commitcomment-484139
http://blog.carbonfive.com/2011/04/06/running-xcode-4-unit-tests-from-the-command-line/
http://longweekendmobile.com/2011/04/17/xcode4-running-application-tests-from-the-command-line-in-ios/
关于使用Jenkins CI,参见Jenkins CI 连接Mac 电脑失败
Comet长连接用于服务器消息推送。两种实现方式long poll和stream。和http 1.1并无直接联系。
Long Poll:服务器在发送响应后保持socket一段时间后才关闭socket连接。CS双方都为对方的request或response设置timeout来探测对方是否还在正常工作,所以每次request还可以起到心跳消息的作用。
Stream:服务器在发送响应后保持socket一段时间后才不关闭socket连接,而是不断写入数据,这样客户端可以持续的分段收到数据。
tomcat提供了特殊的CometServlet来实现此功能。
在浏览器端可以用个隐藏的iframe元素来接受数据,或者google提供的“htmlfile”小工具来接收javascript
新配服务器,intel i3双核,微星主板,8G内存,三块500GB硬盘组成1TB的Raid5阵列,因为其中一块是备份磁盘。raid5的好处是既能使磁盘读写带宽加倍,又具有热备份功能,还比raid0+1少用一块硬盘。
因为是8G内存,所以下载了Ubuntu 11.04桌面版。从liveCD引导,一路回车,到磁盘分区时,提示无法在分区上安装启动程序,列表中可以选择的有/dev/sda,raid-p0等,无论选哪个都不行。