Merge branch 'master' into master

This commit is contained in:
黄朝晖 2019-07-17 12:00:55 +08:00 committed by GitHub
commit 767443855a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 146 additions and 70 deletions

View File

@ -9,17 +9,17 @@ sudo: required
matrix:
include:
- php: 7.2
env: SW_VERSION="4.3.5"
env: SW_VERSION="4.3.6"
- php: 7.2
env: SW_VERSION="4.4.0"
env: SW_VERSION="4.4.1"
- php: 7.3
env: SW_VERSION="4.3.5"
env: SW_VERSION="4.3.6"
- php: 7.3
env: SW_VERSION="4.4.0"
env: SW_VERSION="4.4.1"
- php: master
env: SW_VERSION="4.3.5"
env: SW_VERSION="4.3.6"
- php: master
env: SW_VERSION="4.4.0"
env: SW_VERSION="4.4.1"
allow_failures:
- php: master

View File

@ -1,10 +1,15 @@
# v1.0.5 - TBD
# v1.0.6 - TBD
# v1.0.5 - 2019-07-07
## Added
- [#185](https://github.com/hyperf-cloud/hyperf/pull/185) [#224](https://github.com/hyperf-cloud/hyperf/pull/224) Added support for xml format of response.
- [#202](https://github.com/hyperf-cloud/hyperf/pull/202) Added trace message when throw a uncaptured exception in function `go`.
- [#138](https://github.com/hyperf-cloud/hyperf/pull/138) [#197](https://github.com/hyperf-cloud/hyperf/pull/197) Added crontab component.
# Changed
## Changed
- [#195](https://github.com/hyperf-cloud/hyperf/pull/195) Changed the behavior of parameter `$times` of `retry()` function, means the retry times of the callable function.
- [#198](https://github.com/hyperf-cloud/hyperf/pull/198) Optimized `has()` method of `Hyperf\Di\Container`, if pass a un-instantiable object (like an interface) to `$container->has($interface)`, the method result is `false` now.
@ -15,6 +20,8 @@
- [#176](https://github.com/hyperf-cloud/hyperf/pull/176) Fixed TypeError: Return value of LengthAwarePaginator::nextPageUrl() must be of the type string or null, none returned.
- [#188](https://github.com/hyperf-cloud/hyperf/pull/188) Fixed proxy of guzzle client does not work expected.
- [#211](https://github.com/hyperf-cloud/hyperf/pull/211) Fixed rpc client will be replaced by the latest one.
- [#212](https://github.com/hyperf-cloud/hyperf/pull/212) Fixed config `ssl_key` and `cert` of guzzle client does not work expected.
# v1.0.4 - 2019-07-08
@ -23,12 +30,12 @@
- [#140](https://github.com/hyperf-cloud/hyperf/pull/140) Support Swoole v4.4.0.
- [#163](https://github.com/hyperf-cloud/hyperf/pull/163) Added custom arguments support to AbstractConstants::__callStatic in `hyperf/constants`.
# Changed
## Changed
- [#124](https://github.com/hyperf-cloud/hyperf/pull/124) Added `$delay` parameter for `DriverInterface::push`, and marked `DriverInterface::delay` method to deprecated.
- [#125](https://github.com/hyperf-cloud/hyperf/pull/125) Changed the default value of parameter $default of config() function to null.
# Fixed
## Fixed
- [#110](https://github.com/hyperf-cloud/hyperf/pull/110) [#111](https://github.com/hyperf-cloud/hyperf/pull/111) Fixed Redis::select is not work expected.
- [#131](https://github.com/hyperf-cloud/hyperf/pull/131) Fixed property middlewares not work in `Router::addGroup`.
@ -40,7 +47,7 @@
- [#169](https://github.com/hyperf-cloud/hyperf/pull/169) Fixed array parse failed when handle http request.
- [#170](https://github.com/hyperf-cloud/hyperf/pull/170) Fixed websocket server interrupt when request a not exist route.
# Removed
## Removed
- [#131](https://github.com/hyperf-cloud/hyperf/pull/131) Removed `server` property from Router options.

View File

@ -84,7 +84,7 @@
"hyperf/server": "self.version",
"hyperf/service-governance": "self.version",
"hyperf/swagger": "self.version",
"hyperf/swoole-dashboard": "self.version",
"hyperf/swoole-enterprise": "self.version",
"hyperf/tracer": "self.version",
"hyperf/utils": "self.version",
"hyperf/websocket-client": "self.version",
@ -134,7 +134,7 @@
"Hyperf\\Server\\": "src/server/src/",
"Hyperf\\ServiceGovernance\\": "src/service-governance/src/",
"Hyperf\\Swagger\\": "src/swagger/src/",
"Hyperf\\SwooleDashboard\\": "src/swoole-dashboard/src/",
"Hyperf\\SwooleEnterprise\\": "src/swoole-enterprise/src/",
"Hyperf\\Tracer\\": "src/tracer/src/",
"Hyperf\\Utils\\": "src/utils/src/",
"Hyperf\\WebSocketClient\\": "src/websocket-client/src/",
@ -148,7 +148,7 @@
"HyperfTest\\Constants\\": "./src/constants/tests/",
"HyperfTest\\Consul\\": "./src/consul/tests/",
"HyperfTest\\Di\\": "./src/di/tests/",
"HyperfTest\\Dispatcher\\": "./src/dispatcher/test/",
"HyperfTest\\Dispatcher\\": "./src/dispatcher/tests/",
"HyperfTest\\Database\\": "./src/database/tests/",
"HyperfTest\\DbConnection\\": "./src/db-connection/tests/",
"HyperfTest\\Event\\": "./src/event/tests/",
@ -158,7 +158,7 @@
"HyperfTest\\ModelCache\\": "./src/model-cache/tests/",
"HyperfTest\\Paginator\\": "./src/paginator/tests/",
"HyperfTest\\Redis\\": "./src/redis/tests/",
"HyperfTest\\SwooleDashboard\\": "./src/swoole-dashboard/tests/",
"HyperfTest\\SwooleEnterprise\\": "./src/swoole-enterprise/tests/",
"HyperfTest\\Utils\\": "./src/utils/tests/",
"HyperfTest\\WebSocketClient\\": "src/websocket-client/tests/",
"HyperfTest\\WebSocketServer\\": "src/websocket-server/tests/"

View File

@ -73,7 +73,7 @@
* [开发者工具](zh/devtool.md)
* [辅助类](zh/utils.md)
* [限流器](zh/rate-limit.md)
* [Swoole Dashboard](zh/swoole-dashboard.md)
* [Swoole Enterprise](zh/swoole-enterprise.md)
* [计划任务](zh/crontab.md)
* 应用部署

View File

@ -43,7 +43,7 @@ git clone git@github.com:hyperf-cloud/hyperf.git
"hyperf": {
"type": "path",
"url": "../hyperf/src/*"
}
},
"packagist": {
"type": "composer",
"url": "https://mirrors.aliyun.com/composer"

View File

@ -49,6 +49,7 @@ return [
'default' => [
'driver' => env('DB_DRIVER', 'mysql'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', 3306),
'database' => env('DB_DATABASE', 'hyperf'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
@ -76,6 +77,7 @@ return [
'default' => [
'driver' => env('DB_DRIVER', 'mysql'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', 3306),
'database' => env('DB_DATABASE', 'hyperf'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),

View File

@ -121,9 +121,9 @@ $log->alert('czl');
- 首先, 实例化一个 `Logger`, 取个名字, 名字对应的就是 `channel`
- 可以为 `Logger` 绑定多个 `Handler`, `Logger` 打日志, 交由 `Handler` 来处理
- `Handler` 可以指定需要处理**日志级别** 的日志, 比如 `Logger::WARNING`, 只处理日志级别 `>=Logger::WARNING` 的日志
- `Handler` 可以指定需要处理**日志级别** 的日志, 比如 `Logger::WARNING`, 只处理日志级别 `>=Logger::WARNING` 的日志
- 谁来格式化日志? `Formatter`, 设置好 Formatter 并绑定到相应的 `Handler`
- 日志包含些部分: `"%datetime%||%channel||%level_name%||%message%||%context%||%extra%\n"`
- 日志包含些部分: `"%datetime%||%channel||%level_name%||%message%||%context%||%extra%\n"`
- 区分一下日志中添加的额外信息 `context``extra`: `context` 由用户打日志时额外指定, 更加灵活; `extra` 由绑定到 `Logger` 上的 `Processor` 固定添加, 比较适合收集一些 **常见信息**
## 更多用法
@ -138,34 +138,16 @@ namespace App;
use Hyperf\Logger\Logger;
use Hyperf\Utils\ApplicationContext;
/**
* @method static Logger get($name)
* @method static void log($level, $message, array $context = array())
* @method static void emergency($message, array $context = array())
* @method static void alert($message, array $context = array())
* @method static void critical($message, array $context = array())
* @method static void error($message, array $context = array())
* @method static void warning($message, array $context = array())
* @method static void notice($message, array $context = array())
* @method static void info($message, array $context = array())
* @method static void debug($message, array $context = array())
*/
class Log
{
public static function __callStatic($name, $arguments)
public static function get(string $name = 'app')
{
$container = ApplicationContext::getContainer();
$factory = $container->get(\Hyperf\Logger\LoggerFactory::class);
if ($name === 'get') {
return $factory->get(...$arguments);
}
$log = $factory->get('default');
$log->$name(...$arguments);
return ApplicationContext::getContainer()->get(\Hyperf\Logger\LoggerFactory::class)->get($name);
}
}
```
默认使用 `default` 的 `Channel` 来记录日志,您也可以通过使用 `Log::get($name)` 方法获得不同 `Channel``Logger`, 强大的 `容器(Container)` 帮您解决了这一切
默认使用 `Channel` 名为 `app` 来记录日志,您也可以通过使用 `Log::get($name)` 方法获得不同 `Channel``Logger`, 强大的 `容器(Container)` 帮您解决了这一切
### stdout 日志

View File

@ -1,12 +1,19 @@
# Swoole Dashboard
# Swoole Enterprise
[dashboard](https://www.swoole-cloud.com/dashboard.html) 作为 `Swoole` 官方出品、更专一、更专业。
[Swoole Enterprise](https://www.swoole-cloud.com/dashboard.html) 作为 `Swoole` 官方出品的一款企业级应用解决方案,更专一、更专业。
- 时刻掌握应用架构模型
> 自动发现应用依赖拓扑结构和展示,时刻掌握应用的架构模型
- 分布式跨应用链路追踪
- 完善的系统监控
- 零成本接入
> 支持无侵入的分布式跨应用链路追踪,让每个请求一目了然,全面支持协程/非协程环境,数据实时可视化
- 全面分析报告服务状况
> 各种维度统计服务上报的调用信息, 比如总流量、平均耗时、超时率等,并全面分析报告服务状况
- 拥有强大的调试工具链
> 系统支持远程调试,可远程开启检测内存泄漏、阻塞检测和代码性能分析
- 完善的系统监控
> 支持完善的系统监控零成本部署监控机器的CPU、内存、网络、磁盘等资源可以很方便的集成到现有报警系统
- 零成本接入系统
> Swoole Enterprise系统客户端脚本一键部署服务端可在Docker环境中运行简单快捷
## 安装
@ -29,15 +36,15 @@ php /opt/www/bin/hyperf.php start
```
swoole-tracker.ini
swoole-plus.ini
```bash
[swoole_tracker]
extension=/opt/swoole_tracker.so
[swoole_plus]
extension=/opt/swoole_plus.so
apm.enable=1 #打开总开关
apm.sampling_rate=100 #采样率 例如100%
# 手动埋点时再添加
# 支持远程调试;需要手动埋点时再添加
apm.enable_xhprof=1 #开启性能分析功能 默认0 即为关闭模式
apm.enable_memcheck=1 #开启内存泄漏检测 默认0 关闭
```
@ -90,8 +97,8 @@ WORKDIR /opt/www/.build
# 这里的地址,以客户端中显示的为准
RUN ./deploy_env.sh www.swoole-cloud.com \
&& chmod 755 entrypoint.sh \
&& cp swoole_tracker72.so /opt/swoole_tracker.so \
&& cp swoole-tracker.ini /etc/php7/conf.d/swoole-tracker.ini \
&& cp swoole_plus72.so /opt/swoole_plus.so \
&& cp swoole-plus.ini /etc/php7/conf.d/swoole-plus.ini \
&& php -m
WORKDIR /opt/www
@ -110,7 +117,7 @@ ENTRYPOINT ["sh", ".build/entrypoint.sh"]
首先安装一下对应组件
```bash
composer require hyperf/swoole-dashboard dev-master
composer require hyperf/swoole-enterprise dev-master
```
然后将以下 `Middleware` 写到 `middleware.php` 中。
@ -120,7 +127,7 @@ composer require hyperf/swoole-dashboard dev-master
return [
'http' => [
Hyperf\SwooleDashboard\Middleware\HttpServerMiddleware::class
Hyperf\SwooleEnterprise\Middleware\HttpServerMiddleware::class
],
];

View File

@ -23,16 +23,18 @@ cp /etc/supervisord.conf /etc/supervisord.d/supervisord.conf
```ini
# 新建一个应用并设置一个名称,这里设置为 hyperf
[program:hyperf]
# 这里为您要管理的项目的启动命令,对应您的项目的真实路径
command=php /var/www/hyperf/bin/hyperf.php start
# 设置命令在指定的目录内执行
directory=/var/www/hyperf/
# 这里为您要管理的项目的启动命令
command=php ./bin/hyperf.php start
# 以哪个用户来运行该进程
user=root
# supervisor 启动时自动该应用
autostart=true
# 进程退出后自动重启进程
autorestart=true
# 重试间隔秒数
startsecs=5
# 进程持续运行多久才认为是启动成功
startsecs=1
# 重试次数
startretries=3
# stderr 日志输出位置
@ -60,4 +62,8 @@ supervisorctl restart hyperf
supervisorctl stop hyperf
# 查看所有被管理项目运行状态
supervisorctl status
# 重新加载配置文件
supervisorctl update
# 重新启动所有程序
supervisorctl reload
```

View File

@ -16,6 +16,7 @@
<directory suffix="Test.php">./src/database/tests</directory>
<directory suffix="Test.php">./src/db-connection/tests</directory>
<directory suffix="Test.php">./src/di/tests</directory>
<directory suffix="Test.php">./src/dispatcher/tests</directory>
<directory suffix="Test.php">./src/elasticsearch/tests</directory>
<directory suffix="Test.php">./src/event/tests</directory>
<directory suffix="Test.php">./src/guzzle/tests</directory>

View File

@ -36,7 +36,7 @@
},
"autoload-dev": {
"psr-4": {
"HyperfTest\\Dispatcher\\": "test"
"HyperfTest\\Dispatcher\\": "tests"
}
},
"config": {

View File

@ -10,7 +10,7 @@
stopOnFailure="false">
<testsuites>
<testsuite name="Tests">
<directory suffix="Test.php">./test</directory>
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<filter>

View File

@ -12,11 +12,11 @@ declare(strict_types=1);
namespace HyperfTest\Dispatcher;
use App\Middleware\TestMiddleware;
use Hyperf\Dispatcher\HttpDispatcher;
use Hyperf\HttpMessage\Server\Response;
use Hyperf\Utils\Context;
use HyperfTest\Dispatcher\Middlewares\CoreMiddleware;
use HyperfTest\Dispatcher\Middlewares\TestMiddleware;
use PHPUnit\Framework\TestCase;
use Prophecy\Prophecy\ProphecyInterface;
use Psr\Container\ContainerInterface;

View File

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact group@hyperf.io
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
*/
namespace HyperfTest\Dispatcher\Middlewares;
use Hyperf\Utils\Context;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class TestMiddleware implements MiddlewareInterface
{
/**
* Process an incoming server request and return a response, optionally delegating
* response creation to a handler.
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
/** @var ResponseInterface $response */
$response = Context::get(ResponseInterface::class);
return $response->withAddedHeader('Server', 'Hyperf');
}
}

View File

@ -142,6 +142,10 @@ class CoroutineHandler
}
}
// SSL KEY
isset($options['ssl_key']) && $settings['ssl_key_file'] = $options['ssl_key'];
isset($options['cert']) && $settings['ssl_cert_file'] = $options['cert'];
// Swoole Setting
if (isset($options['swoole']) && is_array($options['swoole'])) {
$settings = array_replace($settings, $options['swoole']);

View File

@ -148,6 +148,33 @@ class CoroutineHandlerTest extends TestCase
$this->assertSame('pass', $setting['http_proxy_password']);
}
public function testSslKeyAndCert()
{
$client = new Client([
'base_uri' => 'http://127.0.0.1:8080',
'handler' => HandlerStack::create(new CoroutineHandlerStub()),
'timeout' => 5,
'cert' => 'apiclient_cert.pem',
'ssl_key' => 'apiclient_key.pem',
]);
$data = json_decode($client->get('/')->getBody()->getContents(), true);
$this->assertSame('apiclient_cert.pem', $data['setting']['ssl_cert_file']);
$this->assertSame('apiclient_key.pem', $data['setting']['ssl_key_file']);
$client = new Client([
'base_uri' => 'http://127.0.0.1:8080',
'handler' => HandlerStack::create(new CoroutineHandlerStub()),
'timeout' => 5,
]);
$data = json_decode($client->get('/')->getBody()->getContents(), true);
$this->assertArrayNotHasKey('ssl_cert_file', $data['setting']);
$this->assertArrayNotHasKey('ssl_key_file', $data['setting']);
}
public function testUserInfo()
{
$url = 'https://username:password@127.0.0.1:8080';

View File

@ -98,7 +98,7 @@ abstract class AbstractServiceClient
$this->dataFormatter = $this->createDataFormatter();
$loadBalancer = $this->createLoadBalancer(...$this->createNodes());
$transporter = $this->createTransporter()->setLoadBalancer($loadBalancer);
$this->client = $this->container->get(Client::class)
$this->client = make(Client::class)
->setPacker($this->createPacker())
->setTransporter($transporter);
}
@ -139,7 +139,7 @@ abstract class AbstractServiceClient
throw new InvalidArgumentException(sprintf('Transporter %s is not exists.', $transporter));
}
/* @var TransporterInterface $instance */
return $this->container->get($transporter);
return make($transporter);
}
protected function createPacker(): PackerInterface

View File

@ -1,12 +1,12 @@
{
"name": "hyperf/swoole-dashboard",
"name": "hyperf/swoole-enterprise",
"description": "A swoole dashboard library for Hyperf.",
"license": "MIT",
"keywords": [
"php",
"swoole",
"hyperf",
"swoole-dashboard"
"swoole-enterprise"
],
"support": {
},
@ -31,7 +31,7 @@
"files": [
],
"psr-4": {
"Hyperf\\SwooleDashboard\\": "src"
"Hyperf\\SwooleEnterprise\\": "src"
}
},
"autoload-dev": {
@ -46,7 +46,7 @@
"dev-master": "1.0-dev"
},
"hyperf": {
"config": "Hyperf\\SwooleDashboard\\ConfigProvider"
"config": "Hyperf\\SwooleEnterprise\\ConfigProvider"
}
},
"bin": [

View File

@ -10,7 +10,7 @@ declare(strict_types=1);
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
*/
namespace Hyperf\SwooleDashboard;
namespace Hyperf\SwooleEnterprise;
class ConfigProvider
{

View File

@ -10,7 +10,7 @@ declare(strict_types=1);
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
*/
namespace Hyperf\SwooleDashboard\Middleware;
namespace Hyperf\SwooleEnterprise\Middleware;
use Hyperf\Contract\ConfigInterface;
use Psr\Http\Message\ResponseInterface;

View File

@ -13,6 +13,7 @@ declare(strict_types=1);
namespace Hyperf\Utils;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\ExceptionHandler\Formatter\FormatterInterface;
use Psr\Log\LoggerInterface;
use Swoole\Coroutine as SwooleCoroutine;
use Throwable;
@ -63,10 +64,16 @@ class Coroutine
if ($container->has(StdoutLoggerInterface::class)) {
/* @var LoggerInterface $logger */
$logger = $container->get(StdoutLoggerInterface::class);
/* @var FormatterInterface $formmater */
if ($container->has(FormatterInterface::class)) {
$formmater = $container->get(FormatterInterface::class);
$logger->warning($formmater->format($throwable));
} else {
$logger->warning(sprintf('Uncaptured exception[%s] detected in %s::%d.', get_class($throwable), $throwable->getFile(), $throwable->getLine()));
}
}
}
}
});
return is_int($result) ? $result : -1;
}