Hyperf微服务初探

960 阅读4分钟

一、微服务

1.什么是微服务?

一种软件开发技术- 面向服务的体系结构(SOA)架构样式的一种变体,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP的RESTful API)。

2.微服务为了解决什么问题?

复用性

代码到处拷贝

专注性

防止底层复杂性扩散。对于调用方来说只要调用接口就好,根本不用关心底层存储的变更。

高质量稳定性

解决初级水平的RD写出低质量SQL问题

扩展性

消除数据库的耦合

高效性

调用方更加专注,只关心自己开发的部分,底层不需要关心。

引入一个题外话:一艘航母的标配是什么?

image.png

  • 1-2艘巡洋舰
  • 2-3艘驱逐舰
  • 1-2艘护卫舰
  • 1-2艘综合补给舰
  • 2-3艘反潜驱护舰

3.微服务的标配有哪些?

  • API Gateway

网关服务Kong、APISIX

  • 服务注册发现

Consul、Nacos

  • 服务调用

RPC、gRPC、HTTP

  • 服务重试

网络通讯天然是不稳定的,需要有良好的容错设计

  • 服务熔断降级及限流

circuit-breaker,程序员为此避免被祭天,引入熔断等服务容错机制来保证服务持续可用性。

  • 服务监控

Prometheus

  • 配置中心

Nacos、Zookeeper

  • 链路追踪

Zipkin、Skywalking

4.微服务好处/坏处

1.好处

边界清晰、开发效率高、扩展易用性好、系统稳定性高

2.坏处

1.系统复杂性上升   2.定位排查问题加大,层次变得复杂    3.运维部署变得复杂   4.监控变得复杂

5.总结

一句话:不要为了微服务化而微服务化

服务化并不是简单的引入一个RPC框架,需要添加一系列的基础设施配合才能完成微服务的架构。微服务会让开发者的边界很清晰,每个开发者只要负责好自己管控的部分即可,开发非常高效。一切以实际情况出发,落地为目标!

二、Hyperf微服务框架

1. Hyperf介绍

Hyperf 是一个高性能、高灵活性的渐进式 PHP 协程框架,内置协程服务器及大量常用的组件,性能较传统基于 PHP-FPM 的框架有质的提升,提供超高性能的同时,也保持着极其灵活的可扩展性,标准组件均基于 PSR 标准 实现,基于强大的依赖注入设计,保证了绝大部分组件或类都是 可替换 与 可复用 的。

2. 快速入门

1)安装只需一条命令

[root@iZ2ze672ze6430xgo22ts6Z ~]# composer create-project hyperf/hyperf-skeleton 

2)服务启动

[root@iZ2ze672ze6430xgo22ts6Z hyperf-skeleton]# php bin/hyperf.php start

3)浏览器输入:127.0.0.1:9501

结果:
{
"method": "GET",
"message": "Hello Hyperf."
}

3.理解几个重要概念

1)注解

注释:给程序员看的,帮助理解代码,对代码起到诠释说明的作用
注解:给应用程序看,用于元数据的定义 路由组件根据这些收集到的元数据,根据规则注册对应的路由

代码示例:

<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
namespace App\Controller;

use App\JsonRpc\UserService;
use Hyperf\HttpServer\Annotation\AutoController;

/**
 * @AutoController()
 */
class IndexController extends AbstractController
{
    public function index()
    {
        $user = $this->request->input('user', 'Hyperf');
        $method = $this->request->getMethod();

        return [
            'method' => $method,
            'message' => "Hello {$user}.",
        ];
    }
}

相当于路由规则:index/index

2)依赖注入(IOC与DI)

  • 通过构造方法注入

代码示例:

<?php
namespace App\Controller;

use App\Service\UserService;

class IndexController
{
    /**
     * @var UserService
     */
    private $userService;
    
    // 通过在构造函数的参数上声明参数类型完成自动注入
    public function __construct(UserService $userService)
    {
        $this->userService = $userService;
    }
    
    public function index()
    {
        $id = 1;
        // 直接使用
        return $this->userService->getInfoById($id);    
    }
}
  • 通过 @Inject 注解注入
<?php
namespace App\Controller;

use App\Service\UserService;

class IndexController
{
    /**
     * @var UserService
     */
    private $userService;
    
    // 通过在构造函数的参数上声明参数类型完成自动注入
    public function __construct(UserService $userService)
    {
        $this->userService = $userService;
    }
    
    public function index()
    {
        $id = 1;
        // 直接使用
        return $this->userService->getInfoById($id);    
    }
}

3)协程

协程是一种轻量级的线程,由用户代码来调度和管理,而不是由操作系统内核来进行调度,也就是在用户态进行。

  • 用户态和内核态区别

image.png

CPU、内存、I/O,内核必须提供一组通用的访问接口,这些接口就叫系统调用。

三、微服务框架设计

1. 结构目录设计

├── app                                             //应用目录
  ├── Amqp                                          //RabbitMQ
  ├── Constants                                       //枚举类
  │   ├── ErrorCode.php
  │   └── SuccessCode.php
  ├── Controller                                      //控制器
  │   ├── AbstractController.php
  │   ├── IndexController.php
  │   └── UserController.php
  ├── Exception                                       //异常处理
  │   ├── BusinessException.php
  │   └── Handler
  ├── Kafka                                           //Kafka消息
  ├── Listener                                        //事件监听
  │   └── DbQueryExecutedListener.php
  ├── Model                                           //数据表Model
  │   ├── Model.php
  │   └── User.php
  ├── Request                                         //Request请求
  │   ├── BaseRequest.php
  │   ├── UserOrderRequest.php
  │   └── UserRequest.php
  └── Service                                         //逻辑处理类
      ├── DataService                                 //数据处理
      ├── PageService                                 //逻辑处理
      └── RemoteService                               //远程调用
├── bin
│   └── hyperf.php                            //项目启动文件
├── config
│   ├── autoload
│   │   ├── annotations.php             
│   │   ├── app_manager.php
│   │   ├── aspects.php
│   │   ├── cache.php
│   │   ├── commands.php
│   │   ├── databases.php
│   │   ├── dependencies.php
│   │   ├── devtool.php
│   │   ├── exceptions.php
│   │   ├── listeners.php
│   │   ├── logger.php
│   │   ├── middlewares.php
│   │   ├── order.php
│   │   ├── processes.php
│   │   ├── redis.php
│   │   └── server.php
│   ├── config.php
│   ├── container.php
│   └── routes.php                             //路由文件                
├── runtime
│   ├── container
│   ├── hyperf.pid
│   └── logs
├── storage
│   └── languages
├── test
│   ├── bootstrap.php
│   ├── Cases
│   └── HttpTestCase.php
└── vendor                                          //composer扩展包
    ├── autoload.php
    ├── bin
    ├── byzy
    ├── composer
    ├── doctrine
    ├── egulias
    ├── elasticsearch
    ├── fig
    ├── friendsofphp
    ├── graham-campbell
    ├── guzzlehttp
    ├── hamcrest
    ├── hyperf
    ├── longlang
    ├── laminas
    ├── mockery
    ├── monolog
    ├── myclabs
    ├── nesbot
    ├── nikic
    ├── phar-io
    ├── php-di
    └── phpoption
    ├── deploy.test.yml
├── Dockerfile
├── phpstan.neon
├── phpunit.xml
├── composer.json
├── composer.lock
├── README.md

2. 服务鉴权设计

元素生成规则
ak'by' + mt_rand(90000, 99999) + mt_rand(10000, 99999) + mt_rand(1000, 9999)
skmd5($appId .str_random() . time())
signmd5($appId . $timestamp . $nonceStr . $secret)
nonceStr0123456789abcdefghijklmnopqrstuvwxyz

元素说明:

  • ak:每个应用的标识
  • sk:由ak+随机字符串+时间戳,md5加密
  • sign:加盐
  • $nonceStr:由10个数字+26个字母随机取出8个字符组成
  • $timestamp:当前时间戳time() * 1000

3. composer包管理

参见composer私有仓库搭建


四、文末彩蛋

翻阅了各种资料,查看了官方文档,安装gRPC,太难了😭,总结了简单可操作的文档,见下方👇
hyperf快速安装gRPC