閱讀目錄
- 什么是服務(wù)
- 構(gòu)建服務(wù)提供者
- 1径缅、創(chuàng)建數(shù)據(jù)表
- 2、構(gòu)建服務(wù)提供者
- 3、安裝json rpc依賴
- 4柜与、安裝rpc server組件
- 5欢峰、修改server配置
- 6膘融、配置數(shù)據(jù)庫
- 7、編寫基礎(chǔ)代碼
- 7-1狼渊、編寫model代碼
- 7-2、編寫service代碼
- postman測試
上一篇文章我們了解了如何使用hyperf對項(xiàng)目進(jìn)行垂直拆分类垦,這是我們整個(gè)微服務(wù)模塊的基礎(chǔ)狈邑。
hyperf支持JSON-RPC和gRPC,我們在分布式服務(wù)架構(gòu)一文中介紹過什么是JSON-RPC以及JSON-RPC請求響應(yīng)的案例(后來做的補(bǔ)充)蚤认,后面我們會(huì)著重以JSON-RPC為例來解決整個(gè)微服務(wù)系統(tǒng)出現(xiàn)的各種問題米苹。
首先我們加以明確什么是服務(wù)。
服務(wù)有兩種角色砰琢,一種是 服務(wù)提供者(ServiceProvider)蘸嘶,即為其它服務(wù)提供服務(wù)的服務(wù),另一種是 服務(wù)消費(fèi)者(ServiceConsumer)陪汽,即依賴其它服務(wù)的服務(wù)训唱,一個(gè)服務(wù)既可能是 服務(wù)提供者(ServiceProvider),同時(shí)又是 服務(wù)消費(fèi)者(ServiceConsumer)挚冤。而兩者直接可以通過 服務(wù)契約 來定義和約束接口的調(diào)用况增,在 Hyperf 里,可直接理解為就是一個(gè) 接口類(Interface)训挡,通常來說這個(gè)接口類會(huì)同時(shí)出現(xiàn)在提供者和消費(fèi)者下澳骤。——摘自官網(wǎng)舍哄。
簡單的說宴凉,我們的項(xiàng)目模塊將會(huì)被分為服務(wù)提供者模塊和服務(wù)消費(fèi)者模塊。 服務(wù)提供者模塊指的是提供各種服務(wù)的模塊表悬,它需要與數(shù)據(jù)庫進(jìn)行交互弥锄。 服務(wù)消費(fèi)者模塊指的是消費(fèi)服務(wù)的模塊。它需要遠(yuǎn)程訪問服務(wù)提供者。
本節(jié)課的源碼已上傳至github籽暇,https://github.com/bailangzhan/hyperf-rpc
下面我們按照步驟温治,看看如何構(gòu)建服務(wù)提供者。
1戒悠、創(chuàng)建數(shù)據(jù)表
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 '創(chuàng)建時(shí)間',
`updated_at` int(11) NOT NULL DEFAULT '0' COMMENT '更新時(shí)間',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用戶基礎(chǔ)表';
2熬荆、構(gòu)建服務(wù)提供者
composer create-project hyperf/hyperf-skeleton shop_provider_user
安裝的時(shí)候會(huì)讓我們選擇默認(rèn)的組件,除了時(shí)區(qū)和數(shù)據(jù)庫外绸狐,其他一律選擇“n”卤恳,選擇如下
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): y
- Adding package hyperf/database (~2.2.0)
- Adding package hyperf/db-connection (~2.2.0)
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
需要什么組件后面可以我們再自行添加。
3寒矿、安裝json rpc依賴
cd shop_provider_user
composer require hyperf/json-rpc
4突琳、安裝rpc server組件
我們準(zhǔn)備讓 shop_provider_user 應(yīng)用對外提供服務(wù),所以需要安裝 rpc server組件
composer require hyperf/rpc-server
5符相、修改server配置
shop_provider_user 提供的是 jsonrpc服務(wù)拆融,不需要提供http服務(wù),所以屏蔽 http 服務(wù)配置啊终,新加 jsonrpc-http 服務(wù)镜豹。
hyperf支持 jsonrpc-http 協(xié)議、jsonrpc 協(xié)議以及jsonrpc-tcp-length-check 協(xié)議蓝牲,我們后續(xù)都將以 jsonrpc-http為例趟脂。
以下配置在 config/autoload/server.php 文件內(nèi),注意 jsonrpc-http服務(wù)配置的端口號(hào)是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例衍、配置數(shù)據(jù)庫
修改.env文件散怖,修改 APP_NAME以及數(shù)據(jù)庫配置
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、編寫基礎(chǔ)代碼
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.
*
* @var string
*/
protected $table = 'user';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['name', 'gender'];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = ['id' => 'integer', 'gender' => 'integer'];
// 自定義時(shí)間戳的格式 U表示int
protected $dateFormat = 'U';
}
7-2镇眷、編寫service代碼
app下新建JsonRpc目錄,編寫UserService.php和UserServiceInterface.php文件翎嫡。
UserServiceInterface 對外提供兩個(gè)接口欠动,一個(gè)用于創(chuàng)建用戶,一個(gè)用于獲取用戶信息惑申。
【UserServiceInterface】
<?php
namespace App\JsonRpc;
interface UserServiceInterface
{
public function createUser(string $name, int $gender);
public function getUserInfo(int $id);
}
【UserService】
<?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 string $gender
* @return string
*/
public function createUser(string $name, int $gender)
{
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)
{
$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 個(gè)參數(shù)人芽,也就是 Hyperf\RpcServer\Annotation\RpcService 的4個(gè)屬性:
- name 屬性為定義該服務(wù)的名稱,注意不同的service不要用相同的名字绩脆,該名字唯一萤厅,Hyperf 會(huì)根據(jù)該屬性生成對應(yīng)的 ID 注冊到服務(wù)中心去橄抹,后面我們會(huì)詳細(xì)介紹,這里有個(gè)印象就好惕味;
- protocol 屬性為定義該服務(wù)暴露的協(xié)議楼誓,目前僅支持 jsonrpc-http, jsonrpc, jsonrpc-tcp-length-check ,分別對應(yīng)于 HTTP 協(xié)議和 TCP 協(xié)議下的兩種協(xié)議名挥,默認(rèn)值為 jsonrpc-http疟羹,這里的值對應(yīng)在 Hyperf\Rpc\ProtocolManager 里面注冊的協(xié)議的 key,它們本質(zhì)上都是 JSON RPC 協(xié)議禀倔,區(qū)別在于數(shù)據(jù)格式化榄融、數(shù)據(jù)打包、數(shù)據(jù)傳輸器等不同救湖;
- server 屬性為綁定該服務(wù)類發(fā)布所要承載的 Server剃袍,默認(rèn)值為 jsonrpc-http,該屬性對應(yīng) config/autoload/server.php 文件內(nèi) servers 下所對應(yīng)的 name捎谨;
- publishTo 屬性為定義該服務(wù)所要發(fā)布的服務(wù)中心,目前僅支持 consul憔维、nacos 或?yàn)榭仗尉龋覀冞@里先不做設(shè)置,留空
到這里我們就構(gòu)建好一個(gè)基本的服務(wù)提供者了业扒。
postman測試
下面我們測試下這兩個(gè)接口是否正常检吆。執(zhí)行命令 php bin/hyperf.php start 啟動(dòng)服務(wù),利用postman發(fā)送請求程储。
請求地址:http://127.0.0.1:9600
請求方法:POST
請求參數(shù)
{
"jsonrpc": "2.0",
"method": "/user/createUser",
"params": {
"name": "zhangsan",
"gender": 3
},
"id": "61025bc35e07d",
"context": []
}
header頭
Content-Type: application/json
響應(yīng)結(jié)果
{
"jsonrpc": "2.0",
"id": "61025bc35e07d",
"result": "success",
"context": []
}
看下數(shù)據(jù)表
created_at 和 update_at 這兩個(gè)字段被自動(dòng)填充蹭沛。
再利用 postman訪問 /user/getUserInfo 方獲試試。
請求地址:http://127.0.0.1:9600
請求方法:POST
請求參數(shù)
{
"jsonrpc": "2.0",
"method": "/user/getUserInfo",
"params": {
"id": 1
},
"id": "61025bc35e07d",
"context": []
}
header頭
Content-Type: application/json
響應(yīng)結(jié)果
{
"jsonrpc": "2.0",
"id": "61025bc35e07d",
"result": {
"id": 1,
"name": "zhangsan",
"gender": 3,
"created_at": "1630101991",
"updated_at": "1630101991"
},
"context": []
}
到這里章鲤,我們的服務(wù)提供者基本上就構(gòu)建好了摊灭,有同學(xué)可能看其他文章介紹還有consul的內(nèi)容,我們后續(xù)還會(huì)介紹更多內(nèi)容败徊,稍安勿躁帚呼。
下一節(jié),我們繼續(xù)構(gòu)建服務(wù)消費(fèi)者皱蹦。