hyperf从零开始构建微服务(一)——构建服务提供者
阅读目录
- 什么是服务
- 构建服务提供者
- 1、创建数据表
- 2、构建服务提供者
- 3、安装json rpc依赖
- 4、安装rpc server组件
- 5、修改server配置
- 6、配置数据库
- 7、编写基础代码
- 7-1、编写model代码
- 7-2、编写service代码
- postman测试
上一篇文章我们了解了如何使用hyperf对项目进行垂直拆分,这是我们整个微服务模块的基础。
hyperf支持JSON-RPC和gRPC,我们在分布式服务架构一文中介绍过什么是JSON-RPC以及JSON-RPC请求响应的案例(后来做的补充),后面我们会着重以JSON-RPC为例来解决整个微服务系统出现的各种问题。
首先我们加以明确什么是服务。
服务有两种角色,一种是 服务提供者(ServiceProvider),即为其它服务提供服务的服务,另一种是 服务消费者(ServiceConsumer),即依赖其它服务的服务,一个服务既可能是 服务提供者(ServiceProvider),同时又是 服务消费者(ServiceConsumer)。而两者直接可以通过 服务契约 来定义和约束接口的调用,在 Hyperf 里,可直接理解为就是一个 接口类(Interface),通常来说这个接口类会同时出现在提供者和消费者下。——摘自官网。
简单的说,我们的项目模块将会被分为服务提供者模块和服务消费者模块。 服务提供者模块指的是提供各种服务的模块,它需要与数据库进行交互。 服务消费者模块指的是消费服务的模块。它需要远程访问服务提供者。
本节课的源码已上传至github,https://github.com/bailangzhan/hyperf-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、构建服务提供者
composer create-project hyperf/hyperf-skeleton shop_provider_user
安装的时候会让我们选择默认的组件,除了时区和数据库外,其他一律选择“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组件
我们准备让 shop_provider_user 应用对外提供服务,所以需要安装 rpc server组件
composer require hyperf/rpc-server
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.
*
* @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'];
// 自定义时间戳的格式 U表示int
protected $dateFormat = 'U';
}
7-2、编写service代码
app下新建JsonRpc目录,编写UserService.php和UserServiceInterface.php文件。
UserServiceInterface 对外提供两个接口,一个用于创建用户,一个用于获取用户信息。
【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 个参数,也就是 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": []
}
到这里,我们的服务提供者基本上就构建好了,有同学可能看其他文章介绍还有consul的内容,我们后续还会介绍更多内容,稍安勿躁。
下一节,我们继续构建服务消费者。
hyperf从零开始构建微服务(一)——构建服务提供者的更多相关文章
- 通过silky框架在.net平台构建微服务应用
目录 必要前提 使用Web主机构建微服务应用 使用.NET通用主机构建微服务应用 构建具有websocket服务能力的微服务应用 构建Silky微服务网关 开源地址 在线文档 在线示例 必要前提 (必 ...
- Kubernetes实战 - 从零开始搭建微服务 1 - 使用kind构建一个单层架构Node/Express网络应用程序
使用kind构建一个单层架构Node/Express网络应用程序 Kubernetes实战-从零开始搭建微服务 1 前言 准备写一个Kubernetes实战系列教程,毕竟cnblogs作为国内最早的技 ...
- Spring Cloud构建微服务架构(二)服务消费者
Netflix Ribbon is an Inter Process Communication (IPC) cloud library. Ribbon primarily provides clie ...
- [译]Spring构建微服务
此文为译文,原文地址 介绍 本文通过一个使用Spring.Spring Boot和Spring Cloud的小例子来说明如何构建微服务系统. 我们可以通过数个微服务组合成一个大型系统. 我们可以想象下 ...
- 构建微服务:Spring boot
构建微服务:Spring boot 在上篇文章构建微服务:Spring boot 提高篇中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jp ...
- 如何使用 Java 构建微服务?
[编者按]微服务背后的大理念是将大型.复杂且历时长久的应用在架构上设计为内聚的服务,这些服务能够随着时间的流逝而演化.本文主要介绍了利用 Java 生态系统构建微服务的多种方法,并分析了每种方法的利弊 ...
- 构建微服务-使用OAuth 2.0保护API接口
微服务操作模型 基于Spring Cloud和Netflix OSS 构建微服务-Part 1 基于Spring Cloud和Netflix OSS构建微服务,Part 2 在本文中,我们将使用OAu ...
- 基于Spring Cloud和Netflix OSS构建微服务,Part 2
在上一篇文章中,我们已使用Spring Cloud和Netflix OSS中的核心组件,如Eureka.Ribbon和Zuul,部分实现了操作模型(operations model),允许单独部署的微 ...
- 构建微服务(Building Microservices)-PDF 文档
闲时翻译了几篇基于Spring Cloud.Netflix OSS 构建微服务的英文文章,为方便分享交流,整理为PDF文档. PDF 文档目录: 目录 一.微服务操作模型... 3 1. 前提 ...
- Chris Richardson微服务翻译:构建微服务之微服务架构的进程通讯
Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯(本文) 微服务架构中的服务发现 微服务之事件驱动的数据管理 微服 ...
随机推荐
- VUE-router-跳转
跳转的 // 字符串 this.$router.push('/home/first') // 对象 this.$router.push({ path: '/home/first' }) // 命名的路 ...
- Github连接远程仓库详细操作
首先 咱们需要配置ssh密钥 如何生成密钥呢 我们先来看下命令 在桌面新建一个文件夹,命名规范尽量不要使用中文,然后在文件夹内 新建测试文本: 如图 在文件夹内空白处右击进入GIt b ...
- 【前端 · 面试 】HTTP 总结(十)—— HTTP 缓存应用
最近我在做前端面试题总结系列,感兴趣的朋友可以添加关注,欢迎指正.交流. 争取每个知识点能够多总结一些,至少要做到在面试时,针对每个知识点都可以侃起来,不至于哑火. 前言 通过前面几篇内容的学习,我们 ...
- (纯js)如何不刷新网页就能链接新的js文件
如何不刷新网页就能链接新的js文件,其实在HTML语言中已经有相关的函数了,就是再添加一个<script src=.....></script>. 函数叫document.bo ...
- 天梯赛 L2-008 最长对称子串
题目是PTA的天梯赛练习集中的L2-008 https://pintia.cn/problem-sets/994805046380707840/problems/994805067704549376 ...
- 使用Freemarker导出Word文档(包含图片)代码实现及总结
.personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ...
- 用VirtualBox搭建虚拟局域网
用 Oracle VM VirtualBox 安装虚拟机,我在Windows 7上安装了ubuntu 11.10和xubuntu12.04两个虚拟机: 将这两个虚拟机的"网络"属性 ...
- repeatedly function in Clojure
user=> (doc repeatedly) clojure.core/repeatedly ([f] [n f]) Takes a function of no args, presumab ...
- MyBatis学习02(配置解析)
配置解析 核心配置文件 mybatis-config.xml 系统核心配置文件 MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息. 能配置的内容如下: configur ...
- Solon 1.5.24 发布
本次版本主要变化: 修复 solon.extend.sessionstate.jwt 在特定场景下会无限次解析的问题 优化 solon.extend.cors 对头信息的处理 插件 solon.boo ...