Drupal與高性能網站架構 http://www.tbdskt.live 基于Drupal平臺的高性能網站架構與研究實驗室 Tue, 08 Aug 2017 11:42:13 +0000 zh-CN hourly 1 http://wordpress.org/?v=3.8 如何用Drupal做統一認證功能? http://www.tbdskt.live/2017/08/drupal-open-auth/ http://www.tbdskt.live/2017/08/drupal-open-auth/#comments Tue, 08 Aug 2017 11:14:26 +0000 http://www.tbdskt.live/?p=1414 真正的統一認證一般指中心登錄,drupal有很多相關的模塊可以實現,比如drupal SSO模塊, 如果都是Drupal站點可以用bakery模塊實現,也可以用CAS模塊實現CAS服務。

oauth2.0

本文重點講得是用open auth 2.0協議實現oauth服務,通過oauth協議實現統一認證的服務。

OAuth本質就是兩個服務之間的通訊,通過一個服務授權另一個服務,通過認證,找了一個圖片,添加了注釋,如下所示:

oauth2

 

所需模塊具體如下:

OAuth2_server: ?https://www.drupal.org/project/oauth2_server

OAuth2_client: ?https://www.drupal.org/project/oauth2_client

以及相應的OAuth2.0的PHP依賴包。

模塊的安裝和配置:

模塊的安裝,比較簡單,下載安裝以及下載依賴包。
模塊的配置,主要是創建一個Oauth server,然后添加客戶端。
創建一個Oauth server實例,注意選擇授權類型,一般code和token都是要選的。

另外,創建一個Client實例的時候,要注意首次需填寫密鑰,另外要設置授權的URL,具體參考下面的截圖:

Oauth Server配置:

oauth-server1

Oauth Server添加Client:

oauth-server2

 

四種授權模式:
Oauth2.0提供了四種授權模式,其中授權碼模式是最經典常用的模式,具體4種如下:
1. 授權碼(認證碼)模式 (Authorization code) response_type=code
2. 簡化(隱形)模式 (Impilict) response_type=token
3. 用戶名密碼模式 (Resource Owner Password Credential) grant_type=password
4. 客戶端模式 (Client Credential) grant_type=client_credential

消費Oauth服務
使用Oauth服務可以用Drupal的Oauth client模塊,也可以自己寫一段代碼測試。

授權發起頁面:

$appid     = 'testapp';
$callback  = "http://testapp.demo.xiao-an.com/callback.php";
$callback  = urlencode($callback);
 
$state = $_SERVER['REQUEST_URI'];
$key   = substr(md5($state), 0, 8);
$type  = 'code'; //token
 
$home = 'http://uauth.demo.xiao-an.com';
$forward = "{$home}/oauth2/authorize?response_type={$type}&client_id={$appid}&redirect_uri={$callback}&state={$key}&scope=openid+unionlib_basic&source=unionlib";
 
header('Location: ' . $forward);

授權回調頁面:

$code = $_REQUEST['code'];
$parameters = array(
    'client_id'  => $appid,
    'client_secret' => $appsecret,
    'grant_type' => 'authorization_code',
    'code' => $code,
    'redirect_uri' => 'http://testapp.demo.xiao-an.com/callback.php'
  );
$param_data = array(
   'data'   => _query_string_encode($parameters),
  );
$headers = array('Content-Type' => 'application/x-www-form-urlencoded');
$url  = 'http://uauth.demo.xiao-an.com/oauth2/token?' . _query_string_encode($parameters);
$http = _http_request($url, $headers, 'POST', _query_string_encode($parameters));
$data = json_decode($http->data);
var_dump($data);

其中http_request函數直接從drupal的函數庫中復制過來。

通過第三方庫實現統一認證

一般情況下,都是通過現有的第三方庫實現統一認證,比如學生庫、讀者庫等,所以要實現通過第三方庫登錄,還要做一些額外的工作。
1. 實現hook_user_login
因為模塊的oauth直接使用drupal的login form實現用戶名密碼認證登錄,所以直接實現這個hook即可。
2. 用戶管理
通過遠程的接口,自定義views的handler來實現遠程用戶管理。
此外,如果不希望用戶通過默認的Drupal Login Form登錄,自定義form的話,可以實現hook_oauth2_server_pre_authorize,如果用戶沒有登錄,直接重定向到自定義form,認證完成之后再重定向回來。

我們針對某圖書館項目,實現完整的統一認證架構,具體可以下載說明文檔:

統一認證系統架構及案例

]]>
http://www.tbdskt.live/2017/08/drupal-open-auth/feed/ 0
如何在阿里云上部署Drupal站點 http://www.tbdskt.live/2017/05/drupal-aliyun/ http://www.tbdskt.live/2017/05/drupal-aliyun/#comments Thu, 11 May 2017 02:45:07 +0000 http://www.tbdskt.live/?p=1406 鑒于大家經常使用阿里云做為站點部署服務器,很多朋友咨詢有沒有drupal在阿里云上的部署建議,所以將之前部署阿里云的一些經驗寫下來共享一下,歡迎拍磚。

ECS的選擇:

  1. CPU相對要高,Drupal比較消耗CPU,開啟OPCache
  2. 硬盤,選擇高速IO硬盤,讀寫文件較快
  3. 定期備份相關文件
  4. 防火墻策略,建議修改SSH默認端口,以免被攻擊

數據庫:

  1. 選擇RDS,不推薦自建MySQL服務,RDS做好定期備份策略
  2. 做好相關mysql配置
  3. 多并發可以做MySQL主從配置

大文件圖片:

  1. 推薦使用OSS,搭配相關Drupal模塊
  2. 為節省OSS流量,可以配搭CDN,流媒體一定要通過OSS播放

多站點集群:

  1. 可以通過varnish + 多個ECS做集群,提高并發
  2. 多個站點可以搭配多個Drupal站點,API站點單獨部署
  3. 推薦將OSS掛載到一臺服務器上,方便做為文件備份服務器

drupal-cluster

Docker和虛擬化:

  1. 推薦使用CentOS7.x做為鏡像
  2. 推薦使用阿里云的容器服務 dev.aliyun.com
  3. 推薦將常用的Docker提交成自有鏡像

RDS數據庫

  1. RDS回滾風險須知
    目前RDS支持數據回滾,回滾是針對整個實例的,不支持單表單庫,在回滾之前備份好重要數據,以免回滾完成以后導致數據丟失。如果只是部分表格或者部分數據需要回滾,我們建議您通過創建臨時實例來恢復數據,臨時實例創建成功后從臨時實例中把需要的數據導回到生產庫。
  2. RDS鎖定策略
    RDS具有鎖定機制,如果您的實例存儲空間滿了,系統就會將您的實例鎖定,實例被鎖定以后會變成只讀,建議定期檢查存儲空間使用情況,同時也可以在RDS控制臺中設置空間占用短信提醒。
  3. RDS故障切換?RDS
    采用一主一備的高可用模式,當主庫出現故障時,RDS會在30秒鐘之內切換到備庫。切換過程中有(小于等于)30秒鐘的不可訪問,需要您設置好程序跟RDS的自動重連,避免因為切換導致您的服務不可用。
  4. RDS切換內外網存在的風險
    RDS在切換內外網的過程中會出現服務器跟RDS的連接斷開,切換完成以后請及時更新程序中的連接地址,同時切換內外網會導致IP地址變更。

購買及費用建議:

  1. 建議購買1M帶寬的多臺服務器做為后端Drupal節點,一次性購買一年以上有優惠
  2. 建議購買彈性帶寬的服務器做為負載均衡服務器,安裝Varnish,內存和CPU不用太高。
  3. RDS建議將不經常訪問的archive數據庫刪掉,自建MySQL用于存儲,因為RDS費用較高。此外MySQL的inodb即使刪除數據也沒法將RDS的存儲降下來,如果要降下來,最好擅長數據庫,重新導入一遍。

 

 

 

 

 

 

]]>
http://www.tbdskt.live/2017/05/drupal-aliyun/feed/ 4
如何開發一套分答系統(微信語音問答系統) http://www.tbdskt.live/2016/09/fenda/ http://www.tbdskt.live/2016/09/fenda/#comments Thu, 22 Sep 2016 09:35:09 +0000 http://www.tbdskt.live/?p=1396
我們近期基于drupal架構了一套分答系統,(分答系統不是嚴格的稱呼,應該稱之為:微信語音問答平臺,只是分答比較火爆,所以說分答,大家都能聽懂)。

主要的工作是基于Drupal大學的社交問答系統進行升級開發,前端主要是用ReactJS,微信API處理主要使用了Drupal架構的一個獨立的微信API接口,另外語音轉碼、OSS存儲等也做了一些工作,

整體的結構參考下圖:

服務器流程處理

主要的開發點包括:

  • 提問、回答內容類型創建
  • 關注、收藏等微社交元素
  • 微信用戶、頭像自動登陸以及OpenID保存
  • 微信語音 JSSDK、消息模板、圖片上傳等調用
  • 微信支付,以及相關的db_transaction支持
  • 同步微信語音到OSS,以及OSS訪問跟Drupal同步
  • 前端圖片壓縮、播放控件等開發

另外,在開發中比較多的使用了Jenkins以及Docker,Jenkins之前的文章也講過很多,大家可以參考,Docker主要用于虛擬化服務以及環境的一致性。

微信語音問答-分答版-服務器架構

具體設計的技術,大家可以在微信公眾號里面,向我提問,或者添加本人微信號:oodeeeer。

 

1分答

PDF資料請點擊下載: http://xiao-an.com/sites/default/files/assets/%E5%BE%AE%E4%BF%A1%E8%AF%AD%E9%9F%B3%E9%97%AE%E7%AD%94%E6%96%B9%E6%A1%88-%E4%BB%8B%E7%BB%8D.pdf

具體的功能介紹,請點擊:http://xiao-an.com/products/wechatqa

 

]]>
http://www.tbdskt.live/2016/09/fenda/feed/ 0
Drupal7集成Solr5.5與IK Analyzer中文分詞 http://www.tbdskt.live/2016/04/drupal7-solr5-ik-analyzer/ http://www.tbdskt.live/2016/04/drupal7-solr5-ik-analyzer/#comments Thu, 28 Apr 2016 08:08:27 +0000 http://www.tbdskt.live/?p=1384 雖然Solr6已經發布了,但是drupal還沒有任何相關的模塊支持,不過Solr5.x已經可以用到drupal上了。 本文把延續之前的Drupal和IK的配置,升級到一鍵安裝包solr5.5,支持中文分詞,支持Drupal7,如果需要新建core,可以把默認的drupal7/conf復制到新建的core下面的conf文件夾即可。

solr5.5配置IK中文分詞

? Solr5.x跟Solr4.x的最大區別是5被發布成一個獨立的應用,而不再需要Tomcat等容器,在其內部集成了一個jetty容器,現在它可以通過bin目錄的腳本直接啟動。因此之前我們寫的Solr4z的腳本也就不需要了,因為Solr5.x自帶了啟動管理等腳本。

Linux下就是默認的腳本,如果是Windows,用.cmd后綴的命令即可。

集成的主要步驟如下:

  1. 下載安裝Solr5運行包
  2. ?配置solr的IK分詞器,主要是jar包放到 solr-webapp下面,以及class下面放置IK的分詞。
  3. ?針對Drupal新建一個Core,比如Drupal7(新建需要在solr啟動的情況下,用 bin/solr create -c drupal7)
  4. ?配置Solr對Drupal7的schema,主要參考是search_api_solr模塊下自帶的配置文件,然后添加text_id字段,最后修改text字段到text_ik字段。
  5. ?重啟Solr : bin/solr restart
  6. ?配置Drupal的search_api_solr模塊,新建一個solr service,然后配置地址為 /solr/[core_name],比如/solr/drupal7
  7. ?新建內容測試。

參考資源:?https://github.com/EugenePig/ik-analyzer-solr5

安裝包的百度下載地址:??http://pan.baidu.com/s/1dDy8KGL?

注意:運行solr5.5一鍵包,需要安裝java1.8及以上版本,如果是java1.7會報錯。

]]>
http://www.tbdskt.live/2016/04/drupal7-solr5-ik-analyzer/feed/ 0
使用站群架構 Drupal 網站 – 2016Drupal 大會分享 http://www.tbdskt.live/2016/02/drupal-cluster/ http://www.tbdskt.live/2016/02/drupal-cluster/#comments Sat, 27 Feb 2016 15:56:35 +0000 http://www.tbdskt.live/?p=1372 本篇內容是關于 2016年drupal 中國會議上關于《 Drupal 高性能實戰講座》的一個簡要回顧,主要的內容點都在 PPT 里面,請大家下載查閱,更多問題,請大家通過 Drupal 大學提問。

Drupal 的站群架構主要解決幾個問題:1. 網站的性能問題。2. 松耦合。3. 擴展性。

Drupal 的站群架構的主要技術:1. 統一用戶和權限。2. 數據的互訪及同步。3. 統一界面。

通過 Drupal 的站群架構,可以解決網站的性能問題,以及保證網站的擴展性,所以,在規劃網站的的時候,如果網站的擴展和數據的增長比較快,那么就要提前考慮分站的架構,也就是通過站群的方式,來提高網站的性能。

Drupal集群

統一用戶

站群,首先就是要保證用戶的統一。Drupal 的統一用戶登錄解決方案主要有一下幾種,

1. CAS 模塊
2. Oauth 模塊
3. Bakery 模塊

其中 Bakery 模塊比較簡單,但是有條件限制,1. 所有網站必須是 Drupa 站點。2. 所有網站需要是同一個跟域名。從通用性和易用性來說,CAS 模塊比較推薦,從用戶認證和登錄的角度來講 ,CAS 比OAuth 更加適合,當然 oauth作為用戶認證一種替代方案,應用也很廣泛。

數據互訪

Drupal 的數據互訪,主要有下面幾個方式:

1. Services 模塊
2. Feeds 模塊 + Views 模塊
3. Custom API

圖片存儲

圖片的存儲可以通過 StorageAPI 模塊輕松實現圖片的分布式存儲,并且通過不同的域名存儲,可以在后期通過 CDN 以及 OSS 來提高網站的并發量。

File System和Stream Wrapper的原理介紹
http://www.tbdskt.live/2015/05/file-system-stream-wrapper/

CronJob 管理

復雜的 Drupal 站點一般會有很多 Cronjob 在運行,因此對 cronjob 的合理管理,也是網站性能以及并發量的關鍵因素。Drupal 的 cron job 推薦使用 ultimate con,以及通過 background process模塊配合使用。

相關鏈接:

Drupal 的 Cronjob 可以指定時間執行嗎? http://drupal001.net/question/2172

詳細的講座 PPT 請點擊連接下載:

http://pan.baidu.com/s/1sldzWRj

更多問題,請關注 Drupal 大學公眾號提問,謝謝!

]]>
http://www.tbdskt.live/2016/02/drupal-cluster/feed/ 1
Web集群中文件存儲系統的解決方案 http://www.tbdskt.live/2015/06/multiple-servers-file-storage/ http://www.tbdskt.live/2015/06/multiple-servers-file-storage/#comments Mon, 15 Jun 2015 08:43:55 +0000 http://www.tbdskt.live/?p=1348 Web集群中,文件系統的分布式是最重要的一個環節,因為多個Web節點需要訪問同一套文件系統,多個節點之間訪問文件需要完全同步,跟一臺機器上的文件一樣。

首先Web集群需要一個Load Balancer,然后多個節點共享數據庫和文件系統,比如訪問網站example.com,上傳了一個文件,這個時候通過LB轉發到了A節點,那么文件保存到了A機器,然后我們刷新頁面,LB轉發到了B節點,如果這個文件在B機器上不存在,就會產生錯誤。
在Drual系統中就是Files目錄,比如我們在A網站上生成了一個image style,如果LB再訪問到B上面,如果這個image style不存在,就會出錯。

上面的問題,就是我們本文要解決的Web集群中的文件共享。

另外,drupal也有臨時文件目錄,這個要不要放到共享文件夾里面呢?這個答案請移步這里:
集群服務器,需要共享temp文件夾嗎?

那么WEB服務器集群中,文件同步的方案主要有一下幾個解決方案。

Rsync

Rsync是最簡單的解決方案,通過Linux的rsync命令,就可以非常迅速的實現多個服務器的文件同步。但是Rsync有致命的缺點,首先,rsync會有延時,因為rsync是定時同步,不可能做到及時同步,因此會出現延時,比如傳到A機器的圖片在B機器上看不見。

說到延時,可以通過session sticky的方案來解決,session sticky簡單來說就是訪問A機器的用戶,會在之后的請求都訪問A機器,這樣就可以保證用戶在下次訪問文件的時候不出錯。

但是,rsync還有一些問題,比如,A機器上面有一個文件,而B機器上面沒有這個文件,從理論上講,我們不知道是B機器刪除了這個文件,還是A機器新加了這個問題,因此這個時候『同步』就是一個很頭疼的問題。

因此,Rsync不是一個有效的解決方案。

GlusterFS

GlusterFS(GNU ClusterFile System)是一個開源的分布式文件系統,它的歷史可以追溯到2006年,最初的目標是代替Lustre和GPFS分布式文件系統。現在,GlusterFS在開源社區活躍度非常高,已經與Lustre、MooseFS、CEPH并列成為四大開源分布式文件系統。
Glusterfs主要有三種基本的集群模式,即分布式集群(Distributed cluster)、條帶集群(Stripe cluster)、復制集群(Replica cluster)。這三種基本集群還可以采用類似堆積木的方式,構成更加復雜的復合集群。
當然,GlusterFS不是一個完美的分布式文件系統,這個系統自身也有許多不足之處,包括眾所周知的元數據性能和小文件問題。

Gluster通過簡單的brick組成一個volume,這個volume就可以被各種終端使用,比如FUSE或者NFS協議等等使用。

具體的GlusterFS的講解請參考這一篇文章:使用GlusterFS做為Drupal文件存儲的云服務

NFS

比較簡單的解決方案就是使用NFS服務,NFS做完linux系統廣泛通用的文件共享系統,從NFSv1,NFSv2到NFSv3和NFSv4,NFS也是非常穩定和久經考驗的解決方案。

NFS的缺點也是比較明顯的,單節點風險,比如NFS服務掛掉,整個文件就能訪問,網站Down掉,因此NFS只能作為一個暫存的解決方案,使用NFS一定要有一個備份系統。

NFS集群

說到NFS的缺點,我們可以使用NFS集群的方案來解決,NFS+DRBD, DRBD是一個用軟件實現的、無共享的、服務器之間鏡像塊設備內容的存儲復制解決方案,因此可以通過DRBD分發實現NFS的復制,來解決單節點NFS的缺點。

DRBD實際上是一種塊設備的實現,主要被用于Linux平臺下的高可用(HA)方案之中。他是有內核模塊和相關程序而組成,通過網絡通信來同步鏡像整個設備,有點類似于一個網絡RAID的功能。也就是說當你將數據寫入本地的DRBD設備上的文件系統時,數據會同時被發送到網絡中的另外一臺 主機之上,并以完全相同的形式記錄在一個文件系統中(實際上文件系統的創建也是由DRBD的同步來實現的)。本地節點(主機)與遠程節點(主機)的數據可以保證實時的同步,并保證IO的一致性。所以當本地節點的主機出現故障時,遠程節點的主機上還會保留有一份完全相同的數據,可以繼續使用,以達到高可用的目的。

DRBD需要構建在底層設備之上,然后構建出一個塊設備出來。對于用戶來說,一個DRBD設備,就像是一塊物理的磁盤,可以在商脈內創建文件系統。DRBD所支持的底層設備有以下這些類:
1. 一個磁盤,或者是磁盤的某一個分區;
2. 一個soft raid 設備;
3. 一個LVM的邏輯卷;
4. 一個EVMS(Enterprise Volume Management System,企業卷管理系統)的卷;
5. 其他任何的塊設備。

nfs-drbd

 

更多參考:

《Drupal 文件系統剖析(二)》

《File System和Stream Wrapper的原理介紹》

PS:本文參考了網上相關文章以及圖片。

相關提問,請到Drupal大學,http://drupal001.net

]]>
http://www.tbdskt.live/2015/06/multiple-servers-file-storage/feed/ 1
Drupal 文件系統剖析(二) http://www.tbdskt.live/2015/06/drupal-file-system-media/ http://www.tbdskt.live/2015/06/drupal-file-system-media/#comments Tue, 09 Jun 2015 01:50:39 +0000 http://www.tbdskt.live/?p=1327 前一篇我們分析了drupal的FileAPI和Stream Wrapper的關系,本文趁熱打鐵,繼續分析一下drupal的Files系統,以便對Drupal的文件處理更加熟悉。
參考上篇:File System和Stream Wrapper的原理介紹

如何實現自有的StreamWrapper

看一個Drupal大學上的提問:《Drupal中如何實現自有的StreamWrapper》,通過上篇文章的閱讀,我們簡單總結一下。
1. 寫一個class,實現DrupalStreamWrapperInterface的接口
2. 實現一個hook,hook_stream_wrappers,返回這個StreamWrapper,通知給Drupal。
通過上面兩個簡單的步驟就實現了Drupal里面一個自有的streamWrapper。

Drupal如何調用StreamWrapper來存儲文件?

Drupal里面,所有的上傳文件的Field都是通過FileField實現(不一定絕對),FileField管理所有的文件,都記錄在Drupal的file_managed表里面,Drupal是通過File Entity來管理(沒有裝file_entity模塊也有這個entity),記錄所有的文件以及文件使用情況(file_usage表)。

我們可以看到file_managed表包含如下字段:
file_managed

Drupal的FileField字段有一個設置,可以選擇一個Upload destination,如下圖所示,

在這個列表里面,Drupal調用了hook_stream_wrappers,得到所有的streamwrapper,然后你指定一個streamwrapper,該FileField就是使用對應的streamwrapper來操作這里的文件。
(還有一種辦法,hook-form_alter,storageapi就是這么干的!)

字段的StreamWrapper修改之后怎么辦?

那么,問題來了。。。
如果我們在這個地方修改了StreamWrapper,之前的存儲的文件怎么處理?
通過查看file_managed表,我們可以知道,Drupal把存儲的所有文件到記錄到file_managed表,每一個文件都有一個url,這個URL是帶有scheme的(參見上篇),在對文件操作的時候,我們知道,文件系統會根據scheme獲取當前文件的StreamWrapper類,然后調用具體的StreamWrapper實例來操作這個文件。

也就是說,默認情況下,之前的文件如果你的StreamWrapper Class還能被加載(模塊沒有禁用),之前的文件還會保持在原有的地方,并且不會修改路徑。
而當前Content-Type的新添加的內容,會使用新的StreamWrapper,存儲新的URL到數據庫(帶有scheme)。
(ps:參考上圖中數據庫存儲的URL字段內容)

這個也適用于Field的存儲路徑有變化,比如之前文件路徑存儲在mydir1里面,我們設置后修改成mydir2/[date]之類的目錄,那么新的文件會變,舊的文件不會變。

問題:我想要原有的文件也修改一下路徑,把之前所有的文件都按照新的設置的路徑來存儲怎么辦???
答案:FileField_Paths模塊。

Drupal里面文件系統選擇文件Upload Destination是做什么的?

Drupal里面默認的文件系統,有一個Download Destination的選擇,這個是指定一個默認的destionation,再創建新的FileField的時候,默認選擇這個。
路徑是: /admin/config/media/file-system

Media模塊的作用?

Drupal里面默認有file entity,但是我們還是沒辦法簡單的給File Entity添加的類型(bundle),比如視頻、音頻、圖片、文檔等等,Drupal的三方模塊File Entity登場了,這個模塊擴展了之前的File實體,增加了更多的屬性,增加了對file的bundle的管理,使File真正成為一個可以管理的的Entity了。

從數據庫的角度來看,File Entity對Drupal的file_managed表進行了擴展,添加了一列type,來指定文件類型,如下圖所示:

file_entity

File Entity模塊是Media模塊的一部分,Media不僅通過FileEntity擴展了Drupal原有的File Entity,Media模塊也增加了對File Entity的管理,所有Drupal里面的Files(file_managed表)都能通過Drupal的后臺簡單的管理,使其界面可視化,更加方便,參考下圖:

media

另外,Drupal的Media模塊還增進了Drupal的upload系統,上傳圖片和media的時候,跟Wordpress的media類似,彈出一個對話框,可以上傳新的文件,也可以選擇之前的上傳的文件,便利性提高了不少,因此Media模塊還是值得一試!

Storage模塊

該模塊功能強大,對Drupal的存儲進行了擴展,方便管理,對于Storage模塊,筆者會專門寫一篇文件,分析一下Drupal的StorageAPI,以便將Drupal的存儲應用到更多的場景,敬請期待!

更多問題,請訪問Dupal大學,解決更多Drupal問題

相關閱讀:File System和Stream Wrapper的原理介紹

 

]]>
http://www.tbdskt.live/2015/06/drupal-file-system-media/feed/ 2
File System和Stream Wrapper的原理介紹 http://www.tbdskt.live/2015/05/file-system-stream-wrapper/ http://www.tbdskt.live/2015/05/file-system-stream-wrapper/#comments Sun, 31 May 2015 06:48:21 +0000 http://www.tbdskt.live/?p=1302 在Drupal7以及PHP(也不知那個版本)后,多了一個概念:Stream,主要用來表示文件流。BTW,追溯起Stream的概念,這個應該很早在Java和C#等OOP的語言中已存在,PHP只是簡單的封裝了file/file_get_content等函數,使用起來方便,所以PHPer們更少的在意stream以及整個底層的操作。

當我們使用一個完整的框架(如:drupal框架),Drupal又更加完善了PHP中stream的概念和使用方式,使其更加OO,更加易用。

注意:PHP本身是支持StreamWrapper的,Drupal只是對其進行完善,因此PHP的函數,如move、fopen、move_uploaded_file等函數是直接可以用scheme的形式訪問(類似php://的形式),在PHP中增加一個streamwrapper需要注冊一個,需要調用stream_wrapper_register函數。
詳情參考: http://php.net/..class.streamwrapper.php


Stream是什么?
Stream其實是一個抽象的概念,類似于傳輸層,位于文件系統的下層。跟Stream相連的就是存儲,也就是Stream相當于一傳輸線,一端連接存儲,一端連接程序。

File的操作

文件的操作基本就是讀寫,讀寫的位置其實就是stream,一般情況下讀寫本地文件,我們認為也是一個stream,可以認為LocalFileStream,讀寫網絡文件(FTP、HTTP、S3、阿里OSS、NFF等)也是一種stream,這樣看來,文件的操作API其實應該是一個抽象的函數,而不是一個具體的函數。
用數據庫作為類比,數據的open、prepare、update、execute、close就是有一個抽象的類,后端用什么數據庫,就有對應的實現,參考下面的圖片:

db-abstract-layer-files

程序調用數據庫的抽象接口,該接口根據數據庫的url,按照不同的scheme返回不同的數據庫操作類,完成對數據庫的操作。

因此文件的操作,我們用數據庫操作做對比,也可以用下圖來表示:
file-abstract-layer

通過上圖,我們就可以理解,其實對文件的操作就是對流的操作,不同的流對應不同的存儲介質,只是默認情況下,我們認為流就是本地文件,但是隨著存儲的日益復雜和云的興起,對文件的操作已不能簡單的理解為對本地文件的操作,而應該是對流(Stream)的操作。

因此,在其他語言里面stream是一個基類,根據不同的存儲介質,stream有不同的實現,比如C#中的stream的集成關系如下,通過OO的方式,更好的理解stream的概念。

C# Stream

Drupal中File API和Stream Wrapper

一圖頂萬言,綜合上面的理解,我們做了下面這張關系圖,雖然不一定準確,但是可以幫助我們理解Drupal中file和stream wrapper的關系。
drupal file system and  streamwrapper

Drupal的stream wrapper只是一個接口,可以實現任意的自定義stream wrapper。
Drupal的第三方stream wrapper:

Remote stream wrapper(http://、https://、feeds://)
https://www.drupal.org/project/remote_stream_wrapper
System stream wrapper (module://、theme://、profile://、library://)
https://www.drupal.org/project/system_stream_wrapper

因此,標準化的File操作,需要傳進去一個帶有scheme的path,在PHP中,默認的不帶scheme就是本地文件。在Drupal中,默認的scheme是public,也是是本地文件的public目錄。

StorageAPI 模塊

Drupal中也許對上面的邏輯坐得不夠完善,或許抽象層不是很完美,因此storageAPI模塊出現了,它擴展的標準的Drupal文件操作,即使你對Drupal的file和stream不懂,裝上這個模塊,加上對應的service就能實現上圖對云文件的操作。 如Amazon S3、Ftp、database等。
(筆者看來,StorageAPI就是對上面圖中文件訪問結構圖中邏輯的實現和完善)

當然這個模塊也有缺陷,那就是跟某些第三方模塊的兼容的問題,并不是所有模塊都能良好的兼容storage api模塊,這個也是drupal第三方模塊的同病。

注意,要啟用drupal文件對storageAPI的支持,需要啟用Core Bridge 模塊。

StorageAPI模塊參考?https://drupal.org/project/storage_api
Storage api stream wrapper :https://www.drupal.org/project/storage_api_stream_wrapper

后記
回顧第一段,PHP內部支持StreamWrapper,在Drupal中,對PHP的StreamWrapper進行了擴展,主要的Interface是:DrupalStreamWrapperInterface

Drupal本身通過這個Interface實現了DrupalLocalStreamWrapper,第三方模塊實現了很多,如下:
HPCloud: HPCloudDrupalStreamWrapper
Storage API: StorageApiStreamWrapper
Storage Core Bridge: DrupalStorageStreamWrapper

本文對Drupal的file操作還沒有完全描述清楚,后續給大家講解Drupal的File管理。
更多問題,請訪問Drupal大學,解答各種Drupal的疑難問題。http://drupal001.net

存儲相關博文:
使用GlusterFS做為Drupal文件存儲的云服務
漫談企業級Drupal架構應用與部署

]]>
http://www.tbdskt.live/2015/05/file-system-stream-wrapper/feed/ 0
Memcache的hash策略及配置總結 http://www.tbdskt.live/2015/04/memcache/ http://www.tbdskt.live/2015/04/memcache/#comments Sun, 19 Apr 2015 01:40:02 +0000 http://www.tbdskt.live/?p=1290 Memcach是web應用/Drupal應用性能提高的利器,近期在使用Memcache中,發現有很多小問題,因此作者特意總結了幾個,放上來供大家參考使用。

1. Memcache和Memcached的區別

這個是歷史問題,但是,言而總之:名字長的更牛逼! ?

所以,推薦使用memcached。
另外,memcached有很多新特性,包括getMulti/setMulti、支持存儲object、支持count+1操作,都會比memcache的好用一些,可以試試,或許以后支持更多的操作,趕上redis。。

Drupal大學上關于memcache的問答:http://../apachesolr_search/memcache


如下(摘自德問):

#Memcache
$m = new Memcache();
$m->addServer('localhost', 11211);
$v = $m->get('counter');
$m->set('counter', $v + 1); 
#由于get/set這兩個動作無法作為一個原子來操作,所以當多個進程同時處理時,
#會出現丟失的可能,更讓人惱火的是,你根本就不知道什么時候出現丟失。

#Memcached
$md = new Memcached();
$md->addServer('localhost', 11211);
$v = $md->get('counter', null, $token)
$md->cas($token, 'counter', $v + 1);
#cas是Memcached版本里提供的功能,說白了就是一個樂觀鎖的功能,
#如果你把$token的值var_dump出來,就會發現$token其實就是一個版本號,
#如果通過get得到的$token版本號在cas的時候不對應,就說明已經有別的操作更新了,
#此時cas操作會失敗,至于如何繼續操作,就看你自己了

兩者的區別如下,下面是Memcache的方法:
memcache

下面是memcached的方法:
memcached

2. Memcache的哈希策略

常規的hash策略是取模,比如key=10, 有兩臺服務,就10%2=0,算出該值分布在第一臺服務器上。
那么缺點也很明顯,比如服務器增加一臺,之前的分布式策略全完蛋。

因此,業界需要更牛逼的算法~

一致性hash算法隆重登場!

簡單說來,一致性hash算法就是先把服務器也通過某一個特征(如IP/MAC地址)hash一下,這樣服務器會按照分布(可能不均勻)在一個范圍,然后把key再hash一下,然后看key最近的下個服務器作為該key的存儲bin。
這樣,如果增加一臺服務器,重新分配的key只是分布再新增的這個服務器和上一個最近的服務器之間的key,其余的都不變。

初步的服務器分布:

hash-1

增加服務器的分布:
hash-2

上面的描述的是白話,可能比較拗口,筆者文字水平有限,詳情見下面的鏈接:

http://blogread.cn/it/article/5271
http://blog.csdn.net/kongqz/article/details/6695417

3. Memcache的hash策略配置

Memcache安裝完成之后,可以設置哈希策略,memcache.hash_strategy。目前有standard模式和consistent模式。standard模式其實就是%,即取模。而consistent,就是hash的一致性算法。

在Memcache中,hash策略在PHP.ini文件中設置

[Memcache] 
Memcache.allow_failover = 1 
…… 
…… 
Memcache.hash_strategy =consistent 
Memcache.hash_function =crc32

在Memcached中,hash策略在PHP的參數中設置:

mem = new memcached(); 
$mem->setOption(Memcached::OPT_DISTRIBUTION,Memcached::DISTRIBUTION_CONSISTENT); 
$mem->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE,true);

 

4. 后記

因此正常情況下,推薦使用一致性哈希算法,但凡事無絕對,比如一個小的站點,memcache的服務幾乎永不會增加,這是用常規的standard的算法也是比較推薦的,畢竟一致性算法存在一個均勻分布的問題(可能已經解決了。。)

打完收工!

關于drupal和memcache的集成,大家參考下面的文章:
如何在Drupal7中配置Memcache
更多問題請到Drupal大學提問:http://drupal001.net/

]]>
http://www.tbdskt.live/2015/04/memcache/feed/ 1
用Drupal做一個郵件訂閱推送系統? http://www.tbdskt.live/2015/02/drupal-newsletter/ http://www.tbdskt.live/2015/02/drupal-newsletter/#comments Mon, 16 Feb 2015 07:39:02 +0000 http://www.tbdskt.live/?p=1278 電子郵件營銷稱為EDM,即Email Direct Marketing的縮寫,是在用戶事先許可的前提下,通過電子郵件的方式向目標用戶傳遞價值信息的一種網絡營銷手段。郵件推送是跟用戶互動最有效的手段之一,因此任何一個平臺,需要跟用戶交流,郵件推送系統是必不可少的一個環節。

本文主要講解如何用drupal搭建一個郵件推送系統,實現用戶訂閱郵件的發送。

email-drupal

本文參考: http://www.wdtutorials.com/…

第一步,安裝模塊Simplenews、MailSystem、HTMLMail。

Simplenews是郵件管理發送的核心模塊,啟用simplenews就可以有一種內容類型,用來創建新的newsletter,MailSystem和HTMLMail,是設置郵件輸出內容以及格式用的。

第二步,創建Newsletter。

A. 設置一個測試郵箱(Test Address)admin/config/services/simplenews/settings
B. 創建Newsletter node/add/simplenews
C. 創建完成之后,到newsletter的tab,點擊發送測試

設置測試郵件地址截圖:

設置測試郵件地址

這時候,我們可以到測試郵箱地址查看是否收到了此郵件(涉及本地的sendmail系統和收件箱是否屏蔽垃圾郵件)。

這樣兩步就完成了一個基本的郵件管理和發送,注意這里的發送用的是Sendmail,也就是系統自帶的發送郵件程序,稍微我們講解如何替換。

第三步,Simplenews高級設置。

a. 默認設置
admin/config/services/simplenews/settings
有很多設置點:默認的format,測試收件箱、發送者、確認郵件的模板、cron發件數量等

b. 創建simplenews分類,然后在具體分類里面設置郵件發送配置
admin/config/services/simplenews

第四步,系統郵件設置 – drupal Mail System

a. admin/config/system/mailsystem
NEW SETTING 里面選擇 simplenews,點擊保存。

b. MAIL SYSTEM SETTINGS 里面會有一個 Simplenews module class,選擇HTMLMailSystem,點擊保存。

給Simplenews模塊添加郵件截圖:
mailsystem_class

保存之后,給Simplenews選擇郵件處理模塊:mailsystem_simplenews

第五步. 郵件輸出:HTMLMail的模板和Simplenews的Formatter

a. HTML Mail基礎設置
admin/config/system/htmlmail

step 1 查看tpl文件和debug屬性
step 2 選擇使用的theme,選擇一個簡單theme或者當前theme即可。
注意,這個theme決定了htmlmail模板需要放置的位置。
step 3 輸出formatter設置。
推薦新建一個formatter用于newsletter,安裝幾個推薦filter,比如Emogrifier。

b. simplenews的輸出格式(都選擇HTML)

默認的formatter在: admin/config/services/simplenews/settings
具體simplenews分類的formatter在: admin/config/services/simplenews
如果分類里面設置為HTML格式,不成功,那就再把默認的formmater也設置為HTML

到這里,就可以測試發送郵件的效果了,看看郵件格式是否正確。

關于郵件的內容正文和內容類型設置有兩種方式:
1. 通過Node的body,發不出來的跟郵件的內容同一個body。
2. 通過自定義的Field,然后在tpl里面拼裝,不同的用于顯示結果不一樣。

需要注意的問題:
Simplenews的相關模板的tpl具體在simplenews下面,需要復制到theme下面的話,一般是seven(自己測試一下為什么放到當前theme下不行),所以,推薦直接修改simplenews模塊下面的tpl。

HTMLMail的相關tpl主要作用是包裝simplenews,把htmlmail–simplenews.tpl.php文件復制到指定的theme或當前theme下面(這個theme可以在htmlmail模塊里設置),然后可以在htmlmail-body標簽外面包裝自己想要的信息即可。
HTMLMail的tpl可以用于郵件的頭尾信息的包裝,比如郵件的頭部的logo,尾部的版權信息等。

步驟六,郵件的訂閱人管理地址: admin/people/simplenews

步驟七,使用Cron發送: admin/config/services/simplenews/settings/mail
sendmail_cron

 

 

設置完成上面的步驟,一個簡單的郵件推送系統就搭建完成了,Drupal里面主要還是管理郵件內容和推送用戶信息、訂閱等信息,真正的發送郵件還是系統的sendmail,如果需要更高效的發送,可以安裝postfix。考慮到郵件的認證、域名反向解析、spf以及垃圾郵件處理,可以考慮使用第三方的發送系統,這個時候,我們可以安裝Drupal的SMTP模塊即可。

其他相關問題:

Postfix發郵件如何管理bounce mail?
Simplenews如何去掉node的標題
Simplenews的郵件里,如何刪除newsletter分類鏈接信息?

更多問題,請到Drupal大學提問或者搜索。

]]>
http://www.tbdskt.live/2015/02/drupal-newsletter/feed/ 0
四川时时彩投注平台