阅读目录

我们说过,服务提供者可以提供各种服务,它可以和数据库进行交互;服务消费者是纯消费的服务,只需要远程访问服务提供者即可。

下面我们按步骤构建消费者模块。

源码已上传至github,https://github.com/bailangzhan/hyperf-rpc

1、构建服务消费者

除了对时区进行设置,其他的组件暂时都不安装,选择“n”即可。

composer create-project hyperf/hyperf-skeleton shop_consumer_user
Creating a "hyperf/hyperf-skeleton" project at "./shop_consumer_user"
Installing hyperf/hyperf-skeleton (v2.2.1)
- Installing hyperf/hyperf-skeleton (v2.2.1): Extracting archive
Created project in /data/web/test/hyperf-rpc/shop_consumer_user
> @php -r "file_exists('.env') || copy('.env.example', '.env');"
> Installer\Script::install
Setting up optional packages
Setup data and cache dir
Removing installer development dependencies
What time zone do you want to setup ?
[n] Default time zone for php.ini
Make your selection or type a time zone name, like Asia/Shanghai (n):
Asia/Shanghai
Do you want to use Database (MySQL Client) ?
[y] yes
[n] None of the above
Make your selection or type a composer package name and version (yes): n
Do you want to use Redis Client ?
[y] yes
[n] None of the above
Make your selection or type a composer package name and version (yes): n
Which RPC protocol do you want to use ?
[1] JSON RPC with Service Governance
[2] JSON RPC
[3] gRPC
[n] None of the above
Make your selection or type a composer package name and version (n): n
Which config center do you want to use ?
[1] Apollo
[2] Aliyun ACM
[3] ETCD
[4] Nacos
[n] None of the above
Make your selection or type a composer package name and version (n): n
Do you want to use hyperf/constants component ?
[y] yes
[n] None of the above
Make your selection (n): n
Do you want to use hyperf/async-queue component ? (A simple redis queue component)
[y] yes
[n] None of the above
Make your selection or type a composer package name and version (n): n
Do you want to use hyperf/amqp component ?
[y] yes
[n] None of the above
Make your selection or type a composer package name and version (n): n
Do you want to use hyperf/model-cache component ?
[y] yes
[n] None of the above
Make your selection or type a composer package name and version (n): n
Do you want to use hyperf/elasticsearch component ?
[y] yes
[n] None of the above
Make your selection or type a composer package name and version (n): n
Do you want to use hyperf/tracer component ? (An open tracing protocol component, adapte with Zipkin etc.)
[y] yes
[n] None of the above
Make your selection or type a composer package name and version (n): n

2、安装json rpc依赖

cd shop_consumer_user
composer require hyperf/json-rpc

3、安装 JSON RPC 客户端

shop_consumer_user 不需要对外提供服务,所以我们只安装客户端,不需要安装hyperf/rpc-server组件

composer require hyperf/rpc-client

4、server配置

server的配置这里用默认的就好了,9501端口提供http服务,不需要改动

'servers' => [
[
'name' => 'http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9501,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
],
],
],

5、编写业务代码

5-1、编写服务消费者类

app下新建JsonRpc目录,编写UserService.php和UserServiceInterface.php文件

【UserServiceInterface.php】

<?php
namespace App\JsonRpc;
interface UserServiceInterface
{
public function createUser(string $name, int $gender);
public function getUserInfo(int $id);
}
<span class="redactor-invisible-space"> </span>【UserService.php】 <?php
namespace App\JsonRpc;
use Hyperf\RpcClient\AbstractServiceClient;
class UserService extends AbstractServiceClient implements UserServiceInterface
{
/**
* 定义对应服务提供者的服务名称
* @var string
*/
protected $serviceName = 'UserService';
/**
* 定义对应服务提供者的服务协议
* @var string
*/
protected $protocol = 'jsonrpc-http';
/**
* @param string $name
* @param int $gender
* @return mixed
*/
public function createUser(string $name, int $gender)
{
return $this->__request(__FUNCTION__, compact('name', 'gender'));
}
/**
* @param int $id
* @return mixed
*/
public function getUserInfo(int $id)
{
return $this->__request(__FUNCTION__, compact('id'));
}
}

hyperf 官方的hyperf/rpc-client组件已经帮我们实现了rpc远程调用的实现,所以我们只需要再配置一下服务消费者,告诉hyperf从哪个节点哪个端口调用即可。

5-2、consumer配置

config/autoload/services.php内定义consumers如下:(没有services.php文件的可以自行创建)

<?php
return [
'consumers' => [
[
// 对应消费者类的 $serviceName
'name' => 'UserService',
// 直接对指定的节点进行消费,通过下面的 nodes 参数来配置服务提供者的节点信息
'nodes' => [
['host' => '127.0.0.1', 'port' => 9600],
],
]
],
];

5-3、配置 UserServiceInterface

为了可以方便的注入 UserServiceInterface,我们在 config/autoload/dependencies.php 内定义 UserServiceInterface 和 UserService 的关系如下:

App\JsonRpc\UserServiceInterface::class => App\JsonRpc\UserService::class,

5-4、编写UserController,实现获取用户和创建用户的接口调用

【app\Controller\UserController.php】

<?php
declare(strict_types=1);
namespace App\Controller;
use App\JsonRpc\UserServiceInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\AutoController;
/**
* Class UserController
* @package App\Controller
* @AutoController()
*/
class UserController extends AbstractController
{
/**
* @Inject()
* @var UserServiceInterface
*/
private $userServiceClient;
public function createUser()
{
$name = (string) $this->request->input('name', '');
$gender = (int) $this->request->input('gender', 0);
return $this->userServiceClient->createUser($name, $gender);
}
public function getUserInfo()
{
$id = (int) $this->request->input('id');
return $this->userServiceClient->getUserInfo($id);
}
}

6、postman访问测试

启动shop_consumer_user项目的同时,务必要保证 shop_provider_user 也启动了,不然请求会失败。

7、自动配置服务消费者

你可能已经注意到 app\JsonRpc\UserService 类的方法并没有实际意义,只是构建参数发起请求并返回响应结果,千篇一律的操作着实增加了复杂度。hyperf支持自动配置服务消费者代理类(生产者暂不支持自动配置)。

自动配置非常简单,只需要在 consumer 配置项增加service配置即可,如下:

return [
'consumers' => [
[
// 对应消费者类的 $serviceName
'name' => 'UserService',
// 服务接口名,可选,默认值等于 name 配置的值,如果 name 直接定义为接口类则可忽略此行配置,
// 如 name 为字符串则需要配置 service 对应到接口类
'service' => \App\JsonRpc\UserServiceInterface::class,
// 直接对指定的节点进行消费,通过下面的 nodes 参数来配置服务提供者的节点信息
'nodes' => [
['host' => '127.0.0.1', 'port' => 9600],
],
]
],
];

现在我们做两件事,测试consumer走的是自动配置还是手动创建的UserService

  1. 把 config/autoload/dependencies.php 内定义 UserServiceInterface 和 UserService 的关系屏蔽
  2. 在 App\JsonRpc\UserService::getUserInfo() 方法内打印点数据测试
GET请求 http://127.0.0.1:9501/user/getUserInfo?id=2
结果发现控制台并没有任何输出,走的是自动配置的consumer

反过来

  1. 我们再把 config/autoload/dependencies.php 内定义 UserServiceInterface 和 UserService 的关系放开
  2. 把 config/autoload/services.php 文件内 consumers 的配置项 service 屏蔽
GET请求 http://127.0.0.1:9501/user/getUserInfo?id=2
string(36) "App\JsonRpc\UserService::getUserInfo"
发现控制台输出了我们在 App\JsonRpc\UserService::getUserInfo() 方法内打印的数据,
走的是手动创建的consumer

在没有特殊情况下,后续consumer我们仅做配置,不在手动创建,因为没有创建的必要。

8、配置优化

我们注意到 config/autoload/services.php 文件内 consumers 的配置,一个服务是一个配置,服务消费者需要消费的服务可能很多,所以我们很有必要优化下这里的写法,下面是参考官网的写法:

// 服务定义
$consumerServices = [
'UserService' => \App\JsonRpc\UserServiceInterface::class,
];
return [
'consumers' => value(function () use ($consumerServices) {
$consumers = [];
foreach ($consumerServices as $name => $interface) {
$consumers[] = [
'name' => $name,
'service' => $interface,
'nodes' => [
['host' => '127.0.0.1', 'port' => 9600],
],
];
}
return $consumers;
}),
];

这样一来,我们每次只需要在数组 $consumerServices 内添加需要新的服务即可。

最后,我们来看一个比较大的问题。

consumer拿到的结果,又是字符串又是对象,还动不动直接 Internal Server Error. 数据格式的不统一非常不利于前端小伙伴解析。

统一结果处理

为了规范,我们制定了一个简单的标准,统一返回带有code,message,data的数据格式,有兴趣的小伙伴可以先研究下怎么解决这个问题,我们下一节继续。

hyperf从零开始构建微服务(二)——构建服务消费者的更多相关文章

  1. .net core编写转发服务(二) 添加服务发布订阅

    源设计就单纯完成了把服务转发到特定的服务模块,一定程度上解耦了业务流程 但是我们实际开发过程中会面临服务转发后还有一些列关联的服务 举个例子 你调用了发送邮件的服务,接下来会面临扣费的服务,扣费之后会 ...

  2. hyperf从零开始构建微服务(一)——构建服务提供者

    阅读目录 什么是服务 构建服务提供者 1.创建数据表 2.构建服务提供者 3.安装json rpc依赖 4.安装rpc server组件 5.修改server配置 6.配置数据库 7.编写基础代码 7 ...

  3. Kubernetes实战 - 从零开始搭建微服务 1 - 使用kind构建一个单层架构Node/Express网络应用程序

    使用kind构建一个单层架构Node/Express网络应用程序 Kubernetes实战-从零开始搭建微服务 1 前言 准备写一个Kubernetes实战系列教程,毕竟cnblogs作为国内最早的技 ...

  4. Spring Cloud构建微服务架构(二)服务消费者

    Netflix Ribbon is an Inter Process Communication (IPC) cloud library. Ribbon primarily provides clie ...

  5. 微服务系列(二):使用 API 网关构建微服务

    编者的话|本文来自 Nginx 官方博客,是微服务系列文章的第二篇,本文将探讨:微服务架构是如何影响客户端到服务端的通信,并提出一种使用 API 网关的方法. 作者介绍:Chris Richardso ...

  6. 构建微服务(Building Microservices)-PDF 文档

    闲时翻译了几篇基于Spring Cloud.Netflix OSS 构建微服务的英文文章,为方便分享交流,整理为PDF文档. PDF 文档目录: 目录 一.微服务操作模型... 3 1.     前提 ...

  7. Spring-Boot:Spring Cloud构建微服务架构

    概述: 从上一篇博客<Spring-boot:5分钟整合Dubbo构建分布式服务> 过度到Spring Cloud,我们将开始学习如何使用Spring Cloud 来搭建微服务.继续采用上 ...

  8. Spring Cloud构建微服务架构

    Dalston版本 由于Brixton和Camden版本的教程已经停止更新,所以笔者计划在2017年上半年完成Dalston版本的教程编写(原计划完成Camden版本教程,但由于写了两篇Dalston ...

  9. 0102-使用 API 网关构建微服务

    一.移动客户端如何访问这些服务 1.1.客户端与微服务直接通信[很少使用] 从理论上讲,客户端可以直接向每个微服务发送请求.每个微服务都有一个公开的端点(https ://.api.company.n ...

  10. Spring Cloud构建微服务架构(三)消息总线

     注:此文不适合0基础学习者直接阅读,请先完整的将作者关于微服务的博文全部阅读一遍,如果还有疑问,可以再来阅读此文,地址:http://blog.csdn.net/sosfnima/article/d ...

随机推荐

  1. Java架构师-十项全能学习笔记(1)

    Java架构师-十项全能学习笔记(1) @Configuration @EnableStateMachine public class OrderStateMachineConfig extends ...

  2. Docker部署Zookeeper部署实践(1)

    Zookeeper可提供的服务主要有:配置服务.名字服务.分布式同步.组服务等 1. 抓取Zookeeper镜像 命令:docker pull zookeeper 2. 将Zookeeper镜像保存为 ...

  3. Linux线程属性总结(一)

    线程属性标识符:pthread_attr_t 包含在 pthread.h 头文件中. [c] view plaincopy //线程属性结构如下: typedef struct { int       ...

  4. nat转换技术,且用且珍惜

    一.NAT转换技术 1.1.NAT技术概述 随着Internet的发展和网络应用的增多,IPv4地址枯竭已经成为制约网络发展的瓶颈.尽管IPv6可以从根本上解决IPv4地址空间不足的问题,但目前众多的 ...

  5. SWAP的罪与罚&&NUMA的取舍

    说个案例:一台Apache服务器,由于其MaxClients参数设置过大,并且恰好又碰到访问量激增,结果内存被耗光,从而引发SWAP,进而负载攀升,最终导致宕机. 正所谓:SWAP,性能之大事,死生之 ...

  6. minio设置永久访问链接

    1.通过minio分享的链接只能支持7天. 解决方案是设置对应的bucket 可通过路径直接访问.(必须通过minio client才能设置下载策略) wget https://dl.min.io/c ...

  7. JavaSE-基础语法

    注释 单行注释: //注释 多行注释: /*注释*/ 文档注释: /** 文档注释 */ 标识符与关键字 下图为Java中所有的关键字 所有标识符必须以大小写字母或$或_开头,首字母之后可以用数字 不 ...

  8. VLAN-4 单臂路由实现vlan之间路由

    一.实验拓扑图 二.实验编址 三.实验步骤 1.给对应的PC设置对应的IP和掩码还有接口,以及根据需要划分不同的vlan区域,再用文本标记出不同部门. 2. 启动设备(全选) 3.创建vlan并配置a ...

  9. 前端从😳 到🚪 gRPC 框架

    RPC 是什么? RPC 英文全称是 Remote Procedure Call 既远程过程调用,维基百科中给的定义是一个计算机调用了一个函数,但这个函数并不在这台计算机上,这种远程调用方式程序员无需 ...

  10. STP规则

    1)每个网络的有且只有一个桥根 2)每个非桥根有且只有一个根端口: 3)每条链路有且只有一个指定端口: 4)根桥的所有端口均为指定端口: 5)根端口和指定端口都是forwading: 6)阻塞端口为B ...