有不同的方法……算了,这个话题另起一篇文章来说,扯远了,想交流可关注我的微博 ,咱继续……
前面讲到,WEB 服务器是要做负载均衡的,图片服务器是要分开的。对于这点,代码在处理客户端状态时,不要把状态放到单机上,
举例,不要用文件session,嗯,常识。 如果有可能,最好在一开始就做好用户单点认证的统一接口,包括跨域如何判断状态、
静态页面如何判断状态,需要登录时的跳转和返回参数定义,底层给好接口, 应用层直接就用(可参考GAE的 user服务)。
登录方面的设计要考虑移动设备的特性,比如电脑可以用浮动层窗口,但NOKIA自带的浏览器或UCWEB就无法处理这种表现形式,
程序一 定既能处理AJAX请求又能直接通过URL来处理请求。图片服务器分开,资源文件最好也布局到图片服务器,也就是WEB服务器只服务动态程序。
虽然开发测 试时稍微复杂(因为需要绝对URI才能访问),但将来页面前端优化上会轻松许多,并且你的WEB服务器IO优化也轻松许多。
程序引用资源文件时,要有一个 统一的处理方法,在方法内部可以自动完成很多事情,例如将css/js根据组合,拼成一个文件,
或者自动在生成的URI后面加上QUERYSTRING, 如果将来前端用了缓存服务,那生成QUERYSTRING是最简单的刷新服务端缓存和客户端缓存的办法。
前面讲到, 数据库会有复制,可能会多主多从,可能会分片。我们程序在处理数据的过程中,最好能抽象出来单独放做一层。
拿现在流行的MVC模式来说,就是在M层下方再 放一个数据层,这个数据层不是通常所说的JDBC/PDO/ActiveRecord等,而是你自己的存取数据层,
仅对外暴露方法,隐藏数据存取细节。这 个数据层内部不要怕写的难看,但一定要提供所有的数据存储功能,其他任何层次不要看到跟数据库打交道的字眼。
之所以这样做,是因为在单关系数据库的情况 下,可能会SELECT…JOIN…或直接INSERT…INTO…,可你可能会将一些表放到key-value数据库里存储,
或者分片,这么做之后原来 的语句和方式要全部改变,如果过于分散,则移植时会耗费很大精力,或得到一个很大的Model。
在数据层面的设计上,尽量避免JOIN查询,我们可以多做 冗余,多做缓存,每种数据尽量只需要一次查询,然后在你的程序里面进行组合。
对于比较复杂的数据组合,在实时性要求不高的情况下,可采用异步处理,用户访 问时只取处理后的结果。在对于主键的处理上,避免使用自增ID,
可以用一定规则生成的唯一值当做主键,这种主键是最简单的分片分布策略。即使用自增ID, 也最好用一个自增ID发生器,否则从数据库不小心被写了一下,
那主键很容易冲突。
前面讲到,咱数据库前面还有某些缓存挡着。别把 mysql的query cache当缓存,应用稍复杂的时候QUERY CACHE反而会成为累赘。
缓存跟数据库和业务结合的很紧密,正因为跟业务关系紧密,所以这点没有放之四海而皆准的方法。但我们还是有一些规则可参照。
规 则一:越接近前端,缓存的颗粒度越大。例如在WEB最前端缓存整个页面,再往后一层缓存部分页面区域,再往后缓存区域内的单条记录。
因为越靠近后端,我们 的可操作性越灵活,并且变化最多的前端代码也比较方便编写。在实践中,因为产品需求变化速度非常快,迭代周期越来越短,
有时很难将Controller和 Model分的那么清楚,Controller层面处理部分缓存必不可免,但要保证如果出现这种情况,
Controller所操作的缓存一定不要影响其他 数据需求方,也就是要保证这个缓存数据只有这一个Controller在用。
规则二:没有缓存时程序不能出错。在不考虑缓存失效引发的雪崩效应时,你的程 序要有缓存跟没缓存一个样,不能像新浪微博一样,缓存一失效,
粉丝微博全空,整个应用都乱套了。在缓存必不可少的情况下,给用户出错信息都比给一个让人误 解的信息强。