本文将补充mod_rewrite
参考文档。介绍使用mod_rewrite
提供的一些高级技术。
注意,许多这些示例在特定服务器配置中不会保持不变,因此您必须了解它们,而不是仅仅将示例剪切并粘贴到配置中。
跨多个后端的基于URL的分片
分配服务器负载或存储空间负担的常用技术称为“分片”。使用此方法时,前端服务器将使用该URL始终“分片”用户或对象以分隔后端服务器。
解决办法:
在外部映射文件中维护从用户到目标服务器的映射。如下所示:
user1 physical_host_of_user1
user2 physical_host_of_user2
: :
将它放入map.users-to-hosts
文件中。目的是绘制映射 -
/u/user1/anypath
转换为 -
http://physical_host_of_user1/u/user/anypath
因此,每个URL路径在每个后端物理主机上都不需要有效。以下规则集在映射文件的帮助下执行此操作,假设server0
是默认服务器,如果用户在映射中没有条目,将使用该服务器,配置如下:
RewriteEngine on
RewriteMap users-to-hosts "txt:/path/to/map.users-to-hosts"
RewriteRule "^/u/([^/]+)/?(.*)" "http://${users-to-hosts:$1|server0}/u/$1/$2"
即时内容再生
有时我们希望动态生成内容,一旦生成内容就会静态存储。此规则将检查静态文件是否存在,如果不存在,则生成它。如果需要,可以定期删除静态文件(例如,通过cron
),并根据需要重新生成。
解决办法:
这是通过以下规则集完成的:
# This example is valid in per-directory context only
RewriteCond "%{REQUEST_URI}" "!-U"
RewriteRule "^(.+)\.html$" "/regenerate_page.cgi" [PT,L]
-U
运算符确定测试字符串(在本例中为REQUEST_URI
)是否为有效URL。它通过子请求来实现。如果此子请求失败 - 也就是说,请求的资源不存在 - 此规则调用CGI程序/regenerate_page.cgi
,它生成所请求的资源并将其保存到文档目录中,以便下次使用时 请求,可以提供静态副本。
通过这种方式,可以以静态形式提供不经常更新的文档。如果需要刷新文档,可以从文档目录中删除它们,然后在下次请求时重新生成它们。
负载均衡
当希望使用mod_rewrite
在多个服务器之间随机分配负载,如何实现?
解决办法:
可使用RewriteMap
和服务器列表来完成此任务。
RewriteEngine on
RewriteMap lb "rnd:/path/to/serverlist.txt"
RewriteRule "^/(.*)" "http://${lb:servers}/$1" [P,L]
serverlist.txt 将包含服务器列表:
## serverlist.txt
servers one.example.com|two.example.com|three.example.com
注:如果希望某个特定服务器获得比其他服务器更多的负载,请将其域名添加到列表中多次。
结构化用户
具有数千个用户的一些站点使用结构化的homedir布局,即每个homedir
位于子目录中,该子目录以(例如)用户名的第一个字符开始。所以,/~larry/anypath
是/home/l/larry/public_html/anypath
而/~waldo/anypath
是/home/w/waldo/public_html/anypath
。
解决办法:
可使用以下规则集将波形符号URL扩展为上述布局。
RewriteEngine on
RewriteRule "^/~(([a-z])[a-z0-9]+)(.*)" "/home/$2/$1/public_html$3"