apache的mod_proxy、mod_rewrite和mod_cache

背景说明:网站A本体是我做的,他的英文站点本来是在一起的二级目录下(虽然里面基本没添加过英文资料。后来英文站重新外包给了第三方,然而他们只提供二级域名。这时就产生了矛盾,因为原来的二级目录做了seo,所以得在访问二级目录的时候跳转到二级域名。还好这个主机是一个liunx虚拟主机而不是一个ftp服务器,我可以对apache进行配置实现这个需求。

方案1:反向代理

反向代理对seo来说是一个完美的解决方案,因为他不会产生域名的变化,没有302,只是增加了服务器的网络流量的压力。在apache上通过配置mod_proxy实现。参考官方文档看清apache版本(2.2还是2.4,语法可能不一样),别瞎JB百度。

当然问题并不仅仅是代理一下页面这么简单,开启代理后发现所有js、css、图片都404了,因为英文站那边资源路径都使用了”/”指向根目录,然而在代理之后他的路径是一个二级目录,这时就需要其他mod来修改页面内容,mod_porxy_html可以满足需求。然而在apache2.4中,mod_porxy_html是官方mod之一,其他版本只能第三方添加,官网编译配置。其中依赖库是libxml2(其实这个东西本来就有对html5兼容的坑),还需要mod_xml2enc对编码进行控制。编译需要apache自带的工具进行编译链接,大致如下

apxs2 -c -I /usr/include/libxml2 -I . -i mod_proxy_html.c

最后在apache2.2.22上配置如下,参考了mod_porxy_html给的proxy_html.conf。

#LoadFile   /usr/lib/x86_64-linux-gnu/libxml2.so
#LoadModule     proxy_module    /usr/lib/apache2/modules/mod_proxy.so
#LoadModule     proxy_html_module       /usr/lib/apache2/modules/mod_proxy_html.so
#LoadModule     proxy_http_module       /usr/lib/apache2/modules/mod_proxy_http.so
#LoadModule     xml2enc_module  modules/mod_xml2enc.so

ProxyHTMLLinks  a               href
ProxyHTMLLinks  area            href
ProxyHTMLLinks  link            href
ProxyHTMLLinks  img             src longdesc usemap
ProxyHTMLLinks  object          classid codebase data usemap
ProxyHTMLLinks  q               cite
ProxyHTMLLinks  blockquote      cite
ProxyHTMLLinks  ins             cite
ProxyHTMLLinks  del             cite
ProxyHTMLLinks  form            action
ProxyHTMLLinks  input           src usemap
ProxyHTMLLinks  head            profile
ProxyHTMLLinks  base            href
ProxyHTMLLinks  script          src for

ProxyHTMLEvents onclick ondblclick onmousedown onmouseup \
                onmouseover onmousemove onmouseout onkeypress \
                onkeydown onkeyup onfocus onblur onload \
                onunload onsubmit onreset onselect onchange


ProxyRequests Off

<Proxy *>
        Order deny,allow
        Allow from all
</Proxy>


ProxyPass /en http://en.foo.cn/
ProxyPassReverse /en http://en.foo.cn/
<Location "/en">
        AddOutputFilterByType SUBSTITUTE text/html
        #Substitute 's|="/|="./|i'
        Substitute 's|"/UpLoadFile|"./UpLoadFile|i'
        #Substitute "s|<body>|<body><base href='http://www.foo.cn/en/'/>|i"
        Substitute 's|&#65279;||i'

        ProxyPassReverse /
        xml2EncDefault UTF-8
        ProxyHTMLCharsetOut UTF-8
        #ProxyHTMLEnable        On
        SetOutputFilter proxy-html
        ProxyHTMLURLMap  / /en/
</Location>

当然这个反向代理并不完美,在实际使用中发现代理过来的页面有utf-8的那个bom头,导致页面上有一个占位符影响布局,暂不知道怎么解决。

方案2:重定向

使用mod_rewrite对某url的请求修改为302重定向到正确的地址。然而我当年实现这一需求的一开始确实尝试用mod_rewrite实现,但是tmd没配置成功(没实现,只能折腾反向代理了)

我现在又tmd配成功了,我也不知道当时为什么不工作。配置直接使用.htaccess文件。

<IfModule mod_rewrite.c>
        RewriteEngine on 

        #RewriteBase "/"

        RewriteRule ^(.+)$ http://en.foo.cn/$1

</IfModule>

<IfModule dir_module>
    DirectoryIndex index.shtml
</IfModule>

其他问题

背景说明:英文站点那边服务态度很差,服务偶尔不可用,现在tmd又换机器了,切换二级域名解析之后,英文站可以正常代理,但是tmd服务器在美国,服务不可用的情况更多了,经常出现以下提示

(104)Connection reset by peer: proxy: error reading status line from remote server

这时本人站了出来,使用mod_cache缓存英文站点页面,反正你们页面基本不会变。参考文档配置如下

<IfModule mod_cache.c>
#LoadModule disk_cache_module modules/mod_disk_cache.so
# If you want to use mod_disk_cache instead of mod_mem_cache,
# uncomment the line above and comment out the LoadModule line below.
        <IfModule mod_disk_cache.c>
                CacheRoot /alidata/www/cache/
                CacheEnable disk /en/
                CacheEnable disk http://en.foo.cn/
                CacheDirLevels 5
                CacheDirLength 3
                CacheIgnoreCacheControl On
                CacheMaxFileSize 100000000
                CacheIgnoreNoLastMod On
                CacheMaxExpire 1209600
                CacheIgnoreQueryString On
                CacheDefaultExpire 3600
                CacheStoreNoStore On
                CacheStorePrivate On
        </IfModule>

# When acting as a proxy, don't cache the list of security updates
#CacheDisable http://security.update.server/update-list/
</IfModule>

为什么不用mem_cache,因为内存不够,总共4G内存,莫名可用才120MB,服务器挂了一个tomcat占用快1G内存,真是黑心老板压榨员工啊。现在公司的话,内存用到这个程度已经紧急报警了。

一开始使用最少的配置,并没有起到缓存效果,后来直接一股脑把配置全开了,it work,也没仔细关心到底是哪个配置项起了作用,谁让http缓存有那么多属性呢。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注