安装使用GAE(Google App Engine)

GAE简介

GAE,(全称Google App Engine),是Google云计算的一部分,是一个互联网应用服务引擎。你可以使用GAE的API开发互联网应用,在 Google 的基础架构上运行你的网络应用程序。 GAE应用程序易于构建和维护,并可根据访问量和数据存储需要的增长轻松扩展,而不用担心带宽和主机问题。使用GAE,只需上传你的应用程序,它便可立即 为你的用户提供服务。 使用GAE是免费的,每个用户可以拥有500MB的存储空间,以及支持每月500万PV,这对普通的用户来说绰绰有余。当然利用GAE搭建博客有优点,也 有缺点。

如何利用GAE平台架设专属于自己的BLOG。

一、运行GAE 的准备工作

安装Google App Engine SDK for Python

http://code.google.com/intl/en/appengine/downloads.html

安装Python

http://www.python.org/download/

请安装Python 2.x的版本!如果安装3.x的版本,GAE是不干活的。

二、申请注册GAE

这里我默认你已经拥有Google帐号,到GAE的页面去注册一个帐号。首次创建GAE会有个欢迎页面。

GAE帐号免费申请,需要手机短信认证,手机号前记得添加国际区号,例如中国的用户写上+86。

注册GAE需要手机 短信验证

三、建立Application

利用短信收到的验证码激活并登录GAE。GAE的每个用户可以创建10个应用,不算多,也不算少了。

当然,你现在还没有 任何应用,那就来创建一个。为你的应用取一个喜欢的名字,不过你可能会发现要找一个别人没用过的好名字,真的很难。

记住你取好的这个名 字,以后就可以通过http://{yourname}.appspot.com
访问你的博客。

四、下载micolog
博客代码

再次感谢xuming的开源博客程序,他在Google Code放出了micolog博客的 GAE代码,任何人可以下载使用。

传送门:http://code.google.com/p/micolog/downloads/list

五、测试运行micolog博客

将下载的压缩包解压到Google App Engine SDK的安装目录,默认目录是『C:\Program Files\Google\google_appengine』,用记事本打开『micolog』文件夹中『app.yaml』文件,把第一行的 『application:』后面的字符串,改成你在GAE上新建的应用名,比如是colin-young。

然后运行 Google App Engine Launcher(安装GAE SDK时默认会添加桌面和开始菜单快捷方式,如果没有,在安装目录『…\google\google_appengine』的子目录『launcher』 下,找到并运行『GoogleAppEngineLauncher.exe』。在GAE Launcher中添加本地的Application。

添加已有的应用

填入micolog 的目录来把它添加到GAE Launcher中

添加好了我们的 micolog程序后,点击Run,等待片刻,再点击Browse,就可以在浏览器中预览你的博客程序了。如果测试一切正常,就可以上传了。

测试应用是否正常运 行

六、上传部署micolog博客

从开始菜单,运行cmd,进入命令行。进入Google App Engine的目录(默认进入命令为『CD  C:\Program Files\Google\google_appengine』),输入命令:『appcfg.py update micolog』。(记得用Tab键哦。这下会体会到Tab键的强大了吧?)

首次上传会要求输入 你的google帐号(******@gmail.com)和密码。然后要做的就是等待。

上传完成后,就可以 通过访问http://{yourname}.appspot.com的方式浏览和管理你在GAE上的博客了。Have Fun。

以后想折腾模板或者 插件等需要到C:\Program Files\Google\google_appengine\micolog目录下,修改相应文件,修改后记得用上述命令上传覆盖哦。主题和插件安装只需把下载的文件解压到micolog下的theme和plugins目录下,上传就好了。

一直想爽爽GAE, 下午抽时间出来试了一下感觉挺好玩的。

网站找的几篇文章这边还不错跟着做就能玩起来了。

Magento添加左侧目录商品菜单导航栏

自己写了一个Magento左侧目录
的实现,跟网上的其他版本不一样。

目标:

首页左侧显示商品目录

内页显示同级目录及父、子目录

商品详细页面显示一路父目录

本范例比较适合综合站使用,当然单独站也兼容。

 

效果:

magento左侧目录效果图1

左侧目录全部展开的情况

magento左侧目录效果图2

展开了二级目录

magento左侧目录效果图3

定位到Magento三级目录

实现:

布局设置,

app\design\frontend\default\default\layout\catalog.xml 加,

<reference name=”left”>
<block type=”catalog/navigation” name=”cms_catalog” template=”catalog/catalog.phtml”/>
</reference>

模板文件,

app\design\frontend\default\default\template\catalog 建catalog.phtml,内容为:

<style>.currentCategory{color:#004cb8; font-weight:bold;}</style>
<!-- /*S_leftNavContainer*/ -->
<div id="leftNavContainer" name="leftNavContainer">
<?php
$_cat        = $this->getCurrentCategory();
$current_cat    = (is_object($_cat) ? $_cat->getName() : '');
$leftNav    = '<ul id="leftNav" name="leftNav">';
switch( $_cat -> getLevel() ){
case '2':
default:
    $leftNav    .= '<li class="leftnav_title"><a href="'.$this -> getCategoryUrl($_cat).'" class="currentCategory">'.$_cat -> getName().'</li>';
    $_categories    = $_cat->getChildrenCategories();
    $leftNav    .= '<ul>';
    foreach( $_categories as $_category ){
        $leftNav    .= '<li class="lefnavtwo"><a href="'.$this -> getCategoryUrl( $_category ).'" >'.$_category -> getName().'</a></li>';
    }
    $leftNav    .= '</ul>';
break;
case '3':
    $_parent    = $_cat -> getParentCategory();
    $leftNav    .= '<li class="leftnav_title"><a href="'.$this -> getCategoryUrl($_parent).'">'.$_parent -> getName().'</a></li>';
    $_categories    = $_parent -> getChildrenCategories();
    $leftNav    .= '<ul>';
    foreach( $_categories as $_category ){
        $leftNav    .= '<li class="lefnavtwo">';
        if( $current_cat == $_category->getName() ){
            $leftNav    .= '<a class="currentCategory" href="'.$this -> getCategoryUrl( $_category ).'" >'.$_category -> getName().'</a>';
            $leftNav    .= '<ul>';
            if( $_category -> hasChildren() ){
                $childCategoies    = $_category -> getChildrenCategories();
                foreach( $childCategoies as $_ccategory ){
                    $leftNav    .= '<li class="lefnavthree"><a href="'.$this -> getCategoryUrl( $_ccategory ).'" >'.$_ccategory -> getName().'</a></li>';
                }
            }
            $leftNav    .= '</ul>';
        }else{
            $leftNav    .= '<a href="'.$this -> getCategoryUrl( $_category ).'" >'.$_category -> getName().'</a>';
        }
        $leftNav    .= '</li>';
    }
    $leftNav    .= '</ul>';
break;
case '4':
    $_parent    = $_cat -> getParentCategory();
    $_pname        = $_parent -> getName();
    $_pparent    = $_parent -> getParentCategory();
    $leftNav    .= '<li class="leftnav_title"><a href="'.$this->getCategoryUrl($_pparent).'">'.$_pparent -> getName().'</h3></li>';
    $_categories    = $_pparent -> getChildrenCategories();
    $leftNav    .= '<ul>';
    foreach( $_categories as $_category ){
        $leftNav    .= '<li class="lefnavtwo">';
        $leftNav    .= '<a href="'.$this -> getCategoryUrl( $_category ).'" >'.$_category -> getName().'</a>';
        if( $_pname == $_category->getName() ){
            $_categories    = $_category -> getChildrenCategories();
            $leftNav    .= '<ul>';
            foreach( $_categories as $_ccategory ){
                $leftNav    .= '<li class="lefnavthree">';
                if( $current_cat == $_ccategory -> getName() ){
                    $leftNav    .= '<a class="currentCategory" href="'.$this -> getCategoryUrl( $_ccategory ).'" >'.$_ccategory -> getName().'</a>';
                }else{
                    $leftNav    .=  '<a href="'.$this -> getCategoryUrl( $_ccategory ).'" >'.$_ccategory -> getName().'</a>';
                }
                $leftNav    .= '</li>';
            }
            $leftNav    .= '</ul>';
        }
        $leftNav    .= '</li>';
    }
    $leftNav    .= '</ul>';
break;
}
$leftNav    .= '</ul>';
echo $leftNav;
?>
</div>
<!-- /*E_leftNavContainer*/ -->
 

这样就实现了Magento左侧目录
的添加。

什么是data URI scheme及如何使用data URI scheme

网页优化的一大首要任务是减少HTTP 请求 (http request) 的次数,例如通过合并多个JS文件,合并CSS样式文件。除此之外,还有一个data URL 的密技,让我们直接把图像的内容崁入网页里面,这个密技的官方名称是 data URI scheme

 

什么是 data URI scheme?

假设你有以下的图像:

A

把它在网页上显示出来的标准方法是:

<img src="//sjolzy.cn/images/A.png"/>

这 种取得资料的方法称为 http URI scheme
,同样的效果使用 data URI scheme
可以写成:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA
7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC" />

换句话说我们把图像档案的内容内置在 HTML 档案中,节省了一个 HTTP 请求。

Data URI scheme 的语法

我们来分析一下这句 img 标签的语法:

<img src="data:image/png;base64,iVBOR....>

它包含一下部分:

data - 取得数据的协定名称

image/png - 数据类型名称

base64 - 数据的编码方法

iVBOR.... - 编码后的数据

: , ; - data URI scheme 指定的分隔符号

Base64 编码?

不知道什么是 base64 吗?简单地说它把一些 8-bit 数据翻译成标准 ASCII 字符,往上有很多免费的 base64 编码和解码的工具,你也可以用 PHP 的 base64_encode() 进行编码:

echo base64_encode(file_get_contents('check.png'));

在 CSS 中使用 data URL

Data URI scheme 也可以在 CSS 中使用,例如:

body { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA
7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC");}

浏 览器会缓存这种图像吗?

不会,Data URL 虽然节省 HTTP 请求,但是倘若这个图像要在网页多个地方显示的话,便会加大网页的内容,延长了下载的时间,其中一个解决办法是在一个 CSS class 中加入 data URL,在需要显示图像的区块调用这个 class,例如:

.logobg {
  background: url(data:…)
}
<div class=”navigation logobg”>..
helo, hello
<div class=”footer logobg”>…

又 是 IE 来搞破坏

任何精采的技巧都可能受到 IE 的排挤,这次也有这种情况,IE8 之前的版本都不支援 data URI scheme。

解决这个问题的办法有:使用MHTML 解决 data URI scheme 的浏览器兼容问题

具体做法看代码(肯定是用css hack来实现)

/*
Content-Type: multipart/related; boundary="_ANY_STRING_WILL_DO_AS_A_SEPARATOR"
 
--_ANY_STRING_WILL_DO_AS_A_SEPARATOR
Content-Location:the9
Content-Transfer-Encoding:base64
 
/9j/4AA....+b0//2Q== (这里是base64编码)
*/
 
#the9{
  background-image: url("data:image/png;base64/9j/4AA....+b0//2Q=="); /* normal */
  *background-image: url(mhtml:http://www.zhangjingwei.com/demo/scheme/style.css!the9);
  width:300px;
  height:300px;
  color:#F00;
  font-weight:900;
}

Nginx+uwsgi快速部署Python应用

从学过的编程语言来说,感觉PHP的部署是最Easy的。只要把环境搭建好,PHP文件丢到路径,访问即可,不用操心php-cgi运行如何,很是方便啊。
而Phthon的部署就麻烦了,以下是总结网上资料关于使用Nginx+uwsgi来部署Python应用。

Python的WEB服务器大部分可分为:Python写的(如Medusa
),嵌入 Python的(如mod_python
的),或者调用Python通过网关协议(例如的CGI,FastCGI的,等等)

Python常见部署方法有

  1. fcgi
    :用spawn-fcgi或者框架自带的工具对各个project分别生成监听进程,然后和http 服务互动
  2. wsgi
    :利用http服务的mod_wsgi模块来跑各个project(Web应用程序或框架简单而通用的Web服务器 之间的接口)。

    其实 WSGI 是分成 server 和 framework (即 application) 两部分 (当然还有 middleware)。严格说 WSGI 只是一个协议, 规范 server 和 framework 之间连接的接口。

    • WSGI server 把服务器功能以 WSGI 接口暴露出来。比如 mod_wsgi 是一种 server, 把 apache 的功能以 WSGI 接口的形式提供出来。
       
    • WSGI framework 就是我们经常提到的 Django 这种框架。不过需要注意的是, 很少有单纯的 WSGI framework , 基于 WSGI 的框架往往都自带 WSGI server。比如 Django、CherryPy 都自带 WSGI server 主要是测试用途, 发布时则使用生产环境的 WSGI server。而有些 WSGI 下的框架比如 pylons、bfg 等, 自己不实现 WSGI server。使用 paste 作为 WSGI server。
       

    Paste 是流行的 WSGI server, 带有很多中间件。还有 flup 也是一个提供中间件的库。

    搞清除 WSGI server 和 application, 中间件自然就清楚了。除了 session、cache 之类的应用, 前段时间看到一个 bfg 下的中间件专门用于给网站换肤的 (skin) 。中间件可以想到的用法还很多。

    这里再补充一下, 像 django 这样的框架如何以 fastcgi 的方式跑在 apache 上的。这要用到 flup.fcgi 或者 fastcgi.py (eurasia 中也设计了一个 fastcgi.py 的实现) 这些工具, 它们就是把 fastcgi 协议转换成 WSGI 接口 (把 fastcgi 变成一个 WSGI server) 供框架接入。整个架构是这样的: django -> fcgi2wsgiserver -> mod_fcgi -> apache 。

    虽然我不是 WSGI 的粉丝, 但是不可否认 WSGI 对 python web 的意义重大。有意自己设计 web 框架, 又不想做 socket 层和 http 报文解析的同学, 可以从 WSGI 开始设计自己的框架。在 python 圈子里有个共识, 自己随手搞个 web 框架跟喝口水一样自然, 非常方便。或许每个 python 玩家都会经历一个倒腾框架的

uWSGI
是一款像php-cgi一样监听同一端口,进行统一管理和负载平衡的工具,uWSGI,既不用wsgi协议也不用fcgi协议,而是自创了一个uwsgi的协议,据说该协议大约是fcgi协议的10倍那么快。

uWSGI的主要特点如下:

  1. 超快的性能。
     
  2. 低内存占用(实测为apache2的mod_wsgi的一半左右)。
     
  3. 多app管理。
     
  4. 详尽的日志功能(可以用来分析app性能和瓶颈)。
     
  5. 高度可定制(内存大小限制,服务一定次数后重启等)。

下面正式介绍Nginx+uwsgi的部署。

uwsgi的官方文档:http://projects.unbit.it/uwsgi/wiki/Doc

1.安装uwsgi

ubuntu有uwsgi的ppa:

add-apt-repository ppa:stevecrozz/ppa 
apt-get update 
apt-get install uwsgi 

2. 用uwsgi代替mod_wsgi

Nginx
的整体配置这里不说了,假设已经明白 Nginx的基本配置,那么uwsgi就类似这么配置:

    location / {  
      include uwsgi_params  
      uwsgi_pass 127.0.0.1:9090  
    } 

再比如django就是:

 .......  
 from django.core.handlers.wsgi import WSGIHandler  
 application = WSGIHandler() 

然后运行uwsgi监听9090,其中-w后跟模块名,也就是刚才配置的myapp

 uwsgi -s :9090 -w myapp 

运行网站发现已经部署完成了。

3.uwsgi的参数

以上是单个project的最简单化部署,uwsgi还是有很多令人称赞的功能的,例如:

并发4个线程:

  uwsgi -s :9090 -w myapp -p 4 

主控制线程+4个线程:

  uwsgi -s :9090 -w myapp -M -p 4 

执行超过30秒的client直接放弃:

  uwsgi -s :9090 -w myapp -M -p 4 -t 30 

限制内存空间128M:

  uwsgi -s :9090 -w myapp -M -p 4 -t 30 --limit-as 128 

服务超过10000个req自动respawn:

  uwsgi -s :9090 -w myapp -M -p 4 -t 30 --limit-as 128 -R 10000 

后台运行等:

  uwsgi -s :9090 -w myapp -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log 

4.为uwsgi配置多个站点

为了让多个站点共享一个uwsgi服务,必须把uwsgi运行成虚拟站点:去掉“-w myapp”加上”–vhost”:

  uwsgi -s :9090 -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log --vhost 

然后必须配置virtualenv,virtualenv是Python的一个很有用的虚拟环境工具,这样安装:

  apt-get install Python-setuptools
  easy_install virtualenv 

然后设置一个/多个app基准环境:

  virtualenv /var/www/myenv 

应用环境,在此环境下安装的软件仅在此环境下有效:

 source /var/www/myenv/bin/activate  
 pip install django  
 pip install mako  
 ... 

最后配置nginx,注意每个站点必须单独占用一个server,同一server不同location定向到不同的应用不知为何总是失败,估计也 算是一个bug。

      server {  
         listen       80;  
         server_name  app1.mydomain.com;  
         location / {  
                 include uwsgi_params;  
                 uwsgi_pass 127.0.0.1:9090;  
                 uwsgi_param UWSGI_PYHOME /var/www/myenv;  
                 uwsgi_param UWSGI_SCRIPT myapp1;  
                 uwsgi_param UWSGI_CHDIR /var/www/myappdir1;  
          }  
     }  
     server {  
         listen       80;  
         server_name  app2.mydomain.com;  
         location / {  
                 include uwsgi_params;  
                 uwsgi_pass 127.0.0.1:9090;  
                 uwsgi_param UWSGI_PYHOME /var/www/myenv;  
                 uwsgi_param UWSGI_SCRIPT myapp2;  
                 uwsgi_param UWSGI_CHDIR /var/www/myappdir2;  
         }  
     } 

这样,重启nginx服务,两个站点就可以共用一个uwsgi服务了。

参考文章:Python 应用程序配置

如果,我们可以晚一些遇见

 

我稀饭这文章。

 

如果,我们可以晚一些遇见。

不需要晚多久,就再过那么几年,

那时我们有稳定的收入,靠谱的工作,所有的一切步入正轨。

你不再是一个青涩的毛头小伙子,而是一个成熟的男人,

我不再是一个追梦的漂浮女生,而是一个只寻求安稳生活的女人。

到那时候, 那时候,我们再相爱。



如果,我们可以晚一些遇见。

不需要多久,就再过那么几年。
那时候我已经学会了知足,学会了包容和珍惜,而你也真的能从容的面对那些不停追逐你的异性。

到那时候,那时候,我们再相爱。




如果,我们可以晚一些遇见。

不需要过多久,就再过那么几年。

那时候社会的历练会让我的身上有足够的闪光点,照耀得你不想再望向别人;

那时候生活和现实会让我觉得家是安稳,使你觉得一直走下去有了“家”的感觉。

到那时候,那时候,我们再相爱。



如果,我们可以晚一些遇见。

不需要多久,就再过那么几年。

那时候我们的人生观、价值观、理想、追求也许会一致,

我们的生活圈子也许会向一起靠拢。

我们不会再因为没有共同语言而争吵,

不会再因为意见不合而互相伤害,不会互相猜疑不信任。

我们会坐在我们共同的房子里听着我们都喜欢的音乐,聊一些工作上的、朋友中的生活琐事。

到那时候,那时候,我们再相爱。



如果,我们可以晚一些遇见。

不需要多久,就再过那么几年。

那时候我们可以一起推着手推车去超级市场购物,

一起去宜家,一起在节假日买礼物送给对方的父母。

我会在母亲节同样给你的妈妈送上康乃馨,

你也会在我父亲生日的时候订做蛋糕并署上你的名字。

到那时候,那时候,我们再相爱。



如果,我们可以晚一些遇见。

不需要多久,就再过那么几年。

那时候我不会再有敏感的神经质,你也不再有暴躁的坏脾气。

到那时候,那时候,我们再相爱。

如果,我们可以晚一些遇见。



那么似乎所有的问题都不再是问题,所有的分歧都不再是分歧。

那时候,我们会不会很合拍?

那时候,我们会不会很默契?

如果真的有那么一天,我们的身边也许已经有了在对的时间遇见的人,

那么对的爱情就应该继续。又也许,你的那个她还幸运的在你身边。



物换星移。

总有一天我们都会明白。

那是一种追寻。

或许到最后都不曾拥有过,但是那是属于最纯真的东西。

每个人简单的时候对于感情都有一个童话。

也许在时间的驾驭下看到了太多的背叛。

当我们学会了享受寂寞,遏制住没有责任感的“新鲜感”的时候。

我们才可以真的羡慕,相濡以沫、执子之手,

我们才不会只听悲伤的歌,看幸福的戏。



经历了青春年少时的疯狂浪漫,

也看懂了许多失落遗憾。

童话般的感情只能留给曾经或是梦境,

生活不会那么单纯。

所以要以一颗坦然的心去生活,

我们的世界可以没那么不简单,

但是要努力对自己简单一些。