Swoft与Consul(四) - 微服务架构RPC通信
当我们的业务需求更高并发处理要求的时候,可以考虑微服务架构,
微服务可以基于不同业务模块拆分,比如商品服务、订单服务、会员服务,
不同的服务有可能部署在不同的机器上,分布式部署提供高并发、高可用的优势,
同时维护成本、容错、网络延迟、分布式事务等都是一个很大的挑战,这就需要根据实际需求来权衡。
参考:swoft微服务RPC Server
RPC 就用于调用者与服务之间的通讯,RPC 协议可基于 TCP、UDP 或者 HTTP 实现,但是更推荐TCP。
例如调用者需要调用商品服务就可以通过 RPC 或者 RESTful API 来调用,那么 RPC 和 RESTful API 区别?
TCP 支持长连接,当调用时不需要每次都进行三次握手。从性能和网络消耗来说 RPC 都具备了很好的优势。
RESTful API 基于 HTTP 的,也就是说每次调用服务都需要进行三次握手建立起通信才可以实现调用,
当我们的并发量高的时候这就会浪费很多带宽资源
服务对外的话采用 RESTful API 会比 RPC 更具备优势,因此看自己团队的服务是对内还是对外
http调用RPC实例思路:
1. 服务端swoft
首先新增一个接口用于定义和约束rpc服务提供的操作:
app\server\swoft\app\Rpc\Lib\GoodsInterface.php
<?php
namespace App\Rpc\Lib;
/**
* Class GoodsInterface
* @since 2.0
*/
interface GoodsInterface
{
/**
* @param int $id
* @param mixed $type
* @param int $count
*
* @return array
*/
public function getList(int $id, $type, int $count = 10): array;
}
?>
增加对应的提供服务的方法:
app\server\swoft\app\Rpc\Service\GoodsService.php
<?php
namespace App\Rpc\Service;
use App\Rpc\Lib\GoodsInterface;
use Swoft\Rpc\Server\Annotation\Mapping\Service;
/**
* Class GoodsService
*
* @since 2.0
*
* @Service()
*/
class GoodsService implements GoodsInterface
{
/**
* @param int $id
* @param mixed $type
* @param int $count
*
* @return array
*/
public function getList(int $id, $type, int $count = 10): array
{
return ['desc' => ['this is goodsService rpc server']];
}
}
?>
1. 客户端swoft
app\client\swoft\app\common\RpcProvider.php
<?php
namespace App\Common;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Bean\Annotation\Mapping\Inject;
use Swoft\Consul\Agent;
use Swoft\Consul\Exception\ClientException;
use Swoft\Consul\Exception\ServerException;
use Swoft\Rpc\Client\Client;
use Swoft\Rpc\Client\Contract\ProviderInterface;
/**
* Class RpcProvider
*
* @since 2.0
*
* @Bean()
*/
class RpcProvider implements ProviderInterface
{
/**
* @param Client $client
*
* @return array
* @throws ClientException
* @throws ServerException
* @example
* [
* 'host:port',
* 'host:port',
* 'host:port',
* ]
*/
public function getList(Client $client): array
{
// $services = $this->agent->services();
return [
// 商品服务信息 这里暂时可以写成固定的
'173.200.7.110:18307',
];
}
}
?>
swoft用于rpc通信的服务:
app\client\swoft\app\bean.php
<?php
use App\Common\RpcProvider;
return [
'user' => [
// ..
'provider' => bean(RpcProvider::class)
],
]
?>
在client中也需要提供GoodsInterface接口
app/Rpc/Lib/GoodsInterface.php
<?php
namespace App\Rpc\Lib;
/**
* Class GoodsInterface
*
* @since 2.0
*/
interface GoodsInterface
{
/**
* @param int $id
* @param mixed $type
* @param int $count
*
* @return array
*/
public function getList(int $id, $type, int $count = 10): array;
}
?>
可以不用提供GoodsServer,提供一个简单的controller;
app\client\swoft\app\Http\Controller\GoodsController.php
<?php
namespace App\Http\Controller;
use App\Rpc\Lib\GoodsInterface;
use Exception;
use Swoft\Co;
use Swoft\Http\Server\Annotation\Mapping\Controller;
use Swoft\Http\Server\Annotation\Mapping\RequestMapping;
use Swoft\Rpc\Client\Annotation\Mapping\Reference;
/**
* Class RpcController
*
* @since 2.0
*
* @Controller(prefix="/goods")
*/
class GoodsController
{
/**
* @Reference(pool="goods.pool")
*
* @var GoodsInterface
*/
private $goodsService;
/**
* @RequestMapping("getList")
*
* @return array
*/
public function getList(): array
{
$result = $this->goodsService->getList(12, 'type');
return [$result];
}
}
?>
3. 调用测试
重启client与server
client 启动命令: php bin/swoft http:start
server 启动命令: php bin/swoft rpc:start
通过以http的方式访问client的goodsController