关于GAE与WordPress的一些进展和经验

        把最近的工作总结一下,大致有以下几点:

  • 在以前教育网镜像站的基础上改进了运行在GAE上的反向代理程序,一是降低了代理出错的几率,二是用memcache大大提高访问速度,三是在源服务器出错时GAE的反向代理能够cache下来用户POST的信息,减少留言丢失的可能。
  • 写了一个缩短网址的python小程序。
  • 尝试使用GAE的Java支持运行Wordpress,取得一些进展,但没有成功。
  • 这个blog搬了两次地方,先是ATBHost挂掉,只好搬到宿舍,用GAE做反向代理 , 昨天Google的ghs以及4个域名停放IP全部被墙,我又搬到DripHost这个免费空间,Dreamhostapps,加拿大,500M空间1G流量,有广告。
        由于#GFW墙了google域名停放,加上我现在有更重要的工作要做,所以这里暂且放下,希望在不久以后能够看到GAE上完美运行wordpress。

        首先是我的这个反向代理,用memcache加速,缓存管理,预存POST,我把它挂在了Google Code,项目地址在:http://code.google.com/p/greproxy/。缩短网址功能也集成在一起。

        在GAE上运行wordpress,需要解决数据库和PHP两个问题。PHP由Quercus实现,这是一个运行于Java的PHP环境。可以先参考将quercus应用在Google App Engine上,英文原文Quercus on Google App Engine。用Quercus在GAE实现了修改过的WP。该文作者把每个调用数据库的函数和变量都进行了修改,wp-db.php这个类基本作废,用JPA存储数据。能够实现发文和发评论。但是RSS等的数据库函数都还没有写。
        另外一篇是jiql – 说明文档(一个运行在GAE上面的Mysql),源地址在在http://code.google.com/p/jiql/。jiql能够在GAE上模拟出MySQL数据库,并且jiql也给出了包含jiql的Quercus
        我尝试在添加了jiql的Quercus上运行WP,PhpMyAdmin根本无法运行,于是手动写了PHP代码,将原先的数据库分批插入。一定要分批是因为jiql之行INSERT非常之慢,WP初始化所需的数据库大约需要分10来次插入。
        然后运行WP2.8.5发现报错,主要问题在引用了限制的Java类,调用java.net.Proxy类出错是http.php这个文件的使用代理、打开Socks等等,以至整个文件中的函数都无法运行,直接删除了这个文件,又把require它的wp-settings.php:352注释掉。又注释了几行:

                cron.php:229
                functions.php:1931-1949,2071,2074,2168,2171
                wp-db.php:700

        最终的结果是一个干净的WP(禁用插件、cron)可以在GAE上完整插入数据库了。但是一个完整的页面都不能显示。昨天的最终错误停留在plugin.php:336-342的do循环上,错误类型是”com.caucho.quercus.QuercusModuleException: java.lang.StackOverflowError”
        应该是算法太复杂导致GAE内存溢出?把循环体注释掉循环是可以执行完毕的。顺便说下GAE的运算能力十分强大,而Quercus也同样强大地消耗CPU资源,数据库INSERT大约20条语句就需要30s的执行时间,消耗60s的cpu时间。这次大约5秒后就报错,不知原因。
        希望ghs尽快解封,也希望有人能够完善Wp on GAE。

        最后说一下我是如何去除目前博客空间DripHost上面的广告的。手段一般,网速不快的话还可以看到上下的广告一闪而过。

        DripHost会自动在文本/html页上生成广告,有两部分,第一部分位于HTTP响应主体开头:

<CENTER>
<script type="text/javascript"><!--
google_ad_client = "pub-4191196622577214";
/* 728x90, created 2/10/09 */
google_ad_slot = "9500732878";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</CENTER>

        第二部分位于响应结尾的</body></html>之前:

<CENTER>
<a href="http://www.driphost.com/"><img src="http://www.driphost.com/eads/72090logo.jpg" /></a>
<br>
<b><A HREF="http://www.driphost.com">Hosted By www.DripHost.com</A></b>
</CENTER>

        对前一部分,解决方法是用JavaScript删除整个<CENTER>标签,我把以下代码插入侧边拦:

<script type="text/javascript">
var x=document.getElementsByTagName("center");
x[0].parentNode.removeChild(x[0]);
</script>

        对后一部分,我不知道JavaScript如何作用载入之后的DOM,于是修改footer.php,在结尾的</body></html>之前加上<script>。于是后面的代码当作JavaScript,不执行了。
        

19 thoughts on “关于GAE与WordPress的一些进展和经验”

    1. 打开edu.py文件,修改开头部分的设置区,把你的WordPress网址和GAE网址填上去。
      这个反向代理程序还有若干小bug,今后会慢慢完善。

      1. 这个代码必须镜像WP网站?
        我的不是WP是个论坛
        另外就算我不改也应该镜像http://www.lostriver.net吧怎么会返回个空的html呢?
        (老大你的http://www.lostriver.net好象被GFW了)

  1. 这个代码必须镜像WP网站?
    我的不是WP是个论坛
    另外就算我不改也应该镜像http://www.lostriver.net吧怎么会返回个空的html呢?

    1. 太活跃的网站不适合用GAE做反向代理,memcache加速不可用,如果你的主机在国内GAE很容易抓取失败。
      如果主机在美国可以试试:
      #修改edu.py:
      TARGET_URL_SHORTER = 被代理论坛地址
      APP_ID = 你GAE的id
      IF_USE_MEMCACHE = False
      另外删掉188-194行,#Strip DRIP Host ADs之后几行,我用来屏蔽广告用的代码。

      这样你的论坛可以通过yourid.appspot.com访问。

      1. 我晕,,,怎么还是返回一个空壳html给我。。
        http://mmqqwwee.appspot.com/
        code;
        TARGET_URL_SHORTER = “www.google.com” #the domain which GAE fetch from
        PROXY_SER_URL = “mmqqwwee.appspot.com” #domain of your GAE app
        APP_ID = “mmqqwwee” #the app-id of GAE
        SHORTLINK_URL = “s.lostriver.net” #the short-links domain

        #Set whether using MEMCACHE or not
        IF_USE_MEMCACHE = False

        #Set forcing https when visit through *.appspot.com
        IF_FORCE_HTTPS = False
        #—————-#
        我一开始想用mirrorrr做镜像的,但是mirrorrr不支持POST方式并且对Cookie的支持也不好,所以才找到这里的

      2. 你去GoogleCode上面下载一个最新版本,刚重看了一下抱歉发现我上次上传了错误的代码。
        设置区域修改你是正确的,如果你GAE绑定了域名,PROXY_SER_URL填你绑的域名。设置区后面区域无需修改了。
        这次对代码略为修改,特意试验了一下,Discuz和水木bbs都可以登录,但一检查Referer就不行。
        我很难有时间不断完善这样一个Python习作,建议你自学一下或者找一个程序员看看吧。

  2. 感谢你,我试了下可以登陆但是不能发帖子,还有就是.html的更新有点慢刷新了N次也没刷出来新内容,不过以经很好了
    (顺便问下,请程序员在GAE上写个类似go2,appspot.com 的代码要多少钱?)

  3. 我还有个建议,能不能同时镜像多个域?
    比如有些网站html在www而图片和css在img和css,镜像www是快了但是图片还是一样的慢~~~

  4. 由于AppEngine不支持MySQL及PHP,我下载了包,并修改部署至。在登录界面,我利用错误用户名/密码则提示登录失败,但是当我用正确的用户名/密码登录的时候,出现了500 Server Error页面,查看日志如下:

    /wordpress-2.7.1/wp-login.php
    java.security.AccessControlException: access denied (java.io.FilePermission /dev/urandom read)
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:355)
    at java.security.AccessController.checkPermission(AccessController.java:567)
    at java.lang.SecurityManager.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkRead(Unknown Source)
    at java.io.FileInputStream.(FileInputStream.java:133)
    at com.caucho.vfs.FilePath.openReadImpl(FilePath.java:543)
    at com.caucho.vfs.Path.openRead(Path.java:1082)
    at com.caucho.quercus.lib.file.FileInput.(FileInput.java:71)
    at com.caucho.quercus.lib.file.FileModule.fopen(FileModule.java:1399)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Method.java:43)
    at com.caucho.quercus.module.StaticFunction.invoke(StaticFunction.java:135)
    at com.caucho.quercus.env.JavaInvoker.callMethod(JavaInvoker.java:670)

    ……

    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:238)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
    at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnecti

    因怀疑是调用了随机数函数导致读取Unix平台下随机数生成器失败,所以我把wp-login.php里用到随机数的地方都硬编码了,可问题依然存在。
    不知是什么问题,请教之。

    1. Caucho的blog上的Demo后台我进不去,但是错误提示和你的不一样,印象中是Null pointer或者stack overflow。

      我后来尝试利用jiql直接移植WordPress也没有成功,但是你这里出现的两个问题也遇到了并且可以解决,第一个确实是/dev/urandom的问题,
      wp-includes/class-phpass.php:Ln59,把if ($fh = @fopen(‘/dev/urandom’, ‘rb’))改成if (0),跳过/dev/urandom问题解决。

      第二个异常是进WordPress后台的时候抓取了官方feed,用到了fsockopen(),GAE不支持。把http.php删掉,其他调用http.php的函数的代码改掉即可。

      我最后的问题出在jiql这里: http://code.google.com/p/jiql/issues/detail?id=1 我是外行,不懂Java,所以停在这里。

      1. 谢谢你的回复,今天研究了一天,发现要搞定这个Wordpress修改版需要的成本还是挺大的。
        首先,采用你的建议解决了/dev/urandom的问题,后来又发现了很多GAE数据操作的问题,因为这个Blog在很多页面里依然在调用访问MySQL的函数,所以,如果将所有MySQL操作替代为对GAE数据区的JPA操作还比较费力(我也是PHP外行)。
        另外有一点,就是这个Wordpress修改版本部署在GAE上访问速度很慢,个人认为Caucho解析PHP页面占用了很多时间,因为所有的页面/控制/JPA操作都在PHP页面定义。
        所以正在考虑寻找一个更好的替代品来搭建基于GAE的Blog,如果博主有好的建议请赐教,谢谢。

      2. 改的代码确实应该比较多,而且要有好的performance还要继续改进。你只是需要一个GAE上的blog?用Micolog或者Cpedia都不错。重要的blog还是不要放在appspot上,app经常被屏蔽没法做百度SEO。

  5. 谢谢指点,我确实只想要一个Blog,自己的小团队用。
    百度居然屏蔽appspot,难怪没看到多少基于GAE搭建的Blog。

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>