• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

在windows使用docker环境搭建hyperf微服务

php 搞代码 4年前 (2022-02-28) 66次浏览 已收录 0个评论
文章目录[隐藏]

在windows应用docker环境搭建hyperf微服务

创立hyperf我的项目环境

docker run -d --name hyperfrpc -v d/dataproject/hyperfrpc:/hyperf-skeleton -p 9501:9501 -it --entrypoint /bin/sh hyperf/hyperf:7.4-alpine-v3.11-swoole

参数解释:

-d 示意在后盾运行

–name 示意给容器取个名字

-v 示意挂载到本机的目录

-p 示意映射到主机的端口,冒号前的是本机,前面是docker容器端口

-it 终端

–entrypoint 通过这个来笼罩dockerfile里定义的entrypoint

镜像容器运行后,而后进入容器中,在容器内装置 Composer

#下载composer.phar文件
wget https://github.com/composer/composer/releases/download/1.8.6/composer.phar
#给composer.phar文件加可执行权限
chmod u+x composer.phar
#挪动该文件到/usr/local/bin/composer
mv composer.phar /usr/local/bin/composer

将 Composer 镜像设置为阿里云镜像,减速国内下载速度

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer

通过 Composer 装置 hyperf/hyperf-skeleton 我的项目

composer create-project hyperf/hyperf-skeleton

进入装置好的 Hyperf 我的项目目录,linux目录

cd hyperf-skeleton

测试 Hyperf环境是否胜利

php bin/hyperf.php start

在powshell关上一个cli

docker exec -it hyperfrpc /bin/bash

进行测试

curl 127.0.0.1:9501

看到输入

{"method":"GET","message":"Hello Hyperf."}

环境胜利

在hyperf-skeleton目录下创立消费者和提供者

删除刚刚创立的hyperf我的项目

rm -rf hyperf-skeleton

创立provider

composer create-project hyperf/hyperf-skeleton hyperf-skeleton/provider

创立时,选项只抉择一个JSON-PRC with Service Governance,其余都选n

创立consumer

cd hyperf-skeleton

复制provider为consumer

cp -r provider consumer

在windows应用编辑器编辑provider

随便应用一个编辑器而后关上我的项目,目录是你创立docker容器时挂载的中央,咱们下面挂载了d/dataproject/hyperfrpc

咱们能够在目录看到存在provider、consumer

编写provider

咱们在app目录下创立一个文件夹,叫Rpc,在Rpc下创立CalculatorService和CalculatorServiceInterface

服务端口

CalculatorServiceInterface是服务接口

<?php
​
namespace AppRpc;
​
interface CalculatorServiceInterface
{
 public function add(int $a, int $b);
​
 public function minus(int $a, int $b);
}

服务实现类

CalculatorService就是咱们服务提供者的服务实现类,咱们只须要服务实现类上增加注解@RpcService就能够将服务公布

name,给服务起个名字

protocol,应用的协定,这里个别应用jsonrpc-http

server,绑定的server

<?php
namespace AppRpc;
​
use HyperfRpcServerAnnotationRpcService;
​
/**
 * Class CalculatorService
 * @package AppRpc
 * @RpcService(name="CalculatorService",protocol="jsonrpc-http",server="jsonrpc-http")
 */
class CalculatorService implements CalculatorServiceInterface
{
​
 public function add(int $a,int $b)
 {
 return $a+$b;
 }
 public function minus(int $a,int $b)
 {
 return $a-$b;
 }
}

增加对应server

接下来,咱们去config/autoload/server.php下,增加刚刚在注解@RpcService上写的server=“jsonrpc-http”的这个server

咱们找到servers

而后发现曾经存在一个name是http的server了,咱们复制一个name是http的server,之后增加在http这个server的上面,而后批改一下

咱们把name批改成jsonrpc-http

咱们把port批改成9502

咱们把callbacks批改一下,把HyperfHttpServerServer::class批改成HyperfJsonRpcHttpServer::class,如上面

'servers' => [
 [
 'name' => 'http',
 'type' => Server::SERVER_HTTP,
 'host' => '0.0.0.0',
 'port' => 9501,
 'sock_type' => SWOOLE_SOCK_TCP,
 'callbacks' => [
 Event::ON_REQUEST => [HyperfHttpServerServer::class, 'onRequest'],
 ],
 ],
 [
 'name' => 'jsonrpc-http',
 'type' => Server::SERVER_HTTP,
 'host' => '0.0.0.0',
 'port' => 9502,
 'sock_type' => SWOOLE_SOCK_TCP,
 'callbacks' => [
 Event::ON_REQUEST => [HyperfJsonRpcHttpServer::class, 'onRequest'],
 ],
 ],

编写consumer

咱们就在consumer我的项目的controller调用一下刚刚写的CalculatorService把。

对应接口

在调用之前咱们须要把服务接口从provider哪里复制一份过去

咱们在consumer的app目录下创立Rpc目录,在Rpc目录下创立刚刚复制的CalculatorServiceInterface

<?php
​
namespace AppRpc;
​
interface CalculatorServiceInterface
{
 public function add(int $a, int $b);
​
 public function minus(int $a, int $b);
}

应用controller调用

咱们就在IndexController外面的index办法调用服务,然而当初还无奈生产胜利,咱们还须要一些配置。

<?php
​
declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  [email protected]
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
namespace AppController;
​
​
​
use HyperfDiAnnotationInject;
​
class IndexController extends AbstractController
{
 /**
 * @Inject
 * @var AppRpcCalculatorServiceInterface
 */
 private $calculatorService;
​
 public function index()
 {
 return $this->calculatorService->add(1,2);
 }
}
​

创立services的配置文件

咱们须要去到/config/autoload目录下创立services.php文件,文件配置如下

<?php
​
​
use AppRpcCalculatorServiceInterface;
​
return [
 'consumers'=>[
 [
 'name'=>'CalculatorService',
 'service'=>CalculatorServiceInterface::class,
 'nodes'=>[
 ['host'=>'127.0.0.1','port'=>9502],
 ],
 ],
 ],
];

这个服务的name和咱们编写注解的name是统一的

服务的service对应consumer的CalculatorServiceInterface,

因为咱们没有应用注册核心,所以咱们间接应用节点地址,对应下面代码中的nodes

批改consumer的启用端口

因为consumer复制过去的,所以咱们须要批改一下端口

在/config/autoload下的server.php文件下

咱们找到server,定位到name是http的server,将端口批改成9503

'servers' => [
 [
 'name' => 'http',
 'type' => Server::SERVER_HTTP,
 'host' => '0.0.0.0',
 'port' => 9503,
 'sock_type' => SWOOLE_SOCK_TCP,
 'callbacks' => [
 Event::ON_REQUEST => [HyperfHttpServerServer::class, 'onRequest'],
 ],
 ],
 ],

consumer编写实现

启动provider

进入终端

cd hyperf-skeleton/
cd provider/
php bin/hyperf.php start

启动consumer

cd hyperf-skeleton/
cd consumer/
php bin/hyperf.php start

发动申请

在关上一个终端

curl 127.0.0.1:9503

咱们应该能够看到输入了

3

应用consul

咱们这里应用的是consul

咱们在终端provider目录试下装置hyperf的服务治理

composer hyperf/service-governance

装置consul组件

composer require hyperf/consul

公布一下对应的配置文件

php bin/hyperf.php vendor:publish hyperf/consul

咱们能够看到consul的配置文件就曾经生成胜利了

能够到cogfig/autoload目录下的consul.php文件查看

return [
 'uri' => 'http://127.0.0.1:8500',
 'token' => '',
];

默认是到本地的8500端口

下载并启动consul服务

#下载并解压consul
cd /opt/
​
mkdir consul
​
chmod 777 consul
​
cd consul
​
wget https://releases.hashicorp.com/consul/1.3.0/consul_1.3.0_linux_amd64.zip
​
unzip consul_1.3.0_linux_amd64.zip
​
cp consul /usr/local/bin/
​
#查看是否装置胜利
consul
​
consul version
​
#启动consul服务
consul agent -dev -ui -node=consul-dev -client=127.0.0.1
​
​
#3.再开一个终端,输出查看8500端口
curl 127.0.0.1:8500
#看见<a href="/ui/">Moved Permanently</a>.就胜利了

将provider的实现类注册进consul

在注解上增加publishTo=”consul”

<?php
​
namespace AppRpc;
​
use HyperfRpcServerAnnotationRpcService;
​
/**
 * Class CalculatorService
 * @package AppRpc
 * @RpcService(name="CalculatorService",protocol="jsonrpc-http",server="jsonrpc-http",publishTo="consul")
 */
class CalculatorService implements CalculatorServiceInterface
{
​
 public function add(int $a,int $b)
 {
 return $a+$b;
 }
 public function minus(int $a,int $b)
 {
 return $a-$b;
 }
}

将consumer的services批改

这里的services是config/autoload下的

<?php
​
​
use AppRpcCalculatorServiceInterface;
​
return [
 'consumers'=>[
 [
 'name'=>'CalculatorService',
 'service'=>CalculatorServiceInterface::class,
 'registry'=>[
 'protocol'=>'consul',
 'address'=>'http://127.0.0.1:8500',
 ],
//            'nodes'=>[
//                ['host'=>'127.0.0.1','port'=>9502],
//            ],
 ],
 ],
];

registry将去consul外面取服务,咱们须要先将nodes正文

重启provider

CTRL+C
php bin/hyperf.php start

重启consumer

CTRL+C
php bin/hyperf.php start

终端测试

curl 127.0.0.1:9503
#能够看到还是输入,咱们曾经把nodes正文了
3

服务熔断

为什么要熔断

分布式系统中常常会呈现因为某个根底服务不可用造成整个零碎不可用的状况,这种景象被称为服务雪崩效应。为了应答服务雪崩,一种常见的做法是服务降级。

比方咱们须要到另外服务中查问用户列表,用户列表须要关联很多的表,查问效率较低,但平时并发量不高的时候,响应速度还说得过去。一旦并发量激增,就会导致响应速度变慢,并会使对方服务呈现慢查。

在比方咱们进行一些Db查问的时候,须要查问多个表,在这种状况下,平时并发量不高的时候,相应速度还能够说得过去。一旦并发量激增得时候,就可能呈现服务不可用的状况,最初导致整个零碎都不可用,这种景象被称为服务雪崩效应。为了应答服务雪崩,一种常见的做法是服务降级。

降级是指本人的待遇降落了,从RPC调用环节来讲,就是去拜访一个本地的伪装者而不是实在的服务。

应用熔断器

熔断器的应用非常简略,只须要退出 HyperfCircuitBreakerAnnotationCircuitBreaker 注解,就能够依据规定策略,进行熔断。

这个时候,咱们只须要配置一下熔断超时工夫 timeout 为 0.05 秒,失败计数 failCounter 超过 1 次后熔断,相应 fallbackAppServiceUserService 类的 searchFallback 办法。这样当响应超时并触发熔断后,就不会再申请对端的服务了,而是间接将服务降级从以后我的项目中返回数据,即依据 fallback 指定的办法来进行返回。

创立应用熔断器的Service

咱们在服务提供者provider里的appService下创立一个UserService来进行应用,

首先,咱们先在APP目录下创立目录Service

而后再Service目录下创立UserService,具体如下:

<?php
​
namespace AppService;
use HyperfCircuitBreakerAnnotationCircuitBreaker;
​
class UserService
{
 /**
 * @return string[]
 * @CircuitBreaker(timeout="0.05",failCounter=1,successCounter=1,fallback="AppSerViceUserService::searchFallback")
 */
 public function search()
 {
 for ($i=1;$i<=3;$i++){
 sleep(1);
 $a=$i;
 print $a."n";
 }
 return [
 'message'=>"失常",
 ];
}
 public static function searchFallback()
 {
 return [
 'message'=>"流量过大,熔断",
 ];
 }
}

在咱们须要的服务上加上@CircuitBreaker这个注解就能够进行服务熔断了,接下来我阐明一下几个参数

timeout=”0.05″熔断超时工夫

failCounter=1失败记数,超过次数后熔断

successCounter=1胜利记数

fallback=”AppSerViceUserService::searchFallback”发送熔断后调用的办法

在控制器中应用

咱们编写一个控制器,就叫做UserController吧。

咱们在UserController中注入刚刚编写的UserService,我为了不便就没有形象成接口了

而后再UserController外面编写一个办法来调用UserService的办法

代码如下:

<?php
namespace AppController;
use HyperfCircuitBreakerAnnotationCircuitBreaker;
use HyperfDiAnnotationInject;
use HyperfHttpServerAnnotationAutoController;
use AppServiceUserService;
​
/**
 * Class UserController
 * @package AppController
 * @AutoController()
 */
class UserController extends AbstractController
{
 /**
 * @Inject
 * @var UserService
 */
 private $UserService;
​
 public function search()
 {
 return  $this->UserService->search();
 }
}

测试

因为咱们之前在创立docker绑定了9501,所以咱们在windows上能够用浏览器拜访9501端口

咱们关上浏览器

拜访,多刷新几次就能够看见服务熔断这个返回,或者你关上2个拜访窗口
`
127.0.0.1:9501/user/search
`
或者咱们能够在终端上拜访,不过须要屡次拜访

curl curl 127.0.0.1:9501/user/search
curl curl 127.0.0.1:9501/user/search
curl curl 127.0.0.1:9501/user/search

服务限流

限流的目标是通过对并发拜访/申请进行限速或者一个工夫窗口内的申请进行限速爱护零碎,一旦达到限度速率就能够拒绝服务(定向到谬误页或告知资源没有了),排队等待(比方秒杀、评论和下单)、降级(返回兜底数据和默认数据,如商品详情页默认有货)。 上面咱们将应用到令牌桶限流器。

装置

咱们先进入provider目录
`
composer require hyperf/rate-limit
`
公布配置

php bin/hyperf.php vendor:publish hyperf/rate-limit

应用

<?php
​
namespace AppController;
​
use HyperfDiAopProceedingJoinPoint;
use HyperfHttpServerAnnotationController;
use HyperfHttpServerAnnotationRequestMapping;
use HyperfRateLimitAnnotationRateLimit;
​
/**
 * @Controller(prefix="rate-limit")
 * @RateLimit(limitCallback={RateLimitController::class, "limitCallback"})
 */
class RateLimitController
{
 /**
 * @RequestMapping(path="test")
 * @RateLimit(create=1, capacity=3)
 */
 public function test()
 {
 return ["QPS 1, 峰值3"];
 }
 
 public static function limitCallback(float $seconds, ProceedingJoinPoint $proceedingJoinPoint)
 {
 // $seconds 下次生成Token 的距离, 单位为秒
 // $proceedingJoinPoint 此次申请执行的切入点
 // 能够通过调用 `$proceedingJoinPoint->process()` 继续执行或者自行处理
 echo "限流中";
 return $proceedingJoinPoint->process();
 }
}

create

1

每秒生成令牌数

consume

1

每次申请耗费令牌数

capacity

2

令牌桶最大容量

limitCallback

[]

触发限流时回调办法

waitTimeout

1

排队超时工夫

参考文档:

https://hyperf.wiki/2.1/#/zh-cn/microservice

https://www.gaodaima.com/weixin_40670060/article/details/109582821


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:在windows使用docker环境搭建hyperf微服务

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址