php redis 傳遞閉包,通過緩存構建高性能 Laravel 應用

通過緩存構建高性能 Laravel 應用

由 學院君 創建于3年前, 最后更新于 11個月前

版本號 #2

20678 views

9 likes

1 collects

c33ded3bfe6afc64dfb1b8bec54e42e1.png

配置

Laravel 為不同的緩存系統提供了統一的 API。緩存配置位于 config/cache.php。在該文件中你可以指定在應用中默認使用哪個緩存驅動。Laravel 開箱支持主流的緩存后端如 Memcached和 Redis 等。

緩存配置文件還包含其他文檔化的選項,確保仔細閱讀這些選項。默認情況下,Laravel 被配置成使用文件緩存,這會將序列化數據和緩存對象存儲到文件系統。對于大型應用,建議使用內存緩存如 Memcached 或 APC,你甚至可以為同一驅動配置多個緩存配置。

驅動預備知識

數據庫

使用 database 緩存驅動時,你需要設置一張表存儲緩存項。下面是該表的 Schema 聲明:

Schema::create('cache', function($table) {

$table->string('key')->unique();

$table->text('value');

$table->integer('expiration');

});

注:你還可以使用 Artisan 命令 php artisan cache:table 通過相應的 schema 生成遷移。

Memcached

使用 Memcached 緩存要求安裝了Memcached PECL 包,即 PHP Memcached 擴展。你可以在配置文件 config/cache.php 中列出所有 Memcached 服務器:

'memcached' => [

[

'host' => '127.0.0.1',

'port' => 11211,

'weight' => 100

],

],

你還可以設置 host 選項為 UNIX socket 路徑,如果你這樣做,port 選項應該置為 0:

'memcached' => [

[

'host' => '/var/run/memcached/memcached.sock',

'port' => 0,

'weight' => 100

],

],

Redis

使用 Laravel 的 Redis 緩存之前,你需要通過 Composer 安裝 predis/predis 包(~1.0)。

想要了解更多關于 Redis 的配置,查看 Larave 的 Redis 文檔。

緩存使用

獲取緩存實例

Illuminate\Contracts\Cache\Factory 和 Illuminate\Contracts\Cache\Repository 契約提供了訪問 Laravel 緩存服務的方法。Factory 契約提供了所有訪問應用定義的緩存驅動的方法。Repository 契約通常是應用中 cache 配置文件中指定的默認緩存驅動的一個實現。

不過,你還可以使用 Cache 門面,這也是我們在整個文檔中使用的方式,Cache 門面提供了簡單方便的方式對底層 Laravel 緩存契約實現進行訪問:

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Cache;

class UserController extends Controller

{

/**

* 顯示應用所有用戶列表.

*

* @return Response

*/

public function index()

{

$value = Cache::get('key');

//

}

}

訪問多個緩存存儲

使用 Cache 門面,你可以使用 store 方法訪問不同的緩存存儲器,傳入 store 方法的鍵就是 cache 配置文件中 stores 配置數組里列出的相應的存儲器:

$value = Cache::store('file')->get('foo');

Cache::store('redis')->put('bar', 'baz', 10);

從緩存中獲取數據

Cache 門面的 get 方法用于從緩存中獲取緩存項,如果緩存項不存在,返回 null。如果需要的話你可以傳遞第二個參數到 get 方法指定緩存項不存在時返回的自定義默認值:

$value = Cache::get('key');

$value = Cache::get('key', 'default');

你甚至可以傳遞一個閉包作為默認值,如果緩存項不存在的話閉包的結果將會被返回。傳遞閉包允許你可以從數據庫或其它外部服務獲取默認值:

$value = Cache::get('key', function() {

return DB::table(...)->get();

});

檢查緩存項是否存在

has 方法用于判斷緩存項是否存在,如果值為 null 或 false 該方法會返回 false:

if (Cache::has('key')) {

//

}

數值增加/減少

increment 和 decrement 方法可用于調整緩存中的整型數值。這兩個方法都可以接收第二個參數來指明緩存項數值增加和減少的數目:

Cache::increment('key');

Cache::increment('key', $amount);

Cache::decrement('key');

Cache::decrement('key', $amount);

獲取&存儲

有時候你可能想要獲取緩存項,但如果請求的緩存項不存在時給它存儲一個默認值。例如,你可能想要從緩存中獲取所有用戶,或者如果它們不存在的話,從數據庫獲取它們并將其添加到緩存中,你可以通過使用 Cache::remember 方法實現:

$value = Cache::remember('users', $minutes, function() {

return DB::table('users')->get();

});

如果緩存項不存在,傳遞給 remember 方法的閉包被執行并且將結果存放到緩存中。

你還可以使用 rememberForever 方法從緩存中獲取數據或者將其永久存儲起來:

$value = Cache::rememberForever('users', function() {

return DB::table('users')->get();

});

獲取&刪除

如果你需要從緩存中獲取緩存項然后刪除,你可以使用 pull 方法,和 get 方法一樣,如果緩存項不存在的話返回 null:

$value = Cache::pull('key');

在緩存中存儲數據

你可以使用 Cache 門面上的 put 方法在緩存中存儲數據。當你在緩存中存儲數據的時候,需要指定數據被緩存的時間(分鐘數):

Cache::put('key', 'value', $minutes);

除了傳遞緩存項失效時間,你還可以傳遞一個代表緩存項有效時間的 PHP Datetime 實例:

$expiresAt = Carbon::now()->addMinutes(10);

Cache::put('key', 'value', $expiresAt);

緩存不存在時存儲數據

add 方法只會在緩存項不存在的情況下添加數據到緩存,如果數據被成功添加到緩存返回 true,否則,返回false:

Cache::add('key', 'value', $minutes);

永久存儲數據

forever 方法用于持久化存儲數據到緩存,這些值必須通過 forget 方法手動從緩存中移除:

Cache::forever('key', 'value');

注:如果你使用的是 Memcached 驅動,當緩存數據達到上限后永久存儲的數據就會被移除。

從緩存中移除數據

你可以使用 Cache 門面上的 forget 方法從緩存中移除緩存項數據:

Cache::forget('key');

還可以使用 flush 方法清除所有緩存:

Cache::flush();

注:清除緩存并不管什么緩存鍵前綴,而是從緩存系統中移除所有數據,所以在使用這個方法時如果其他應用與本應用有共享緩存時需要格外注意。

緩存輔助函數

除了使用 Cache 門面或緩存契約,還可以使用全局的 cache 函數來通過緩存獲取和存儲數據。當帶有一個字符串參數的 cache 函數被調用時,會返回給定鍵對應的緩存值(取值):

$value = cache('key');

如果你提供了鍵值對數組和一個過期時間給該函數,則會在指定的有效期內存儲緩存值(存儲):

cache(['key' => 'value'], $minutes);

cache(['key' => 'value'], Carbon::now()->addSeconds(10));

測試調用 cache 函數時,可以像測試門面一樣使用 Cache::shouldReceive 方法。

緩存標簽

注:緩存標簽目前不支持 file 或 database 緩存驅動,此外,當使用多標簽的緩存被設置為永久存儲時,使用 memcached 驅動的緩存有著最佳性能表現,因為 Memcached 會自動清除陳舊記錄。

存儲被打上標簽的緩存項

緩存標簽允許你給相關緩存項打上同一個標簽以便于后續清除這些緩存值,被打上標簽的緩存可以通過傳遞一個被排序的標簽數組來訪問。例如,我們可以通過以下方式在添加緩存的時候設置標簽:

Cache::tags(['people', 'artists'])->put('John', $john, $minutes);

Cache::tags(['people', 'authors'])->put('Anne', $anne, $minutes);

你可以給多個緩存項打上相同標簽,這是沒有數目限制的。

訪問被打上標簽的緩存項

要獲取被打上標簽的緩存項,傳遞同樣的有序標簽數組到 tags 方法然后使用你想要獲取的key來調用 get 方法:

$john = Cache::tags(['people', 'artists'])->get('John');

$anne = Cache::tags(['people', 'authors'])->get('Anne');

移除被打上標簽的數據項

你可以同時清除被打上同一標簽/標簽列表的所有緩存項,例如,以下語句會移除被打上 people 或 authors 標簽的所有緩存:

Cache::tags(['people', 'authors'])->flush();

這樣,上面設置的 Anne 和 John 緩存項都會從緩存中移除。

相反,以下語句只移除被打上 authors 標簽的語句,所以只有 Anne 會被移除而 John 不會:

Cache::tags('authors')->flush();

添加自定義緩存驅動

編寫驅動

要創建自定義的緩存驅動,首先需要實現 Illuminate\Contracts\Cache\Store 契約,所以,我們的 MongoDB 緩存實現看起來會像這樣子:

namespace App\Extensions;

use Illuminate\Contracts\Cache\Store;

class MongoStore implements Store

{

public function get($key) {}

public function many(array $keys);

public function put($key, $value, $minutes) {}

public function putMany(array $values, $minutes);

public function increment($key, $value = 1) {}

public function decrement($key, $value = 1) {}

public function forever($key, $value) {}

public function forget($key) {}

public function flush() {}

public function getPrefix() {}

}

我們只需要使用一個 MongoDB 連接來實現其中的每一個方法,想要看如何實現每個方法的示例,可以參考 Laravel 底層源碼 Illuminate\Cache\MemcachedStore,實現完成后,我們就可以完成自定義驅動注冊:

Cache::extend('mongo', function($app) {

return Cache::repository(new MongoStore);

});

注:如果你在擔心將自定義緩存驅動代碼放到哪,可以在 app 目錄下創建一個Extensions 命名空間。不過,記住 Laravel 并沒有一個嚴格的應用目錄結構,你可以基于你的需要自由的組織目錄結構。

注冊驅動

要通過 Laravel 注冊自定義的緩存驅動,可以使用 Cache 門面上的 extend 方法。對 Cache::extend 的調用可以在 Laravel 自帶的 App\Providers\AppServiceProvider 提供的 boot 方法中完成,或者,你也可以創建自己的服務提供者來存放擴展——只是別忘了在配置文件 config/app.php 中注冊服務提供者到 providers 數組:

namespace App\Providers;

use App\Extensions\MongoStore;

use Illuminate\Support\Facades\Cache;

use Illuminate\Support\ServiceProvider;

class CacheServiceProvider extends ServiceProvider

{

/**

* Perform post-registration booting of services.

*

* @return void

* @translator laravelacademy.org

*/

public function boot()

{

Cache::extend('mongo', function($app) {

return Cache::repository(new MongoStore);

});

}

/**

* Register bindings in the container.

*

* @return void

*/

public function register()

{

//

}

}

傳遞給 extend 方法的第一個參數是驅動名稱。該值對應配置文件 config/cache.php 中的 driver 選項。第二個參數是返回 Illuminate\Cache\Repository 實例的閉包。該閉包中被傳入一個 $app 實例,也就是服務容器的一個實例。

擴展被注冊后,只需簡單更新配置文件 config/cache.php 的 driver 選項為自定義擴展名稱即可。

緩存事件

要在每次緩存操作時執行代碼,你可以監聽緩存觸發的事件,通常,你可以將這些緩存處理器代碼放到 EventServiceProvider 中:

/**

* The event listener mappings for the application.

*

* @var array

*/

protected $listen = [

'Illuminate\Cache\Events\CacheHit' => [

'App\Listeners\LogCacheHit',

],

'Illuminate\Cache\Events\CacheMissed' => [

'App\Listeners\LogCacheMissed',

],

'Illuminate\Cache\Events\KeyForgotten' => [

'App\Listeners\LogKeyForgotten',

],

'Illuminate\Cache\Events\KeyWritten' => [

'App\Listeners\LogKeyWritten',

],

];

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/529506.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/529506.shtml
英文地址,請注明出處:http://en.pswp.cn/news/529506.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

imclearboder matlab,Lucas

Lucas-Kanade跟蹤算法是視覺跟蹤中一個很經典的基于點的逐幀跟蹤算法。起初這個算法是用來求解stero matching1的,后來經過Carlo Tomasi2和Jianbo Shi3等人的發展漸趨成熟。Jianbo Shi提出了一種篩選跟蹤點特征的方法,使得特征的跟蹤更可靠。Jean-Yves B…

php判斷url參數為空,PHP檢查url鏈接是否已經有參數的簡單示例

這篇文章主要為大家詳細介紹了PHP檢查url鏈接是否已經有參數的簡單示例,具有一定的參考價值,可以用來參考一下。感興趣的小伙伴,下面一起跟隨512筆記的小編小韻來看看吧!比如分頁,因為有些鏈接已經有參數了&#xff0c…

java 讀取 郵件 附件,JavaMail 中對附件下載的處理

在項目中使用 JavaMail 作為郵件核心庫,但是一直遇到一個比較頭疼的問題,當郵件中存在附件時,此封郵件加載速度很慢,最高時之后 80k/s.通過 log 打印看出,當獲取附件時,獲取一段之后等待一段時間在獲取另一端.導致 io 開銷過大,等待網絡讀取時間過長.相關日志如下:O24 FETCH 27…

matlab求勒讓德多項式零點,有沒有勒讓德多項式導數 零點程序

求N1次勒讓德多項式的m(m0,1,...)階導數零點Matlab程序子程序:function xjp(N,alpha,beta)n1:N;a(1)(alphabeta2)/2;b(1)(beta-alpha)/2;a([2:N1])(2*nalphabeta1).*(2*nalphabeta2)./(2*(n1).*(nalphabeta1));b([2:N1])(alpha*alpha-beta*beta)*(2*nalphabeta1)./(…

js_long.php,protobuf.js 與 Long.js的使用詳解

這次給大家帶來protobuf.js 與 Long.js的使用詳解,是急用protobuf.js 與 Long.js的注意事項有哪些,下面就是實戰案例,一起來看一下。protobuf.js的結構和webpack的加載之后的結構很相似。這樣的模塊化組合是個不錯的結構方式。1個是適應了不同…

微分進化算法解決函數優化問題的matlab代碼,Matlab微分進化算法及優化函數測試...

微分進化(Difference Evolution,DE)算法是一種優化算法,據稱其比GA(遺傳算法)等更為優秀。借鑒網上實現的DE算法,用Matlab實現了對若干函數優化問題的解法,代碼如下:function [] de_testclear all;close all;clc;%解&…

Oracle中獲取文件中的數據,操作oracle中的數據文件

收藏于http://dev.yesky.com/296/8090796.shtmlOracle數據庫中管理表空間和數據文件數據庫的三大組成部分:數據文件,控制文件,Redo日志。表空間分為系統表空間和非系統表空間。SYSTEM表空間是最基本的,必須的,Oracle建議你為用戶數…

oracle 存儲過程設置回滾點,(轉)oracle 存儲過程事宜使用斷點回滾 -savepoint

學習存儲過程中使用斷點回滾事務時,發現目前網絡上存在一個問題,那就是使用斷點回滾后,都忘記了一個很重要的事情,提交事務。雖然使用了斷點回滾,但是斷點回滾不像rollBack或commit一樣結束當前事務,而使用…

php tp5清空數據表并主鍵,tp5數據庫——更新數據

更新數據更新數據表中的數據Db::table(think_user)->where(id, 1)->update([name > thinkphp]);如果數據中包含主鍵,可以直接使用:Db::table(think_user)->update([name > thinkphp,id>1]);update 方法返回影響數據的條數,…

oracle幾個網絡,ORACLE網絡的幾個重點概念

數據庫名(DB_NAME)、數據庫實例名(INSTANCE_NAME)、操作系統環境變量ORACLE_SID、數據庫服務名 (SERVICE_NAME)、數據庫域名(DB_DOMAIN)以及全局數據庫名(GLOBAL_DB_NAME)是幾個使用Oracle數據庫容易混 淆的概念。1、數據庫名與實例名數據庫名(DB_NAME):是區分數據的…

oracle每季度補丁,Oracle 2020 年第四季度補丁發布

半個月前,也就是 10 月 20 日, Oracle 發布了今年最后一次補丁更新,那么很多人都想打最新的 PSU,理由是有被掃到各種漏洞,有的掃描工具著實太坑,這里就不用說了,前幾天看到蓋總發布的文章2020年…

php flash上傳進度條,PHP_PHP+FLASH實現上傳文件進度條相關文件 下載,PHP之所以很難實現上傳進度條 - phpStudy...

PHPFLASH實現上傳文件進度條相關文件 下載PHP之所以很難實現上傳進度條是因為在我們上傳文件到服務器的時候,要等到文件全部送到服務器之后,才執行相應的php文件。在這之前,文件數據保存在一個臨時文件里面,而php無法獲得這個文件…

oracle截取時間函數6,SQL 取日期部分函數

convert(varchar(10),getdate(),120)這個函數就可以得到日期部分了,我覺得還是比較方便的,我覺得SQL在日期方面,沒有ORACLE函數坐的好。。Sql Server中的日期與時間函數1. 當前系統日期、時間select getdate()2. dateadd 在向指定日期加上一…

oracle 找不到程序,Oracle 找不到監聽程序

Oracle服務器文件 app\Administrator\product\11.2.0\dbhome_1\NETWORK\ADMIN\listener.oraSID_LIST_LISTENER (SID_LIST (SID_DESC (SID_NAME CLRExtProc)(ORACLE_HOME D:\app\Administrator\product\11.2.0\dbhome_1)(PROGRAM extproc)(ENVS "EXTPROC_DLLSONLY:D:\…

oracle中的存儲過程教程,oracle 存儲過程

-- 查看系統定時任務SELECT * FROM DBA_JOBS-- 新建定時任務DECLAREjobno NUMBER;BEGINSYS.DBMS_JOB.SUBMIT(JOB > jobno, /*自動生成JOB_ID*/WHAT > qmcb_ls_data;, /*需要執行的存儲過程名稱或SQL語句*/NEXT_DATE > SYSDATE, /*初次執行時間-立即執行*/INTERVAL >…

Oracle segment啥意思,關于oracle數據庫段segment的小結

段(segment)是一種在數據庫中消耗物理存儲空間的任何實體(一個段可能存在于多個數據文件中,因為物理的數據文件是組成邏輯表空間的基本物理存儲單位)今天碰到一個高水位問題:一個分區表,刪除某個分區中的一些數據后,表空間并沒有回…

Linux在文件第一行添加字符,使用shell命令給文件中每一行的前面、后面、指定列添加字符...

shell給一個文件中的每一行開頭插入字符的方法:awk {print "X"$0} fileNameshell給一個文件中的每一行結尾插入字符的方法:awk {print $0"X"} fileNameshell給一個文件中的每一行的指定列插入字符的方法:awk $O$O" …

路由器 刷 linux系統版本,在Linux下用tftp刷寫路由器固件

(以Buffalo WHR-G300N V2路由器為例)以發行版Ubuntu為例(如果你在Windows下,可下載Ubuntu的ISO文件,再用wubi安裝Ubuntu,可免去重新分區的麻煩),下載Buffalo WHR-G300N V2路由器的FTP版固件文件,放到Ubuntu的/home目錄…

linux沒有etho網卡,關于怎么解決CENTOS7沒有ETH0網卡這個問題

CentOS7系統安裝完畢之后,輸入ifconfig命令發現沒有eth0,不符合我們的習慣。而且也無法遠程ssh連接。1.進入目錄/etc/sysconfig/network-scripts/2.將文件ifcfg-ens33重命名為ifcfg-eth0;(注意:修改需要切換至root用戶)3.編輯ifcfg-eth0使用命令&#xf…

linux添加物理卷編輯文件夾,Red hat Linux下的邏輯卷管理器LVM-上

【IT168 專稿】Red hat 下的LVM 上 LVM是Logical Volume Manager(邏輯卷管理器)的簡寫,它為主機提供了更高層次的磁盤存儲管理能力。LVM可以幫助系統管理員為應用與用戶方便地分配存儲空間。在LVM管理下的邏輯卷可以按需改變大小或添加移除。另外,LVM可以…