hyperf 从零开始构建微服务(一)——构建服务提供者(3.0)
阅读目录
上一篇文章我们了解了如何使用hyperf对项目进行垂直拆分,这是我们整个微服务模块的基础。
hyperf支持JSON-RPC和gRPC,我们在分布式服务架构一文中介绍过什么是JSON-RPC以及JSON-RPC请求响应的案例,后面我们会着重以JSON-RPC为例来解决整个微服务系统出现的各种问题。
首先我们加以明确什么是服务。
服务有两种角色,一种是 服务提供者(ServiceProvider),即为其它服务提供服务的服务,另一种是 服务消费者(ServiceConsumer),即依赖其它服务的服务,一个服务既可能是 服务提供者(ServiceProvider),同时又是 服务消费者(ServiceConsumer)。而两者直接可以通过 服务契约 来定义和约束接口的调用,在 Hyperf 里,可直接理解为就是一个 接口类(Interface),通常来说这个接口类会同时出现在提供者和消费者下。——摘自官网。
简单的说,我们的项目模块将会被分为服务提供者模块和服务消费者模块。 服务提供者模块指的是提供各种服务的模块,它需要与数据库进行交互。 服务消费者模块指的是消费服务的模块。它需要远程访问服务提供者。
本节课的源码已上传至github,https://github.com/bailangzhan/hyper3-rpc
1、创建数据表
CREATE DATABASE hyperf; USE hyperf; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(30) NOT NULL DEFAULT '' COMMENT '姓名', `gender` tinyint(1) NOT NULL DEFAULT '0' COMMENT '性别 1男 2女 0未知', `created_at` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', `updated_at` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户基础表';
2、构建服务提供者
我们在上文讲述了hyperf3.0的升级安装,为了方便,这里我们直接对 base 项目进行复制。
cp -R base shop_provider_user
登录容器继续操作
➜ ~ docker exec -it c6a9f27f4642 /bin/bash bash-5.1# cd /data/project/shop_provider_user bash-5.1# composer info | grep hyperf hyperf/cache v3.0.0-beta.11 A cache component for hyperf. hyperf/code-generator v0.3.3 Code Generator for Hyperf hyperf/command v3.0.0-beta.4 Command for hyperf hyperf/config v3.0.0-beta.1 An independent component that provides configuration container. hyperf/context v3.0.0-beta.2 A coroutine context library. hyperf/contract v3.0.0-beta.11 The contracts of Hyperf. hyperf/coordinator v3.0.0-beta.1 Hyperf Coordinator hyperf/database v3.0.0-beta.10 A flexible database library. hyperf/db-connection v3.0.0-beta.9 A hyperf db connection handler for hyperf/database. hyperf/devtool v3.0.0-beta.1 A Devtool for Hyperf. hyperf/di v3.0.0-beta.11 A DI for Hyperf. hyperf/dispatcher v3.0.0-beta.1 A HTTP Server for Hyperf. hyperf/engine v1.2.1 hyperf/event v3.0.0-beta.1 an event manager that implements PSR-14. hyperf/exception-handler v3.0.0-beta.1 Exception handler for hyperf hyperf/framework v3.0.0-beta.1 A coroutine framework that focuses on hyperspeed and flexible, specifically use for build microservices and middlewares. hyperf/guzzle v3.0.0-beta.1 Swoole coroutine handler for guzzle hyperf/http-message v3.0.0-beta.1 microservice framework base on swoole hyperf/http-server v3.0.0-beta.11 A HTTP Server for Hyperf. hyperf/ide-helper v3.0.0-beta.1 IDE help files for Hyperf. hyperf/logger v3.0.0-beta.3 A logger component for hyperf. hyperf/macroable v3.0.0-beta.1 Hyperf Macroable package which come from illuminate/macroable hyperf/memory v3.0.0-beta.1 An independent component that use to operate and manage memory. hyperf/model-listener v3.0.0-beta.1 A model listener for Hyperf. hyperf/pool v3.0.0-beta.1 An independent universal connection pool component. hyperf/process v3.0.0-beta.2 A process component for hyperf. hyperf/redis v3.0.0-beta.2 A redis component for hyperf. hyperf/server v3.0.0-beta.11 A base server library for Hyperf. hyperf/testing v3.0.0-beta.1 Testing for hyperf hyperf/utils v3.0.0-beta.12 A tools package that could help developer solved the problem quickly.
以上是已安装的默认组件,我们继续安装本节课需要的其他依赖。
3、安装json rpc依赖
cd shop_provider_user composer require hyperf/json-rpc:*
4、安装rpc server组件
我们准备让 shop_provider_user 应用对外提供服务,所以需要安装 rpc server组件
composer require hyperf/rpc-server:*
下面看下刚刚安装的依赖的版本
bash-5.1# composer info | grep 'hyperf/rpc-server\|hyperf/json-rpc' hyperf/json-rpc v3.0.0-beta.1 A JSON RPC component for Hyperf RPC Server or Client. hyperf/rpc-server v3.0.0-beta.1 An abstract rpc server component for Hyperf.
5、修改server配置
shop_provider_user 提供的是 jsonrpc服务,不需要提供http服务,所以屏蔽 http 服务配置,新加 jsonrpc-http 服务。
hyperf支持 jsonrpc-http 协议、jsonrpc 协议以及jsonrpc-tcp-length-check 协议,我们后续都将以 jsonrpc-http为例。
以下配置在 config/autoload/server.php 文件内,注意 jsonrpc-http服务配置的端口号是9600。
'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'], // ], // ], [ 'name' => 'jsonrpc-http', 'type' => Server::SERVER_HTTP, 'host' => '0.0.0.0', 'port' => 9600, 'sock_type' => SWOOLE_SOCK_TCP, 'callbacks' => [ Event::ON_REQUEST => [\Hyperf\JsonRpc\HttpServer::class, 'onRequest'], ], ], ],
6、配置数据库
修改.env文件,修改 APP_NAME以及数据库配置
APP_NAME=shop_provider_user DB_DRIVER=mysql DB_HOST=192.168.33.20 DB_PORT=3306 DB_DATABASE=hyperf DB_USERNAME=www DB_PASSWORD=123456 DB_CHARSET=utf8mb4 DB_COLLATION=utf8mb4_unicode_ci DB_PREFIX=
7、编写基础代码
7-1、编写model代码
生成model并修改如下:
php bin/hyperf.php gen:model User 【app/Model/User.php】 <?php declare(strict_types=1); namespace App\Model; use Hyperf\DbConnection\Model\Model; /** */ class User extends Model { /** * The table associated with the model. */ protected ?string $table = 'user'; /** * The attributes that are mass assignable. */ protected array $fillable = ['name', 'gender']; /** * The attributes that should be cast to native types. */ protected array $casts = ['id' => 'integer', 'gender' => 'integer']; /** * 自定义时间戳的格式 U表示int * @var string|null */ protected ?string $dateFormat = 'U'; }
7-2、编写service代码
app下新建JsonRpc目录,编写UserService.php和UserServiceInterface.php文件。
UserServiceInterface 对外提供两个接口,一个用于创建用户,一个用于获取用户信息。
【App/JsonRpc/UserServiceInterface.php】
<?php namespace App\JsonRpc; interface UserServiceInterface { /** * @param string $name * @param int $gender * @return string */ public function createUser(string $name, int $gender): string; /** * @param int $id * @return array */ public function getUserInfo(int $id): array; }
【App/JsonRpc/UserService.php】
<?php namespace App\JsonRpc; use App\Model\User; use Hyperf\RpcServer\Annotation\RpcService; #[RpcService(name: "UserService", protocol: "jsonrpc-http", server: "jsonrpc-http")] class UserService implements UserServiceInterface { /** * @param string $name * @param int $gender * @return string */ public function createUser(string $name, int $gender): string { if (empty($name)) { throw new \RuntimeException("name不能为空"); } $result = User::query()->create([ 'name' => $name, 'gender' => $gender, ]); return $result ? "success" : "fail"; } /** * @param int $id * @return array */ public function getUserInfo(int $id): array { $user = User::query()->find($id); if (empty($user)) { throw new \RuntimeException("user not found"); } return $user->toArray(); } }
注意,在 UserService 类中,我们使用了 RpcService 注解,记得 use Hyperf\RpcServer\Annotation\RpcService;
RpcService 共有 4 个参数,也就是 Hyperf\RpcServer\Annotation\RpcService 的4个属性:
- name 属性为定义该服务的名称,注意不同的service不要用相同的名字,该名字唯一,Hyperf 会根据该属性生成对应的 ID 注册到服务中心去,后面我们会详细介绍,这里有个印象就好;
- protocol 属性为定义该服务暴露的协议,目前仅支持 jsonrpc-http, jsonrpc, jsonrpc-tcp-length-check ,分别对应于 HTTP 协议和 TCP 协议下的两种协议,默认值为 jsonrpc-http,这里的值对应在 Hyperf\Rpc\ProtocolManager 里面注册的协议的 key,它们本质上都是 JSON RPC 协议,区别在于数据格式化、数据打包、数据传输器等不同;
- server 属性为绑定该服务类发布所要承载的 Server,默认值为 jsonrpc-http,该属性对应 config/autoload/server.php 文件内 servers 下所对应的 name;
- publishTo 属性为定义该服务所要发布的服务中心,目前仅支持 consul、nacos 或为空,我们这里先不做设置,留空
到这里我们就构建好一个基本的服务提供者了。
postman测试
下面我们测试下这两个接口是否正常。执行命令 php bin/hyperf.php start 启动服务,利用postman发送请求。
请求地址:http://127.0.0.1:9600 请求方法:POST 请求参数 { "jsonrpc": "2.0", "method": "/user/createUser", "params": { "name": "zhangsan", "gender": 3 }, "id": "61025bc35e07d", "context": [] } header头 Content-Type: application/json 响应结果 { "jsonrpc": "2.0", "id": "61025bc35e07d", "result": "success", "context": [] }
看下数据表
created_at 和 update_at 这两个字段被自动填充。
再利用 postman访问 /user/getUserInfo 方获试试。
请求地址:http://127.0.0.1:9600 请求方法:POST 请求参数 { "jsonrpc": "2.0", "method": "/user/getUserInfo", "params": { "id": 1 }, "id": "61025bc35e07d", "context": [] } header头 Content-Type: application/json 响应结果 { "jsonrpc": "2.0", "id": "61025bc35e07d", "result": { "id": 1, "name": "zhangsan", "gender": 3, "created_at": "1630101991", "updated_at": "1630101991" }, "context": [] }
有同学可能会遇到9600端口不通的情况,这个我们在上一节课已经介绍过,你需要给已有的容器增加新的端口映射,后面不再另做介绍。
到这里,我们的服务提供者基本上就构建好了。
有同学可能看其他文章介绍还有consul的内容,我们后续还会介绍更多内容,稍安勿躁。
下一节,我们继续构建服务消费者。
- 评论区