阅读目录

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

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

源码已上传至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. alpakka-kafka(6)-kafka应用案例,用户接口

    了解了kafka原理之后,对kafka的的应用场景有了一些想法.在下面的一系列讨论中把最近一个项目中关于kafka的应用介绍一下. 先介绍一下使用kafka的起因:任何进销存系统,销售开单部分都应该算 ...

  2. 如何实现让div垂直居中,左右10px,高度始终为宽度一半

    方法一:利用height:0; padding-bottom: 50%; <!DOCTYPE html><html lang="en"> <head& ...

  3. [开源]C++实现控制台随机迷宫

    我全程使用TCHAR系列函数,亲测可以不改动代码兼容Unicode/ANSI开发环境,功能正常.大概有100行代码是来自网络的,我也做了改动,侵权请联系删除.本文作者szx0427,只发布于CSDN与 ...

  4. Linux中DNS分离解析

    目录 一.分离解析概述 二.DNS分离解析实验 要求 实验步骤 一.分离解析概述 分离解析:同一个dns服务器,同一个域名情况下,不同网段进行访问会解析出不同的IP地址 分离解析的域名服务器实际也是主 ...

  5. AI+云原生,把卫星遥感虐的死去活来

    摘要:遥感影像,作为地球自拍照,能够从更广阔的视角,为人们提供更多维度的辅助信息,来帮助人类感知自然资源.农林水利.交通灾害等多领域信息. 本文分享自华为云社区<AI+云原生,把卫星遥感虐的死去 ...

  6. murmur3 hash(hash算法)

    HashUtil.java package com.example.test.util; import com.google.common.base.Charsets; import com.goog ...

  7. Python - typing 模块 —— Any Type

    前言 typing 是在 python 3.5 才有的模块 前置学习 Python 类型提示:https://www.cnblogs.com/poloyy/p/15145380.html 常用类型提示 ...

  8. S3C2440—4.时钟系统

    文章目录 一.S3C2440时钟体系介绍 1.总线与时钟 2.时钟来源 3.选择时钟 4.产生时钟 5.流程 二.如何配置时钟源 1.设置FCLK频率寄存器 MPLLCON 2.设置分频HDIV.PD ...

  9. STM32—串口使用总结

    文章目录 一.仅向上位机打印调试信息 二.与上位机交互信息 三.作为驱动接口 四.结合DMA接收数据帧 在日常学习中,串口经常作为和上位机通信的接口,进行打印信息方便调试程序,有时也会作为模块的驱动接 ...

  10. 获取访问者真实ip地址?我觉得不可能

    我们真的能通过请求来获取用户真实的ip地址嘛? 答案是不能,如果能,肯定是我学的不够深入,欢迎交流指正. 那么写这篇文章的意义是什么?我们接着往下看. IP地址相当于电脑在网络上的身份证,但事实上IP ...