亚洲国产精品99久久久久久久久,国产一区二区三区视频在线观看,久久久国产精品亚洲一区http://cppblog.com/guojingjia2006/category/11424.htmlPay it forword - 我并不覺的自豪,我所嘗試的事情都失敗了······習(xí)慣原本生活的人不容易改變,就算現(xiàn)狀很糟,他們也很難改變,在過程中,他們還是放棄了······他們一放棄,大家就都是輸家······讓愛傳出去,很困難,也無法預(yù)料,人們需要更細(xì)心的觀察別人,要隨時(shí)注意才能保護(hù)別人,因?yàn)樗麄兾幢刂雷约阂裁础ぁぁぁぁ?/description>zh-cnWed, 14 May 2014 14:21:39 GMTWed, 14 May 2014 14:21:39 GMT60 shrio 權(quán)限管理filterChainDefinitions過濾器配置 http://m.shnenglu.com/guojingjia2006/archive/2014/05/14/206956.html小果子小果子Wed, 14 May 2014 03:57:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2014/05/14/206956.htmlhttp://m.shnenglu.com/guojingjia2006/comments/206956.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2014/05/14/206956.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/206956.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/206956.html

/**

* Shiro-1.2.2內(nèi)置的FilterChain

* @see =============================================================================================================================

* @see 1)Shiro驗(yàn)證URL時(shí),URL匹配成功便不再繼續(xù)匹配查找(所以要注意配置文件中的URL順序,尤其在使用通配符時(shí))

* @see   故filterChainDefinitions的配置順序?yàn)樽陨隙?以最上面的為準(zhǔn)

* @see 2)當(dāng)運(yùn)行一個(gè)Web應(yīng)用程序時(shí),Shiro將會創(chuàng)建一些有用的默認(rèn)Filter實(shí)例,并自動(dòng)地在[main]項(xiàng)中將它們置為可用

* @see   自動(dòng)地可用的默認(rèn)的Filter實(shí)例是被DefaultFilter枚舉類定義的,枚舉的名稱字段就是可供配置的名稱

* @see   anon---------------org.apache.shiro.web.filter.authc.AnonymousFilter

* @see   authc--------------org.apache.shiro.web.filter.authc.FormAuthenticationFilter

* @see   authcBasic---------org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter

* @see   logout-------------org.apache.shiro.web.filter.authc.LogoutFilter

* @see   noSessionCreation--org.apache.shiro.web.filter.session.NoSessionCreationFilter

* @see   perms--------------org.apache.shiro.web.filter.authz.PermissionAuthorizationFilter

* @see   port---------------org.apache.shiro.web.filter.authz.PortFilter

* @see   rest---------------org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter

* @see   roles--------------org.apache.shiro.web.filter.authz.RolesAuthorizationFilter

* @see   ssl----------------org.apache.shiro.web.filter.authz.SslFilter

 *@see   user---------------org.apache.shiro.web.filter.authz.UserFilter

* @see =============================================================================================================================

* @see 3)通常可將這些過濾器分為兩組

* @see   anon,authc,authcBasic,user是第一組認(rèn)證過濾器

* @see   perms,port,rest,roles,ssl是第二組授權(quán)過濾器

* @see   注意user和authc不同:當(dāng)應(yīng)用開啟了rememberMe時(shí),用戶下次訪問時(shí)可以是一個(gè)user,但絕不會是authc,因?yàn)閍uthc是需要重新認(rèn)證的

* @see                      user表示用戶不一定已通過認(rèn)證,只要曾被Shiro記住過登錄狀態(tài)的用戶就可以正常發(fā)起請求,比如rememberMe

* @see                      說白了,以前的一個(gè)用戶登錄時(shí)開啟了rememberMe,然后他關(guān)閉瀏覽器,下次再訪問時(shí)他就是一個(gè)user,而不會authc

* @see =============================================================================================================================

* @see 4)舉幾個(gè)例子

* @see   /admin=authc,roles[admin]      表示用戶必需已通過認(rèn)證,并擁有admin角色才可以正常發(fā)起'/admin'請求

* @see   /edit=authc,perms[admin:edit]  表示用戶必需已通過認(rèn)證,并擁有admin:edit權(quán)限才可以正常發(fā)起'/edit'請求

* @see   /home=user                     表示用戶不一定需要已經(jīng)通過認(rèn)證,只需要曾經(jīng)被Shiro記住過登錄狀態(tài)就可以正常發(fā)起'/home'請求

* @see =============================================================================================================================

* @see 5)各默認(rèn)過濾器常用如下(注意URL Pattern里用到的是兩顆星,這樣才能實(shí)現(xiàn)任意層次的全匹配)

* @see   /admins/**=anon             無參,表示可匿名使用,可以理解為匿名用戶或游客

* @see   /admins/user/**=authc       無參,表示需認(rèn)證才能使用

* @see   /admins/user/**=authcBasic  無參,表示httpBasic認(rèn)證

* @see   /admins/user/**=user        無參,表示必須存在用戶,當(dāng)?shù)侨氩僮鲿r(shí)不做檢查

* @see   /admins/user/**=ssl         無參,表示安全的URL請求,協(xié)議為https

* @see   /admins/user/**=perms[user:add:*]

* @see       參數(shù)可寫多個(gè),多參時(shí)必須加上引號,且參數(shù)之間用逗號分割,如/admins/user/**=perms["user:add:*,user:modify:*"]

* @see       當(dāng)有多個(gè)參數(shù)時(shí)必須每個(gè)參數(shù)都通過才算通過,相當(dāng)于isPermitedAll()方法

* @see   /admins/user/**=port[8081]

* @see       當(dāng)請求的URL端口不是8081時(shí),跳轉(zhuǎn)到schemal://serverName:8081?queryString

* @see       其中schmal是協(xié)議http或https等,serverName是你訪問的Host,8081是Port端口,queryString是你訪問的URL里的?后面的參數(shù)

* @see   /admins/user/**=rest[user]

* @see       根據(jù)請求的方法,相當(dāng)于/admins/user/**=perms[user:method],其中method為post,get,delete等

* @see   /admins/user/**=roles[admin]

* @see       參數(shù)可寫多個(gè),多個(gè)時(shí)必須加上引號,且參數(shù)之間用逗號分割,如/admins/user/**=roles["admin,guest"]

* @see       當(dāng)有多個(gè)參數(shù)時(shí)必須每個(gè)參數(shù)都通過才算通過,相當(dāng)于hasAllRoles()方法

* @see

http://liureying.blog.163.com/blog/static/61513520136205574873/

spring中 shiro logout 配置方式
有兩種方式實(shí)現(xiàn)logout
1. 普通的action中 實(shí)現(xiàn)自己的logout方法,取到Subject,然后logout
這種需要在ShiroFilterFactoryBean 中配置 filterChainDefinitions
對應(yīng)的action的url為anon
<property name="filterChainDefinitions">
            <value>
                # some example chain definitions:
                /index.htm = anon
                /logout = anon
                /unauthed = anon
                /console/** = anon
                /css/** = anon
                /js/** = anon
                /lib/** = anon
                /admin/** = authc, roles[admin]
                /docs/** = authc, perms[document:read]
                /** = authc
                # more URL-to-FilterChain definitions here
            </value>

2. 使用shiro提供的logout filter
需要定義 相應(yīng)的bean
<bean id="logout" class="org.apache.shiro.web.filter.authc.LogoutFilter">
        <property name="redirectUrl" value="/loginform" />
    </bean>

然后將相應(yīng)的url filter配置為logout如下
<property name="filterChainDefinitions">
            <value>
                # some example chain definitions:
                /index.htm = anon
                /logout = logout
                /unauthed = anon
                /console/** = anon
                /css/** = anon
                /js/** = anon
                /lib/** = anon
                /admin/** = authc, roles[admin]
                /docs/** = authc, perms[document:read]
                /** = authc
                # more URL-to-FilterChain definitions here
            </value>

http://kdboy.iteye.com/blog/1154652
http://blog.csdn.net/peterwanghao/article/details/8084126
http://www.oschina.net/question/593111_62454
http://blog.csdn.net/shadowsick/article/details/17265625



小果子 2014-05-14 11:57 發(fā)表評論
]]>
CentOS 6下安裝nodejs 0.9.0http://m.shnenglu.com/guojingjia2006/archive/2014/01/20/205486.html小果子小果子Mon, 20 Jan 2014 02:11:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2014/01/20/205486.htmlhttp://m.shnenglu.com/guojingjia2006/comments/205486.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2014/01/20/205486.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/205486.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/205486.html

確保安裝了python,大部分安裝失敗都是由于python版本過低導(dǎo)致。安裝之前,升級python版本,升級步驟 http://www.tomtalk.net/wiki/Python

[root@SNDA-192-168-15-161 ~]# python -V
Python 2.7.3
開始安裝:

1).下載nodejs到本地并解壓縮
[root@SNDA-192-168-15-161 node]# wget http://nodejs.org/dist/v0.9.0/node-v0.9.0.tar.gz
[root@SNDA-192-168-15-161 node]# tar zxvf node-v0.9.0.tar.gz
2).進(jìn)入到該目錄編譯和安裝
[root@SNDA-192-168-15-161 node-v0.9.0]# cd node-v0.9.0
[root@SNDA-192-168-15-161  node-v0.9.0]# ./configure --prefix=/usr/local/node/0.9.0
這里安裝在了/usr/local/node/0.9.0目錄下
[root@SNDA-192-168-15-161 node-v0.9.0]# make
[root@SNDA-192-168-15-161 node-v0.9.0]# make install
3).配置NODE_HOME
[root@SNDA-192-168-15-161 node-v0.9.0]# vi /etc/profile
在export PATH USER 。。。一行的上面添加如下內(nèi)容,并將NODE_HOME/bin設(shè)置到系統(tǒng)path中
#set for nodejs
export NODE_HOME=/usr/local/node/0.9.0
export PATH=$NODE_HOME/bin:$PATH
保存退出后執(zhí)行如下命令,使剛才的配置生效
[root@SNDA-192-168-15-161 node-v0.9.0]# source /etc/profile

執(zhí)行node -h命令驗(yàn)證設(shè)置成功

[root@SNDA-192-168-15-161 ~]# node -h
Usage: node [options] [ -e script | script.js ] [arguments]
       node debug script.js [arguments]

Options:
  -v, --version        print node's version
  -e, --eval script    evaluate script
  -p, --print          print result of --eval
  -i, --interactive    always enter the REPL even if stdin
                       does not appear to be a terminal
  --no-deprecation     silence deprecation warnings
  --trace-deprecation  show stack traces on deprecations
  --v8-options         print v8 command line options
  --max-stack-size=val set max v8 stack size (bytes)

Environment variables:
NODE_PATH              ':'-separated list of directories
                       prefixed to the module search path.
NODE_MODULE_CONTEXTS   Set to 1 to load modules in their own
                       global contexts.
NODE_DISABLE_COLORS    Set to 1 to disable colors in the REPL

Documentation can be found at http://nodejs.org/
至此安裝設(shè)置完畢。

運(yùn)行一個(gè)簡單的node應(yīng)用程序 + socket.io,首先需要安裝socket.io模塊

[root@SNDA-192-168-15-161 ~]# npm install socket.io

[root@SNDA-192-168-15-161 ~]# vi app.js

var http=require('http');
var io =require('socket.io');
var server = http.createServer(function(req,res){

    res.writeHead(200,{'Content-Type':'text/plain'});
    res.end('Hello world');
});

server.listen(process.argv[2]);

var socket = io.listen(server);
socket.on('connection',function(client){
    console.log('client has connected');
    client.on('message',function(){ });
});
 

[root@SNDA-192-168-15-161 ~]# nodejs ./app.js 8001 &

[root@SNDA-192-168-15-161 ~]# nodejs ./app.js 8002 &

[root@SNDA-192-168-15-161 ~]# nodejs ./app.js 8003 &

[root@SNDA-192-168-15-161 ~]# nodejs ./app.js 8004 &

更詳細(xì)的參照socket.io的官網(wǎng)的例子。

websocket與node.js的完美結(jié)合

http://wanshuiqianshan.iteye.com/blog/1618498



小果子 2014-01-20 10:11 發(fā)表評論
]]>
Meteor:讓實(shí)時(shí)Web App成為主流http://m.shnenglu.com/guojingjia2006/archive/2013/03/22/198709.html小果子小果子Fri, 22 Mar 2013 01:41:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2013/03/22/198709.htmlhttp://m.shnenglu.com/guojingjia2006/comments/198709.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2013/03/22/198709.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/198709.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/198709.html

Meteor是一個(gè)新鮮出爐的現(xiàn)代網(wǎng)站開發(fā)平臺,目前發(fā)布的是開發(fā)預(yù)覽版0.5.8,代碼以GPL協(xié)議開源。大家可以去 GitHub上關(guān)注它。Meteor本質(zhì)上是Node.JS應(yīng)用的開發(fā),繼承了Ruby on Rails、Node.JS、MongoDB API等框架的基礎(chǔ)特性,模糊了服務(wù)器端和客戶端,弱化網(wǎng)絡(luò)連接質(zhì)量造成的影響。

如果簡單定義“現(xiàn)代網(wǎng)站”是一個(gè)實(shí)時(shí)交互、超高性能、具備非凡體驗(yàn)的網(wǎng)站,那么 Meteor就是一個(gè)可為開發(fā)者以簡單高效而且充滿樂趣的方式進(jìn)行現(xiàn)代網(wǎng)站開發(fā)的平臺,以往開發(fā)周期需要幾周到幾個(gè)月的項(xiàng)目,現(xiàn)在可能只需要幾個(gè)小時(shí)或者 一個(gè)周末的時(shí)間就可以完成。Meteor構(gòu)建的應(yīng)用體驗(yàn),會讓人覺得瀏覽器的刷新按鈕和地址欄是多余的。

Meteor在2012年4月首次發(fā)布,該消息一經(jīng)發(fā)布,便迅速占據(jù)了Haceker News頭條寶座,并且成為Hacker News上最熱門的文章之一。本文是作者Sacha Greif使用Meteor開發(fā)的心得體會,他認(rèn)為Meteor會讓實(shí)時(shí)Web App在未來成為主流。

下面是對原文的翻譯:

在過去6個(gè)月里,我使用Meteor做了點(diǎn)東西( Telescope,Meteor開源的主要應(yīng)用程序之一),我覺得有必要分享一下我的感受。


首先聲明:在和Meteor代碼打交道的每一天里,我的大部分時(shí)間都在使Telescope變更加可用,而不是去深入挖掘Meteor,所以我不敢 自稱是Meteor方面的專家,而之所以能很快上手,很大一部分原因是因?yàn)樗且粋€(gè)非常好用且高效的框架,即使在你不精通的情況下也能開發(fā)出非常出色的應(yīng) 用。

簡單 智能

Meteor的一大特色就是可以輕松構(gòu)建高品質(zhì)的實(shí)時(shí)Web應(yīng)用程序,相信很多程序員都是因?yàn)檫@一特性而熟知Meteor的。當(dāng)開始使用Meteor時(shí),會讓你的生活變得很簡單。

安裝Meteor也非常簡單,只需一行命令即可。隨即便創(chuàng)建第一個(gè)應(yīng)用程序,就連部署也都非常簡單,由于Meteor提供免費(fèi)的托管,因此你可以在線部署,供世界各地的人來瀏覽。


此外,使用Meteor編寫的應(yīng)用程序運(yùn)行速度也非常快。例如,當(dāng)你的項(xiàng)目引用JS或CSS文件時(shí),這些文件將會被自動(dòng)加載,而Meteor也提供了內(nèi)置的用戶管理,自動(dòng)完成UI部件的加載。

Meteor九大特性

  1. 純JavaScript
  2. 實(shí)時(shí)頁面更新
  3. 干凈、強(qiáng)大的數(shù)據(jù)同步
  4.  延遲補(bǔ)償
  5. 代碼熱推送
  6. 敏感代碼運(yùn)行于受限環(huán)境中
  7.  完全獨(dú)立的應(yīng)用包
  8. 互操作
  9. 智能的包

實(shí)時(shí)的未來

說實(shí)話,實(shí)時(shí)框架是Meteor的最大賣點(diǎn),實(shí)時(shí)Web應(yīng)用程序會讓人聯(lián)想到多人游戲和實(shí)時(shí)在線文檔編輯,但在使用Meteor時(shí),我快速發(fā)現(xiàn)實(shí)時(shí)也可以編寫出更加實(shí)用且非常好的應(yīng)用程序,而這種實(shí)時(shí)很有可能會成為未來幾年內(nèi)Web應(yīng)用程序的默認(rèn)編寫方式。

在桌面應(yīng)用系統(tǒng)中,如果一個(gè)目錄被兩個(gè)窗口同時(shí)打開,那么當(dāng)你在其中一個(gè)窗口刪除一個(gè)文件后,你必須刷新另一個(gè)窗口,那個(gè)文件才會“消失”。因此,這就缺乏了實(shí)時(shí)性,而Meteor框架就可彌補(bǔ)這方面的不足。

此外,實(shí)時(shí)也影響到我們的編碼風(fēng)格。你無需刷新頁面或使用特定的回調(diào)邏輯來使應(yīng)用程序做出響應(yīng):每一個(gè)塊數(shù)據(jù)都會自動(dòng)監(jiān)測、任何與UI元素有關(guān)的數(shù)據(jù)也會自動(dòng)更新。

下面提供一個(gè)案例,一旦有人投票,就響應(yīng)upvote按鈕的“disable”類,模板代碼(Meteor使用 Handlebars):

1
2
3
4
<div class="post">
  <a href="#" class="upvote btn {{upvotedClass}}">?<a />
  <h3><a href="{{url}}">{{title}}</a></h3>
</div>

下面是與之匹配的控制器代碼:

1
2
3
4
5
6
7
8
9
10
11
12
Template.post.helpers({
  upvotedClass: function() {
    // test if user is logged in, and if their userId
    // is included in the 'upvoters' array
    var userId = Meteor.userId();
    if (userId && !_.include(this.upvoters, userId)) {
      return 'upvoteable';
    } else {
      return 'disabled'
    }
  }
});

這段代碼妙在何處呢?如果用戶的userid從upvoters數(shù)組中刪除(例如,實(shí)現(xiàn)一個(gè)“cancel upvote”操作),這會自動(dòng)在UI上反應(yīng)出來,無需編寫額外的代碼。

一切就緒了嗎?

現(xiàn)在,你可能會隨著這一行行代碼思考些東西:“好,它看起來很棒,但是它真的就可以作為現(xiàn)實(shí)應(yīng)用( real-world apps)嗎?”

答案肯定是依情況而定。Meteor當(dāng)然可以作為現(xiàn)實(shí)應(yīng)用使用。Telescope和Sidebar(基于Telescope)就是非常完美的例子。

但并不是說Meteor就可以完全作為現(xiàn)實(shí)應(yīng)用使用。Meteor沒有服務(wù)端渲染功能,有些網(wǎng)站對加載速度要求特別高,比如電子商務(wù)網(wǎng)站,而有些則需要在舊的/老的設(shè)備上運(yùn)行,比如過時(shí)的手機(jī)。

Meteor Book

目前,我和 Tom Coleman(Meteor開源生態(tài)系統(tǒng)的主要貢獻(xiàn)者之一,創(chuàng)建Meteor包管理器 Meteorite)正在專注于 The Meteor Book,教你如何使用Meteor編寫基本的應(yīng)用程序。

更多精彩內(nèi)容,大家可以來到Hacker News上和我一起 探討。(編譯/張紅月 責(zé)編/付江)


學(xué)習(xí)資料:

官方提供的3個(gè)示例:

GitHub項(xiàng)目頁:

Meteor@StackOverflow

文檔:

FAQ:



小果子 2013-03-22 09:41 發(fā)表評論
]]>
eclipse 4.2 aptanahttp://m.shnenglu.com/guojingjia2006/archive/2013/02/22/197992.html小果子小果子Fri, 22 Feb 2013 02:25:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2013/02/22/197992.htmlhttp://m.shnenglu.com/guojingjia2006/comments/197992.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2013/02/22/197992.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/197992.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/197992.html

1、使用軟件更新的方式:

打開Eclipse -> Help -> Install New Software 然后在彈出對話框的 Work with 框中輸入如下的地址,回車。

http://update.aptana.com/update/studio/3.2/

然后就會一步步選擇需要安裝的組件即可。

2、在Eclipse 4.2 上安裝 Aptana 3.2遇到的錯(cuò)誤,提示找不到 org.eclipse.update.ui 0.0.0

通過google(這種時(shí)候記得別使用百度),看到有同樣的問題:

http://boards.developerforce.com/t5/General-Development/Trouble-with-Force-com-IDE-installation-in-Eclipse-4-2/m-p/480891#M73687

 

其中的有人回答:

Hi, After i am downloadinng org.eclipse.update.ui_3.2.300.v20100512.jar and org.eclipse.update.ui.source_3.2.300.v20100512.jar files from the below site and placed it under eclipse/plugins directory and it worked for me.http://grepcode.com/snapshot/repository.grepcode.com/java/eclipse.org/3.6/org.eclipse.update/ui/3.2.... thanks, Ravi
 
按照提示的這個(gè)網(wǎng)址,去下載 ui組件,放置到eclipse目錄的 plugins 之中,重啟eclipse,再次安裝即可成功。
 
注:Eclipse 4.2的update ui,在這里:http://grepcode.com/search /?r=repository.grepcode.com$java$eclipse.org$4.2&start=20&query=org.eclipse.update+ui+3.2....&entity=project
 
另外如果要安裝Aptana直接輸入:http://download.aptana.com/studio3/plugin/install 進(jìn)行更新即可。

Re: Trouble with Force.com IDE installation in Eclipse 4.2

‎08-09-2012 10:06 AM

Update:

 

In the post I linked above: http://boards.developerforce.com/t5/General-Development/Install-Eclipse-Juno-4-2-with-Force-com-IDE/..., there's been a solution that worked for me.

 

To Quote Zokito:

 

08-09-2012 09:04 AM

Hi,

 

cause of the problem lies here:

 

http://www.eclipse.org/eclipse/development/porting/4.2/incompatibilities.html

(search for org.eclipse.update.ui)

 

It should be possible to fetch the deependency automatically through the marketplace but for me it's not working.... so what would you need to do is install the org.eclipse.update.ui manually from e.g.

http://www.java2s.com/Code/Jar/o/Downloadorgeclipseupdateui32300v20100512jar.htm

 

 

extract it and than copy the jar file to your eclipse/plugins/ directory. 

Start Eclipse again and then try to install the Force IDE plugin.

 

 

this solved the issue for me

 

Hope this is helpful!

 

Kelly



小果子 2013-02-22 10:25 發(fā)表評論
]]>
Yii RBAC(轉(zhuǎn))http://m.shnenglu.com/guojingjia2006/archive/2013/01/15/197298.html小果子小果子Tue, 15 Jan 2013 11:38:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2013/01/15/197298.htmlhttp://m.shnenglu.com/guojingjia2006/comments/197298.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2013/01/15/197298.html#Feedback1http://m.shnenglu.com/guojingjia2006/comments/commentRss/197298.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/197298.html

寫在前面

  • 以下內(nèi)容適合Yii 1.0.x,其他版本可能有略微的差別。
  • 根據(jù)您的評論和反饋,本文會不斷進(jìn)行修改和補(bǔ)充,以方便新學(xué)習(xí)者。

開始準(zhǔn)備

Yii提供了強(qiáng)大的配置機(jī)制和很多現(xiàn)成的類庫。在Yii中使用RBAC是很簡單的,完全不需要再寫RBAC代碼。所以準(zhǔn)備工作就是,打開編輯器,跟我來。

設(shè)置參數(shù)、建立數(shù)據(jù)庫

在配置數(shù)組中,增加以下內(nèi)容:

components => array(
//……
authManager=>array(
class=>CDbAuthManager,//認(rèn)證類名稱
defaultRoles=>array(guest),//默認(rèn)角色
itemTable => pre_auth_item,//認(rèn)證項(xiàng)表名稱
itemChildTable => pre_auth_item_child,//認(rèn)證項(xiàng)父子關(guān)系
assignmentTable => pre_auth_assignment,//認(rèn)證項(xiàng)賦權(quán)關(guān)系
),
//……

那這三個(gè)數(shù)據(jù)表怎么建立呢?很簡單,去看framework/web/auth/schema.sql。注意要和你的自定義的表名稱對應(yīng)起來。比如SQL文件中的AuthItem你要修改為pre_auth_item。然后在數(shù)據(jù)庫中運(yùn)行這個(gè)SQL文件中的語句。

了解概念

你可能要問,剩下的代碼呢?我告訴你,沒有啦。RBAC系統(tǒng)就這樣建立起來了。但是為了使用它,你需要了解它的運(yùn)行機(jī)制。我會盡量講的啰嗦一點(diǎn)……(官方的RBAC文檔在這里,但是我曾經(jīng)看了4-5遍才明白。)

三個(gè)概念

你需要了解的是,授權(quán)項(xiàng)目可分為operations(行動(dòng)),tasks(任務(wù))和 roles(角色)。

一個(gè)用戶擁有一個(gè)或者多個(gè)角色,比如,我們這里有三個(gè)角色:銀行行長銀行職員顧客。我們假設(shè):

  • 張行長 有角色:銀行行長、銀行職員、顧客(人家自己可以存錢嘛)。
  • 王職員 有角色:銀行職員、顧客。
  • 小李 有角色:顧客。

那么,相應(yīng)的,只要顧客可以做的事情,小李就可以做,王職員和張行長也可以。銀行職員可以做的事情,王職員和張行長都可以做,小李就不可以了。

比如,一個(gè)“顧客”可以存錢,那么擁有“顧客”角色的張行長、王職員、小李都可以存錢。“銀行職員”可以打印顧客的交易記錄,那么有“銀行職員”角 色的張行長和王職員都可以,而小李不行,必須找一個(gè)有“銀行職員”角色的人才可以打印詳細(xì)的交易記錄。一個(gè)“銀行行長”才可以進(jìn)入銀行錢庫提錢,那么只有 張行長可以,因?yàn)樗庞?#8220;銀行行長”的角色。

這就是基于角色的認(rèn)證體系,簡稱RBAC。

角色的繼承

角色是可以繼承的,比如我們規(guī)定如下:

  • 凡是“銀行行長”都是“銀行職員”,也就是說,只要銀行職員可以做的事情,銀行行長都可以做。
  • 凡是“銀行職員”都是顧客,同上,顧客可以做的事情銀行職員也可以做。

那么角色關(guān)系就變成了:

  • 張行長 有角色:銀行行長。
  • 王職員 有角色:銀行職員。
  • 小李 有角色:顧客。

這樣更簡單了,這就是角色的繼承。

任務(wù)的繼承

一個(gè)任務(wù)(task)是可以包含另外一個(gè)任務(wù)的,我們舉個(gè)例子,比如“進(jìn)入銀行”。

我們設(shè)定“顧客”這個(gè)角色有“進(jìn)入銀行”的權(quán)限。也就是說,“顧客”可以執(zhí)行“進(jìn)入銀行”的任務(wù)。接下來,我們假設(shè)“進(jìn)入柜臺”是進(jìn)入銀行的父權(quán) 限,也就是說,“進(jìn)入柜臺”包含“進(jìn)入銀行”。只要能“進(jìn)入柜臺”的人都可以“進(jìn)入銀行”。我們把“進(jìn)入柜臺”這個(gè)任務(wù)權(quán)限給“銀行職員”。

那么從角色上來說,王職員可以進(jìn)入銀行,因?yàn)橥趼殕T的角色是“銀行職員”,而“銀行職員”包含了“顧客”的角色。那么“顧客”可以進(jìn)行的“任務(wù)”對于“銀行職員”來說也是可以進(jìn)行的。而“顧客”可以“進(jìn)入銀行”,那么王職員也可以“進(jìn)入銀行”。這是角色的繼承帶來的。

我們再假設(shè)有個(gè)趙領(lǐng)導(dǎo),是上級領(lǐng)導(dǎo),可以進(jìn)入柜臺進(jìn)行視察。那么,我們的任務(wù)關(guān)系是:

  • 趙領(lǐng)導(dǎo) 有任務(wù):進(jìn)入柜臺。

那么,趙領(lǐng)導(dǎo)就可以“進(jìn)入銀行”。因?yàn)?#8220;進(jìn)入銀行”是被“進(jìn)入柜臺”包含的任務(wù)。只要可以執(zhí)行“進(jìn)入柜臺”的人都可以執(zhí)行“進(jìn)入銀行”。這就是任務(wù)的繼承。

關(guān)于行動(dòng)

行動(dòng)是不可劃分的一級。也就是說。而一個(gè)行動(dòng)是不能包含其他行動(dòng)的。假設(shè)我們有個(gè)行動(dòng)叫“從銀行倉庫中提錢”。我們把這個(gè)行動(dòng)作包含“進(jìn)入柜臺”。那么只要可以執(zhí)行“從銀行倉庫中提錢”的角色都可以執(zhí)行“進(jìn)入柜臺”這個(gè)任務(wù)。

三者關(guān)系

  • 一個(gè)角色可以包含另外一個(gè)或者幾個(gè)角色。
  • 一個(gè)角色可以包含另外一個(gè)或者幾個(gè)任務(wù)。
  • 一個(gè)角色可以包含另外一個(gè)或者幾個(gè)行動(dòng)。
  • 一個(gè)任務(wù)可以包含另外一個(gè)或者幾個(gè)任務(wù)。
  • 一個(gè)任務(wù)可以包含另外一個(gè)或者幾個(gè)行動(dòng)。
  • 一個(gè)行動(dòng)只能被角色或者任務(wù)包含,行動(dòng)是不可以包含其他,也不可再分。

這樣,就形成了一個(gè)權(quán)限管理體系。關(guān)于“任務(wù)”和“行動(dòng)”,你不必思考其字面上的意義。這兩者就是形成兩層權(quán)限。

進(jìn)行賦權(quán)

我們建立了RBAC權(quán)限管理,就需要進(jìn)行對權(quán)限的WEB管理。這些就需要你自己寫代碼了。

根據(jù)不同種類的項(xiàng)目調(diào)用下列方法之一定義授權(quán)項(xiàng)目:

一旦我們擁有一套授權(quán)項(xiàng)目,我們可以調(diào)用以下方法建立授權(quán)項(xiàng)目關(guān)系:

最后,我們調(diào)用下列方法來分配角色項(xiàng)目給各個(gè)用戶:

下面我們將展示一個(gè)例子是關(guān)于用所提供的API建立一個(gè)授權(quán)等級:

$auth=Yii::app()->authManager;  
$auth->createOperation('createPost','create a post');
$auth->createOperation('readPost','read a post');
$auth->createOperation('updatePost','update a post');
$auth->createOperation('deletePost','delete a post');

$bizRule='return Yii::app()->user->id==$params["post"]->authID;';
$task=$auth->createTask('updateOwnPost','update a post by author himself',$bizRule);
$task->addChild('updatePost');

$role=$auth->createRole('reader');
$role->addChild('readPost');

$role=$auth->createRole('author');
$role->addChild('reader');
$role->addChild('createPost');
$role->addChild('updateOwnPost');

$role=$auth->createRole('editor');
$role->addChild('reader');
$role->addChild('updatePost');

$role=$auth->createRole('admin');
$role->addChild('editor');
$role->addChild('author');
$role->addChild('deletePost');

$auth->assign('reader','readerA');
$auth->assign('author','authorB');
$auth->assign('editor','editorC');
$auth->assign('admin','adminD');
也就是說,你需要自己寫一個(gè)管理界面,來列出你的角色、任務(wù)、行動(dòng),然后可以在這個(gè)界面上進(jìn)行管理。比如增加、刪除、修改。

權(quán)限檢查

假設(shè)你在你的管理界面進(jìn)行了賦權(quán),那么可以在程序里面進(jìn)行權(quán)限檢查:

if(  Yii::app()->user->checkAccess('createPost')  )
{
// 這里可以顯示表單等操作
} else {
// 檢查沒有通過的可以跳轉(zhuǎn)或者顯示警告
}
上面的代碼就檢查了用戶是否可以執(zhí)行“createPost”,這createPost可能是一個(gè)任務(wù),也可以是一個(gè)行動(dòng)。

其他的

對于很多說Yii權(quán)限體系RBAC不好用的人其實(shí)都沒有看懂文檔。綜合我的體驗(yàn),我感覺Yii框架的RBAC是我用過的框架里面最好用的。而且是需要自己寫代碼最少的。

Yii的RBAC有更加高級的用法,比如“業(yè)務(wù)規(guī)則”,“默認(rèn)角色”。你可以去參考官方文檔。

我知道,會有部分人仍舊不理解RBAC,或者不會用Yii的RBAC。沒有關(guān)系,你可以在下方的評論框里提問。

happy Yii !



小果子 2013-01-15 19:38 發(fā)表評論
]]>
yii 源碼調(diào)試筆記(1)---theme - module - controller about layouthttp://m.shnenglu.com/guojingjia2006/archive/2013/01/11/197181.html小果子小果子Thu, 10 Jan 2013 16:03:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2013/01/11/197181.htmlhttp://m.shnenglu.com/guojingjia2006/comments/197181.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2013/01/11/197181.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/197181.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/197181.htmlstring(79) "D:\Program Files\Apach\htdocs\novemweb\themes\classic\views/admin/default\index" string(81) "D:\Program Files\Apach\htdocs\novemweb\themes\classic\views/admin/layouts/column1" string(78) "D:\Program Files\Apach\htdocs\novemweb\themes\classic\views/admin/layouts/main" string(81) "D:\Program Files\Apach\htdocs\novemweb\protected\modules\admin\views/layouts/main"

admin/default/index

This is the view content for action "index". The action belongs to the controller "DefaultController" in the "admin" module.

You may customize this page by editing D:\Program Files\Apach\htdocs\novemweb\themes\classic\views\admin\default\index.php

test--------------



小果子 2013-01-11 00:03 發(fā)表評論
]]>
centos 上安裝gearmanhttp://m.shnenglu.com/guojingjia2006/archive/2013/01/07/197076.html小果子小果子Mon, 07 Jan 2013 08:39:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2013/01/07/197076.htmlhttp://m.shnenglu.com/guojingjia2006/comments/197076.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2013/01/07/197076.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/197076.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/197076.html
官網(wǎng):http://gearman.org/

跨多種環(huán)境部署 Gearman
http://www.ibm.com/developerworks/cn/opensource/os-gearman/index.html
利用開源的Gearman框架構(gòu)建分布式圖片處理平臺-張宴
http://blog.s135.com/dips/
監(jiān)控:
https://github.com/yugene/Gearman-Monitor

一、簡介
Gearman是一個(gè)分發(fā)任務(wù)的程序架構(gòu),由三部分組成:
Gearman client:提供gearman client API給應(yīng)用程序調(diào)用。API可以使用C,PHP,PERL,MYSQL UDF等待呢個(gè)語言,它是請求的發(fā)起者。
Gearman job server:將客戶端的請求分發(fā)到各個(gè)gearman worker的調(diào)度者,相當(dāng)于中央控制器,但它不處理具體業(yè)務(wù)邏輯。
Gearman worker:提供gearman worker API給應(yīng)用程序調(diào)用,具體負(fù)責(zé)客戶端的請求,并將處理結(jié)果返回給客戶端。
Mogilefs的分布式文件系統(tǒng)的核心就是用gearman實(shí)現(xiàn)的。
這個(gè)軟件的應(yīng)用場景很多,比如視頻網(wǎng)站的視頻處理,分布式日志處理,電子郵件處理,文件同步處理,圖片處理等等,只要是可以放開,不影響體驗(yàn)和響應(yīng)的場 景,需要并行進(jìn)行大量計(jì)算和處理的程序都是可以的。Yahoo在60或更多的服務(wù)器上使用gearman每天處理600萬個(gè)作業(yè)。新聞聚合器digg構(gòu)建 了一個(gè)相同規(guī)模的gearman網(wǎng)絡(luò),每天可處理400000個(gè)作業(yè)。
Gearman不但可以做為任務(wù)分發(fā),還可以做為應(yīng)用方面的負(fù)載均衡。可以讓worker放在不同的一堆服務(wù)器上,也可以啟動(dòng)放在同一個(gè)cpu的多個(gè)核 上。比如,應(yīng)用視頻轉(zhuǎn)換程序,不希望web服務(wù)器來處理視頻格式轉(zhuǎn)換,這時(shí),可以在這一堆服務(wù)器上進(jìn)行任務(wù)分發(fā),在上面加載worker處理視頻格式,對 外的web服務(wù)器就不會被視頻轉(zhuǎn)換過程影響。而且擴(kuò)展方便,加一臺服務(wù)器到任務(wù)調(diào)度中心,注冊成worker即可,這時(shí)job server會在請求到來的時(shí)候,將請求發(fā)送給空閑的worker。還可以運(yùn)行多個(gè)job server,組成ha架構(gòu),如果一個(gè)job server當(dāng)?shù)袅耍琧lient和worker會自動(dòng)遷移到另一臺job server上。

二、安裝
[Job Server (gearmand) -- 172.16.1.183]
1.首先安裝libdrizzle
    #yum install libdrizzle libdrizzle-devel
2.安裝gearman(兩種方法1.yum2.源碼包)。(c版的server)
    1)yum安裝
    #rpm -ivh http://dl.iuscommunity.org/pub/ius/stable/Redhat/6/x86_64/epel-release-6-5.noarch.rpm
    #yum install -y gearmand
    2)源碼包安裝
    #cd /opt/build/
    #wget https://launchpad.net/gearmand/trunk/0.34/+download/gearmand-0.34.tar.gz
    #tar zxf gearmand-0.34.tar.gz
    #cd gearmand-0.34
    #./configure
    #make && make install
3.啟動(dòng)gearman服務(wù)
    1)yum安裝方式
    #/etc/init.d/gearmand start
    2)源碼包安裝方式
    #/opt/build/gearmand-0.34/sbin/gearmand -d

    #gearmand -vvv -u root
    INFO Starting up
    INFO Listening on :::4730 (6)
    INFO Creating wakeup pipe
    INFO Creating IO thread wakeup pipe
    INFO Adding event for listening socket (6)
    INFO Adding event for wakeup pipe
    INFO Entering main event loop

worker&&client以php方式
[worker --  172.16.1.180]
安裝gearmand如上所示

安裝 Gearman PHP extension
1.下載gearman-0.8.0.tgz并安裝
    #cd /opt/build/
    #wget http://pecl.php.net/get/gearman-0.8.0.tgz
    # yum install -y libgearman-devel.x86_64
    # yum install -y re2c
    #tar zxf gearman-0.8.0.tgz
    #cd gearman-0.8.0.tgz
    #phpize
    # ./configure
    # make && make install
2.編輯php.ini配置文件加載相應(yīng)模塊并使之生效
    # vim /etc/php.ini
    extension = "gearman.so"
3.查看gearman.so模塊是否加載
    # php --info | grep gearman
    gearman
    gearman support => enabled
    libgearman version => 0.14
    PWD => /opt/build/gearman-0.8.0
    _SERVER["PWD"] => /opt/build/gearman-0.8.0
    # php -m | grep gearman
    gearman
4.啟動(dòng)job
gearmand -d
如果當(dāng)前用戶是 root 的話,則需要這樣操作:
gearmand -d -u root
缺省會使用 4730 端口,下面會用到。
    注意:如果找不到 gearmand 命令的路徑,別忘了用 whereis gearmand 確認(rèn)

[client -- 172.16.1.181]
    安裝如work同。如上所示。

三、測試:
[Job Server (gearmand) -- 172.16.1.183]
啟動(dòng)gearmand

以命令行工具來驗(yàn)證gearman的功能
啟動(dòng) Worker:gearman -h 172.16.1.183 -w -f wc -- wc -l &
運(yùn)行Client:gearman -h 172.16.1.183 -f wc < /etc/passwd
42
可以看到驗(yàn)證成功。

以php驗(yàn)證gearman的功能
編寫 Worker
worker.php 文件內(nèi)容如下:
<?php
$worker= new GearmanWorker();
$worker->addServer('172.16.1.183', 4730);
$worker->addFunction('reverse', 'my_reverse_function');
while ($worker->work());
function my_reverse_function($job) {
return strrev($job->workload());
}
?>
設(shè)置后臺運(yùn)行 work
php worker.php &
編寫 Client
client.php 文件內(nèi)容如下:
<?php
$client= new GearmanClient();
$client->addServer('172.16.1.183', 4730);
echo $client->do('reverse', 'Hello World!'), "\n";
?>
運(yùn)行 client
php client.php
輸出:!dlroW olleH

Q:

I've been trying to get Gearman compiled on CentOS 5.8 all afternoon. Unfortunately I am restricted to this version of CentOS by my CTO and how he has our entire network configured. I think it's simply because we don't have enough resources to upgrade our network... But anyways, the problem at hand.

I have searched through Server Fault, Stack Overflow, Google, and am unable to locate a working solution. What I have below is stuff I have pieced together from my searching.

Searches have told said to install the following via yum:

yum -y install --enablerepo=remi boost141-devel libgearman-devel e2fsprogs-devel e2fsprogs gcc44 gcc-c++ 

To get the Boost headers working correctly I did this:

cp -f /usr/lib/boost141/* /usr/lib/ cp -f /usr/lib64/boost141/* /usr/lib64/ rm -f /usr/include/boost ln -s /usr/include/boost141/boost /usr/include/boost 

With all of the dependancies installed and paths setup I then download and compile gearmand-1.1.2 just fine.

wget -O /tmp/gearmand-1.1.2.tar.gz https://launchpad.net/gearmand/1.2/1.1.2/+download/gearmand-1.1.2.tar.gz cd /tmp && tar zxvf gearmand-1.1.2.tar.gz ./configure && make -j8 && make install 

That works correctly. So now I need to install the Gearman library for PHP. I have attempted through PECL and downloading the source directly, both result in the same error:

checking whether to enable gearman support... yes, shared not found configure: error: Please install libgearman 

What I don't understand is I installed the libgearman-devel package which also installed the core libgearman. The installation installs libgearman-devel-0.14-3.el5.x86_64, libgearman-devel-0.14-3.el5.i386, libgearman-0.14-3.el5.x86_64, and libgearman-0.14-3.el5.i386.

Is it possible the package version is lower than what is required? I'm still poking around with this, but figured I'd throw this up to see if anyone has a solution while I continue to research a fix.

Thanks!


A:

This should do the trick:

export GEARMAN_LIB_DIR=/usr/include/libgearman 
export GEARMAN_INC_DIR=/usr/include/libgearman

That should work, if not you'll have to do some minor edits to config.m4.


other:

http://gearman.org/gearman_php_extension
http://blog.csdn.net/aidenliu/article/details/7406390
http://www.php.net/manual/en/gearmanclient.dobackground.php
http://www.wenzizone.com/2012/09/27/how_to_fix_rpm_filedigests_payloadisxz_is_needed.html
http://www.2cto.com/os/201206/136785.html
http://blog.s135.com/dips
http://blog.csdn.net/hfahe/article/details/5519582
http://hi.baidu.com/sunjiujiu/item/4406281c952cf47a7b5f2594



小果子 2013-01-07 16:39 發(fā)表評論
]]>
Gearman簡單介紹http://m.shnenglu.com/guojingjia2006/archive/2012/12/27/196738.html小果子小果子Thu, 27 Dec 2012 12:19:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2012/12/27/196738.htmlhttp://m.shnenglu.com/guojingjia2006/comments/196738.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2012/12/27/196738.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/196738.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/196738.html

Gearman是一個(gè)分布式的任務(wù)調(diào)度框架,它包括 a client,a worker ,a job server這三部分組成。

Gearman的執(zhí)行過程:客戶端通過客戶端API(PHP,C,Perl等)創(chuàng)建一個(gè)任務(wù)發(fā)送到j(luò)ob server上,Job Server 通過客戶端的function name 查找合適的worker,并分到該worker上,worker接收到任務(wù)后根據(jù)worker的規(guī)則執(zhí)行,并返回?cái)?shù)據(jù)到j(luò)ob Server,而Job Server則把數(shù)據(jù)返回給客戶端,這樣Gearman的執(zhí)行過程就結(jié)束了。

用戶可以根據(jù)不同的需求制定不同的worker來處理不同的任務(wù),將這些worker存放到不同的服務(wù)器上,Job Server會根據(jù)不同的客戶端發(fā)送來的任務(wù)的function name尋找worker來執(zhí)行,從而達(dá)到為業(yè)務(wù)服務(wù)器減輕壓力;

Gearman的安裝:

下載http://launchpad.net/gearmand/trunk/0.12/+download/gearmand-0.12.tar.gz



[falcon@www-001  ~/src/]$ wget http://launchpad.net/gearmand/tr ... earmand-0.12.tar.gz
[falcon@www-001  ~/src/]$ cd gearmand-0.12

[falcon@www-001  ~/src/gearmand-0.12]$ ./configure --prefix=/home/falcon/gearmand

[falcon@www-001  ~/src/gearmand-0.12]$ make && make instal

運(yùn)行g(shù)earman 的job Server


[falcon@www-001  ~/src/gearmand-0.12]$ cd ~/gearmand

[falcon@www-001  ~/gearmand]$ ls
bin  include  lib  sbin  share
[falcon@www-001  ~/gearmand]$ sbin/gearmand --help
gearmand 0.12 - https://launchpad.net/gearmand
usage: sbin/gearmand
[OPTIONS]Main Options:
-b, --backlog=BACKLOG       Number of backlog connections for listen.
-d, --daemon                Daemon, detach and run in the background.
-f, --file-descriptors=FDS  Number of file descriptors to allow for the process                             
(total connections will be slightly less). Default     is max allowed for user.
-h, --help                  Print this help menu.
-j, --job-retries=RETRIES   Number of attempts to run the job before the job  server removes it. Thisis helpful to ensure a bad  job does not crash all available workers. Default  is no limit.
-l, --log-file=FILE         Log file to write errors and information to. Turning this option on also forces the first  verbose level to be enabled.
-L, --listen=ADDRESS        Address the server should listen on. Default is  INADDR_ANY.
-p, --port=PORT             Port the server should listen on.
-P, --pid-file=FILE         File to write process ID out to.
-r, --protocol=PROTOCOL     Load protocol module.
-R, --round-robin           Assign work in round-robin order per  workerconnection. The default is to assign work in  the order of functions added by the worker.
-q, --queue-type=QUEUE      Persistent queue type to use.
-t, --threads=THREADS       Number of I/O threads to use. Default=0.
-u, --user=USER             Switch to given user after startup.
-v, --verbose               Increase verbosity level by one.
-V, --version               Display the version of gearmand and exit.
-w, --worker-wakeup=WORKERS Number of workers to wakeup for each job received.   The default is to wakeup all available workers.



運(yùn)行Job Server服務(wù)

[falcon@www-001  ~/gearmand]$ sbin/gearmand -d



判斷gearmand是否運(yùn)行

[falcon@www-001  ~/gearmand]$ ps -ef|grep gearmand

falcon    9083     1  0 02:46 ?        00:00:00 sbin/gearmand -d -vv

falcon    9112 28298  0 02:47 pts/1    00:00:00 grep gearmand

[falcon@www-001  ~/gearmand]$ netstat -an -t|grep 4730

tcp        0      0 0.0.0.0:4730                0.0.0.0:*                   LISTEN  



到此Job Server運(yùn)行正常,下面我們可以簡單的在本地上測試Worker和Client是否能夠正常接收任務(wù)

我們這里用gearman命令來測試

[falcon@www-001  ~/gearmand]$ bin/gearman --help

bin/gearman: invalid option -- -

Client mode: bin/gearman [options] [<data>]

Worker mode: bin/gearman -w [options] [<command> [<args> ...]]

公共參數(shù)區(qū)

Common options to both client and worker modes.  

        -f <function> - Function name to use for jobs (can give many)處理任務(wù)的函數(shù)名

        -h <host>     - Job server host  (Job Server主機(jī),默認(rèn)是localhost)

        -H            - Print this help menu

        -p <port>     - Job server port (Job Server端口,默認(rèn)是4730)

        -t <timeout>  - Timeout in milliseconds  (執(zhí)行多長時(shí)間超時(shí),微秒)

        -i <pidfile>  - Create a pidfile for the process (創(chuàng)建進(jìn)程的pid文件)

Client部分參數(shù)

Client options:

        -b            - Run jobs in the background (后臺運(yùn)行任務(wù))

        -I            - Run jobs as high priority (高優(yōu)先級運(yùn)行任務(wù))

        -L            - Run jobs as low priority (低優(yōu)先級運(yùn)行任務(wù))

        -n            - Run one job per line (逐行執(zhí)行任務(wù))

        -N            - Same as -n, but strip off the newline  

        -P            - Prefix all output lines with functions names (在輸入結(jié)果前面加處理的函數(shù)名)

        -s            - Send job without reading from standard input 執(zhí)行任務(wù)不返回結(jié)果

        -u <unique>   - Unique key to use for job 任務(wù)的唯一標(biāo)識

Worker部分參數(shù)

Worker options:

        -c <count>    - Number of jobs for worker to run before exiting (統(tǒng)計(jì)worker進(jìn)程處理多少個(gè)任務(wù)后中止)

        -n            - Send data packet for each line

        -N            - Same as -n, but strip off the newline

        -w            - Run in worker mode   以worker模式運(yùn)行




示例一、以命令行方式模擬worker 和 client來處理任務(wù)

開啟一個(gè)worker,以function name 為 tongji 來處理輸入的數(shù)據(jù),統(tǒng)計(jì)行數(shù)并返回結(jié)果

[falcon@www-001  ~/gearmand]$ bin/gearman -w -f tongji -- wc -l  

模擬客戶端連接到Job Server,以tongji函數(shù)名來提交一個(gè)文件,并接收結(jié)果

[falcon@www-001  ~/gearmand]$ bin/gearman -f tongji  < /etc/profile

54




示例二、利用Gearman的php擴(kuò)展來測試Gearman



安裝PHP的Gearman擴(kuò)展模塊

[falcon@www-001  ~/src]$ wget  http://pecl.php.net/get/gearman-0.7.0.tgz

[falcon@www-001  ~/src]$ cd gearman-0.7.0

[falcon@www-001  ~/src/gearman-0.7.0]$ /home/falcon/php/bin/phpize

......

[falcon@www-001  ~/src/gearman-0.7.0]$ ./configure \

--with-php-config=/home/falcon/php/bin/php-config --with-gearman=/home/falcon/gearmand

[falcon@www-001  ~/src/gearman-0.7.0]$ make && make install

將gearman.so加入到php.ini配置文件使其生效

測試php是否加載gearman模塊



[falcon@www-001  ~/php/bin]$ php -m|grep gearman




官方示例:

將提交的字符串翻轉(zhuǎn)后返回



Worker :worker_reverse.php



<?php

$worker= new GearmanWorker();

$worker->addServer();

$worker->addFunction("reverse", "my_reverse_function");

while ($worker->work());


function my_reverse_function($job)

{

  return strrev($job->workload());

}

?>


運(yùn)行worker

$php work_reverse.php &




Client:client_reverse.php



<?php

$client= new GearmanClient();

$client->addServer();

print $client->do("reverse", "Hello World!");

?>


執(zhí)行client_reverse.php



$ php client_reverse.php

!dlroW olleH

參考資料:


http://gearman.org/index.php?id=getting_started


http://pecl.php.net/package/gearman


http://www.ibm.com/developerworks/cn/opensource/os-php-gearman/

小果子 2012-12-27 20:19 發(fā)表評論
]]>
Yii - Create your own Validation Rulehttp://m.shnenglu.com/guojingjia2006/archive/2012/12/26/196679.html小果子小果子Wed, 26 Dec 2012 07:39:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2012/12/26/196679.htmlhttp://m.shnenglu.com/guojingjia2006/comments/196679.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2012/12/26/196679.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/196679.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/196679.html

Some times the core validation rules provided by Yii won't satisfy all your needs, so you'll need to create your very own validation rule.

Easy approach: inside-model rule

The easiest way to create a new validation rule is inside the model that is going to use it.

Let's say that you want to check if a user password is safe enough.
Usually you could achieve this result just by using the CRegularExpressionValidator but for the sake of this guide let's pretend that validator does not exist.

first of all in your model class you'll have to add two constants

const WEAK = 0; const STRONG = 1;

then in your rules method you'll have to set the rule

/**  * @return array validation rules for model attributes.  */ public function rules() {     return array(        array('password', 'passwordStrength', 'strength'=>self::STRONG),     ); }

make sure that you won't give the rule the name of an existing one, otherwise you are going to have some troubles later.

Now the only thing you need to do is create a new method inside the model, named after the validation rule you just declared.

/**  * check if the user password is strong enough  * check the password against the pattern requested  * by the strength parameter  * This is the 'passwordStrength' validator as declared in rules().  */ public function passwordStrength($attribute,$params) {     if ($params['strength'] === self::WEAK)         $pattern = '/^(?=.*[a-zA-Z0-9]).{5,}$/';       elseif ($params['strength'] === self::STRONG)         $pattern = '/^(?=.*\d(?=.*\d))(?=.*[a-zA-Z](?=.*[a-zA-Z])).{5,}$/';         if(!preg_match($pattern, $this->$attribute))       $this->addError($attribute, 'your password is not strong enough!'); }

The new method you just created accepts two arguments:

  • $attribute = is the name of the attribute that the method is validating
  • $params = additional parameters that you could define in the rules

In our rules method we used this rule on the password attribute, so the value of attribute inside our validation model will be password

In the rule we also setted an additional parameter named strength
the value of that parameter will be inside the $params array

As you can see inside the method we are making a call to CModel::addError().
Add Error accepts two parameters: the first one is the name of the attribute that you want to display the error in your form, the second one is the actual error string you want to be displayed.

Complete approach: extending the CValidator class

If you need your custom validation rule in more then one model the best thing to do is extending the CValidator class.
Extending this class you also can take advantage of other features, like CActiveForm::$enableClientValidation, first implemented with Yii 1.1.7 release.

Creating the class file

The first thing that you have to do is create your class file. The best thing is to always name it after your class name, to best use Yii lazy loading feature. Let's create a new directory inside your application extensions directory (which is located inside the protected directory).
Name this directory MyValidators.
Then we create our own file: passwordStrength.php

Inside this file create our CValidator class

class passwordStrength extends CValidator {       public $strength;       private $weak_pattern = '/^(?=.*[a-zA-Z0-9]).{5,}$/';     private $strong_pattern = '/^(?=.*\d(?=.*\d))(?=.*[a-zA-Z](?=.*[a-zA-Z])).{5,}$/'; ...

In the class file create one attribute for each additional parameter that you want to use inside your validation rule.
CValidator will take care to populate that attribute with the parameter value all by itself.
We also created two other attributes, each containing the patterns we want to use in our preg_match function.

Now we have to override the parent abstract method validateAttribute

/**  * Validates the attribute of the object.  * If there is any error, the error message is added to the object.  * @param CModel $object the object being validated  * @param string $attribute the attribute being validated  */ protected function validateAttribute($object,$attribute) {     // check the strength parameter used in the validation rule of our model     if ($this->strength == 'weak')       $pattern = $this->weak_pattern;     elseif ($this->strength == 'strong')       $pattern = $this->strong_pattern;       // extract the attribute value from it's model object     $value=$object->$attribute;     if(!preg_match($pattern, $value))     {         $this->addError($object,$attribute,'your password is too weak!');     } }

The method above is self explanatory i think.
Of course you could use constants in those IF, and I actually recommend it.

Implementing Client Validation

If you want to implement client validation you'll need to override another method inside your class: clientValidateAttribute

/**  * Returns the JavaScript needed for performing client-side validation.  * @param CModel $object the data object being validated  * @param string $attribute the name of the attribute to be validated.  * @return string the client-side validation script.  * @see CActiveForm::enableClientValidation  */ public function clientValidateAttribute($object,$attribute) {       // check the strength parameter used in the validation rule of our model     if ($this->strength == 'weak')       $pattern = $this->weak_pattern;     elseif ($this->strength == 'strong')       $pattern = $this->strong_pattern;            $condition="!value.match({$pattern})";       return " if(".$condition.") {     messages.push(".CJSON::encode('your password is too weak, you fool!')."); } "; }

As you can see this method simply returns the javascript that you need to use for your validation

Last step: how to use your validation class inside the module rules

There are several approach you can use here.

You could first use Yii::import in the rules method before returning the rules array, or you can just use Yii dot notation:

/**  * @return array validation rules for model attributes.  */ public function rules() {     return array(        array('password', 'ext.MyValidators.passwordStrength', 'strength'=>self::STRONG),     ); }
more:
http://www.yiiframework.com/wiki/168/create-your-own-validation-rule/


小果子 2012-12-26 15:39 發(fā)表評論
]]>
Yii - How to use AJAX form validationhttp://m.shnenglu.com/guojingjia2006/archive/2012/12/26/196672.html小果子小果子Wed, 26 Dec 2012 04:45:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2012/12/26/196672.htmlhttp://m.shnenglu.com/guojingjia2006/comments/196672.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2012/12/26/196672.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/196672.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/196672.html

Yii supports AJAX form validation, which essentially posts the form values to the server, validates them, and sends back the validation errors, all without leaving the page. It does this every time you tab out of a (changed) field.

As of 1.1.7, Yii supports regular Javascript validation in addition to AJAX validation, but I'll talk about that in another post.

Here's how Yii's AJAX validation works:

  1. in your yii form declaration, put:
    <php $form = $this->beginWidget('CActiveForm', array(
    'id'=>'lowercasemodelname-form', //not technically required but works w gii generated controllers
    'enableAjaxValidation'=>true //turn on ajax validation on the client side )); 
    And have at least one form element with a matching error function:
    <?php echo $form->textField($model, 'my_attribute'); ?>
    <?php echo $form->error($model, 'my_attribute'); ?> 
    This makes Yii include the JQuery javascript library, as well as a Yii javascript file called jquery.yiiactiveform.js
  2. In your controller, in create or update, after you load the model, but before you load it from POST, call this
    if(Yii::app()->getRequest()->getIsAjaxRequest()) {
    echo CActiveForm::validate( array( $model)); 
    Yii::app()->end(); 
    } 
    Which is sligtly different than how Gii generates it, but no big diff. CActiveForm::validate() can take an array of models, which is not clear the way Gii does it.
  3. Also make sure that your model has at lease one validation rule for the insert or update scenario. After you tab out of a changed field, Yii sends a standard AJAX POST to the server, and gets back a JSON response like this:
    {"Field_id":["Validation error a"],"Another_field_id":["Validation error B"]} 
    which yii then plugs into the error field below your field.
  4. When you use the $form->error() function, Yii adds a hidden div after your form element:
    <div id="Model_attributename_em_" class="errorMessage" style="display:none"></div>
    If that field has a validation error, then Yii sets the display to block, writes the validation error message to its innerHtml, and then you see the error. If it later validates, yii hides it again.
  5. Yii will also add class names to the parent container of the field that it's validating. In most cases, this is a <div class="row">. When a form field is valid, it adds "success" class to the div - which makes it green. When it's invalid, it adds "error" class, which makes it red. It also quickly adds a "validating" class, which does nothing, but you can supply it yourself and change the look of a field while it's validating.
轉(zhuǎn)自:http://learnyii.blogspot.tw/2010/12/yii.html

小果子 2012-12-26 12:45 發(fā)表評論
]]>
分布式基礎(chǔ)學(xué)習(xí)【二】 —— 分布式計(jì)算系統(tǒng)(Map/Reduce)(轉(zhuǎn))http://m.shnenglu.com/guojingjia2006/archive/2012/12/19/196448.html小果子小果子Wed, 19 Dec 2012 11:18:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2012/12/19/196448.htmlhttp://m.shnenglu.com/guojingjia2006/comments/196448.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2012/12/19/196448.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/196448.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/196448.html

二. 分布式計(jì)算(Map/Reduce)

分布式式計(jì)算,同樣是一個(gè)寬泛的概念,在這里,它狹義的指代,按Google Map/Reduce框架所設(shè)計(jì)的分布式框架。在Hadoop中,分布式文件系統(tǒng),很大程度上,是為各種分布式計(jì)算需求所服務(wù)的。我們說分布式文件系統(tǒng)就是加了分布式的文件系統(tǒng),類似的定義推廣到分布式計(jì)算上,我們可以將其視為增加了分布式支持的計(jì)算函數(shù)。 從計(jì)算的角度上看,Map/Reduce框架接受各種格式的鍵值對文件作為輸入,讀取計(jì)算后,最終生成自定義格式的輸出文件。而從分布式的角度上看,分布 式計(jì)算的輸入文件往往規(guī)模巨大,且分布在多個(gè)機(jī)器上,單機(jī)計(jì)算完全不可支撐且效率低下,因此Map/Reduce框架需要提供一套機(jī)制,將此計(jì)算擴(kuò)展到無 限規(guī)模的機(jī)器集群上進(jìn)行。依照這樣的定義,我們對整個(gè)Map/Reduce的理解,也可以分別沿著這兩個(gè)流程去看。。。
在Map/Reduce框架中,每一次計(jì)算請求,被稱為作業(yè)。在分布式計(jì)算Map/Reduce框架中,為了完成這個(gè)作業(yè),它進(jìn)行兩步走的戰(zhàn)略,首先是將其拆分成若干個(gè)Map任務(wù), 分配到不同的機(jī)器上去執(zhí)行,每一個(gè)Map任務(wù)拿輸入文件的一部分作為自己的輸入,經(jīng)過一些計(jì)算,生成某種格式的中間文件,這種格式,與最終所需的文件格式 完全一致,但是僅僅包含一部分?jǐn)?shù)據(jù)。因此,等到所有Map任務(wù)完成后,它會進(jìn)入下一個(gè)步驟,用以合并這些中間文件獲得最后的輸出文件。此時(shí),系統(tǒng)會生成若 干個(gè)Reduce任務(wù),同樣也是分配到不同的機(jī)器去執(zhí)行,它的目標(biāo),就是將若干個(gè)Map任務(wù)生成的中間文件為匯總到最后的輸出文件中去。當(dāng)然,這個(gè)匯總不總會像1 + 1 = 2那么直接了當(dāng),這也就是Reduce任務(wù)的價(jià)值所在。經(jīng)過如上步驟,最終,作業(yè)完成,所需的目標(biāo)文件生成。整個(gè)算法的關(guān)鍵,就在于增加了一個(gè)中間文件生成的流程,大大提高了靈活性,使其分布式擴(kuò)展性得到了保證。。。

I. 術(shù)語對照

和分布式文件系統(tǒng)一樣,Google、Hadoop和....我,各執(zhí)一種方式表述統(tǒng)一概念,為了保證其統(tǒng)一性,特有下表。。。

文中翻譯 Hadoop術(shù)語 Google術(shù)語 相關(guān)解釋
作業(yè) Job Job 用戶的每一個(gè)計(jì)算請求,就稱為一個(gè)作業(yè)。
作業(yè)服務(wù)器 JobTracker Master 用戶提交作業(yè)的服務(wù)器,同時(shí),它還負(fù)責(zé)各個(gè)作業(yè)任務(wù)的分配,管理所有的任務(wù)服務(wù)器。
任務(wù)服務(wù)器 TaskTracker Worker 任勞任怨的工蜂,負(fù)責(zé)執(zhí)行具體的任務(wù)。
任務(wù) Task Task 每一個(gè)作業(yè),都需要拆分開了,交由多個(gè)服務(wù)器來完成,拆分出來的執(zhí)行單位,就稱為任務(wù)。
備份任務(wù) Speculative Task Buckup Task 每一個(gè)任務(wù),都有可能執(zhí)行失敗或者緩慢,為了降低為此付出的代價(jià),系統(tǒng)會未雨綢繆的實(shí)現(xiàn)在另外的任務(wù)服務(wù)器上執(zhí)行同樣一個(gè)任務(wù),這就是備份任務(wù)。

II. 基本架構(gòu)

與分布式文件系統(tǒng)類似,Map/Reduce的集群,也由三類服務(wù)器構(gòu)成。其中作業(yè)服務(wù)器,在Hadoop中稱為Job Tracker,在Google論文中稱為Master。前者告訴我們,作業(yè)服務(wù)器是負(fù)責(zé)管理運(yùn)行在此框架下所有作業(yè)的,后者告訴我們,它也是為各個(gè)作業(yè)分配任務(wù)的核心。與HDFS的主控服務(wù)器類似,它也是作為單點(diǎn)存在的,簡化了負(fù)責(zé)的同步流程。具體的負(fù)責(zé)執(zhí)行用戶定義操作的,是任務(wù)服務(wù)器,每一個(gè)作業(yè)被拆分成很多的任務(wù),包括Map任務(wù)Reduce任務(wù)等,任務(wù)是具體執(zhí)行的基本單元,它們都需要分配到合適任務(wù)服務(wù)器上去執(zhí)行,任務(wù)服務(wù)器一邊執(zhí)行一邊向作業(yè)服務(wù)器匯報(bào)各個(gè)任務(wù)的狀態(tài),以此來幫助作業(yè)服務(wù)器了解作業(yè)執(zhí)行的整體情況,分配新的任務(wù)等等。。。
除了作業(yè)的管理者執(zhí)行者,還需要有一個(gè)任務(wù)的提交者,這就是客戶端。與分布式文件系統(tǒng)一樣,客戶端也不是一個(gè)單獨(dú)的進(jìn)程,而是一組API,用戶需要自定義好自己需要的內(nèi)容,經(jīng)由客戶端相關(guān)的代碼,將作業(yè)及其相關(guān)內(nèi)容和配置,提交到作業(yè)服務(wù)器去,并時(shí)刻監(jiān)控執(zhí)行的狀況。。。
同作為Hadoop的實(shí)現(xiàn),與HDFS的通信機(jī)制相同,Hadoop Map/Reduce也是用了協(xié)議接口來進(jìn)行服務(wù)器間的交流。實(shí)現(xiàn)者作為RPC服務(wù)器,調(diào)用者經(jīng)由RPC的代理進(jìn)行調(diào)用,如此,完成大部分的通信,具體服 務(wù)器的架構(gòu),和其中運(yùn)行的各個(gè)協(xié)議狀況,參見下圖。從圖中可以看到,與HDFS相比,相關(guān)的協(xié)議少了幾個(gè),客戶端與任務(wù)服務(wù)器,任務(wù)服務(wù)器之間,都不再有 直接通信關(guān)系。這并不意味著客戶端就不需要了解具體任務(wù)的執(zhí)行狀況,也不意味著,任務(wù)服務(wù)器之間不需要了解別家任務(wù)執(zhí)行的情形,只不過,由于整個(gè)集群各機(jī) 器的聯(lián)系比HDFS復(fù)雜的多,直接通信過于的難以維系,所以,都統(tǒng)一由作業(yè)服務(wù)器整理轉(zhuǎn)發(fā)。另外,從這幅圖可以看到,任務(wù)服務(wù)器不是一個(gè)人在戰(zhàn)斗,它會像 孫悟空一樣招出一群寶寶幫助其具體執(zhí)行任務(wù)。這樣做的好處,個(gè)人覺得,應(yīng)該有安全性方面的考慮,畢竟,任務(wù)的代碼是用戶提交的,數(shù)據(jù)也是用戶指定的,這質(zhì) 量自然良莠不齊,萬一碰上個(gè)搞破壞的,把整個(gè)任務(wù)服務(wù)器進(jìn)程搞死了,就因小失大了。因此,放在單獨(dú)的地盤進(jìn)行,愛咋咋地,也算是權(quán)責(zé)明確了。。。
與分布式文件系統(tǒng)相比,Map/Reduce框架的還有一個(gè)特點(diǎn),就是可定制性強(qiáng)。文件系統(tǒng)中很多的算法, 都是很固定和直觀的,不會由于所存儲的內(nèi)容不同而有太多的變化。而作為通用的計(jì)算框架,需要面對的問題則要復(fù)雜很多,在各種不同的問題、不同的輸入、不同 的需求之間,很難有一種包治百病的藥能夠一招鮮吃遍天。作為Map/Reduce框架而言,一方面要盡可能的抽取出公共的一些需求,實(shí)現(xiàn)出來。更重要的, 是需要提供良好的可擴(kuò)展機(jī)制,滿足用戶自定義各種算法的需求。Hadoop是由Java來實(shí)現(xiàn)的,因此通過反射來實(shí)現(xiàn)自定義的擴(kuò)展,顯得比較小菜一碟了。 在JobConf類中,定義了大量的接口,這基本上是Hadoop Map/Reduce框架所有可定制內(nèi)容的一次集中展示。在JobConf中,有大量set接口接受一個(gè)Class<? extends xxx>的參數(shù),通常它都有一個(gè)默認(rèn)實(shí)現(xiàn)的類,用戶如果不滿意,則可自定義實(shí)現(xiàn)。。。

III. 計(jì)算流程

如果一切都按部就班的進(jìn)行,那么整個(gè)作業(yè)的計(jì)算流程,應(yīng)該是作業(yè)的提交 -> Map任務(wù)的分配和執(zhí)行 -> Reduce任務(wù)的分配和執(zhí)行 -> 作業(yè)的完成。而在每個(gè)任務(wù)的執(zhí)行中,又包含輸入的準(zhǔn)備 -> 算法的執(zhí)行 -> 輸出的生成,三個(gè)子步驟。沿著這個(gè)流程,我們可以很快的整理清晰整個(gè)Map/Reduce框架下作業(yè)的執(zhí)行。。。

1、作業(yè)的提交

一個(gè)作業(yè),在提交之前,需要把所有應(yīng)該配置的東西都配置好,因?yàn)橐坏┨峤坏搅俗鳂I(yè)服務(wù)器上,就陷入了完全自動(dòng)化的流程,用戶除了觀望,最多也就能起一個(gè)監(jiān)督作用,懲治一些不好好工作的任務(wù)。。。
基本上,用戶在提交代碼階段,需要做的工作主要是這樣的:
首先,書寫好所有自定的代碼,最起碼,需要有Map和Reduce的執(zhí)行代碼。在Hadoop中,Map需要派生自Mapper<K1, V1, K2, V2>接口,Reduce需要派生自Reducer<K2, V2, K3, V3>接口。這里都是用的泛型,用以支持不同的鍵值類型。這兩個(gè)接口都僅有一個(gè)方法,一個(gè)是map,一個(gè)是reduce,這兩個(gè)方法都直接受四個(gè)參數(shù),前兩個(gè)是輸入的相關(guān)的數(shù)據(jù)結(jié)構(gòu),第三個(gè)是作為輸出相關(guān)的數(shù)據(jù)結(jié)構(gòu),最后一個(gè),是一個(gè)Reporter類的實(shí)例,實(shí)現(xiàn)的時(shí)候可以利用它來統(tǒng)計(jì)一些計(jì)數(shù)。除了這兩個(gè)接口,還有大量可以派生的接口,比如分割的Partitioner<K2, V2>接口。。。
然后,需要書寫好主函數(shù)的代碼,其中最主要的內(nèi)容就是實(shí)例化一個(gè)JobConf類的對象,然后調(diào)用其豐富的setXXX接口,設(shè)定好所需的內(nèi)容,包括輸入輸出的文件路徑,Map和Reduce的類,甚至包括讀取寫入文件所需的格式支持類,等等。。。
最后,調(diào)用JobClientrunJob方法,提交此JobConf對象。runJob方法會先行調(diào)用到JobSubmissionProtocol接口所定義的submitJob方法,將此作業(yè),提交給作業(yè)服務(wù)器。接著,runJob開始循環(huán),不停的調(diào)用JobSubmissionProtocol的getTaskCompletionEvents方法,獲得TaskCompletionEvent類的對象實(shí)例,了解此作業(yè)各任務(wù)的執(zhí)行狀況。。。

2、Map任務(wù)的分配

當(dāng)一個(gè)作業(yè)提交到了作業(yè)服務(wù)器上,作業(yè)服務(wù)器會生成若干個(gè)Map任務(wù),每一個(gè)Map任務(wù),負(fù)責(zé)將一部分的輸入轉(zhuǎn)換成格式與最終格式相同的中間文件。通常一個(gè)作業(yè)的輸入都是基于分布式文件系統(tǒng)的文件(當(dāng)然在單機(jī)環(huán)境下,文件系統(tǒng)單機(jī)的也可以...),因?yàn)椋梢院芴烊坏暮头植际降挠?jì)算產(chǎn)生聯(lián)系。而對于一個(gè)Map任務(wù)而言,它的輸入往往是輸入文件的一個(gè)數(shù)據(jù)塊,或者是數(shù)據(jù)塊的一部分,但通常,不跨數(shù)據(jù)塊。因?yàn)椋坏┛缌藬?shù)據(jù)塊,就可能涉及到多個(gè)服務(wù)器,帶來了不必要的復(fù)雜性。。。
當(dāng)一個(gè)作業(yè),從客戶端提交到了作業(yè)服務(wù)器上,作業(yè)服務(wù)器會生成一個(gè)JobInProgress對象,作為與 之對應(yīng)的標(biāo)識,用于管理。作業(yè)被拆分成若干個(gè)Map任務(wù)后,會預(yù)先掛在作業(yè)服務(wù)器上的任務(wù)服務(wù)器拓?fù)錁洹_@是依照分布式文件數(shù)據(jù)塊的位置來劃分的,比如一 個(gè)Map任務(wù)需要用某個(gè)數(shù)據(jù)塊,這個(gè)數(shù)據(jù)塊有三份備份,那么,在這三臺服務(wù)器上都會掛上此任務(wù),可以視為是一個(gè)預(yù)分配。。。
關(guān)于任務(wù)管理和分配的大部分的真實(shí)功能和邏輯的實(shí)現(xiàn),JobInProgress則依托JobInProgressListenerTaskScheduler的子類。TaskScheduler,顧名思義是用于任務(wù)分配的策略類(為了簡化描述,用它代指所有TaskScheduler的子類...)。它會掌握好所有作業(yè)的任務(wù)信息,其assignTasks函數(shù),接受一個(gè)TaskTrackerStatus作為參數(shù),依照此任務(wù)服務(wù)器的狀態(tài)和現(xiàn)有的任務(wù)狀況,為其分配新的任務(wù)。而為了掌握所有作業(yè)相關(guān)任務(wù)的狀況,TaskScheduler會將若干個(gè)JobInProgressListener注冊到JobTracker中去,當(dāng)有新的作業(yè)到達(dá)、移除或更新的時(shí)候,JobTracker會告知給所有的JobInProgressListener,以便它們做出相應(yīng)的處理。。。
任務(wù)分配是一個(gè)重要的環(huán)節(jié),所謂任務(wù)分配,就是將合適作業(yè)的合適任務(wù)分配到合適的服務(wù)器上。不難看出,里面 蘊(yùn)含了兩個(gè)步驟,先是選擇作業(yè),然后是在此作業(yè)中選擇任務(wù)。和所有分配工作一樣,任務(wù)分配也是一個(gè)復(fù)雜的活。不良好的任務(wù)分配,可能會導(dǎo)致網(wǎng)絡(luò)流量增加、 某些任務(wù)服務(wù)器負(fù)載過重效率下降,等等。不僅如此,任務(wù)分配還是一個(gè)無一致模式的問題,不同的業(yè)務(wù)背景,可能需要不同的算法才能滿足需求。因此,在 Hadoop中,有很多TaskScheduler的子類,像Facebook,Yahoo,都為其貢獻(xiàn)出了自家用的算法。在Hadoop中,默認(rèn)的任務(wù) 分配器,是JobQueueTaskScheduler類。它選擇作業(yè)的基本次序是:Map Clean Up Task(Map任務(wù)服務(wù)器的清理任務(wù),用于清理相關(guān)的過期的文件和環(huán)境...) -> Map Setup Task(Map任務(wù)服務(wù)器的安裝任務(wù),負(fù)責(zé)配置好相關(guān)的環(huán)境...) -> Map Tasks -> Reduce Clean Up Task -> Reduce Setup Task -> Reduce Tasks。在這個(gè)前提下,具體到Map任務(wù)的分配上來。當(dāng)一個(gè)任務(wù)服務(wù)器工作的游刃有余,期待獲得新的任務(wù)的時(shí)候,JobQueueTaskScheduler會按照各個(gè)作業(yè)的優(yōu)先級,從最高優(yōu)先級的作業(yè)開 始分配。每分配一個(gè),還會為其留出余量,已被不時(shí)之需。舉一個(gè)例子:系統(tǒng)目前有優(yōu)先級3、2、1的三個(gè)作業(yè),每個(gè)作業(yè)都有一個(gè)可分配的Map任務(wù),一個(gè)任 務(wù)服務(wù)器來申請新的任務(wù),它還有能力承載3個(gè)任務(wù)的執(zhí)行,JobQueueTaskScheduler會先從優(yōu)先級3的作業(yè)上取一個(gè)任務(wù)分配給它,然后再 留出一個(gè)1任務(wù)的余量。此時(shí),系統(tǒng)只能在將優(yōu)先級2作業(yè)的任務(wù)分配給此服務(wù)器,而不能分配優(yōu)先級1的任務(wù)。這樣的策略,基本思路就是一切為高優(yōu)先級的作業(yè)服務(wù),優(yōu)先分配不說,分配了好保留有余力以備不時(shí)之需,如此優(yōu)待,足以讓高優(yōu)先級的作業(yè)喜極而泣,讓低優(yōu)先級的作業(yè)感慨既生瑜何生亮,甚至是活活餓死。。。
確定了從哪個(gè)作業(yè)提取任務(wù)后,具體的分配算法,經(jīng)過一系列的調(diào)用,最后實(shí)際是由JobInProgressfindNewMapTask函數(shù)完成的。它的算法很簡單,就是盡全力為此服務(wù)器非配且盡可能好的分配任務(wù), 也就是說,只要還有可分配的任務(wù),就一定會分給它,而不考慮后來者。作業(yè)服務(wù)器會從離它最近的服務(wù)器開始,看上面是否還掛著未分配的任務(wù)(預(yù)分配上的), 從近到遠(yuǎn),如果所有的任務(wù)都分配了,那么看有沒有開啟多次執(zhí)行,如果開啟,考慮把未完成的任務(wù)再分配一次(后面有地方詳述...)。。。
對于作業(yè)服務(wù)器來說,把一個(gè)任務(wù)分配出去了,并不意味著它就徹底解放,可以對此任務(wù)可以不管不顧了。因?yàn)槿蝿?wù)可以在任務(wù)服務(wù)器上執(zhí)行失敗,可能執(zhí)行緩慢,這都需要作業(yè)服務(wù)器幫助它們再來一次。因此在Task中,記錄有一個(gè)TaskAttemptID,對于任務(wù)服務(wù)器而言,它們每次跑的,其實(shí)都只是一個(gè)Attempt而已,Reduce任務(wù)只需要采信一個(gè)的輸出,其他都算白忙乎了。。。

3、Map任務(wù)的執(zhí)行

與HDFS類似,任務(wù)服務(wù)器是通過心跳消息,向作業(yè)服務(wù)器匯報(bào)此時(shí)此刻其上各個(gè)任務(wù)執(zhí)行的狀況,并向作業(yè)服務(wù)器申請新的任務(wù)的。具體實(shí)現(xiàn),是TaskTracker調(diào)用InterTrackerProtocol協(xié)議的heartbeat方法來做的。這個(gè)方法接受一個(gè)TaskTrackerStatus對象作為參數(shù),它描述了此時(shí)此任務(wù)服務(wù)器的狀態(tài)。當(dāng)其有余力接受新的任務(wù)的時(shí)候,它還會傳入acceptNewTasks為true的參數(shù),表示希望作業(yè)服務(wù)器委以重任。JobTracker接收到相關(guān)的參數(shù)后,經(jīng)過處理,會返回一個(gè)HeartbeatResponse對象。這個(gè)對象中,定義了一組TaskTrackerAction,用于指導(dǎo)任務(wù)服務(wù)器進(jìn)行下一步的工作。系統(tǒng)中已定義的了一堆其TaskTrackerAction的子類,有的對攜帶的參數(shù)進(jìn)行了擴(kuò)充,有的只是標(biāo)明了下ID,具體不詳寫了,一看便知。。。
當(dāng)TaskTracker收到的TaskTrackerAction中,包含了LaunchTaskAction,它會開始執(zhí)行所分配的新的任務(wù)。在TaskTracker中,有一個(gè)TaskTracker.TaskLauncher線程(確切的說是兩個(gè),一個(gè)等Map任務(wù),一個(gè)等Reduce任務(wù)),它們在癡癡的守候著新任務(wù)的來到。一旦等到了,會最終調(diào)用到Task的createRunner方法,構(gòu)造出一個(gè)TaskRunner對象,新建一個(gè)線程來執(zhí)行。對于一個(gè)Map任務(wù),它對應(yīng)的Runner是TaskRunner的子類MapTaskRunner, 不過,核心部分都在TaskRunner的實(shí)現(xiàn)內(nèi)。TaskRunner會先將所需的文件全部下載并拆包好,并記錄到一個(gè)全局緩存中,這是一個(gè)全局的目 錄,可以供所有此作業(yè)的所有任務(wù)使用。它會用一些軟鏈接,將一些文件名鏈接到這個(gè)緩存中來。然后,根據(jù)不同的參數(shù),配置出一個(gè)JVM執(zhí)行的環(huán)境,這個(gè)環(huán)境 與JvmEnv類的對象對應(yīng)。
接著,TaskRunner會調(diào)用JvmManagerlaunchJvm方 法,提交給JvmManager處理。JvmManager用于管理該TaskTracker上所有運(yùn)行的Task子進(jìn)程。在目前的實(shí)現(xiàn)中,嘗試的是池化 的方式。有若干個(gè)固定的槽,如果槽沒有滿,那么就啟動(dòng)新的子進(jìn)程,否則,就尋找idle的進(jìn)程,如果是同Job的直接放進(jìn)去,否則殺死這個(gè)進(jìn)程,用一個(gè)新 的進(jìn)程代替。每一個(gè)進(jìn)程都是由JvmRunner來管理的,它也是位于單獨(dú)線程中的。但是從實(shí)現(xiàn)上看,這個(gè)機(jī)制好像沒有部署開,子進(jìn)程是死循環(huán)等待,而不 會阻塞在父進(jìn)程的相關(guān)線程上,父線程的變量一直都沒有個(gè)調(diào)整,一旦分配,始終都處在繁忙的狀況了。
真實(shí)的執(zhí)行載體,是Child,它包含一個(gè) main函數(shù),進(jìn)程執(zhí)行,會將相關(guān)參數(shù)傳進(jìn)來,它會拆解這些參數(shù),并且構(gòu)造出相關(guān)的Task實(shí)例,調(diào)用其run函數(shù)進(jìn)行執(zhí)行。每一個(gè)子進(jìn)程,可以執(zhí)行指定 個(gè)數(shù)量的Task,這就是上面所說的池化的配置。但是,這套機(jī)制在我看來,并沒有運(yùn)行起來,每個(gè)進(jìn)程其實(shí)都沒有機(jī)會不死而執(zhí)行新的任務(wù),只是傻傻的等待進(jìn) 程池滿,而被一刀斃命。也許是我老眼昏花,沒看出其中實(shí)現(xiàn)的端倪。。。

4、Reduce任務(wù)的分配與執(zhí)行

比之Map任務(wù),Reduce的分配及其簡單,基本上是所有Map任務(wù)完成了,有空閑的任務(wù)服務(wù)器,來了就給分配一個(gè)Job任務(wù)。因?yàn)镸ap任 務(wù)的結(jié)果星羅棋布,且變化多端,真要搞一個(gè)全局優(yōu)化的算法,絕對是得不償失。而Reduce任務(wù)的執(zhí)行進(jìn)程的構(gòu)造和分配流程,與Map基本完全的一致,沒 有啥可說的了。。。
但其實(shí),Reduce任務(wù)與Map任務(wù)的最大不同,是Map任務(wù)的文件都在本地隔著,而Reduce任務(wù)需要到處采集。這個(gè)流程是作業(yè)服務(wù)器經(jīng) 由此Reduce任務(wù)所處的任務(wù)服務(wù)器,告訴Reduce任務(wù)正在執(zhí)行的進(jìn)程,它需要的Map任務(wù)執(zhí)行過的服務(wù)器地址,此Reduce任務(wù)服務(wù)器會于原 Map任務(wù)服務(wù)器聯(lián)系(當(dāng)然本地就免了...),通過FTP服務(wù),下載過來。這個(gè)隱含的直接數(shù)據(jù)聯(lián)系,就是執(zhí)行Reduce任務(wù)與執(zhí)行Map任務(wù)最大的不 同了。。。

5、作業(yè)的完成

當(dāng)所有Reduce任務(wù)都完成了,所需數(shù)據(jù)都寫到了分布式文件系統(tǒng)上,整個(gè)作業(yè)才正式完成了。此中,涉及到很多的類,很多的文件,很多的服務(wù)器,所以說起來很費(fèi)勁,話說,一圖解千語,說了那么多,我還是畫兩幅圖,徹底表達(dá)一下吧。。。
首先,是一個(gè)時(shí)序圖。它模擬了一個(gè)由3個(gè)Map任務(wù)和1個(gè)Reduce任務(wù)構(gòu)成的作業(yè)執(zhí)行流程。我們可以看到,在執(zhí)行的過程中,只要有人太慢, 或者失敗,就會增加一次嘗試,以此換取最快的執(zhí)行總時(shí)間。一旦所有Map任務(wù)完成,Reduce開始運(yùn)作(其實(shí),不一定要這樣的...),對于每一個(gè) Map任務(wù)來說,只有執(zhí)行到Reduce任務(wù)把它上面的數(shù)據(jù)下載完成,才算成功,否則,都是失敗,需要重新進(jìn)行嘗試。。。
而第二副圖,不是我畫的,就不轉(zhuǎn)載了,參見這里, 它描述了整個(gè)Map/Reduce的服務(wù)器狀況圖,包括整體流程、所處服務(wù)器進(jìn)程、輸入輸出等,看清楚這幅圖,對Map/Reduce的基本流程應(yīng)該能完 全跑通了。有這幾點(diǎn),可能圖中描述的不夠清晰需要提及一下,一個(gè)是在HDFS中,其實(shí)還有日志文件,圖中沒有標(biāo)明;另一個(gè)是步驟5,其實(shí)是由 TaskTracker主動(dòng)去拉取而不是JobTracker推送過來的;還有步驟8和步驟11,創(chuàng)建出來的MapTask和ReduceTask,在 Hadoop中都是運(yùn)行在獨(dú)立的進(jìn)程上的。。。

IV. Map任務(wù)詳請

從上面,可以了解到整個(gè)Map和Reduce任務(wù)的整體流程,而后面要啰嗦的,是具體執(zhí)行中的細(xì)節(jié)。Map任務(wù)的輸入,是分布式文件系統(tǒng)上的, 包含鍵值對信息的文件。為了給每一個(gè)Map任務(wù)指定輸入,我們需要掌握文件格式把它分切成塊,并從每一塊中分離出鍵值信息。在HDFS中,輸入的文件格 式,是由InputFormat<K, V>類來表示的,在JobConf中,它的默認(rèn)值是TextInputFormat類(見getInputFormat),此類是特化的FileInputFormat<LongWritable, Text>子類,而FileInputFormat<K, V>正是InputFormat<K, V>的子類。通過這樣的關(guān)系我們可以很容易的理解,默認(rèn)的文件格式是文本文件,且鍵是LongWritable類型(整形數(shù)),值是Text類型(字符串)。僅僅知道文件類型是不夠的,我們還需要將文件中的每一條數(shù)據(jù),分離成鍵值對,這個(gè)工作,是RecordReader<K, V>來做的。在TextInputFormat的getRecordReader方法中我們可以看到,與TextInputFormat默認(rèn)配套使用的,是LineRecordReader類,是特化的RecordReader<LongWritable, Text>的子類,它將每一行作為一個(gè)記錄,起始的位置作為鍵,整行的字符串作為值。有了格式,分出了鍵值,還需要切開分給每一個(gè)Map任務(wù)。每一個(gè)Map任務(wù)的輸入用InputSplit接口表示,對于一個(gè)文件輸入而言,其實(shí)現(xiàn)是FileSplit,它包含著文件名、起始位置、長度和存儲它的一組服務(wù)器地址。。。
當(dāng)Map任務(wù)拿到所屬的InputSplit后,就開始一條條讀取記錄,并調(diào)用用于定義的Mapper,進(jìn)行計(jì)算(參見MapRunner<K1, V1, K2, V2>和MapTask的run方法),然后,輸出。MapTask會傳遞給Mapper一個(gè)OutputCollector<K, V>對象,作為輸出的數(shù)據(jù)結(jié)構(gòu)。它定義了一個(gè)collect的函數(shù),接受一個(gè)鍵值對。在MapTask中,定義了兩個(gè)OutputCollector的子類,一個(gè)是MapTask.DirectMapOutputCollector<K, V>,人如其名,它的實(shí)現(xiàn)確實(shí)很Direct,直截了當(dāng)。它會利用一個(gè)RecordWriter<K, V>對象,collect一調(diào)用,就直接調(diào)用RecordWriter<K, V>的write方法,寫入本地的文件中去。如果覺著RecordWriter<K, V>出現(xiàn)的很突兀,那么看看上一段提到的RecordReader<K, V>,基本上,數(shù)據(jù)結(jié)構(gòu)都是對應(yīng)著的,一個(gè)是輸入一個(gè)是輸出。輸出很對稱也是由RecordWriter<K, V>和OutputFormat<K, V>來協(xié)同完成的,其默認(rèn)實(shí)現(xiàn)是LineRecordWriter<K, V>和TextOutputFormat<K, V>,多么的眼熟啊。。。
除了這個(gè)非常直接的實(shí)現(xiàn)之外,MapTask中還有一個(gè)復(fù)雜的多的實(shí)現(xiàn),是MapTask.MapOutputBuffer<K extends Object, V extends Object>。有道是簡單壓倒一切,那為什么有很簡單的實(shí)現(xiàn),要琢磨一個(gè)復(fù)雜的呢。原因在于,看上去很美的往往帶著刺,簡單的輸出實(shí)現(xiàn),每調(diào)用一 次collect就寫一次文件,頻繁的硬盤操作很有可能導(dǎo)致此方案的低效。為了解決這個(gè)問題,這就有了這個(gè)復(fù)雜版本,它先開好一段內(nèi)存做緩存,然后制定一個(gè)比例做閾值開一個(gè)線程監(jiān)控此緩存。collect來的內(nèi)容,先寫到緩存中,當(dāng)監(jiān)控線程發(fā)現(xiàn)緩存的內(nèi)容比例超過閾值,掛起所有寫入操作,建一個(gè)新的文件,把緩存的內(nèi)容批量刷到此文件中去,清空緩存,重新開放,接受繼續(xù)collect。。。
為什么說是刷到文件中去呢。因?yàn)檫@不是一個(gè)簡單的照本宣科簡單復(fù)制的過程,在寫入之前,會先將緩存中的內(nèi)存,經(jīng)過排序、合并器 (Combiner)統(tǒng)計(jì)之后,才會寫入。如果你覺得Combiner這個(gè)名詞聽著太陌生,那么考慮一下Reducer,Combiner也就是一個(gè) Reducer類,通過JobConf的setCombinerClass進(jìn)行設(shè)置,在常用的配置中,Combiner往往就是用用戶為Reduce任務(wù) 定義的那個(gè)Reducer子類。只不過,Combiner只是服務(wù)的范圍更小一些而已,它在Map任務(wù)執(zhí)行的服務(wù)器本地,依照Map處理過的那一小部分?jǐn)?shù) 據(jù),先做一次Reduce操作,這樣,可以壓縮需要傳輸內(nèi)容的大小,提高速度。每一次刷緩存,都會開一個(gè)新的文件,等此任務(wù)所有的輸入都處理完成后,就有 了若干個(gè)有序的、經(jīng)過合并的輸出文件。系統(tǒng)會將這些文件搞在一起,再做一個(gè)多路的歸并外排,同時(shí)使用合并器進(jìn)行合并,最終,得到了唯一的、有序的、經(jīng)過合 并的中間文件(注:文件數(shù)量等同于分類數(shù)量,在不考慮分類的時(shí)候,簡單的視為一個(gè)...)。它,就是Reduce任務(wù)夢寐以求的輸入文件。。。
除了做合并,復(fù)雜版本的OutputCollector,還具有分類的功能。分類,是通過Partitioner<K2, V2>來定義的,默認(rèn)實(shí)現(xiàn)是HashPartitioner<K2, V2>,作業(yè)提交者可以通過JobConf的setPartitionerClass來自定義。分類的含義是什么呢,簡單的說,就是將Map任務(wù)的輸出,劃分到若干個(gè)文件中(通常與Reduce任務(wù)數(shù)目相等),使得每一個(gè)Reduce任務(wù),可以處理某一類文件。這樣的好處是大大的,舉一個(gè)例子說明一下。比如有一個(gè)作業(yè)是進(jìn)行單詞統(tǒng)計(jì)的,其Map任務(wù)的中間結(jié)果應(yīng)該是以單詞為鍵,以單詞數(shù)量為值的文件。如果這時(shí)候只有一個(gè)Reduce任務(wù),那還好說,從全部的Map任務(wù)那里收集文件過來,分別統(tǒng)計(jì)得到最后的輸出文件就好。但是,如果單Reduce任務(wù)無法承載此負(fù)載或效率太低,就需要多個(gè)Reduce任務(wù)并行執(zhí)行。此時(shí),再沿用之前的模式就有了問題。每個(gè)Reduce任務(wù)從一部分Map任務(wù)那 里獲得輸入文件,但最終的輸出結(jié)果并不正確,因?yàn)橥粋€(gè)單詞可能在不同的Reduce任務(wù)那里都有統(tǒng)計(jì),需要想方法把它們統(tǒng)計(jì)在一起才能獲得最后結(jié)果,這 樣就沒有將Map/Reduce的作用完全發(fā)揮出來。這時(shí)候,就需要用到分類。如果此時(shí)有兩個(gè)Reduce任務(wù),那么將輸出分成兩類,一類存放字母表排序 較高的單詞,一類存放字母表排序低的單詞,每一個(gè)Reduce任務(wù)從所有的Map任務(wù)那里獲取一類的中間文件,得到自己的輸出結(jié)果。最終的結(jié)果,只需要把各個(gè)Reduce任務(wù)輸出的,拼接在一起就可以了。本質(zhì)上,這就是將Reduce任務(wù)的輸入,由垂直分割,變成了水平分割。Partitioner的作用,正是接受一個(gè)鍵值,返回一個(gè)分類的序號。它會在從緩存刷到文件之前做這個(gè)工作,其實(shí)只是多了一個(gè)文件名的選擇而已,別的邏輯都不需要變化。。。
除了緩存、合并、分類等附加工作之外,復(fù)雜版本的OutputCollector還支持錯(cuò)誤數(shù)據(jù)的跳過功能,在后面分布式將排錯(cuò)的時(shí)候,還會提及,標(biāo)記一下,按下不表。。。

V. Reduce任務(wù)詳情

理論上看,Reduce任務(wù)的整個(gè)執(zhí)行流程要比Map任務(wù)更為的羅嗦一些,因?yàn)椋枰占斎胛募缓蟛拍苓M(jìn)行處理。Reduce任務(wù),主要有這么三個(gè)步驟:CopySortReduce(參見ReduceTask的run方法)。所謂Copy,就是從執(zhí)行各個(gè)Map任務(wù)的服務(wù)器那里,收羅到本地來。拷貝的任務(wù),是由ReduceTask.ReduceCopier類來負(fù)責(zé),它有一個(gè)內(nèi)嵌類,叫MapOutputCopier, 它會在一個(gè)單獨(dú)的線程內(nèi),負(fù)責(zé)某個(gè)Map任務(wù)服務(wù)器上文件的拷貝工作。遠(yuǎn)程拷貝過來的內(nèi)容(當(dāng)然也可以是本地了...),作為MapOutput對象存 在,它可以在內(nèi)存中也可以序列化在磁盤上,這個(gè)根據(jù)內(nèi)存使用狀況來自動(dòng)調(diào)節(jié)。整個(gè)拷貝過程是一個(gè)動(dòng)態(tài)的過程,也就是說它不是一次給好所有輸入信息就不再變 化了。它會不停的調(diào)用TaskUmbilicalProtocol協(xié)議的getMapCompletionEvents方 法,向其父TaskTracker詢問此作業(yè)個(gè)Map任務(wù)的完成狀況(TaskTracker要向JobTracker詢問后再轉(zhuǎn)告給它...)。當(dāng)獲取 到相關(guān)Map任務(wù)執(zhí)行服務(wù)器的信息后,都會有一個(gè)線程開啟,做具體的拷貝工作。同時(shí),還有一個(gè)內(nèi)存Merger線程和一個(gè)文件Merger線程在同步工 作,它們將新鮮下載過來的文件(可能在內(nèi)存中,簡單的統(tǒng)稱為文件...),做著歸并排序,以此,節(jié)約時(shí)間,降低輸入文件的數(shù)量,為后續(xù)的排序工作減 負(fù)。。。
Sort,排序工作,就相當(dāng)于上述排序工作的一個(gè)延續(xù)。它會在所有的文件都拷貝完畢后進(jìn)行,因?yàn)殡m然同步有做著歸并的工作,但可能留著尾巴,沒 做徹底。經(jīng)過這一個(gè)流程,該徹底的都徹底了,一個(gè)嶄新的、合并了所有所需Map任務(wù)輸出文件的新文件,誕生了。而那些千行萬苦從其他各個(gè)服務(wù)器網(wǎng)羅過來的 Map任務(wù)輸出文件,很快的結(jié)束了它們的歷史使命,被掃地出門一掃而光,全部刪除了。。。
所謂好戲在后頭,Reduce任務(wù)的最后一個(gè)階段,正是Reduce本身。它也會準(zhǔn)備一個(gè)OutputCollector收集輸出,與MapTask不同,這個(gè)OutputCollector更為簡單,僅僅是打開一個(gè)RecordWriter,collect一次,write一次。最大的不同在于,這次傳入RecordWriter的文件系統(tǒng),基本都是分布式文件系統(tǒng), 或者說是HDFS。而在輸入方面,ReduceTask會從JobConf那里調(diào)用一堆getMapOutputKeyClass、 getMapOutputValueClass、getOutputKeyComparator等等之類的自定義類,構(gòu)造出Reducer所需的鍵類型, 和值的迭代類型Iterator(一個(gè)鍵到了這里一般是對應(yīng)一組值)。具體實(shí)現(xiàn)頗為拐彎抹角,建議看一下Merger.MergeQueueRawKeyValueIteratorReduceTask.ReduceValuesIterator等等之類的實(shí)現(xiàn)。有了輸入,有了輸出,不斷循環(huán)調(diào)用自定義的Reducer,最終,Reduce階段完成。。。

VI. 分布式支持

1、服務(wù)器正確性保證

Hadoop Map/Reduce服務(wù)器狀況和HDFS很類似,由此可知,救死扶傷的方法也是大同小異。廢話不多說了,直接切正題。同作為客戶端,Map /Reduce的客戶端只是將作業(yè)提交,就開始搬個(gè)板凳看戲,沒有占茅坑的行動(dòng)。因此,一旦它掛了,也就掛了,不傷大雅。而任務(wù)服務(wù)器,也需要隨時(shí)與作業(yè) 服務(wù)器保持心跳聯(lián)系,一旦有了問題,作業(yè)服務(wù)器可以將其上運(yùn)行的任務(wù),移交給它人完成。作業(yè)服務(wù)器,作為一個(gè)單點(diǎn),非常類似的是利用還原點(diǎn)(等同于 HDFS的鏡像)和歷史記錄(等同于HDFS的日志),來進(jìn)行恢復(fù)。其上,需要持久化用于恢復(fù)的內(nèi)容,包含作業(yè)狀況、任務(wù)狀況、各個(gè)任務(wù)嘗試的工作狀況 等。有了這些內(nèi)容,再加上任務(wù)服務(wù)器的動(dòng)態(tài)注冊,就算挪了個(gè)窩,還是很容易恢復(fù)的。JobHistory是歷史記錄相 關(guān)的一個(gè)靜態(tài)類,本來,它也就是一個(gè)干寫日志活的,只是在Hadoop的實(shí)現(xiàn)中,對日志的寫入做了面向?qū)ο蟮姆庋b,同時(shí)又大量用到觀察者模式做了些嵌入, 使得看起來不是那么直觀。本質(zhì)上,它就是打開若干個(gè)日志文件,利用各類接口來往里面寫內(nèi)容。只不過,這些日志,會放在分布式文件系統(tǒng)中,就不需要像 HDFS那樣,來一個(gè)SecondXXX隨時(shí)候命,由此可見,有巨人在腳下踩著,真好。JobTracker.RecoveryManager類是作業(yè)服 務(wù)器中用于進(jìn)行恢復(fù)相關(guān)的事情,當(dāng)作業(yè)服務(wù)器啟動(dòng)的時(shí)候,會調(diào)用其recover方法,恢復(fù)日志文件中的內(nèi)容。其中步驟,注釋中寫的很清楚,請自行查 看。。。

2、任務(wù)執(zhí)行的正確和速度

整個(gè)作業(yè)流程的執(zhí)行,秉承著木桶原理。執(zhí)行的最慢的Map任務(wù)和Reduce任務(wù),決定了系統(tǒng)整體執(zhí)行時(shí)間(當(dāng)然,如果執(zhí)行時(shí)間在整個(gè)流程中占 比例很小的話,也許就微不足道了...)。因此,盡量加快最慢的任務(wù)執(zhí)行速度,成為提高整體速度關(guān)鍵。所使用的策略,簡約而不簡單,就是一個(gè)任務(wù)多次執(zhí)行。 當(dāng)所有未執(zhí)行的任務(wù)都分配出去了,并且先富起來的那部分任務(wù)已經(jīng)完成了,并還有任務(wù)服務(wù)器孜孜不倦的索取任務(wù)的時(shí)候,作業(yè)服務(wù)器會開始炒剩飯,把那些正在 吭哧吭哧在某個(gè)服務(wù)器上慢慢執(zhí)行的任務(wù),再把此任務(wù)分配到一個(gè)新的任務(wù)服務(wù)器上,同時(shí)執(zhí)行。兩個(gè)服務(wù)器各盡其力,成王敗寇,先結(jié)束者的結(jié)果將被采納。這樣 的策略,隱含著一個(gè)假設(shè),就是我們相信,輸入文件的分割算法是公平的,某個(gè)任務(wù)執(zhí)行慢,并不是由于這個(gè)任務(wù)本身負(fù)擔(dān)太重,而是由于服務(wù)器不爭氣負(fù)擔(dān)太重能 力有限或者是即將撒手西去,給它換個(gè)新環(huán)境,人挪死樹挪活事半功倍。。。
當(dāng)然,肯定有哽咽的任務(wù),不論是在哪個(gè)服務(wù)器上,都無法順利完成。這就說明,此問題不在于服務(wù)器上,而是任務(wù)本身天資有缺憾。缺憾在何處?每個(gè)作業(yè),功能 代碼都是一樣的,別的任務(wù)成功了,就是這個(gè)任務(wù)不成功,很顯然,問題出在輸入那里。輸入中有非法的輸入條目,導(dǎo)致程序無法辨識,只能揮淚惜別。說到這里, 解決策略也浮出水面了,三十六計(jì)走位上,惹不起,還是躲得起的。在MapTask中的 MapTask.SkippingRecordReader<K, V>和ReduceTask里的 ReduceTask.SkippingReduceValuesIterator<KEY,VALUE>,都是用于干這個(gè)事情的。它們的原 理很簡單,就是在讀一條記錄前,把當(dāng)前的位置信息,封裝成SortedRanges.Range對象,經(jīng)由Task的 reportNextRecordRange方法提交到TaskTracker上去。TaskTracker會把這些內(nèi)容,擱在TaskStatus對象 中,隨著心跳消息,匯報(bào)到JobTracker上面。這樣,作業(yè)服務(wù)器就可以隨時(shí)隨刻了解清楚,每個(gè)任務(wù)正讀取在那個(gè)位置,一旦出錯(cuò),再次執(zhí)行的時(shí)候,就 在分配的任務(wù)信息里面添加一組SortedRanges信息。MapTask或ReduceTask讀取的時(shí)候,會看一下這些區(qū)域,如果當(dāng)前區(qū)域正好處于 上述雷區(qū),跳過不讀。如此反復(fù),正可謂,道路曲折,前途光明啊。。。

VII. 總結(jié)

對于Map/Reduce而言,真正的困難,在于提高其適應(yīng)能力,打造一款能夠包治百病的執(zhí)行框架。Hadoop已經(jīng)做得很好了,但只有真正搞清楚了整個(gè)流程,你才能幫助它做的更好。。。


小果子 2012-12-19 19:18 發(fā)表評論
]]>
使用Yii進(jìn)行PHP的命令行程序(Console command)開發(fā)http://m.shnenglu.com/guojingjia2006/archive/2012/12/12/196195.html小果子小果子Wed, 12 Dec 2012 06:41:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2012/12/12/196195.htmlhttp://m.shnenglu.com/guojingjia2006/comments/196195.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2012/12/12/196195.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/196195.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/196195.htmlhttp://www.yiiframework.com/doc/guide/1.1/zh_cn/topics.console
PHP提供的cli模式可以進(jìn)行一些簡單的shell程序開發(fā),Yii框架也提供了cli程序開發(fā)的解決方案。

在Yii項(xiàng)目的protected目錄下,存在yiic和yii.bat兩個(gè)文件,它們分別是類unix系統(tǒng)和windows系統(tǒng)下執(zhí)行Yii項(xiàng)目的命令行程序的入口,例如:

1
$ yiic command action --param=value

或者

1
 $ php yiic sitemap test --type=value

具體使用哪種寫法,取決于入口程序是否有執(zhí)行權(quán)限,例如,在linux系統(tǒng)下,如果執(zhí)行命令:

1
chmod +x yiic

給予了yiic執(zhí)行權(quán)限,就可以用第一種方式來執(zhí)行php命令行程序,否則需要使用第二種方式。

執(zhí)行Yii的命令行程序的命令有四部分組成:
命令行入口程序yiic
要執(zhí)行的命令名稱,類似Yii框架web程序的controller
要執(zhí)行的動(dòng)作名稱,類似Yii框架web程序controller的action
提供給程序的外部參數(shù),以兩個(gè)短橫線“–”開頭,參數(shù)沒有順序

要建立一個(gè)命令行程序,需要繼承一個(gè)CConsoleCommand的子類:


class SitemapCommand extends CConsoleCommand
{
    public function actionTest($type, $limit=5) { ... }
}

保存到protected/commands/SitemapCommand.php文件。

在命令行下執(zhí)行:

1
$ php yiic sitemap test --type=value

SitemapCommand類的 actionTest 方法就會被執(zhí)行,并獲得值為value的$type參數(shù)。

可以在protected/config/console.php文件中進(jìn)行命令行模式下相關(guān)參數(shù)的配置,例如數(shù)據(jù)庫連接信息等,配置方法和Yii的web模式一樣。



小果子 2012-12-12 14:41 發(fā)表評論
]]>
linux tomcat安裝http://m.shnenglu.com/guojingjia2006/archive/2012/11/13/195106.html小果子小果子Tue, 13 Nov 2012 03:09:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2012/11/13/195106.htmlhttp://m.shnenglu.com/guojingjia2006/comments/195106.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2012/11/13/195106.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/195106.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/195106.html2) 下載tomcat,解壓 (version 7)
3) 修改tomcat bin目錄下setclasspath.sh,
增加 export JRE_HOME=/usr/local/src/jdk1.7.0_04

啟動(dòng)tomcat,如果正常的話,可以看見貓了


小果子 2012-11-13 11:09 發(fā)表評論
]]>
yii (3)http://m.shnenglu.com/guojingjia2006/archive/2012/08/30/188729.html小果子小果子Thu, 30 Aug 2012 04:16:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2012/08/30/188729.htmlhttp://m.shnenglu.com/guojingjia2006/comments/188729.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2012/08/30/188729.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/188729.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/188729.html$criteria = new CDbCriteria; 
     
    $criteria->addCondition("id=1"); //查詢條件,即where id = 1  
    $criteria->addInCondition('id', array(1,2,3,4,5)); //代表where id IN (1,23,,4,5,);  
    $criteria->addNotInCondition('id', array(1,2,3,4,5));//與上面正好相法,是NOT IN  
    $criteria->addCondition('id=1','OR');//這是OR條件,多個(gè)條件的時(shí)候,該條件是OR而非AND  
    $criteria->addSearchCondition('name', '分類');//搜索條件,其實(shí)代表了。。where name like '%分類%'  
    $criteria->addBetweenCondition('id', 1, 4);//between 1 and 4   
      
    $criteria->compare('id', 1);    //這個(gè)方法比較特殊,他會根據(jù)你的參數(shù)自動(dòng)處理成addCondition或者addInCondition,  
                                    //即如果第二個(gè)參數(shù)是數(shù)組就會調(diào)用addInCondition  
     
    $criteria->addCondition("id = :id");  
    $criteria->params[':id']=1;  
     
    $criteria->select = 'id,parentid,name'; //代表了要查詢的字段,默認(rèn)select='*';  
    $criteria->join = 'xxx'; //連接表  
    $criteria->with = 'xxx'; //調(diào)用relations   
    $criteria->limit = 10;    //取1條數(shù)據(jù),如果小于0,則不作處理  
    $criteria->offset = 1;   //兩條合并起來,則表示 limit 10 offset 1,或者代表了。limit 1,10  
    $criteria->order = 'xxx DESC,XXX ASC' ;//排序條件  
    $criteria->group = 'group 條件';  
    $criteria->having = 'having 條件 ';  
    $criteria->distinct = FALSE; //是否唯一查詢 


小果子 2012-08-30 12:16 發(fā)表評論
]]>
phpunithttp://m.shnenglu.com/guojingjia2006/archive/2012/05/04/173650.html小果子小果子Fri, 04 May 2012 03:39:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2012/05/04/173650.htmlhttp://m.shnenglu.com/guojingjia2006/comments/173650.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2012/05/04/173650.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/173650.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/173650.html

最近研究php的單元測試功能,在centos下和widows下安裝了phpunit

首先要保證你裝的php中安裝了pear

linux下輸入命令pear 回車可看一下是否安裝了

windows下可以用dos進(jìn)入到php的安裝目錄 ,輸入命令pear 回車可看一下是否安裝了 

在默認(rèn)情況下php中都會安裝的

pear的安裝

wwindows下用dos進(jìn)入php的安裝根目錄  運(yùn)行g(shù)o-pear,r然后輸入兩次yes 然后 后邊的選項(xiàng)直接用回車

然后我們要添加Channel

pear channel-discover pear.phpunit.de

pear channel-discover components.ez.no

pear channel-discover pear.symfony-project.com


我在這個(gè)地方遇到了 .lock 訪問權(quán)限的錯(cuò)誤而安裝失敗,這是我們可以在PEAR文件夾下刪除此文件

接下來執(zhí)行pear install phpunit/PHPUnit,此時(shí)我遇到了下圖所示的問題,包依賴

很簡單 我們把這些包用pear install命令安裝了 即可

可能執(zhí)行完這個(gè)之后你的phpunit還是提示安裝失敗

它提示我們要更新pear包

pear upgrade-all 

按照提示操作,可能會提示你更新Channel,那么更新即可

此時(shí)在執(zhí)行pear install phpunit/PHPUnit 可以看到提示安裝成功了



我們會發(fā)現(xiàn)在PEAR目錄下多了PHPUnit 這表明安裝成功,另外在安裝pear的時(shí)候回修改php.ini文件

;***** Added by go-pear

include_path=".;E:\webserver\php\pear"

;*****

小提示:直接輸入pear可現(xiàn)實(shí)pear命令下的所有選項(xiàng)

phpunit 使用手冊 http://www.phpunit.de/manual/3.5/en/index.html



小果子 2012-05-04 11:39 發(fā)表評論
]]>
yii 路由http://m.shnenglu.com/guojingjia2006/archive/2012/03/20/168433.html小果子小果子Tue, 20 Mar 2012 12:59:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2012/03/20/168433.htmlhttp://m.shnenglu.com/guojingjia2006/comments/168433.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2012/03/20/168433.html#Feedback1http://m.shnenglu.com/guojingjia2006/comments/commentRss/168433.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/168433.html閱讀全文

小果子 2012-03-20 20:59 發(fā)表評論
]]>
JQuery ajax 參數(shù)詳細(xì)列表http://m.shnenglu.com/guojingjia2006/archive/2012/01/15/164209.html小果子小果子Sun, 15 Jan 2012 05:02:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2012/01/15/164209.htmlhttp://m.shnenglu.com/guojingjia2006/comments/164209.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2012/01/15/164209.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/164209.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/164209.html下面是Jquery中AJAX參數(shù)詳細(xì)列表:
 


參數(shù)名
 
類型
 
描述

 

url

String
 
(默認(rèn): 當(dāng)前頁地址) 發(fā)送請求的地址。

 

type
 
String
 
(默認(rèn): "GET") 請求方式 ("POST" 或 "GET"), 默認(rèn)為 "GET"。注意:其它 HTTP 請求方法,如 PUT 和 DELETE 也可以使用,但僅部分瀏覽器支持。

 

timeout
 
Number
 
設(shè)置請求超時(shí)時(shí)間(毫秒)。此設(shè)置將覆蓋全局設(shè)置。

 

async

Boolean
 
(默認(rèn): true) 默認(rèn)設(shè)置下,所有請求均為異步請求。如果需要發(fā)送同步請求,請將此選項(xiàng)設(shè)置為 false。注意,同步請求將鎖住瀏覽器,用戶其它操作必須等待請求完成才可以執(zhí)行。

 

beforeSend

Function
 
發(fā)送請求前可修改 XMLHttpRequest 對象的函數(shù),如添加自定義 HTTP 頭。XMLHttpRequest 對象是唯一的參數(shù)。
function (XMLHttpRequest) { this; // the options for this ajax request }


cache

Boolean
 
(默認(rèn): true) jQuery 1.2 新功能,設(shè)置為 false 將不會從瀏覽器緩存中加載請求信息。

 

complete

Function
 
請求完成后回調(diào)函數(shù) (請求成功或失敗時(shí)均調(diào)用)。參數(shù): XMLHttpRequest 對象,成功信息字符串。
function (XMLHttpRequest, textStatus) { this; // the options for this ajax request }


contentType

String
 
(默認(rèn): "application/x-www-form-urlencoded") 發(fā)送信息至服務(wù)器時(shí)內(nèi)容編碼類型。默認(rèn)值適合大多數(shù)應(yīng)用場合。

 

data

Object,
String
 
發(fā)送到服務(wù)器的數(shù)據(jù)。將自動(dòng)轉(zhuǎn)換為請求字符串格式。GET 請求中將附加在 URL 后。查看 processData 選項(xiàng)說明以禁止此自動(dòng)轉(zhuǎn)換。必須為 Key/Value 格式。如果為數(shù)組,jQuery 將自動(dòng)為不同值對應(yīng)同一個(gè)名稱。如 {foo:["bar1", "bar2"]} 轉(zhuǎn)換為 '&foo=bar1&foo=bar2'。

 

dataType

String
 

預(yù)期服務(wù)器返回的數(shù)據(jù)類型。如果不指定,jQuery 將自動(dòng)根據(jù) HTTP 包 MIME 信息返回 responseXML 或 responseText,并作為回調(diào)函數(shù)參數(shù)傳遞,可用值:
 
"xml": 返回 XML 文檔,可用 jQuery 處理。
 
"html": 返回純文本 HTML 信息;包含 script 元素。
 
"script": 返回純文本 JavaScript 代碼。不會自動(dòng)緩存結(jié)果。
 
"json": 返回 JSON 數(shù)據(jù) 。
 
"jsonp": JSONP 格式。使用 JSONP 形式調(diào)用函數(shù)時(shí),如 "myurl?callback=?" jQuery 將自動(dòng)替換 ? 為正確的函數(shù)名,以執(zhí)行回調(diào)函數(shù)。
 


error

Function
 
(默認(rèn): 自動(dòng)判斷 (xml 或 html)) 請求失敗時(shí)將調(diào)用此方法。這個(gè)方法有三個(gè)參數(shù):XMLHttpRequest 對象,錯(cuò)誤信息,(可能)捕獲的錯(cuò)誤對象。
function (XMLHttpRequest, textStatus, errorThrown) { // 通常情況下textStatus和errorThown只有其中一個(gè)有值  this; // the options for this ajax request }


global

Boolean
 
(默認(rèn): true) 是否觸發(fā)全局 AJAX 事件。設(shè)置為 false 將不會觸發(fā)全局 AJAX 事件,如 ajaxStart 或 ajaxStop 。可用于控制不同的Ajax事件

 

ifModified

Boolean
 
(默認(rèn): false) 僅在服務(wù)器數(shù)據(jù)改變時(shí)獲取新數(shù)據(jù)。使用 HTTP 包 Last-Modified 頭信息判斷。

 

processData

Boolean
 
(默認(rèn): true) 默認(rèn)情況下,發(fā)送的數(shù)據(jù)將被轉(zhuǎn)換為對象(技術(shù)上講并非字符串) 以配合默認(rèn)內(nèi)容類型 "application/x-www-form-urlencoded"。如果要發(fā)送 DOM 樹信息或其它不希望轉(zhuǎn)換的信息,請?jiān)O(shè)置為 false。

 

success

Function
 
請求成功后回調(diào)函數(shù)。這個(gè)方法有兩個(gè)參數(shù):服務(wù)器返回?cái)?shù)據(jù),返回狀態(tài)
function (data, textStatus) { // data could be xmlDoc, jsonObj, html, text, etc... this; // the options for this ajax request }


代碼:$(document).ready(function() {
            jQuery("#clearCac").click(function() {
                jQuery.ajax({
                    url: "/Handle/Do.aspx",
                    type: "post",
                    data: { id: '0' },
                    dataType: "json",
                    success: function(msg) {
                        alert(msg);
                    },
                    error: function(XMLHttpRequest, textStatus, errorThrown) {
                        alert(XMLHttpRequest.status);
                        alert(XMLHttpRequest.readyState);
                        alert(textStatus);
                    },
                    complete: function(XMLHttpRequest, textStatus) {
                        this; // 調(diào)用本次AJAX請求時(shí)傳遞的options參數(shù)
                    }
                });
            });
        });
 
 
 
一、error:function (XMLHttpRequest, textStatus, errorThrown)
{
}
(默認(rèn): 自動(dòng)判斷 (xml 或 html)) 請求失敗時(shí)調(diào)用時(shí)間。參數(shù)有以下三個(gè):XMLHttpRequest 對象、錯(cuò)誤信息、(可選)捕獲的錯(cuò)誤對象。如果發(fā)生了錯(cuò)誤,錯(cuò)誤信息(第二個(gè)參數(shù))除了得到null之外,還可能是"timeout", "error", "notmodified" 和 "parsererror"。
 
textStatus:
 
 "timeout", "error", "notmodified" 和 "parsererror"。
 
二、error事件返回的第一個(gè)參數(shù)XMLHttpRequest有一些有用的信息:
 
XMLHttpRequest.readyState:

狀態(tài)碼 

0 - (未初始化)還沒有調(diào)用send()方法 

1 - (載入)已調(diào)用send()方法,正在發(fā)送請求 

2 - (載入完成)send()方法執(zhí)行完成,已經(jīng)接收到全部響應(yīng)內(nèi)容 

3 - (交互)正在解析響應(yīng)內(nèi)容 

4 - (完成)響應(yīng)內(nèi)容解析完成,可以在客戶端調(diào)用了
 
三、data:"{}", data為空也一定要傳"{}";不然返回的是xml格式的。并提示parsererror.
 
四、parsererror的異常和Header 類型也有關(guān)系。及編碼header('Content-type: text/html; charset=utf8');

五、XMLHttpRequest.status:
1xx-信息提示 
這些狀態(tài)代碼表示臨時(shí)的響應(yīng)。客戶端在收到常規(guī)響應(yīng)之前,應(yīng)準(zhǔn)備接收一個(gè)或多個(gè)1xx響應(yīng)。 
100-繼續(xù)。 
101-切換協(xié)議。 
2xx-成功 
這類狀態(tài)代碼表明服務(wù)器成功地接受了客戶端請求。 
200-確定。客戶端請求已成功。 
201-已創(chuàng)建。 
202-已接受。 
203-非權(quán)威性信息。 
204-無內(nèi)容。 
205-重置內(nèi)容。 
206-部分內(nèi)容。 
3xx-重定向 
客戶端瀏覽器必須采取更多操作來實(shí)現(xiàn)請求。例如,瀏覽器可能不得不請求服務(wù)器上的不同的頁面,或通過代理服務(wù)器重復(fù)該請求。 
301-對象已永久移走,即永久重定向。 
302-對象已臨時(shí)移動(dòng)。 
304-未修改。 
307-臨時(shí)重定向。 
4xx-客戶端錯(cuò)誤 
發(fā)生錯(cuò)誤,客戶端似乎有問題。例如,客戶端請求不存在的頁面,客戶端未提供有效的身份驗(yàn)證信息。400-錯(cuò)誤的請求。 
401-訪問被拒絕。IIS定義了許多不同的401錯(cuò)誤,它們指明更為具體的錯(cuò)誤原因。這些具體的錯(cuò)誤代碼在瀏覽器中顯示,但不在IIS日志中顯示: 
401.1-登錄失敗。 
401.2-服務(wù)器配置導(dǎo)致登錄失敗。 
401.3-由于ACL對資源的限制而未獲得授權(quán)。 
401.4-篩選器授權(quán)失敗。 
401.5-ISAPI/CGI應(yīng)用程序授權(quán)失敗。 
401.7–訪問被Web服務(wù)器上的URL授權(quán)策略拒絕。這個(gè)錯(cuò)誤代碼為IIS6.0所專用。 
403-禁止訪問:IIS定義了許多不同的403錯(cuò)誤,它們指明更為具體的錯(cuò)誤原因: 
403.1-執(zhí)行訪問被禁止。 
403.2-讀訪問被禁止。 
403.3-寫訪問被禁止。 
403.4-要求SSL。 
403.5-要求SSL128。 
403.6-IP地址被拒絕。 
403.7-要求客戶端證書。 
403.8-站點(diǎn)訪問被拒絕。 
403.9-用戶數(shù)過多。 
403.10-配置無效。 
403.11-密碼更改。 
403.12-拒絕訪問映射表。 
403.13-客戶端證書被吊銷。 
403.14-拒絕目錄列表。 
403.15-超出客戶端訪問許可。 
403.16-客戶端證書不受信任或無效。 
403.17-客戶端證書已過期或尚未生效。 
403.18-在當(dāng)前的應(yīng)用程序池中不能執(zhí)行所請求的URL。這個(gè)錯(cuò)誤代碼為IIS6.0所專用。 
403.19-不能為這個(gè)應(yīng)用程序池中的客戶端執(zhí)行CGI。這個(gè)錯(cuò)誤代碼為IIS6.0所專用。 
403.20-Passport登錄失敗。這個(gè)錯(cuò)誤代碼為IIS6.0所專用。 
404-未找到。 
404.0-(無)–沒有找到文件或目錄。 
404.1-無法在所請求的端口上訪問Web站點(diǎn)。 
404.2-Web服務(wù)擴(kuò)展鎖定策略阻止本請求。 
404.3-MIME映射策略阻止本請求。 
405-用來訪問本頁面的HTTP謂詞不被允許(方法不被允許) 
406-客戶端瀏覽器不接受所請求頁面的MIME類型。 
407-要求進(jìn)行代理身份驗(yàn)證。 
412-前提條件失敗。 
413–請求實(shí)體太大。 
414-請求URI太長。 
415–不支持的媒體類型。 
416–所請求的范圍無法滿足。 
417–執(zhí)行失敗。 
423–鎖定的錯(cuò)誤。 
5xx-服務(wù)器錯(cuò)誤 
服務(wù)器由于遇到錯(cuò)誤而不能完成該請求。 
500-內(nèi)部服務(wù)器錯(cuò)誤。 
500.12-應(yīng)用程序正忙于在Web服務(wù)器上重新啟動(dòng)。 
500.13-Web服務(wù)器太忙。 
500.15-不允許直接請求Global.asa。 
500.16–UNC授權(quán)憑據(jù)不正確。這個(gè)錯(cuò)誤代碼為IIS6.0所專用。 
500.18–URL授權(quán)存儲不能打開。這個(gè)錯(cuò)誤代碼為IIS6.0所專用。 
500.100-內(nèi)部ASP錯(cuò)誤。 
501-頁眉值指定了未實(shí)現(xiàn)的配置。 
502-Web服務(wù)器用作網(wǎng)關(guān)或代理服務(wù)器時(shí)收到了無效響應(yīng)。 
502.1-CGI應(yīng)用程序超時(shí)。 
502.2-CGI應(yīng)用程序出錯(cuò)。application. 
503-服務(wù)不可用。這個(gè)錯(cuò)誤代碼為IIS6.0所專用。 
504-網(wǎng)關(guān)超時(shí)。 
505-HTTP版本不受支持。 
FTP 
1xx-肯定的初步答復(fù) 
這些狀態(tài)代碼指示一項(xiàng)操作已經(jīng)成功開始,但客戶端希望在繼續(xù)操作新命令前得到另一個(gè)答復(fù)。 
110重新啟動(dòng)標(biāo)記答復(fù)。 
120服務(wù)已就緒,在nnn分鐘后開始。 
125數(shù)據(jù)連接已打開,正在開始傳輸。 
150文件狀態(tài)正常,準(zhǔn)備打開數(shù)據(jù)連接。 
2xx-肯定的完成答復(fù) 
一項(xiàng)操作已經(jīng)成功完成。客戶端可以執(zhí)行新命令。200命令確定。 
202未執(zhí)行命令,站點(diǎn)上的命令過多。 
211系統(tǒng)狀態(tài),或系統(tǒng)幫助答復(fù)。 
212目錄狀態(tài)。 
213文件狀態(tài)。 
214幫助消息。 
215NAME系統(tǒng)類型,其中,NAME是AssignedNumbers文檔中所列的正式系統(tǒng)名稱。 
220服務(wù)就緒,可以執(zhí)行新用戶的請求。 
221服務(wù)關(guān)閉控制連接。如果適當(dāng),請注銷。 
225數(shù)據(jù)連接打開,沒有進(jìn)行中的傳輸。 
226關(guān)閉數(shù)據(jù)連接。請求的文件操作已成功(例如,傳輸文件或放棄文件)。 
227進(jìn)入被動(dòng)模式(h1,h2,h3,h4,p1,p2)。 
230用戶已登錄,繼續(xù)進(jìn)行。 
250請求的文件操作正確,已完成。 
257已創(chuàng)建“PATHNAME”。 
3xx-肯定的中間答復(fù) 
該命令已成功,但服務(wù)器需要更多來自客戶端的信息以完成對請求的處理。331用戶名正確,需要密碼。 
332需要登錄帳戶。 
350請求的文件操作正在等待進(jìn)一步的信息。 
4xx-瞬態(tài)否定的完成答復(fù) 
該命令不成功,但錯(cuò)誤是暫時(shí)的。如果客戶端重試命令,可能會執(zhí)行成功。421服務(wù)不可用,正在關(guān)閉控制連接。如果服務(wù)確定它必須關(guān)閉,將向任何命令發(fā)送這一應(yīng)答。 
425無法打開數(shù)據(jù)連接。 
426Connectionclosed;transferaborted. 
450未執(zhí)行請求的文件操作。文件不可用(例如,文件繁忙)。 
451請求的操作異常終止:正在處理本地錯(cuò)誤。 
452未執(zhí)行請求的操作。系統(tǒng)存儲空間不夠。 
5xx-永久性否定的完成答復(fù) 
該命令不成功,錯(cuò)誤是永久性的。如果客戶端重試命令,將再次出現(xiàn)同樣的錯(cuò)誤。500語法錯(cuò)誤,命令無法識別。這可能包括諸如命令行太長之類的錯(cuò)誤。 
501在參數(shù)中有語法錯(cuò)誤。 
502未執(zhí)行命令。 
503錯(cuò)誤的命令序列。 
504未執(zhí)行該參數(shù)的命令。 
530未登錄。 
532存儲文件需要帳戶。 
550未執(zhí)行請求的操作。文件不可用(例如,未找到文件,沒有訪問權(quán)限)。 
551請求的操作異常終止:未知的頁面類型。 
552請求的文件操作異常終止:超出存儲分配(對于當(dāng)前目錄或數(shù)據(jù)集)。 
553未執(zhí)行請求的操作。不允許的文件名。 

本篇文章來源于 Linux公社網(wǎng)站(www.linuxidc.com)  原文鏈接:http://www.linuxidc.com/Linux/2011-11/47495.htm



小果子 2012-01-15 13:02 發(fā)表評論
]]>
Yii sql (3)http://m.shnenglu.com/guojingjia2006/archive/2012/01/13/164104.html小果子小果子Fri, 13 Jan 2012 01:51:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2012/01/13/164104.htmlhttp://m.shnenglu.com/guojingjia2006/comments/164104.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2012/01/13/164104.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/164104.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/164104.html$criteria = new CDbCriteria;

$criteria->addCondition("id=1"); //查詢條件,即where id = 1

$criteria->addInCondition('id', array(1,2,3,4,5)); //代表where id IN (1,23,,4,5,);

$criteria->addNotInCondition('id', array(1,2,3,4,5));//與上面正好相法,是NOT IN

$criteria->addCondition('id=1','OR');//這是OR條件,多個(gè)條件的時(shí)候,該條件是OR而非AND

$criteria->addSearchCondition('name', '分類');//搜索條件,其實(shí)代表了。。where name like '%分類%'

$criteria->addBetweenCondition('id', 1, 4);//between 1 and 4

$criteria->compare('id', 1); //這個(gè)方法比較特殊,他會根據(jù)你的參數(shù)自動(dòng)處理成addCondition或者addInCondition,

//即如果第二個(gè)參數(shù)是數(shù)組就會調(diào)用addInCondition
$criteria->addCondition("id = :id");

$criteria->params[':id']=1;

//一些public vars

$criteria->select = 'id,parentid,name'; //代表了要查詢的字段,默認(rèn)select='*';

$criteria->join = 'xxx'; //連接表

$criteria->with = 'xxx'; //調(diào)用relations

$criteria->limit = 10; //取1條數(shù)據(jù),如果小于0,則不作處理

$criteria->offset = 1; //兩條合并起來,則表示 limit 10 offset 1,或者代表了。limit 1,10

$criteria->order = 'xxx DESC,XXX ASC' ;//排序條件

$criteria->group = 'group 條件'; $criteria->having = 'having 條件 ';

$criteria->distinct = FALSE; //是否唯一查詢

小果子 2012-01-13 09:51 發(fā)表評論
]]>
Yii 數(shù)據(jù)庫 (2)http://m.shnenglu.com/guojingjia2006/archive/2012/01/04/163555.html小果子小果子Wed, 04 Jan 2012 08:18:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2012/01/04/163555.htmlhttp://m.shnenglu.com/guojingjia2006/comments/163555.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2012/01/04/163555.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/163555.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/163555.html
  • 目錄
    一、增刪查改
    二、驗(yàn)證規(guī)則
    三、事務(wù)管理
    四、名字空間。參考:Yii數(shù)據(jù)庫操作——名字空間(named scopes)的三種用法

    一、增刪查改
    1,創(chuàng)建
    $post = new Post;
    $post->title = "";
    $post->content = "";
    $post->created_at = "CDbExpression('NOW()')";
    $post->save();

    (1) 插入后可立即獲得主鍵id。
    $id = $post->id;   // 前提是auto_increment

    (2) 某一個(gè)字段的值為缺省值時(shí),可以在models/Class.php中修改
    Class Post extends CActiveRecord{
    public $title = 'new title';
    $post = new Post;
    echo $post->title; // 輸出是: new title
    }

    (3) 使用CDbExpression
    $post->create_time = new CDbExpression('NOW()');


    2,查詢【待補(bǔ)充】
    (1) 通過主鍵查詢
    find("postID=:postID", array(':postID' => postID)
    findByPk($id) // 單主鍵

    (2) 通過非主鍵查詢
    find("postID=:postID", array(':postID' => postID)
    findAll( id = $id )
    findAll( id IN ( $id ) )



    3,更新【待補(bǔ)充】
    先find,并將對應(yīng)字段賦新值,再保存

    可以通過CActiveRecord::isNewRecord來判斷是新建,還是更新。


    4,刪除
    (1) 如果是一條記錄
    先找到后刪除
    $post=Post::model->findByPk(10);
    $post->delete();

    直接通過主鍵刪除(類級別刪除,不需要先載入記錄)
    Post::model->deleteByPk(10);

    (2) 如果是多條記錄(類級別刪除,不需要先載入記錄)
    Post::model->deleteAll();


    二、驗(yàn)證規(guī)則
    驗(yàn)證規(guī)則(Data validation)發(fā)生在調(diào)用save()方法的時(shí)候。驗(yàn)證是基于在rules()方法中的定義。

    if( $post->save() ){
    // 驗(yàn)證通過
    } else {
    // 驗(yàn)證失敗。通過getErrors()返回錯(cuò)誤信息。
    }

    獲取用戶從表單提交的數(shù)據(jù)
    $post->title   = $_POST['title'];
    $post->content = $_POST['content'];
    $post->save();

    如果多了,可以通過下面的方式減輕(alleviate)復(fù)雜程度:

    Php代碼
    1. $post->attributes = $_POST['Post'];   
    2. $post->save();   
    3. //類似于:   
    4. foreach($_POST['Post'as $name=>$value){   
    5.     if($name is a safe attribute)   
    6.         $model->$name = $value;   
    7. }  
    $post->attributes = $_POST['Post'];$post->save();//類似于:foreach($_POST['Post'] as $name=>$value){	if($name is a safe attribute)		$model->$name = $value;}


    注意:里面的驗(yàn)證檢驗(yàn)非常重要,否則用戶可能繞過授權(quán)。


    三、事務(wù)管理
    dbConnection是CDbConnection的實(shí)例
    官方文檔

    Php代碼
    1. $model = Post::model();   
    2. $transaction = $model->dbConnection->beginTransaction();   
    3. try{   
    4.     $post = $model->findByPk(10);   
    5.     $post->title = 'new post title';   
    6.     $post->save();   
    7.     $transaction->commit();   
    8. } catch (Exception $e){   
    9.     $transaction->rollback();   
    10. }  
    $model = Post::model();$transaction = $model->dbConnection->beginTransaction();try{	$post = $model->findByPk(10);	$post->title = 'new post title';	$post->save();	$transaction->commit();} catch (Exception $e){	$transaction->rollback();}



    實(shí)際項(xiàng)目

    Php代碼
    1. $trans = Yii::app()->db->beginTransaction();   
    2. try {   
    3.     $manufacturer = new Manufacturer();    
    4.     $manufacturer->name = $name;   
    5.     $manufacturer->email = $email;   
    6.     $manufacturer->save();   
    7.     $trans->commit();   
    8. } catch (Exception $e) {   
    9.     $trans->rollback();   
    10.     $this->response(array('status' => 1, 'msg' => $e->getMessage()));      
    11. }  
    $trans = Yii::app()->db->beginTransaction();try {	$manufacturer = new Manufacturer();		$manufacturer->name = $name;	$manufacturer->email = $email;	$manufacturer->save();	$trans->commit();} catch (Exception $e) {	$trans->rollback();	$this->response(array('status' => 1, 'msg' => $e->getMessage()));	}



    其實(shí)使用的時(shí)候跟凡客體的我是凡客或淘寶體的親一樣。

    注:Yii::app()后面的db在../config/main.php中已配置

    Php代碼
    1. 'components'=>array(   
    2.     'user'=>array('allowAutoLogin'=>true,),   
    3.     'db'=>array("數(shù)據(jù)庫連接參數(shù)"),   
    4. )  



  • 小果子 2012-01-04 16:18 發(fā)表評論
    ]]>
    Yii 框架里數(shù)據(jù)庫操作詳解-[增加、查詢、更新、刪除的方法 'AR一、查詢數(shù)據(jù)集合http://m.shnenglu.com/guojingjia2006/archive/2012/01/04/163553.html小果子小果子Wed, 04 Jan 2012 08:06:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2012/01/04/163553.htmlhttp://m.shnenglu.com/guojingjia2006/comments/163553.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2012/01/04/163553.html#Feedback1http://m.shnenglu.com/guojingjia2006/comments/commentRss/163553.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/163553.html閱讀全文

    小果子 2012-01-04 16:06 發(fā)表評論
    ]]>
    YIIhttp://m.shnenglu.com/guojingjia2006/archive/2011/12/02/161321.html小果子小果子Fri, 02 Dec 2011 05:16:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2011/12/02/161321.htmlhttp://m.shnenglu.com/guojingjia2006/comments/161321.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2011/12/02/161321.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/161321.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/161321.htmlhttp://www.yiiframework.com/
    http://www.yiiframework.com/doc/guide/1.1/zh_cn/quickstart.what-is-yii
    http://yp.oss.org.cn/blog/show_resource.php?resource_id=774
    http://www.yiieye.com/book_cn/
    http://blog.csdn.net/dxxgiupel/article/details/5803864
    http://wenku.baidu.com/view/7d7d65ecaeaad1f346933fb5.html


    小果子 2011-12-02 13:16 發(fā)表評論
    ]]>
    struts2 - resulthttp://m.shnenglu.com/guojingjia2006/archive/2011/04/05/143462.html小果子小果子Tue, 05 Apr 2011 10:17:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2011/04/05/143462.htmlhttp://m.shnenglu.com/guojingjia2006/comments/143462.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2011/04/05/143462.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/143462.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/143462.html
    struts.xml配置文件中result的語法:<result name="" type="">xxxxx</result>

    Struts2支持的不同類型的返回結(jié)果為:

    Chain Result-->type="chain"
    用來處理Action鏈

    Dispatcher Result -->type="dispatcher"
    用來轉(zhuǎn)向頁面,通常處理JSP

    FreeMarker Result -->type="freemarker"
    處理FreeMarker模板

    HttpHeader Result -->type="httpheader"
    用來控制特殊的Http行為

    Redirect Result -->type="redirect"
    重定向到一個(gè)URL

    Redirect Action Result -->type="redirectAction"
    重定向到一個(gè)Action

    Stream Result -->type="stream"
    向?yàn)g覽器發(fā)送InputSream對象,通常用來處理文件下載

    Velocity Result -->type="velocity"
    處理Velocity模板

    XLST Result -->type="xslt"
    處理XML/XLST模板

    PlainText Result -->type="plainText"
    顯示原始文件內(nèi)容,例如文件源代碼


    另外第三方的result類型還包括JasperReports Plugin,專門用來處理JasperReport類型的報(bào)表輸出。

    在struts-default.xml文件中已經(jīng)有了對于所有類型Result的定義:

    Java 代碼

    1. <result-types>  
    2.  
    3.     <result-type name="chain"  
    4.  
    5.              class="com.opensymphony.xwork2.ActionChainResult"/>  
    6.  
    7.     <result-type name="dispatcher"  
    8.  
    9.              class="org.apache.struts2.dispatcher.ServletDispatcherResult"  
    10.  
    11.              default="true"/>  
    12.  
    13.     <result-type name="freemarker"  
    14.  
    15.              class="org.apache.struts2.views.freemarker.FreemarkerResult"/>  
    16.  
    17.     <result-type name="httpheader"  
    18.  
    19.              class="org.apache.struts2.dispatcher.HttpHeaderResult"/>  
    20.  
    21.     <result-type name="redirect"  
    22.  
    23.              class="org.apache.struts2.dispatcher.ServletRedirectResult"/>  
    24.  
    25.     <result-type name="redirectAction"  
    26.  
    27.              class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>  
    28.  
    29.     <result-type name="stream"  
    30.  
    31.              class="org.apache.struts2.dispatcher.StreamResult"/>  
    32.  
    33.     <result-type name="velocity"  
    34.  
    35.              class="org.apache.struts2.dispatcher.VelocityResult"/>  
    36.  
    37.     <result-type name="xslt"  
    38.  
    39.              class="org.apache.struts2.views.xslt.XSLTResult"/>  
    40.  
    41.     <result-type name="plainText"  
    42.  
    43.              class="org.apache.struts2.dispatcher.PlainTextResult" />  
    44.  
    45.     <!-- Deprecated name form scheduled for removal in Struts 2.1.0.  
    46.  
    47.          The camelCase versions are preferred. See ww-1707 -->  
    48.  
    49.     <result-type name="redirect-action"  
    50.  
    51.              class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>  
    52.  
    53.     <result-type name="plaintext"  
    54.  
    55.              class="org.apache.struts2.dispatcher.PlainTextResult" />  
    56.  
    57. </result-types>  

    <result-types>

    <result-type name="chain"

    class="com.opensymphony.xwork2.ActionChainResult"/>

    <result-type name="dispatcher"

    class="org.apache.struts2.dispatcher.ServletDispatcherResult"

    default="true"/>

    <result-type name="freemarker"

    class="org.apache.struts2.views.freemarker.FreemarkerResult"/>

    <result-type name="httpheader"

    class="org.apache.struts2.dispatcher.HttpHeaderResult"/>

    <result-type name="redirect"

    class="org.apache.struts2.dispatcher.ServletRedirectResult"/>

    <result-type name="redirectAction"

    class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>

    <result-type name="stream"

    class="org.apache.struts2.dispatcher.StreamResult"/>

    <result-type name="velocity"

    class="org.apache.struts2.dispatcher.VelocityResult"/>

    <result-type name="xslt"

    class="org.apache.struts2.views.xslt.XSLTResult"/>

    <result-type name="plainText"

    class="org.apache.struts2.dispatcher.PlainTextResult" />

    <!-- Deprecated name form scheduled for removal in Struts 2.1.0.

    The camelCase versions are preferred. See ww-1707 -->

    <result-type name="redirect-action"

    class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>

    <result-type name="plaintext"

    class="org.apache.struts2.dispatcher.PlainTextResult" />

    </result-types>



    從上述代碼中可以看出在不指定Result類型的時(shí)候默認(rèn)使用dispatcher類型。


    定義一個(gè)Result值,

    Java 代碼

    1. <result name="success" type="dispatcher">  
    2.  
    3.     <param name="location">/myjsp.jsp</param>  
    4.  
    5. </result>  

    <result name="success" type="dispatcher">

    <param name="location">/myjsp.jsp</param>

    </result>


    由于type默認(rèn)值是dispatcher,所以這里不需要定義,另外name的默認(rèn)值為success所以這里也不需要定義。
    上述代碼可以簡寫為:

    Java 代碼

    1. <result>  
    2.  
    3.     <param name="location">/myjsp.jsp</param>  
    4.  
    5. </result>  

    <result>

    <param name="location">/myjsp.jsp</param>

    </result>




    另外location參數(shù)也可以直接卸載result標(biāo)簽內(nèi)部(也就是無需再result里面使用),所以上述代碼的最簡單的寫法為:

    Java 代碼

    1. <result>/myjsp.jsp</result>  

    <result>/myjsp.jsp</result>



    我們也可以定義多個(gè)不同的result

    Java 代碼

    1. <action name="Hello">  
    2.  
    3. <result>/hello/hello.jsp</result>  
    4.  
    5. <result name="error">/hello/error.jsp</result>  
    6.  
    7. <result name="input">/hello/input.jsp</result>  
    8.  
    9. </action>  

    <action name="Hello">

    <result>/hello/hello.jsp</result>

    <result name="error">/hello/error.jsp</result>

    <result name="input">/hello/input.jsp</result>

    </action>



    上 述代碼的含義為,名字為Hello的Action有三個(gè)返回結(jié)果,并且都是 dispatcher類型(默認(rèn)類型),這三個(gè)返回值的名字分別為success(默認(rèn)值),error,input(當(dāng)輸入不通過時(shí),action 方法返回input),對應(yīng)的頁面的路徑分別為 /hello/result.jsp,/hello/error.jsp,/hello/input.jsp。

    有些時(shí)候我們需要一個(gè)定義在全局的result,這個(gè)時(shí)候我們可以在package內(nèi)部定義全局的result,例如:

    Java 代碼

    1. <global-results>  
    2.  
    3. <result name="error">/error.jsp</result>  
    4.  
    5. <result name="invalid.token">/error.jsp</result>  
    6.  
    7. <result name="login" type="redirect-action">login!input</result>  
    8.  
    9. </global-results>  

    <global-results>

    <result name="error">/error.jsp</result>

    <result name="invalid.token">/error.jsp</result>

    <result name="login" type="redirect-action">login!input</result>

    </global-results>



    動(dòng)態(tài)返回結(jié)果

    有些時(shí)候,只有當(dāng)Action執(zhí)行完璧的時(shí)候我們才知道要返回哪個(gè)結(jié)果,這個(gè)時(shí)候我們可以在Action內(nèi)部定義一個(gè)屬性,這個(gè)屬性用來存儲 Action執(zhí)行完璧之后的Result值,例如:

    Java 代碼

    1. private String nextAction;  
    2.  
    3. public String getNextAction() {  
    4.  
    5.     return nextAction;  
    6.  
    7. }  

    private String nextAction;

    public String getNextAction() {

    return nextAction;

    }



    在strutx.xml配置文件中,我們可以使用${nextAction}來引用到Action中的屬性,通過${nextAction}表示的內(nèi)容來動(dòng)態(tài)的返回結(jié)果,例如:

    Java 代碼

    1. <action name="fragment" class="FragmentAction">  
    2.  
    3. <result name="next" type="redirect-action">${nextAction}</result>  
    4.  
    5. </action>  

    <action name="fragment" class="FragmentAction">

    <result name="next" type="redirect-action">${nextAction}</result>

    </action>



    上述Action的execute方法返回next的時(shí)候,還需要根據(jù)nextAction的屬性來判斷具體定位到哪個(gè)Action。


    在struts.xml配置文件中,我們可以使用method=""來設(shè)置調(diào)用類的哪個(gè)方法,這樣就可以在一個(gè)JAVA類中使用不同的方法來實(shí)現(xiàn)不同的功能,就無需每個(gè)功能寫一類了,例如:
    Java 代碼

    1. <action name="fragment" class="cn.com.web.FragmentAction" method="add">  
    2.       <result>/success.jsp</result>  
    3. </action> 

    小果子 2011-04-05 18:17 發(fā)表評論
    ]]>
    struts2 - constant http://m.shnenglu.com/guojingjia2006/archive/2011/04/05/143458.html小果子小果子Tue, 05 Apr 2011 09:58:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2011/04/05/143458.htmlhttp://m.shnenglu.com/guojingjia2006/comments/143458.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2011/04/05/143458.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/143458.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/143458.html

    在struts的配置文件中的形式為:

    <constant name="struts.i18n.encoding" value="UTF-8" />

    struts.action.extension
    The URL extension to use to determine if the request is meant for a Struts action
    用URL擴(kuò)展名來確定是否這個(gè)請求是被用作Struts action,其實(shí)也就是設(shè)置 action的后綴,例如login.do的'do'字。

    struts.configuration
    The org.apache.struts2.config.Configuration implementation class
    org.apache.struts2.config.Configuration接口名

    struts.configuration.files
    A list of configuration files automatically loaded by Struts
    struts自動(dòng)加載的一個(gè)配置文件列表

    struts.configuration.xml.reload
    Whether to reload the XML configuration or not
    是否加載xml配置(true,false)

    struts.continuations.package
    The package containing actions that use Rife continuations
    含有actions的完整連續(xù)的package名稱

    struts.custom.i18n.resources
    Location of additional localization properties files to load
    加載附加的國際化屬性文件(不包含.properties后綴)

    struts.custom.properties
    Location of additional configuration properties files to load
    加載附加的配置文件的位置


    struts.devMode
    Whether Struts is in development mode or not
    是否為struts開發(fā)模式

    struts.dispatcher.parametersWorkaround
    Whether to use a Servlet request parameter workaround necessary for some versions of WebLogic
    (某些版本的weblogic專用)是否使用一個(gè)servlet請求參數(shù)工作區(qū)(PARAMETERSWORKAROUND)

    struts.enable.DynamicMethodInvocation
    Allows one to disable dynamic method invocation from the URL
    允許動(dòng)態(tài)方法調(diào)用

    struts.freemarker.manager.classname
    The org.apache.struts2.views.freemarker.FreemarkerManager implementation class
    org.apache.struts2.views.freemarker.FreemarkerManager接口名

    struts.i18n.encoding
    The encoding to use for localization messages
    國際化信息內(nèi)碼

    struts.i18n.reload
    Whether the localization messages should automatically be reloaded
    是否國際化信息自動(dòng)加載

    struts.locale
    The default locale for the Struts application
    默認(rèn)的國際化地區(qū)信息

    struts.mapper.class
    The org.apache.struts2.dispatcher.mapper.ActionMapper implementation class
    org.apache.struts2.dispatcher.mapper.ActionMapper接口

    struts.multipart.maxSize
    The maximize size of a multipart request (file upload)
    multipart請求信息的最大尺寸(文件上傳用)

    struts.multipart.parser
    The org.apache.struts2.dispatcher.multipart.MultiPartRequest parser implementation for a multipart request (file upload)
    專為multipart請求信息使用的 org.apache.struts2.dispatcher.multipart.MultiPartRequest解析器接口(文件上傳用)


    struts.multipart.saveDir
    The directory to use for storing uploaded files
    設(shè)置存儲上傳文件的目錄夾

    struts.objectFactory
    The com.opensymphony.xwork2.ObjectFactory implementation class
    com.opensymphony.xwork2.ObjectFactory接口(spring)

    struts.objectFactory.spring.autoWire
    Whether Spring should autoWire or not
    是否自動(dòng)綁定Spring

    struts.objectFactory.spring.useClassCache
    Whether Spring should use its class cache or not
    是否spring應(yīng)該使用自身的cache

    struts.objectTypeDeterminer
    The com.opensymphony.xwork2.util.ObjectTypeDeterminer implementation class
    com.opensymphony.xwork2.util.ObjectTypeDeterminer接口

    struts.serve.static.browserCache
    If static content served by the Struts filter should set browser caching header properties or not
    是否struts過濾器中提供的靜態(tài)內(nèi)容應(yīng)該被瀏覽器緩存在頭部屬性中

    struts.serve.static
    Whether the Struts filter should serve static content or not
    是否struts過濾器應(yīng)該提供靜態(tài)內(nèi)容

    struts.tag.altSyntax
    Whether to use the alterative syntax for the tags or not
    是否可以用替代的語法替代tags

    struts.ui.templateDir
    The directory containing UI templates
    UI templates的目錄夾

    struts.ui.theme
    The default UI template theme
    默認(rèn)的UI template主題

    struts.url.http.port
    The HTTP port used by Struts URLs
    設(shè)置http端口

    struts.url.https.port
    The HTTPS port used by Struts URLs
    設(shè)置https端口

    struts.url.includeParams
    The default includeParams method to generate Struts URLs
    在url中產(chǎn)生 默認(rèn)的includeParams


    struts.velocity.configfile
    The Velocity configuration file path
    velocity配置文件路徑

    struts.velocity.contexts
    List of Velocity context names
    velocity的context列表


    struts.velocity.manager.classname
    org.apache.struts2.views.velocity.VelocityManager implementation class
    org.apache.struts2.views.velocity.VelocityManager接口名

    struts.velocity.toolboxlocation
    The location of the Velocity toolbox
    velocity工具盒的位置
    struts.xslt.nocache
    Whether or not XSLT templates should not be cached
    是否XSLT模版應(yīng)該被緩存

    【原創(chuàng)】struts2的struts.properties配置文件詳解

    struts.action.extension
    The URL extension to use to determine if the request is meant for a Struts action
    用URL擴(kuò)展名來確定是否這個(gè)請求是被用作Struts action,其實(shí)也就是設(shè)置 action的后綴,例如login.do的'do'字。

    struts.configuration
    The org.apache.struts2.config.Configuration implementation class
    org.apache.struts2.config.Configuration接口名

    struts.configuration.files
    A list of configuration files automatically loaded by Struts
    struts自動(dòng)加載的一個(gè)配置文件列表

    struts.configuration.xml.reload
    Whether to reload the XML configuration or not
    是否加載xml配置(true,false)

    struts.continuations.package
    The package containing actions that use Rife continuations
    含有actions的完整連續(xù)的package名稱

    struts.custom.i18n.resources
    Location of additional localization properties files to load
    加載附加的國際化屬性文件(不包含.properties后綴)

    struts.custom.properties
    Location of additional configuration properties files to load
    加載附加的配置文件的位置


    struts.devMode
    Whether Struts is in development mode or not
    是否為struts開發(fā)模式

    struts.dispatcher.parametersWorkaround
    Whether to use a Servlet request parameter workaround necessary for some versions of WebLogic
    (某些版本的weblogic專用)是否使用一個(gè)servlet請求參數(shù)工作區(qū)(PARAMETERSWORKAROUND)

    struts.enable.DynamicMethodInvocation
    Allows one to disable dynamic method invocation from the URL
    允許動(dòng)態(tài)方法調(diào)用

    struts.freemarker.manager.classname
    The org.apache.struts2.views.freemarker.FreemarkerManager implementation class
    org.apache.struts2.views.freemarker.FreemarkerManager接口名

    struts.i18n.encoding
    The encoding to use for localization messages
    國際化信息內(nèi)碼

    struts.i18n.reload
    Whether the localization messages should automatically be reloaded
    是否國際化信息自動(dòng)加載

    struts.locale
    The default locale for the Struts application
    默認(rèn)的國際化地區(qū)信息

    struts.mapper.class
    The org.apache.struts2.dispatcher.mapper.ActionMapper implementation class
    org.apache.struts2.dispatcher.mapper.ActionMapper接口

    struts.multipart.maxSize
    The maximize size of a multipart request (file upload)
    multipart請求信息的最大尺寸(文件上傳用)

    struts.multipart.parser
    The org.apache.struts2.dispatcher.multipart.MultiPartRequest parser implementation for a multipart request (file upload)
    專為multipart請求信息使用的 org.apache.struts2.dispatcher.multipart.MultiPartRequest解析器接口(文件上傳用)


    struts.multipart.saveDir
    The directory to use for storing uploaded files
    設(shè)置存儲上傳文件的目錄夾

    struts.objectFactory
    The com.opensymphony.xwork2.ObjectFactory implementation class
    com.opensymphony.xwork2.ObjectFactory接口(spring)

    struts.objectFactory.spring.autoWire
    Whether Spring should autoWire or not
    是否自動(dòng)綁定Spring

    struts.objectFactory.spring.useClassCache
    Whether Spring should use its class cache or not
    是否spring應(yīng)該使用自身的cache

    struts.objectTypeDeterminer
    The com.opensymphony.xwork2.util.ObjectTypeDeterminer implementation class
    com.opensymphony.xwork2.util.ObjectTypeDeterminer接口

    struts.serve.static.browserCache
    If static content served by the Struts filter should set browser caching header properties or not
    是否struts過濾器中提供的靜態(tài)內(nèi)容應(yīng)該被瀏覽器緩存在頭部屬性中

    struts.serve.static
    Whether the Struts filter should serve static content or not
    是否struts過濾器應(yīng)該提供靜態(tài)內(nèi)容

    struts.tag.altSyntax
    Whether to use the alterative syntax for the tags or not
    是否可以用替代的語法替代tags

    struts.ui.templateDir
    The directory containing UI templates
    UI templates的目錄夾

    struts.ui.theme
    The default UI template theme
    默認(rèn)的UI template主題

    struts.url.http.port
    The HTTP port used by Struts URLs
    設(shè)置http端口

    struts.url.https.port
    The HTTPS port used by Struts URLs
    設(shè)置https端口

    struts.url.includeParams
    The default includeParams method to generate Struts URLs
    在url中產(chǎn)生 默認(rèn)的includeParams


    struts.velocity.configfile
    The Velocity configuration file path
    velocity配置文件路徑

    struts.velocity.contexts
    List of Velocity context names
    velocity的context列表


    struts.velocity.manager.classname
    org.apache.struts2.views.velocity.VelocityManager implementation class
    org.apache.struts2.views.velocity.VelocityManager接口名

    struts.velocity.toolboxlocation
    The location of the Velocity toolbox
    velocity工具盒的位置
    struts.xslt.nocache
    Whether or not XSLT templates should not be cached
    是否XSLT模版應(yīng)該被緩存

    struts2加載常量的順序
    struts-default.xml
    struts-plugin.xml
    struts.xml
    struts.properties
    web.xml
    后面的會覆蓋掉前面的常量,最好在struts.xml中定義

     

    怎么由.action改為.do
    <constant name="struts.action.extension" value="do"/>
    do或action
    <constant name="struts.action.extension" value="do,action"/>


    truts2用來指定默認(rèn)編碼的
    <constant name="struts.i18n.encoding" value="UTF-8"/>

     

    改變常量后不許重啟服務(wù)器
    <constant name="struts.configuration.xml.reload" value="true"/>
    系統(tǒng)默認(rèn)為false 


    便于排錯(cuò),打印出更詳細(xì)的錯(cuò)誤信息
    <constant name="struts.devMode" value="true">

     

    設(shè)置瀏覽器是否緩存靜態(tài)內(nèi)容,默認(rèn)為TRUE  開發(fā)階段最好關(guān)閉
    <constant name="struts.server.static.browserCache" valur="false"/>

     

    默認(rèn)的視圖主題
    <constant name="struts.ui.theme" value="simple"/>

     

    與spring集成時(shí),指定spring負(fù)責(zé)action對象的創(chuàng)建
    <struts name="struts.objectFactory" value="spring"/>

     

    上傳文件大小限制
    <struts name="struts.multipart.maxSize" value="10241024"/>



    小果子 2011-04-05 17:58 發(fā)表評論
    ]]>
    flex 獲取 flickr 圖片 http://m.shnenglu.com/guojingjia2006/archive/2010/07/20/120905.html小果子小果子Tue, 20 Jul 2010 14:10:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2010/07/20/120905.htmlhttp://m.shnenglu.com/guojingjia2006/comments/120905.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2010/07/20/120905.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/120905.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/120905.html
    最 近打開Flickr發(fā)現(xiàn)有些圖片總是顯示小紅叉,開始以為是網(wǎng)速問題沒有在意,昨天有個(gè)朋友說他存在Flickr上的圖片都不能顯示了,發(fā)覺情況不對勁 了。
    今天看到了這篇帖子:
    http://www.flickr.com/help/forum/zh-hk/117995/
    原來又是偉大的墻在作怪,這次的癥狀是所有的網(wǎng)通線路都無法 訪問farm3.static.flickr.com和farm5.static.flickr.com這兩個(gè)服務(wù)器,由于這次只是讓域名無法解析,所以 最簡單的解決辦法是修改host文件,方法如下:
    用記事本打開C:\Windows\System32\drivers\etc\hosts 這個(gè)文件,然后在文件最后追加兩行:

    然 后重啟一下瀏覽器,我們親愛的Flickr又復(fù)活了  : )

    由于自己是網(wǎng)通的,圖片是farm5服務(wù)器的,所以圖片也顯示不了,不過修改下host表就OK了

    寫這個(gè)的主要目的還是學(xué)習(xí)下cairgorm框架,學(xué)習(xí)他的MVC思想,目的算基本達(dá)到,flickr的問題實(shí)在有點(diǎn)煩,不過還是走過來了,下面是運(yùn)行效果:


    有用的幾個(gè)網(wǎng)址:
    http://code.google.com/p/as3flickrlib/issues/detail?id=14#makechanges
    http://www.flickr.com/services/api/
    http://naramiki.blogbus.com/logs/57133710.html

    最后附上flickr自己編譯的庫
    http://m.shnenglu.com/Files/guojingjia2006/flickr087.swc.rar



    小果子 2010-07-20 22:10 發(fā)表評論
    ]]>
    jQuery 左右移動(dòng)http://m.shnenglu.com/guojingjia2006/archive/2009/08/29/94781.html小果子小果子Sat, 29 Aug 2009 14:22:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2009/08/29/94781.htmlhttp://m.shnenglu.com/guojingjia2006/comments/94781.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2009/08/29/94781.html#Feedback0http://m.shnenglu.com/guojingjia2006/comments/commentRss/94781.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/94781.html閱讀全文

    小果子 2009-08-29 22:22 發(fā)表評論
    ]]>
    commons-fileupload 中文亂碼問題的解決http://m.shnenglu.com/guojingjia2006/archive/2009/08/25/94366.html小果子小果子Tue, 25 Aug 2009 06:33:00 GMThttp://m.shnenglu.com/guojingjia2006/archive/2009/08/25/94366.htmlhttp://m.shnenglu.com/guojingjia2006/comments/94366.htmlhttp://m.shnenglu.com/guojingjia2006/archive/2009/08/25/94366.html#Feedback1http://m.shnenglu.com/guojingjia2006/comments/commentRss/94366.htmlhttp://m.shnenglu.com/guojingjia2006/services/trackbacks/94366.html2.設(shè)置一個(gè)filter,統(tǒng)一用utf-8
    3.文件域亂碼解決:
    String encode=request.getCharacterEncoding();
    ServletFileUpload upload = new ServletFileUpload(factory);
    upload.setHeaderEncoding(encoding);

    4.表單域亂碼解決:
    item.getString(encode);

    小果子 2009-08-25 14:33 發(fā)表評論
    ]]>
    青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久亚洲视频| 亚洲精品一区二区三区福利| 国产精品亚洲成人| 欧美系列精品| 免费一级欧美片在线播放| 欧美一区二区视频在线| 欧美一区三区三区高中清蜜桃 | 国产精品网站视频| 国产麻豆综合| 国产有码一区二区| 亚洲国产精品视频| 一本色道久久精品| 亚洲欧美日本日韩| 欧美在线视频观看| 久久综合色8888| 欧美激情视频在线免费观看 欧美视频免费一| 久久综合狠狠综合久久综青草 | 欧美一区激情| 免费不卡在线观看av| 欧美精品久久久久久| 国产精品久久久久久影院8一贰佰| 国产精品日产欧美久久久久| 黄色一区二区三区| 一区二区三区精品视频在线观看| 亚洲欧美国产高清va在线播| 亚洲欧美一区二区激情| 久久久噜噜噜久久中文字免| 亚洲国产成人久久综合| 在线亚洲欧美| 六十路精品视频| 国产精品激情电影| 亚洲国产精品久久久久| 亚洲一区二区三区在线观看视频 | 久久成人18免费网站| 欧美激情按摩| 亚洲主播在线播放| 你懂的视频欧美| 国产女人水真多18毛片18精品视频| 1024成人| 久久精品99国产精品日本| 亚洲国产另类 国产精品国产免费| 亚洲欧美另类在线观看| 亚洲私人黄色宅男| 欧美成人精品福利| 亚洲欧美日本日韩| 欧美精品97| 在线成人h网| 久久国产精品99国产| 亚洲精品乱码久久久久久| 久久国产精品72免费观看| 国产精品国产三级国产普通话99| 在线观看日韩| 久久午夜羞羞影院免费观看| 一区二区三区产品免费精品久久75| 免费在线欧美黄色| 亚洲成人在线网站| 老司机精品视频网站| 午夜精品999| 国产精品男女猛烈高潮激情| 国产精品99久久久久久有的能看| 欧美激情一区二区三区全黄 | 国产精品99久久久久久久久| 欧美看片网站| 亚洲最新在线| 夜夜嗨av一区二区三区中文字幕| 欧美成人综合| 一本一本a久久| 亚洲美女av在线播放| 欧美片第一页| 亚洲综合国产精品| 亚洲图片在线| 国产乱码精品一区二区三区av| 亚洲综合成人在线| 亚洲欧美综合网| 国内精品久久久久影院 日本资源| 久久成人人人人精品欧| 欧美一二三区在线观看| 韩日视频一区| 欧美成人午夜激情| 欧美人与禽猛交乱配视频| 一区二区日韩精品| 一区二区三区导航| 国产亚洲亚洲| 欧美成人精品在线播放| 免费成人美女女| 亚洲图片在区色| 性做久久久久久免费观看欧美| 在线成人免费视频| 亚洲黄一区二区三区| 欧美三级在线播放| 久久在线免费观看视频| 欧美精品九九| 久久综合九九| 国产精品成人aaaaa网站 | 久久久另类综合| 欧美激情免费观看| 久久精品中文字幕免费mv| 欧美成人精品三级在线观看| 欧美精品一区在线观看| 国产欧美日韩不卡免费| 欧美大片一区| 国产色视频一区| 亚洲日本中文字幕区| 国产小视频国产精品| 亚洲人成人一区二区三区| 国产一区二区你懂的| 日韩五码在线| 亚洲激情在线观看| 亚洲欧美日韩另类精品一区二区三区| 在线欧美三区| 亚洲欧美在线一区二区| 亚洲精品少妇30p| 久久久久久一区| 亚洲已满18点击进入久久| 久久综合一区二区三区| 国产精品久久久久9999| 免费观看成人网| 国产精品国产三级国产aⅴ浪潮 | 午夜国产精品影院在线观看 | 99精品视频一区| 亚洲精品日本| 在线日本高清免费不卡| 日韩午夜一区| 亚洲第一精品福利| 亚洲影视在线播放| 91久久久在线| 久久综合久久久久88| 亚洲欧美电影院| 欧美激情综合在线| 久久久久久久精| 国产精品ⅴa在线观看h| 在线观看三级视频欧美| 久久精品国产999大香线蕉| 日韩一本二本av| 久久色中文字幕| 久久精品国产999大香线蕉| 欧美国产综合视频| 亚洲黄色成人| 狠狠色综合网站久久久久久久| 亚洲精品乱码久久久久久蜜桃麻豆| 好看的日韩av电影| 西西裸体人体做爰大胆久久久| 国产欧美一区二区三区久久人妖| 亚洲综合欧美| 亚洲综合第一| 欧美视频一区| 亚洲破处大片| 亚洲国产高清aⅴ视频| 欧美成人国产一区二区| 欧美va亚洲va香蕉在线| 国内精品久久国产| 欧美中文字幕视频在线观看| 亚洲在线免费视频| 欧美日韩精品三区| 亚洲欧洲一区二区三区在线观看| 韩日精品视频一区| 久久99伊人| 国产精品美女在线观看| 一区二区三区欧美| 欧美精品色一区二区三区| 欧美激情一区二区三区成人| 精品91免费| 久久免费午夜影院| 久久尤物电影视频在线观看| 欧美精品自拍| 午夜欧美视频| 久久久999成人| 国产综合网站| 裸体丰满少妇做受久久99精品| 久久久久久久波多野高潮日日| 国产欧美一区二区视频| 亚洲欧美日韩精品久久| 久久精品二区| 亚洲福利久久| 可以看av的网站久久看| 米奇777在线欧美播放| 亚洲国产高清在线观看视频| 欧美成人国产| 亚洲视频免费在线观看| 欧美成人自拍| 中文日韩在线视频| 国产日韩欧美亚洲| 久久视频精品在线| 欧美在线在线| 亚洲午夜小视频| 国产一区久久久| 欧美成人a∨高清免费观看| 一本色道久久综合一区| 永久免费精品影视网站| 国产精品视频精品| 久久亚洲欧美国产精品乐播| 亚洲人成在线观看网站高清| 亚洲欧美日韩国产综合精品二区| 最新日韩中文字幕| 国产精品久久久久久久久久直播| 欧美中文日韩| 夜久久久久久| 欧美国产日韩一区二区三区| 91久久精品国产91性色tv| 国产精品久99|