欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解PHP中互斥鎖庫(kù)hyperf-wise-locksmith的使用

 更新時(shí)間:2024年11月28日 10:48:38   作者:左詩(shī)右碼  
hyperf-wise-locksmith?庫(kù)作為?Hyperf?框架中的一員,提供了一個(gè)高效、簡(jiǎn)潔的互斥鎖解決方案,下面就跟隨小編一起了解下它的具體使用吧

在分布式系統(tǒng)中,如何確保多臺(tái)機(jī)器之間不會(huì)產(chǎn)生競(jìng)爭(zhēng)條件,是一個(gè)常見且重要的問題。hyperf-wise-locksmith 庫(kù)作為 Hyperf 框架中的一員,提供了一個(gè)高效、簡(jiǎn)潔的互斥鎖解決方案。

本文將帶你了解這個(gè)庫(kù)的安裝、特性、基本與高級(jí)功能,并結(jié)合實(shí)際應(yīng)用場(chǎng)景,展示其在項(xiàng)目中的應(yīng)用。

hyperf-wise-locksmith 庫(kù)簡(jiǎn)介

hyperf-wise-locksmith 是一個(gè)適配 Hyperf 框架的互斥鎖庫(kù),它基于 pudongping/wise-locksmith 庫(kù)構(gòu)建。它可以幫助我們?cè)诜植际江h(huán)境下進(jìn)行鎖的管理,確保同一時(shí)刻只有一個(gè)進(jìn)程能夠操作某些共享資源,從而避免數(shù)據(jù)的競(jìng)爭(zhēng)和不一致問題。

安裝

要在你的 Hyperf 項(xiàng)目中使用 hyperf-wise-locksmith,你需要通過 Composer 進(jìn)行安裝:

composer require pudongping/hyperf-wise-locksmith -vvv

確保你的環(huán)境滿足以下要求:

  • PHP >= 8.0
  • hyperf ~3.0.0。

特性

hyperf-wise-locksmith 提供了多種鎖機(jī)制,包括文件鎖、分布式鎖紅鎖協(xié)程級(jí)別的互斥鎖。這些鎖機(jī)制可以幫助開發(fā)者在不同的場(chǎng)景下保護(hù)共享資源,避免競(jìng)態(tài)條件。

基本功能

文件鎖(flock)

文件鎖是一種簡(jiǎn)單的鎖機(jī)制,它依賴于文件系統(tǒng)。以下是一個(gè)使用文件鎖的示例:

    private function flock(float $amount)
    {
        $path = BASE_PATH . '/runtime/alex.lock.cache';
        $fileHandler = fopen($path, 'a+');
        // fwrite($fileHandler, sprintf("%s - %s \r\n", 'Locked', microtime()));

        $res = $this->locker->flock($fileHandler, function () use ($amount) {
            return $this->deductBalance($amount);
        });
        return $res;
    }

分布式鎖(redisLock)

分布式鎖適用于分布式系統(tǒng),它依賴于 Redis。以下是一個(gè)使用分布式鎖的示例:

    private function redisLock(float $amount)
    {
        $res = $this->locker->redisLock('redisLock', function () use ($amount) {
            return $this->deductBalance($amount);
        }, 10);
        return $res;
    }

高級(jí)功能

紅鎖(redLock)

紅鎖是一種更安全的分布式鎖實(shí)現(xiàn),它需要多個(gè) Redis 實(shí)例。以下是一個(gè)使用紅鎖的示例:

    private function redLock(float $amount)
    {
        $res = $this->locker->redLock('redLock', function () use ($amount) {
            return $this->deductBalance($amount);
        }, 10);
        return $res;
    }

協(xié)程級(jí)別的互斥鎖(channelLock)

協(xié)程級(jí)別的互斥鎖適用于協(xié)程環(huán)境,它提供了一種輕量級(jí)的鎖機(jī)制。以下是一個(gè)使用協(xié)程鎖的示例:

    private function channelLock(float $amount)
    {
        $res = $this->locker->channelLock('channelLock', function () use ($amount) {
            return $this->deductBalance($amount);
        });
        return $res;
    }

實(shí)際應(yīng)用場(chǎng)景

假設(shè)我們有一個(gè)在線支付系統(tǒng),需要在多個(gè)請(qǐng)求中扣減用戶的余額。如果不使用互斥鎖,可能會(huì)導(dǎo)致超扣或扣減失敗。使用 hyperf-wise-locksmith 庫(kù),我們可以確保每次扣減操作都是原子性的。

代碼示例

以下是一個(gè)扣減用戶余額的示例,使用了 hyperf-wise-locksmith 庫(kù):

<?php
declare(strict_types=1);

namespace App\Services;

use Hyperf\Contract\StdoutLoggerInterface;
use Pudongping\HyperfWiseLocksmith\Locker;
use Pudongping\WiseLocksmith\Exception\WiseLocksmithException;
use Pudongping\WiseLocksmith\Support\Swoole\SwooleEngine;
use Throwable;

class AccountBalanceService
{

    /**
     * 用戶賬戶初始余額
     *
     * @var float|int
     */
    private float|int $balance = 10;

    public function __construct(
        private StdoutLoggerInterface $logger,
        private Locker                $locker
    ) {
        $this->locker->setLogger($logger);
    }

    private function deductBalance(float|int $amount)
    {
        if ($this->balance >= $amount) {
            // 模擬業(yè)務(wù)處理耗時(shí)
            usleep(500 * 1000);
            $this->balance -= $amount;
        }

        return $this->balance;
    }

    /**
     * @return float
     */
    private function getBalance(): float
    {
        return $this->balance;
    }

    public function runLock(int $i, string $type, float $amount)
    {
        try {
            $start = microtime(true);

            switch ($type) {
                case 'flock':
                    $this->flock($amount);
                    break;
                case 'redisLock':
                    $this->redisLock($amount);
                    break;
                case 'redLock':
                    $this->redLock($amount);
                    break;
                case 'channelLock':
                    $this->channelLock($amount);
                    break;
                case 'noMutex':
                default:
                    $this->deductBalance($amount);
                    break;
            }

            $balance = $this->getBalance();
            $id = SwooleEngine::id();
            $cost = microtime(true) - $start;
            $this->logger->notice('[{type} {cost}] ==> [{i}<=>{id}] ==> 當(dāng)前用戶的余額為:{balance}', compact('type', 'i', 'balance', 'id', 'cost'));

            return $balance;
        } catch (WiseLocksmithException|Throwable $e) {
            return sprintf('Err Msg: %s ====> %s', $e, $e->getPrevious());
        }
    }

}

然后我們?cè)賹懸粋€(gè)控制器進(jìn)行調(diào)用

<?php

declare(strict_types=1);

namespace App\Controller;

use Hyperf\HttpServer\Annotation\AutoController;
use App\Services\AccountBalanceService;
use Hyperf\Coroutine\Parallel;
use function \Hyperf\Support\make;

#[AutoController]
class BalanceController extends AbstractController
{

    // curl '127.0.0.1:9511/balance/consumer?type=noMutex'
    public function consumer()
    {
        $type = $this->request->input('type', 'noMutex');
        $amount = (float)$this->request->input('amount', 1);

        $parallel = new Parallel();
        $balance = make(AccountBalanceService::class);

        // 模擬 20 個(gè)并發(fā)
        for ($i = 1; $i <= 20; $i++) {
            $parallel->add(function () use ($balance, $i, $type, $amount) {
                return $balance->runLock($i, $type, $amount);
            }, $i);
        }

        $result = $parallel->wait();

        return $this->response->json($result);
    }

}

當(dāng)我們?cè)L問 /balance/consumer?type=noMutex 地址時(shí),我們可以看到用戶的余額會(huì)被扣成負(fù)數(shù),這明顯不符合邏輯。 然而當(dāng)我們?cè)L問下面幾個(gè)地址時(shí),我們可以看到用戶余額不會(huì)被扣成負(fù)數(shù),則說明很好的保護(hù)了競(jìng)態(tài)下的共享資源的準(zhǔn)確性。

  • /balance/consumer?type=flock :文件鎖
  • /balance/consumer?type=redisLock :分布式鎖
  • /balance/consumer?type=redLock :紅鎖
  • /balance/consumer?type=channelLock :協(xié)程級(jí)別的互斥鎖

注意

關(guān)于使用到 redisLockredLock 時(shí):

  • 使用 redisLock 默認(rèn)采用的 config/autoload/redis.php 配置文件中的第一個(gè) key 配置 redis 實(shí)例(即 default)??砂葱鑲魅氲?4 個(gè)參數(shù) string|null $redisPoolName 進(jìn)行重新指定。
  • 使用 redLock 默認(rèn)采用的 config/autoload/redis.php 配置文件中的所有 key 對(duì)應(yīng)的配置 redis 實(shí)例。可按需傳入第 4 個(gè)參數(shù) ?array $redisPoolNames = null 進(jìn)行重新指定。

文檔

詳細(xì)文檔可見 pudongping/wise-locksmith。

結(jié)語(yǔ)

hyperf-wise-locksmith 庫(kù)為 Hyperf 框架的開發(fā)者提供了強(qiáng)大的互斥鎖功能,可以幫助我們?cè)诟卟l(fā)場(chǎng)景下保護(hù)共享資源。

通過本文的介紹,希望你能對(duì) hyperf-wise-locksmith 有一個(gè)全面的了解,并在你的項(xiàng)目中靈活運(yùn)用。如果你覺得這個(gè)庫(kù)對(duì)你有幫助,希望你可以幫忙點(diǎn)個(gè) Star 喲~

以上就是詳解PHP中互斥鎖庫(kù)hyperf-wise-locksmith的使用的詳細(xì)內(nèi)容,更多關(guān)于PHP hyperf-wise-locksmith的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論