Skip to content

Commit

Permalink
Squashed 'src/service-governance/' changes from 6c3533fa..9608c9bc
Browse files Browse the repository at this point in the history
9608c9bc 修复两个导致Rpc Fallback不生效的问题 (#84)
c0bdbfc6  add coWrite(); use swoft/swoole-ide-helper (#83)

git-subtree-dir: src/service-governance
git-subtree-split: 9608c9bc08f0f469462ced02af0fc3081265032c
  • Loading branch information
huangzhhui committed Jul 10, 2018
1 parent cb724b3 commit cb2a75a
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 31 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"swoft/framework": "^1.0"
},
"require-dev": {
"eaglewu/swoole-ide-helper": "dev-master",
"swoft/swoole-ide-helper": "dev-master",
"phpunit/phpunit": "^5.7"
},
"autoload": {
Expand Down
34 changes: 20 additions & 14 deletions src/Circuit/CircuitBreaker.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<?php

/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @document https://doc.swoft.org
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/
namespace Swoft\Sg\Circuit;

use Swoft\App;
Expand All @@ -13,22 +20,22 @@ class CircuitBreaker
/**
* 关闭状态
*/
const CLOSE = "close";
const CLOSE = 'close';

/**
* 开启状态
*/
const OPEN = "open";
const OPEN = 'open';

/**
* 半开起状态
*/
const HALF_OPEN_STATE = "halfOpenState";
const HALF_OPEN_STATE = 'halfOpenState';

/**
* 未初始化
*/
const PENDING = "pending";
const PENDING = 'pending';

/**
* @var int 错误请求计数
Expand All @@ -40,7 +47,6 @@ class CircuitBreaker
*/
public $successCounter = 0;


/**
* @var int 开启状态切换到半开状态时间
*/
Expand All @@ -49,7 +55,7 @@ class CircuitBreaker
/**
* @var string 服务名称
*/
public $serviceName = "breakerService";
public $serviceName = 'breakerService';

/**
* @var CircuitBreakerState 熔断器状态,开启、半开、关闭
Expand Down Expand Up @@ -160,7 +166,7 @@ public function isHalfOpen()
*/
public function switchToCloseState()
{
App::debug($this->serviceName . "服务,当前[" . $this->getCurrentState() . "],熔断器状态切换,切换到[关闭]状态");
App::debug($this->serviceName . '服务,当前[' . $this->getCurrentState() . '],熔断器状态切换,切换到[关闭]状态');
$this->circuitState = new CloseState($this);
}

Expand All @@ -169,7 +175,7 @@ public function switchToCloseState()
*/
public function switchToOpenState()
{
App::debug($this->serviceName . "服务,当前[" . $this->getCurrentState() . "],熔断器状态切换,切换到[开启]状态");
App::debug($this->serviceName . '服务,当前[' . $this->getCurrentState() . '],熔断器状态切换,切换到[开启]状态');
$this->circuitState = new OpenState($this);
}

Expand All @@ -178,7 +184,7 @@ public function switchToOpenState()
*/
public function switchToHalfState()
{
App::debug($this->serviceName . "服务,当前[" . $this->getCurrentState() . "],熔断器状态切换,切换到[半开]状态");
App::debug($this->serviceName . '服务,当前[' . $this->getCurrentState() . '],熔断器状态切换,切换到[半开]状态');

$this->circuitState = new HalfOpenState($this);
}
Expand All @@ -194,15 +200,15 @@ public function switchToHalfState()
public function fallback($fallback = null, array $params = [])
{
if ($fallback == null) {
App::debug($this->serviceName . "服务,当前[" . $this->getCurrentState() . "],服务降级处理,fallback未定义");
App::debug($this->serviceName . '服务,当前[' . $this->getCurrentState() . '],服务降级处理,fallback未定义');
return null;
}

if (is_array($fallback) && count($fallback) == 2) {
list($className, $method) = $fallback;
App::debug($this->serviceName . "服务,服务降级处理,执行fallback, class=" . $className . " method=" . $method);
list($fallbackObj, $method) = $fallback;
App::debug($this->serviceName . '服务,服务降级处理,执行fallback, class=' . get_class($fallbackObj) . ' method=' . $method);

return $className->$method(...$params);
return $fallbackObj->$method(...$params);
}

return null;
Expand Down
25 changes: 18 additions & 7 deletions src/Circuit/CloseState.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
<?php

/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @document https://doc.swoft.org
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/
namespace Swoft\Sg\Circuit;

use Swoft\App;
use Swoole\Coroutine\Client;
use Swoft\Pool\ConnectionInterface;

/**
* 关闭状态及切换(close)
Expand All @@ -29,30 +37,33 @@ public function doCall($callback, $params = [], $fallback = null)

try {
if ($class == null) {
throw new \Exception($this->circuitBreaker->serviceName . "服务,连接建立失败(null)");
throw new \Exception($this->circuitBreaker->serviceName . '服务,连接建立失败(null)');
}

if ($class instanceof Client && $class->isConnected() == false) {
throw new \Exception($this->circuitBreaker->serviceName . "服务,当前连接已断开");
if (
($class instanceof Client && $class->isConnected() == false) ||
($class instanceof ConnectionInterface && $class->check() == false)
) {
throw new \Exception($this->circuitBreaker->serviceName . '服务,当前连接已断开');
}
$data = $class->$method(...$params);
} catch (\Exception $e) {
if ($this->circuitBreaker->isClose()) {
$this->circuitBreaker->incFailCount();
}

App::error($this->circuitBreaker->serviceName . "服务,当前[关闭状态],服务端调用失败,开始服务降级容错处理,error=" . $e->getMessage());
App::error($this->circuitBreaker->serviceName . '服务,当前[关闭状态],服务端调用失败,开始服务降级容错处理,error=' . $e->getMessage());
$data = $this->circuitBreaker->fallback($fallback);
}

$failCount = $this->circuitBreaker->getFailCounter();
$switchToFailCount = $this->circuitBreaker->getSwitchToFailCount();
if ($failCount >= $switchToFailCount && $this->circuitBreaker->isClose()) {
App::trace($this->circuitBreaker->serviceName . "服务,当前[关闭状态],服务失败次数达到上限,开始切换为开启状态,failCount=" . $failCount);
App::trace($this->circuitBreaker->serviceName . '服务,当前[关闭状态],服务失败次数达到上限,开始切换为开启状态,failCount=' . $failCount);
$this->circuitBreaker->switchToOpenState();
}

App::trace($this->circuitBreaker->serviceName . "服务,当前[关闭状态],failCount=" . $this->circuitBreaker->getFailCounter());
App::trace($this->circuitBreaker->serviceName . '服务,当前[关闭状态],failCount=' . $this->circuitBreaker->getFailCounter());
return $data;
}
}
29 changes: 20 additions & 9 deletions src/Circuit/HalfOpenState.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
<?php

/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @document https://doc.swoft.org
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/
namespace Swoft\Sg\Circuit;

use Swoft\App;
use Swoole\Coroutine\Client;
use Swoft\Pool\ConnectionInterface;

/**
* 半开状态及切换(half-open)
Expand Down Expand Up @@ -36,20 +44,23 @@ public function doCall($callback, $params = [], $fallback = null)

try {
if ($class === null) {
throw new \Exception($this->getServiceName() . "服务, 建立连接失败(null)");
throw new \Exception($this->getServiceName() . '服务, 建立连接失败(null)');
}

if ($class instanceof Client && $class->isConnected() == false) {
throw new \Exception($this->circuitBreaker->serviceName . "服务,当前连接已断开");
if (
($class instanceof Client && $class->isConnected() == false) ||
($class instanceof ConnectionInterface && $class->check() == false)
) {
throw new \Exception($this->circuitBreaker->serviceName . '服务,当前连接已断开');
}

$data = $class->$method(...$params);
$this->circuitBreaker->incSuccessCount();
App::trace($this->getServiceName() . "服务,当前[半开状态],尝试执行成");
App::trace($this->getServiceName() . '服务,当前[半开状态],尝试执行成');
} catch (\Exception $e) {
$this->circuitBreaker->incFailCount();
$data = $this->circuitBreaker->fallback($fallback);
App::error($this->getServiceName() . "服务,当前[半开状态],尝试执行失败, error=" . $e->getMessage());
App::error($this->getServiceName() . '服务,当前[半开状态],尝试执行失败, error=' . $e->getMessage());
}

$failCount = $this->circuitBreaker->getFailCounter();
Expand All @@ -59,18 +70,18 @@ public function doCall($callback, $params = [], $fallback = null)

if ($failCount >= $switchToFailCount && $this->circuitBreaker->isHalfOpen()) {
$this->circuitBreaker->switchToOpenState();
App::trace($this->getServiceName() . "服务,当前[半开状态],失败次数达到上限,开始切换到开启状态");
App::trace($this->getServiceName() . '服务,当前[半开状态],失败次数达到上限,开始切换到开启状态');
}

if ($successCount >= $switchToSuccessCount) {
$this->circuitBreaker->switchToCloseState();
App::trace($this->getServiceName() . "服务,当前[半开状态],成功次数达到上限,服务以及恢复,开始切换到关闭状态");
App::trace($this->getServiceName() . '服务,当前[半开状态],成功次数达到上限,服务以及恢复,开始切换到关闭状态');
}

// 释放锁
$lock->unlock();

App::trace($this->getServiceName() . "服务,当前[半开状态], failCount=" . $failCount . " successCount=" . $successCount);
App::trace($this->getServiceName() . '服务,当前[半开状态], failCount=' . $failCount . ' successCount=' . $successCount);

return $data;
}
Expand Down

0 comments on commit cb2a75a

Please sign in to comment.