经过去一个月的开发,于上周末终于迎来了我们产品的第一个beta版本,该版本实现了产品最核心的功能,所有不是那么“不重要”的都被排除在外:它没有搜索功能,它没有站内消息功能,它也没有可嵌套的评论,甚至连找回密码都没有。因为以上的我们现在都不需要,我们只做了一个像样一点的帐号管理功能、登录、注册,你可以换一下头像,按我们的指引发布一个关于穿衣打扮的意见,关注其他用户关于穿衣打扮的见解,评论它。就是这么简单的一个“可用”版本,它也僅僅是“可用”,我们甚至打算为它准备好几天来Debug。但没有关系,我们都准备好了面对这一切,我们打算把它做得更好一些。
而在过去的一周,我一直在期待这一个beta版本的来临,为了给将来的产品模式部署做好准备,我谋划着如何为它准备测试机的测试环境。并尽量让测试环境接近于产品环境。
我们用到的技术:
- PlayFramework 1.1 ,刚刚升级到1.1.1
- MySQL 5.1.41 , 打算在5.5测试通过后,升级到 5.5
- JDK 1.6.0_21
- memcached 1.4.2 , Cached部分
- GlassFish 3.0.1 , Application 服务器
- Mercurial Server (hg) , 代码仓库
- nginx 0.7.67 , Proxy + 静态Host
- ubuntu-10.04.1-server-amd64 , 服务器系统
- GraphicsMagick 1.3.12
- 为什么选择PlayFramework ?一开始我们想用Rails,敏捷而且快速。但团队更熟悉Java,而本人认为SSH风格的开发模式过于繁锁,我们需要的是一个能够快速开发,快速迭代的框架,PlayFramework看起来不错,我们就尝试着用它。
- 项目目录结构 为日后可能的多项目公共代码引用,我们将一些公共代码抽取放入到Play 的Modules 里,各项目以引用modules的方式共享公共代码。看起来像这样:
sources
|- apps
| |- main
| |- passport
|- modules
| |- models
| |- commons
| |- statics - 为CDN分发做准备 我们将所有apps的静态文件都放入了statics modules中分类存放,通过Play的routes配置,在开发者环境中各apps通过引入modules来做路径的相对引用,而产品模式可以配置成对应的host路由,像我们的配置文件一样:
#{if play.mode.isDev()}
以图片举例,在开发环境中,html片段为: /public/images/commons/foo.jpg
GET /public/images/ staticDir:public/images
GET /public/ staticDir:public/
#{/}
#{else}
GET imgs.domain.com.cn/ staticDir:public/images
GET jscss.domain.com.cn/javascripts/ staticDir:public/javascripts
GET jscss.domain.com.cn/stylesheets/ staticDir:public/stylesheets
#{/}
而在产品模式下,html片段为: imgs.domain.com.cn/public/images/commons/foo.jpg
要运用以上技巧,除了配置routes外,还需要修改HTML模板中的路由引用:
将
<script src="@{'/public/javascripts/common/jquery-1.4.2-noConflict.min.js'}"></script>
修改为
注意引用@符号从一个修改为两个,@表示当前域名相对路径引用,@@表示绝对路径引用。
<script src="@@{'/public/javascripts/common/jquery-1.4.2-noConflict.min.js'}"></script>
client_max_body_size 5m;
worker_rlimit_nofile 65535;
- 在NginX 中添加X-Forwarded-For header
- 在Play中添加application.conf文件中添加X-Forwarded-For支持
location ~ .* {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://127.0.0.1:9000;
}
[/codesyntax][codesyntax lang=”text” title=”application.conf” container=”none” capitalize=”no” strict=”no”]
XForwardedSupport=127.0.0.1,10.0.0.25[/codesyntax]
在Controller中通过request.remoteAddress获取真实IP
标题上的ouxifan是我们的项目开发代码