国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

緩存系統(tǒng)

緩存系統(tǒng)


緩存系統(tǒng)

配置

Laravel 為各種后端緩存提供豐富而統(tǒng)一的 API,其配置信息位于  config/cache.php 文件中。在該文件中你可以指定應(yīng)用默認(rèn)使用哪個緩存驅(qū)動。Laravel 支持當(dāng)前流行的后端緩存,例如 MemcachedRedis 。

緩存配置文件還包含各種其他選項,這些選項都記錄在文件中,因此請確保閱讀這些選項。默認(rèn)情況下,Laravel 配置為使用 file 緩存驅(qū)動,它將序列化的緩存對象存儲在文件系統(tǒng)中。對于大型應(yīng)用,建議您使用更強(qiáng)大的驅(qū)動程序,例如 Memcached 或 Redis。你甚至可以為同一個驅(qū)動程序配置多個緩存配置。

驅(qū)動的前提條件

數(shù)據(jù)庫

當(dāng)使用 database 緩存驅(qū)動時,你需要配置一個表來存放緩存數(shù)據(jù)。下面是構(gòu)建緩存數(shù)據(jù)表結(jié)構(gòu)的 Schema 聲明示例:

Schema::create('cache', function ($table) {
    $table->string('key')->unique();    
    $table->text('value');    
    $table->integer('expiration');
});

{tip} 你也可以使用 Artisan 命令 php artisan cache:table 來生成合適的遷移。

Memcached

使用 Memcached 驅(qū)動需要安裝 Memcached PECL 擴(kuò)展包 。你可以把所有的 Memcached 服務(wù)器都列在 config/cache.php 配置文件中:

'memcached' => [ 
   [       
    'host' => '127.0.0.1',        
    'port' => 11211,        
    'weight' => 100    
   ],
 ],

你可以將 host 選項設(shè)置為 UNIX socket 路徑。如果你這樣配置了, port 選項應(yīng)該設(shè)置為 0

'memcached' => [ 
   [      
     'host' => '/var/run/memcached/memcached.sock',        
     'port' => 0,        
     'weight' => 100   
    ],
],

Redis

在使用 Laravel 的 Redis 緩存之前,你需要通過 Composer 安裝 predis/predis 擴(kuò)展包 (~1.0) 或者使用 PECL 安裝 PhpRedis PHP 擴(kuò)展。

如需了解更多關(guān)于 Redis 的配置,請參考 Laravel Redis 文檔。

緩存的使用

獲取緩存實例

Illuminate\Contracts\Cache\FactoryIlluminate\Contracts\Cache\Repository 契約 提供了 Laravel 緩存服務(wù)的訪問機(jī)制。 Factory 契約為你的應(yīng)用程序定義了訪問所有緩存驅(qū)動的機(jī)制。 Repository 契約通常是由你的 cache 配置文件指定的默認(rèn)緩存驅(qū)動實現(xiàn)的。

不過,你也可以使用 Cache Facade,我們將在后續(xù)的文檔中介紹。 Cache Facade 為 Laravel 緩存契約底層的實現(xiàn)提供了方便又簡潔的方法:

<?php
    namespace App\Http\Controllers;
    use Illuminate\Support\Facades\Cache;
    class UserController extends Controller{   
     /**
     * 展示應(yīng)用的所有用戶列表。
     *
     * @return Response
     */ 
      public function index() 
         {     
            $value = Cache::get('key');    
                //  
          }
     }

訪問多個緩存存儲

使用 Cache Facade,你可以通過 store 方法來訪問各種緩存存儲。傳入 store 方法的鍵應(yīng)該對應(yīng) cache 配置信息文件中的 stores 配置數(shù)組中所列的存儲之一:

$value = Cache::store('file')->get('foo');
Cache::store('redis')->put('bar', 'baz', 600); 
// 10 分鐘

從緩存中獲取數(shù)據(jù)

Cache Facade 的 get 方法是用來從緩存中獲取數(shù)據(jù)的方法。如果該數(shù)據(jù)在緩存中不存在,那么該方法將返回 null 。正如你想的那樣,你也可以向  get 方法傳遞第二個參數(shù),用來指定如果查找的數(shù)據(jù)不存在時你希望返回的默認(rèn)值:

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

你甚至可以傳遞 Closure 作為默認(rèn)值。如果指定的數(shù)據(jù)在緩存中不存在,將返回 Closure 的結(jié)果。傳遞閉包的方法允許你從數(shù)據(jù)庫或其他外部服務(wù)中獲取默認(rèn)值:

$value = Cache::get('key', function () {
    return DB::table(...)->get();
 });

檢查緩存項是否存在

has 方法可以用于判斷緩存項是否存在。如果為 nullfalse 則該方法將會返回 false

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

遞增與遞減值

incrementdecrement 方法可以用來調(diào)整緩存中整數(shù)項的值。這兩個方法都可以傳入第二個可選參數(shù),這個參數(shù)用來指明要遞增或遞減的數(shù)量:

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

獲取和存儲

有時你可能想從緩存中獲取一個數(shù)據(jù),而當(dāng)請求的緩存項不存在時,程序能為你存儲一個默認(rèn)值。例如,你可能想從緩存中獲取所有用戶,當(dāng)緩存中不存在這些用戶時,程序?qū)臄?shù)據(jù)庫將這些用戶取出并放入緩存。你可以使用 Cache::remember 方法來實現(xiàn):

$value = Cache::remember('users', $seconds, function () {
    return DB::table('users')->get();
 });

如果緩存中不存在你想要的數(shù)據(jù)時,則傳遞給 remember 方法的 閉包 將被執(zhí)行,然后將其結(jié)果返回并放置到緩存中。

你可以使用 rememberForever 方法從緩存中獲取數(shù)據(jù)或者永久存儲它:

$value = Cache::rememberForever('users', function () {
    return DB::table('users')->get();
});

獲取和刪除

如果你需要從緩存中獲取到數(shù)據(jù)之后再刪除它,你可以使用 pull 方法。和 get 方法一樣,如果緩存不存在,則返回 null

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

在緩存中存儲數(shù)據(jù)

你可以使用 Cache Facade 的 put 方法將數(shù)據(jù)存儲到緩存中:

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

如果緩存的過期時間沒有傳遞給 put 方法, 則緩存將永久有效:

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

除了以整數(shù)形式傳遞過期時間的秒數(shù),你還可以傳遞一個 DateTime 實例來表示該數(shù)據(jù)的過期時間:

Cache::put('key', 'value', now()->addMinutes(10));

只存儲沒有的數(shù)據(jù)

add 方法將只存儲緩存中不存在的數(shù)據(jù)。如果存儲成功,將返回 true ,否則返回 false

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

數(shù)據(jù)永久存儲

forever 方法可用于持久化將數(shù)據(jù)存儲到緩存中。因為這些數(shù)據(jù)不會過期,所以必須通過 forget 方法從緩存中手動刪除它們:

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

{tip} 如果你使用 Memcached 驅(qū)動,當(dāng)緩存數(shù)據(jù)達(dá)到存儲上限時,「永久存儲」 的數(shù)據(jù)可能會被刪除。

刪除緩存中的數(shù)據(jù)

你可以使用 forget 方法從緩存中刪除這些數(shù)據(jù):

Cache::forget('key');

你也可以通過提供零或者負(fù)的 TTL 值刪除這些數(shù)據(jù):

Cache::put('key', 'value', 0);
Cache::put('key', 'value', -5);

你可以使用 flush 方法清空所有的緩存:

Cache::flush();

{note} 清空緩存的方法并不會考慮緩存前綴,會將緩存中的所有內(nèi)容刪除。因此在清除與其它應(yīng)用程序共享的緩存時,請慎重考慮。

原子鎖

{note} 要使用該特性,你的應(yīng)用必須使用 memcached, dynamodbredis 緩存驅(qū)動作為你應(yīng)用的默認(rèn)緩存驅(qū)動。此外,所有服務(wù)器必須與同一中央緩存服務(wù)器進(jìn)行通信。

原子鎖允許對分布式鎖進(jìn)行操作而不必?fù)?dān)心競爭條件。例如, Laravel Forge 使用原子鎖來確保在一臺服務(wù)器上每次只有一個遠(yuǎn)程任務(wù)在執(zhí)行。你可以使用 Cache::lock 方法來創(chuàng)建和管理鎖:

use Illuminate\Support\Facades\Cache;
$lock = Cache::lock('foo', 10);
if ($lock->get()) {
    //獲取鎖定10秒...    
    $lock->release();
}

get 方法也可以接收一個閉包。在閉包執(zhí)行之后,Laravel 將會自動釋放鎖:

Cache::lock('foo')->get(function () {
    // 獲取無限期鎖并自動釋放...
});

如果你在請求時鎖無法使用,你可以控制 Laravel 等待指定的秒數(shù)。如果在指定的時間限制內(nèi)無法獲取鎖,則會拋出 Illuminate\Contracts\Cache\LockTimeoutException

use Illuminate\Contracts\Cache\LockTimeoutException;
$lock = Cache::lock('foo', 10);try {
    $lock->block(5);    
    // 等待最多5秒后獲取的鎖...
   } catch (LockTimeoutException $e) {
       // 無法獲取鎖...
   } finally {
       optional($lock)->release();
   }
Cache::lock('foo', 10)->block(5, function () {
    // 等待最多5秒后獲取的鎖...
   });

管理跨進(jìn)程的鎖

有時,你希望在一個進(jìn)程中獲取鎖并在另外一個進(jìn)程中釋放它。例如,你可以在 Web 請求期間獲取鎖,并希望在該請求觸發(fā)的隊列作業(yè)結(jié)束時釋放鎖。在這種情況下,你應(yīng)該將鎖的作用域「owner token」傳遞給隊列作業(yè),以便作業(yè)可以使用給定的 token 重新實例化鎖:

// 控制器里面...
$podcast = Podcast::find($id);
if ($lock = Cache::lock('foo', 120)->get()) {
    ProcessPodcast::dispatch($podcast, $lock->owner());
    }
// ProcessPodcast Job 里面...
Cache::restoreLock('foo', $this->owner)->release();

如果你想在不尊重當(dāng)前鎖的所有者的情況下釋放鎖,你可以使用 forceRelease 方法:

Cache::lock('foo')->forceRelease();

Cache 輔助函數(shù)

除了可以使用 Cache Facade 或 Cache 契約 外,你還可以使用全局輔助函數(shù) cache 來獲取和保存緩存數(shù)據(jù)。當(dāng) cache 函數(shù)只接收一個字符串參數(shù)的時候,它將會返回給定鍵對應(yīng)的值:

$value = cache('key');

如果你向函數(shù)提供了一組鍵值對和過期時間,它將會在指定時間內(nèi)緩存數(shù)據(jù):

cache(['key' => 'value'], $seconds);
cache(['key' => 'value'], now()->addMinutes(10));

當(dāng) cache 函數(shù)在沒有任何參數(shù)的情況下被調(diào)用時,它返回一個 Illuminate\Contracts\Cache\Factory 實現(xiàn)的實例,允許你調(diào)用其它緩存方法:

cache()->remember('users', $seconds, function () {
    return DB::table('users')->get();
 });

{tip} 如果在測試中使用全局輔助函數(shù) cache ,你可以使用 Cache::shouldReceive 方法就像 測試 Facade。

緩存標(biāo)記

{note} 緩存標(biāo)記不支持使用 filedatabase 緩存驅(qū)動。此外,當(dāng)使用多個緩存標(biāo)記的緩存設(shè)置為「永久」時,類似 memcached 的緩存驅(qū)動性能最佳,它會自動清除舊的記錄。

寫入被標(biāo)記的緩存數(shù)據(jù)

緩存標(biāo)記允許你給緩存相關(guān)進(jìn)行標(biāo)記,以便后續(xù)清除這些緩存值。你可以通過傳入標(biāo)記名稱的有序數(shù)組來訪問標(biāo)記的緩存。例如,我們可以使用標(biāo)記的同時使用 put 方法設(shè)置緩存。

Cache::tags(['people', 'artists'])->put('John', $john, $seconds);
Cache::tags(['people', 'authors'])->put('Anne', $anne, $seconds);

訪問被標(biāo)記的緩存數(shù)據(jù)

若要獲取一個被標(biāo)記的緩存數(shù)據(jù),請將相同的有序標(biāo)記數(shù)組傳遞給 tags 方法,然后調(diào)用 get 方法來獲取你要檢索的鍵:

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

移除被標(biāo)記的緩存數(shù)據(jù)

你可以清空有單個標(biāo)記或是一組標(biāo)記的所有緩存數(shù)據(jù)。例如,下面的語句會被標(biāo)記為 people,authors 或兩者都有的緩存。所以,AnneJohn 都會從緩存中被刪除:

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

相反,下面的語句只會刪除被標(biāo)記 authors 的緩存,所以 Anne 會被刪除,但 John 不會:

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

增加自定義的緩存驅(qū)動

編寫驅(qū)動

要創(chuàng)建自定義的緩存驅(qū)動,首先需要實現(xiàn) Illuminate\Contracts\Cache\Store 契約。因此, MongoDB 的緩存實現(xiàn)看起來會像這樣:

<?php
    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, $seconds) {}    
       public function putMany(array $values, $seconds);    
       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 的連接來實現(xiàn)這些方法。關(guān)于如何實現(xiàn)這些方法的實例,可以參閱框架源代碼中的 Illuminate\Cache\MemcachedStore 。一旦完成契約額實現(xiàn)后,就可以像下面這樣完成自定義驅(qū)動的注冊了。

Cache::extend('mongo', function ($app) {
    return Cache::repository(new MongoStore);
  });

{tip} 如果你不知道將緩存驅(qū)動代碼放在哪,你可以在 app 目錄下創(chuàng)建一個 Extensions 命名空間。然而,Laravel 并沒有硬性規(guī)定應(yīng)用程序的結(jié)構(gòu),你可以根據(jù)自己的喜好自由組織你的應(yīng)用程序。

注冊驅(qū)動

要使用 Laravel 來注冊自定義緩存驅(qū)動,就要在 Cache Facade 上使用 extend 方法。 對 Cache::extend 的調(diào)用可以在新的 Laravel 應(yīng)用程序中自帶的 App\Providers\AppServiceProviderboot 方法中完成,或者你也可以創(chuàng)建自己的服務(wù)提供者來存放擴(kuò)展,只是不要忘記在 config/app.php 的 provider 數(shù)組中注冊服務(wù)提供者:

<?php
    namespace App\Providers;use App\Extensions\MongoStore;
    use Illuminate\Support\Facades\Cache;
    use Illuminate\Support\ServiceProvider;
    class CacheServiceProvider extends ServiceProvider{   
     /**
     * 執(zhí)行服務(wù)的注冊后引導(dǎo)。
     *
     * @return void
     */   
       public function boot()   
        {      
          Cache::extend('mongo', function ($app) {     
                 return Cache::repository(new MongoStore);        
             });   
          }   
     /**
     * 在容器中注冊綁定。
     *
     * @return void
     */    
     public function register()   
      {      
        //   
       }
    }

傳遞給 extend 方法的第一個參數(shù)是驅(qū)動程序的名稱。這將與 config/cache.php 配置文件的 driver 選項相對應(yīng)。第二個參數(shù)是一個應(yīng)該返回 Illuminate\Cache\Repository 實例的閉包。該閉包將傳遞一個 服務(wù)容器 的 $app 實例。

一旦你的擴(kuò)展程序注冊后,需要將 config/cache.php 配置文件中的 driver 選項更新為你的擴(kuò)展名稱。

事件

要在每次緩存操作時執(zhí)行代碼,你可以監(jiān)聽緩存觸發(fā)的 事件 。通常,你應(yīng)該將這些事件監(jiān)聽器放在 EventServiceProvider 中:

/**
 * 應(yīng)用的事件監(jiān)聽器映射
 *
 * @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', 
           ],
        ];
本文章首發(fā)在 LearnKu.com 網(wǎng)站上。