用groovyServlet和TemplateServlet快速开发网页

July 8th, 2009 by sulong 1 comment »

Groovy是专门为java设计的脚本语言,可以和java无缝的结合,为java带来了脚本语言的能力。作为一个脚本语言,groovy有丰富的特性,比如动态类型,闭包等。如果能掌握groovy,并用其来开发,可以大大提高java程序员的生产力。Grails是用groovy写的一个类似于rails的web框架,实际上就是spring+hibernate+groovy。我想用groovy来写写页面,但是又不想用grails这种笨重的东西,正好groovy自带的了两个类可以完成这个任务,就是groovy.servlet包下的 GroovyServlet 和 TemplateServlet类。

下载安装好groovy后,在安装目录的embeddabe目录下复制groovy-all-1.6.3.jar到war/WEB-INF/lib/下。然后,在web.xml里添加如下代码:

  <servlet>
    <servlet-name>groovlet</servlet-name>
    <servlet-class>groovy.servlet.GroovyServlet</servlet-class>
  </servlet>
 
  <servlet>
    <servlet-name>gsp</servlet-name>
    <servlet-class>com.liba.link.groovy.MyTemplateServlet</servlet-class>
  </servlet>
 
  <servlet-mapping>
    <servlet-name>groovlet</servlet-name>
    <url-pattern>*.groovy</url-pattern>
  </servlet-mapping>  
 
  <servlet-mapping>
    <servlet-name>gsp</servlet-name>
    <url-pattern>*.gsp</url-pattern>
  </servlet-mapping>

这样,就可以在web目录下用groovy写以.groovy或.gsp结尾的页面代码了。GroovyServlet就是一个普通的servlet,只不过,它会编译执行指定url对应的.groovy文件,来产生html。这和直接用groovy写servlet的区别是,GroovyServlet为你做了一些特殊变量的绑定,在.groovy里可以通过request, out, application, session等访问HttpServletRequest, HttpServletResponse, ServletContext和Session。而System.out被重定向客户端的输出,因而,可以这样写html了:

out.print("<h1>${request.getParameter('username')}</h1>")

GroovyServlet还绑定了一个MarkupBuilder,名称为html,所以可以用MarkupBuilder快速的生成简单的页面,比如:

html.div {
    table {
        tr {
            td {
                span(style:"color:red", "Hello world")     
            }
        }
    }
}

如果页面里有大量的html,只有少量的html代码,那么用groovyServlet的方式来写,还是会有些麻烦,这时候使用TemplateServlet会好一些。像上面的那样的配置,只要在web目录里写上以.gsp结尾的文件就可以了。在html代码里像jsp那样用 <% %>来插入groovy代码,比如:

<table>
  <tr>
    <td>
       <span style="color:red">
       <% print "Hello world" %>
       </span>
    </td>
   </tr>
</table>

TemplateServlet和GroovyServlet一样,也把常用的对象绑定成里脚本里的变量。

也许有人会问,这比直接用java和jsp有什么好的呢?没有多大好处,就是可以使用groovy代替java而已,但是我觉得就这一点就是很大的进步了。

  • Share/Bookmark

IO和性能

July 3rd, 2009 by sulong 5 comments »

最近几天看了几家互联网公司的和架构有关的PPT,有支付宝,linkedin,douban等。这些公司所使用的具体的技术有差别,但是为了能做到支持大规模访问,他们都在与缓慢的IO做斗争! 比如说豆瓣网的历次架构变迁,不是因为磁盘IO成为瓶颈,就是因为网络IO成为瓶颈。如果能把IO的问题解决掉,那么对于互联网企业来说,性能问题就解决掉一半了,我想。

与飞速的CPU和内存相比,磁盘和网络的IO慢如蜗牛,这是问题的根源。如果没有大规模廉价而又足够快的存储方案出现的话,这个问题还将继续下去。我们只能期待这一革命性的技术出现来从根本上解决这一问题吧!

那对于现在的我们该怎么办呢?大家的想法可能都是一样的,一是加快IO速度,二是避免不必要的IO。豆瓣曾经通过购买更高性能的硬盘来解决这个问题,如果想要更好的效果,需要投入更多的资金来购买整套的高性能存储方案,但是这成本太高了,很多公司后来都会放弃。于是大部分公司都会极力采用后者,就是避免不必要的IO,缓存就是用来做这样的事的。

将低速介质上的数据放到高速介质上,访问者先访问高速介质,在找不到需要数据时才访问低速介质,以此来提升访问数据的速度,这样的技术就是缓存了。设在一段时间内有m次没有命中缓存,n次命中,而访问一次缓存的时间是t1, 访问慢速介质的时间是t2,那么为了是缓存有效就得满足不等式: m * (t1 + t2) + n * t1 < (m + n) * t2, 于是有 m / n < t2 / t1 -1 。由此可见,在介质的速度比一定的情况下,命中比率要高于一定的值,缓存才有效果。提高命中比率,就是要把那些最常用的数据放到缓存里。另一方面,缓存里数据如果被修改了,就要同步到低速存储介质中,同样的,如果低速存储介质的数据被修改了,也要同步到缓存里。如果加上同步的开销,就需要更高的命中率。提高命中率和保证数据的同步,是使用缓存的两个艰巨的任务。

豆瓣网使用memcache,还使用专门的nigix服务器来提供图片的服务,其实也是cache。linkedin则使用了数十台大内存的服务器作为缓存服务器,运行着用c++写的专门的缓存程序。可见这些网站在使用缓存方面都是不遗余力呀。如果能把缓存用好,那么就把一大半的IO问题解决掉了。

IO往往会成为程序的瓶颈,因此,程序员应当时刻的注意,你写的代码是否在进行IO操作,是否可以减少IO操作,等等。

  • Share/Bookmark

DRY, Don’t Repeat Yourself!

July 1st, 2009 by sulong 1 comment »

DRY,就是不要写重复的代码,这也是程序设计的一个黄金准则之一。

1 引申自关注点分离

其实这一条准则,也是从关注点分离引申而来的。如果完成相同或相似功能的代码片段,在一个程序的很多地方出现,那么无疑会使包含它的代码多了一个关注点。把相同或相似的代码抽象出来,放在一个地方,这样就可以使调用者减少一个关注点,同时将所有的对同类问题的关注合并到一个地方。比如说,判断一个用户是否登录,这一功能被很多地方使用,如果把这一功能包装成函数放到一个地方,需要使用的地方只要引用一下函数就可以了,这样引用者就不用关心如何判断一个用户是否登录了。

2 好处

2.1 提高效率

同样的功能,完成一次就可以了,如果每次要使用轮子的时候,都重复发明轮子,那是对人类智慧的浪费。如果发明一个万用轮子不容易,那么发明一个够用的可以反复使用的轮子就可以了。

2.2 更易读

如过你打开一个程序的源代码,发现有大量类似又稍有差别的代码,你还有多少心情读下去吗?要读下去的话,你就得像diff工具一样去比较类似代码间的细微差别,还要揣摩它的含义。这样的代码读起来太痛苦了。因此,如果没有重复的代码,就没有这份痛苦。

2.3 更易维护

如果你用类似的算法,重复写了很多的程序,结果却发现这个算法有个错误,那你不得不小心翼翼的找到所有的这样的程序,并一个一个又一个的修正。那是一个多么无聊的工作呀。如果漏掉了,或者将其中的某些一不小心修改错了,还得回头再重新修改,那台痛苦了!所以充斥着copy&paste的代码,是维护者的噩梦。

3 怎么做

程序语言和编程方法的进步,也就是人们在实践DRY的过程。要做到DRY,就是要不断的通过抽象,把重复的功能抽象并包装起来。我们先是有了函数和子程序,后来有了类和方法,等等。我知道,为了DRY,还会有新的工具和方法论被发明。

  • Share/Bookmark

企业应用与游戏开发的差别

July 1st, 2009 by wuwei 12 comments »

两个领域完全不一样,包括关注点,技术,运营等..我总结了一下:

1. 企业应用有很多功能属于增删改查的类型.有的是单表操作,有的是多表的JOIN,有的可能需要些逻辑判断,但大致的基本思路是这样,一个企业应用大约逃离不出这些结构.游戏不同.没有增删改查,没有任何的模式套路!做企业应用的思路和做游戏的思路完全不同.我们部门曾经单独为游戏的后台做了机器人脚本,能自动创建对游戏的表的管理功能,而游戏的后台管理功能大体与企业应用类似,这样想来可能企业应用还是有套路可循的.

2.二者的关注点不同.企业应用关注的是功能能否实现,模块,代码写的是否秀雅,当然游戏的开发也肯定关注这个,但游戏更要关注:性能,画面和可玩性…性能包括游戏的响应速度,能否支撑玩家的巨大的并发量 等.画面也非常重要,一个好的游戏能让人有赏心悦目的感觉.同样可玩性也要挖掘出来.要让玩家玩的爽,有能从中盈利,难度比较高呢…

3.代码编写的方式不同.企业应用的思路大多可以想到.比如页面列表显示,无法是取数据,然后转换成一个VIEW在页面上显示出来.而游戏呢,逻辑性之复杂令人瞠目.这里不多说了.可能一个简单的功能,需要上千行代码…还有一系列的算法等等,同时还要考虑到编写代码后游戏的运行速度和性能…

4.做企业应用很多人习惯用模型的方式设计数据库,比如一个表代码一个对象等.这样会产生可能一个查询有涉及到5张表之多.游戏呢?一个月就会有50万条记录,如何JOIN?JOIN一次要让你必须在1秒内响应,并且线上还有1000个玩家在玩,你能行吗?不行!尽量少JOIN表,这是提高数据库效率的一个非常好的方法.

5.多用缓存.不多说了,优势是:1减少访问数据库的时间和数据库的压力 2.提高请求响应速度.等等…

还有很多…呵呵

  • Share/Bookmark