技术标签: Hyperf 微服务 原创 JSON RPC php
提示:JSON RPC 是一种基于 JSON 格式的轻量级的 RPC 协议标准,易于使用和阅读。在 Hyperf 里由 hyperf/json-rpc 组件来实现,可自定义基于 HTTP 协议来传输,或直接基于 TCP 协议来传输。
提示:以下例子使用TCP服务,例子经过作者验证
服务有两种角色,一种是 服务提供者(ServiceProvider),即为其它服务提供服务的服务,另一种是 服务消费者(ServiceConsumer),即依赖其它服务的服务。两者直接可以通过 服务契约 来定义和约束接口的调用,在 Hyperf 里,可直接理解为就是一个 接口类(Interface),通常来说这个接口类会同时出现在提供者和消费者下。
提示:推荐使用docker容器进行实验,毕竟模拟分布式可以更加直观
本次我搭建了一个服务提供者 hyperf_server
,为其他服务提供计算逻辑功能;一个消费者hyperf_client
,通过 jsonrpc 协议调用 hyperf_server
提供的计算功能。搭建过程如下:
hyperf_server
服务提供者# composer 下载全新的hyperf
composer create-project hyperf/hyperf-skeleton hyperf_server
## composer 安装相关需要的扩展
composer require hyperf/json-rpc
composer require hyperf/service-governance # consul 服务中心扩展
composer require hyperf/rpc-server # JSON RPC 服务端
hyperf_client
服务消费者# composer 下载全新的hyperf
composer create-project hyperf/hyperf-skeleton hyperf_client
## composer 安装相关需要的扩展
composer require hyperf/json-rpc
composer require hyperf/service-governance # consul 服务中心扩展
composer require hyperf/rpc-client # JSON RPC 服务端
hyperf_server
功能开发app
Constants
Controller
Exception
JsonRpc *
CalculatorService.php *
CalculatorServiceInterface.php *
Listener
Model
Process
app\JsonRpc\CalculatorService.php
<?php
namespace App\JsonRpc;
use Hyperf\RpcServer\Annotation\RpcService;
/**
* 注意,如希望通过服务中心来管理服务,需在注解内增加 publishTo 属性
* @RpcService(name="CalculatorService", protocol="jsonrpc", server="jsonrpc", publishTo="consul")
*/
class CalculatorService implements CalculatorServiceInterface
{
public function sum(int $v1, int $v2): int
{
return $v1 + $v2;
}
}
app\JsonRpc\CalculatorServiceInterface.php
<?php
namespace App\JsonRpc;
/**
* Class CalculatorService
* @package App\JsonRpc
*/
interface CalculatorServiceInterface
{
public function sum(int $a, int $b): int;
}
hyperf_server
服务配置config\autoload\server.php
<?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
*/
use Hyperf\Server\Server;
use Hyperf\Server\SwooleEvent;
return [
'mode' => SWOOLE_PROCESS,
'servers' => [
// [
// 'name' => 'http',
// 'type' => Server::SERVER_HTTP,
// 'host' => '0.0.0.0',
// 'port' => 9501,
// 'sock_type' => SWOOLE_SOCK_TCP,
// 'callbacks' => [
// SwooleEvent::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
// ],
// ],
[
// 这里是HTTP通讯形式
'name' => 'jsonrpc-http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9504,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
SwooleEvent::ON_REQUEST => [\Hyperf\JsonRpc\HttpServer::class, 'onRequest'],
],
],
[
// 这里是TCP通讯形式
'name' => 'jsonrpc',
'type' => Server::SERVER_BASE,
'host' => '0.0.0.0',
'port' => 9501,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
SwooleEvent::ON_RECEIVE => [\Hyperf\JsonRpc\TcpServer::class, 'onReceive'],
],
'settings' => [
'open_eof_split' => true,
'package_eof' => "\r\n",
],
],
],
'settings' => [
'enable_coroutine' => true,
'worker_num' => swoole_cpu_num(),
'pid_file' => BASE_PATH . '/runtime/hyperf.pid',
'open_tcp_nodelay' => true,
'max_coroutine' => 100000,
'open_http2_protocol' => true,
'max_request' => 100000,
'socket_buffer_size' => 2 * 1024 * 1024,
'buffer_output_size' => 2 * 1024 * 1024,
],
'callbacks' => [
SwooleEvent::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'],
SwooleEvent::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'],
SwooleEvent::ON_WORKER_EXIT => [Hyperf\Framework\Bootstrap\WorkerExitCallback::class, 'onWorkerExit'],
],
];
hyperf_client
功能开发app
Constants
Controller *
IndexController.php *
Exception
JsonRpc *
CalculatorServiceInterface.php *
Listener
Model
Process
app\JsonRpc\CalculatorServiceInterface.php
<?php
declare(strict_types=1);
namespace App\JsonRpc;
interface CalculatorServiceInterface
{
public function sum(int $v1, int $v2): int;
}
app\Controller\IndexController.php
<?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 App\Controller;
use App\JsonRpc\CalculatorServiceInterface;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Di\Annotation\Inject;
/**
* @Controller()
* Class IndexController
* @package App\Controller
*/
class IndexController extends AbstractController
{
/**
* @GetMapping(path="sum")
* @return int
*/
public function sum()
{
$client = ApplicationContext::getContainer()->get(CalculatorServiceInterface::class);
$value = $client->sum(1, 2);
return $value;
}
/**
* //在这里我们注入了一个接口类,并直接调用接口的sum方法,但在本项目并没有add
方法的实现,真正的add方法在服务提供者里已经实现了,hyperf会帮我们找到相应服务并使用
* @Inject()
* @var CalculatorServiceInterface
*/
private $calculatorService;
/**
* @GetMapping(path="sum2")
* @return int
*/
public function sum2(){
return $this->calculatorService->sum(1,2);
}
}
hyperf_client
服务配置config\autoload\server.php
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact [email protected]
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
*/
use Hyperf\Server\Server;
use Hyperf\Server\SwooleEvent;
return [
'mode' => SWOOLE_PROCESS,
'servers' => [
[
'name' => 'http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9500, // 修改http端口 免得端口占用
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
SwooleEvent::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
],
],
],
'settings' => [
'enable_coroutine' => true,
'worker_num' => swoole_cpu_num(),
'pid_file' => BASE_PATH . '/runtime/hyperf.pid',
'open_tcp_nodelay' => true,
'max_coroutine' => 100000,
'open_http2_protocol' => true,
'max_request' => 100000,
'socket_buffer_size' => 2 * 1024 * 1024,
],
'callbacks' => [
SwooleEvent::ON_BEFORE_START => [Hyperf\Framework\Bootstrap\ServerStartCallback::class, 'beforeStart'],
SwooleEvent::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'],
SwooleEvent::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'],
],
];
config\autoload\services.php
没有这个配置文件则新建
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact [email protected]
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
*/
return [
'consumers' => [
[
// name 需与服务提供者的 name 属性相同
'name' => 'CalculatorService',
// 服务接口名,可选,默认值等于 name 配置的值,如果 name 直接定义为接口类则可忽略此行配置,如 name 为字符串则需要配置 service 对应到接口类
'service' => \App\JsonRpc\CalculatorServiceInterface::class,
// 对应容器对象 ID,可选,默认值等于 service 配置的值,用来定义依赖注入的 key
'id' => \App\JsonRpc\CalculatorServiceInterface::class,
// 服务提供者的服务协议,可选,默认值为 jsonrpc-http
'protocol' => 'jsonrpc',
// 负载均衡算法,可选,默认值为 random
'load_balancer' => 'random',
// 这个消费者要从哪个服务中心获取节点信息,如不配置则不会从服务中心获取节点信息
'registry' => [
'protocol' => 'consul',
'address' => 'http://127.0.0.1:8500',
],
// 如果没有指定上面的 registry 配置,即为直接对指定的节点进行消费,通过下面的 nodes 参数来配置服务提供者的节点信息
// 'nodes' => [
// ['host' => '127.0.0.1', 'port' => 9501],
// ],
]
],
];
consul
服务中心consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul -node=Dome -bind=127.0.0.1 -ui -client=0.0.0.0
hyperf_client
服务php hyperf_client/bin/hyperf.php start
hyperf_server
服务php hyperf_server/bin/hyperf.php start
curl http://127.0.0.1:9500/sum
# 返回3 则正确
CentOS下mysql数据库常用命令总结mysql数据库使用总结本文主要记录一些mysql日常使用的命令,供以后查询。1.更改root密码mysqladmin -uroot password 'yourpassword'2.远程登陆mysql服务器mysql -uroot -p -h192.168.137.10 -P33063.查询数据库...
打开受管理的系统。 在开机自检(POST)过程中按。 在系统设置主菜单页面中,单击iDRAC Settings(iDRAC设置)。随即显示iDRAC Settings(iDRAC设置)页面。 单击"Network(网络)"。随即显示Networking(网络)页面。 指定网络设置。在"Enable NIC"(启用NIC)下面,选择Enabled(启用)。-Shared LOM(共享LOM)(1、2、3或4)将共享主板上的其中一个NIC -Dedicate..._dell poweredge http管理界面
7-1 实验10_9_指针数组进阶 (100 分)已知正整数n,n的范围是1—100。你要从键盘读入n个字符串,每个字符串的长度不确定,但是n个字符串的总长度不超过100000。你要利用字符指针数组将这n个字符串按照ASCII码顺序进行升序排序,然后再打印到屏幕上。字符串中可能包含ASCII码中的任意字符,每个字符串以换行符结束输入。要求:不允许定义如char str[100][100000];这样的二维数组,因为会极大的浪费内存空间。你应定义char str[100000];这样的存储空间,将n个字符_从键盘上输入n个字符串(每个字符串的长度小于20,字符串包含空白字符),对其进行升
代理服务器的问题https://tieba.baidu.com/p/5771890231但是有些网站还是打不开啊_由于不能验证所收到的数据是否可信,无法显示您想要查看的页面。 建议向此网站的管
使用Mybatis/TkMybatis/Mybatis-Plus框架报错:无效的列类型: 1111_mybatis-plus 写入oracle报错1111
1、Python生成RSA秘钥,与签名验证# rsa签名,保存私钥公钥到本地from cryptography.hazmat.primitives.asymmetric import paddingfrom cryptography.hazmat.primitives import hashesfrom cryptography.hazmat.primitives import serializationfrom OpenSSL import cryptorsa_key = crypto.r_crypto库生成的签名值要经过反序后才能由openssl库进行验证
文章目录1 概述2 Optional类的方法3 总结参考资料1 概述到目前为止,臭名昭著的空指针异常是导致Java应用程序失败的最常见原因。以前,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类, Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。受到GoogleGuava的启发,Optional类已经成为Java8类库的一部分。Optional<T>类(java.util.Optional) 是一个容器类,它可以保存类型T的值,
https://blog.csdn.net/demonson/article/details/79474133转载于:https://www.cnblogs.com/ritchy/p/10460984.html_oracle awr最好多长
Windows10在线安装Selenium遇到的问题(超时和没有权限)1.安装时出现超时2.安装时提示没有权限具体遇到问题的解决方案:1.在cmd进入命令行:pip install selenium,结果提示安装失败排查:原因是因为超时解决方案:因为超时了,所以加上超时时间。命令行:pip --default-timeout=150 install selenium..._selenium wos you don't have permission
你真的会使用google么? 如今遇到问题都会在搜索引擎中寻找答案,如何快速准确的寻找出你xiang
问题描述 从键盘输入一个字符,如果是大写字母(A-Z),就转换成小写;如果是小写字母(a-z),就转换成大写,如果是其他字符原样保持并将结果输出。输入格式 输入一行,包含一个字符。输出格式 输出一行,即按照要求输出的字符。样例输入a样例输出A思路:直接转成字符数组,然后利用ASCII码值,就可,结果千算万算没算出来这个居然还要求了 @ ( * . ?这几个字符,然后我的代...
题目移出:移入:分析思路清晰,onmouseover和onmouseout的使用,注意的地方有:width和height设置的是content的内容,padding和border要注意设置,实现前后大小相同,就要让整个盒子大小一致,即border也进行设置。cssText设置内联样式,cssText=""可清空内联样式。之前没明白onload的作用,这次理解了,之前onload..._网购界面鼠标移入变化 条件渲染 js