php 创建64位的数_PHP搭建微服务(一)

本篇文章开始写利用swoole的Hyperf框架搭建一个微服务架构。

首先我们安装一个Hyperf的项目,按照官方文档来利用composer安装,最好用阿里云的源。

  composer create-project hyperf/hyperf-skeleton user-srv 

选择rpc的时候选择grpc。其他的看自己的需求。

进入user-srv的根目录,创建一个protoc的文件,用户书写我们的协议文件。并且在protoc文件夹下新建一个user.proto的文件。文件如下

syntax = "proto3";

package php.micro.srv.user;

service user {
    rpc find (Request) returns (Response) {}
    rpc create(User) returns (Response) {}
}

// 用户信息
message User {
    // 用户ID
    int64  userId     = 1;
    // 用户名称
    string username   = 2;
    string phone      = 3;
    string password   = 4;
    string email      = 5;
    string nickname   = 6;
    string avatar     = 7;
    string signature  = 8;
}

// 错误码
message Error {
    int64 code      = 1;
    string message  = 2;
}

// 请求
message Request {
    int64  userId    = 1;
    string username  = 2;
    string email     = 3;
    string phone     = 4;
    enum Type {
        ID        = 0;
        USERNAME  = 1;
        EMAIL     = 2;
        PHONE     = 3;
    }
    Type  type       = 5;
}

// 响应
message Response {
    Error error = 1;
    User user   = 2;
}

我们定义了两个接口,一个查询find一个create。具体关于protoc的教程可以百度和谷歌。

然后生成protocbuf文件

protoc --php_out=grpc protoc/user.proto 

这时候会在根目录下的grpc文件夹中生成依赖的文件。

├── GPBMetadata
│   └── Protoc
│       └── User.php
└── Php
    └── Micro
        └── Srv
            └── User
                ├── Error.php
                ├── Request
                │   └── Type.php
                ├── Request.php
                ├── Request_Type.php
                ├── Response.php
                └── User.php

修改composer.json文件,在psr-4下面新增依赖,加完之后如下

"psr-4": {
    "App": "app/",
    "GPBMetadata": "grpc/GPBMetadata",
    "Php": "grpc/Php"
}

然后执行命令行

根据刚刚定义的proto创建自己的user表。我简单创建如下

CREATE TABLE `user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `username` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '用户名',
  `phone` char(24) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '手机号',
  `password` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '密码',
  `email` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '邮箱',
  `nickname` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '昵称',
  `avatar` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '头像',
  `signature` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '用户签名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';

然后根据文档生成自己的model文件和Repository文件。

<?php

declare (strict_types=1);
namespace AppRepository;

/**
 */
class UserRepository
{
    private $user;

    /**
     * User constructor.
     * @param $user
     */
    public function __construct(AppModelUser $user)
    {
        $this->user = $user;
    }

    //创建
    public function create(PhpMicroSrvUserUser $userInfo)
    {
        $user = new AppModelUser();
        $user->username  = $userInfo->getUsername();
        $user->nickname  = $userInfo->getNickname();
        $user->phone     = $userInfo->getPhone();
        $user->email     = $userInfo->getEmail();
        $user->password  = $userInfo->getPassword();
        $user->avatar    = $userInfo->getAvatar();
        $user->signature = $userInfo->getSignature();
        $saved = $user->save();
        if ($saved) {
            return $user;
        }
        return null;

    }




}

这里其实是是把请求过来的数据拿到然后写进数据库。

再然后定义我们的控制器。文件内容如下。

<?php

declare(strict_types=1);

namespace AppControllerRpcController;

use AppControllerAbstractController;
use AppRepositoryUserRepository;
use PhpMicroSrvUserError;
use PhpMicroSrvUserRequest;
use PhpMicroSrvUserResponse;
use PhpMicroSrvUserUser;

class UserController extends AbstractController
{

    private $userRepository;

    /**
     * UserController constructor.
     * @param $userRepository
     */
    public function __construct(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }


    /**
     * rpc 用户查询服务
     * @param Request $request
     * @return Response
     */
    public function find (Request $request)
    {
        $rsp = new Response();
        $user = new User();
        $user->setUsername("陈偲");
        $user->setUserId(1);
        $user->setEmail("741001560@qq.com");
        $rsp->setUser($user);
        return $rsp;

    }

    /**
     * rpc 用户创建服务
     * @param User $user
     * @return Response
     */
    public function create (User $user)
    {
        $rsp = new Response();


        $userEntity = $this->userRepository->create($user);

        if ($userEntity) {
            $userInfo = new User();
            $userInfo->setUsername($userEntity->username);
            $userInfo->setUserId($userEntity->id);
            $userInfo->setEmail($userEntity->email);
            $userInfo->setAvatar($userEntity->avatar);
            $userInfo->setNickname($userEntity->nickname);
            $userInfo->setSignature($userEntity->signature);
            $rsp->setUser($userInfo);
            return $rsp;
        }
        $error = new Error();
        $error->setCode(10001);
        $error->setMessage("创建用户失败");
        $rsp->setError($error);
        $rsp->setUser(null);

        return $rsp;
    
    }

}

这个文件定义了两个grpc接口一个find一个create。在然后就是定义路由了。

Router::addServer('grpc', function () {
    Router::addGroup('/user.user', function () {
        Router::post('/find', 'AppControllerRpcControllerUserController@find');
        Router::post('/create', 'AppControllerRpcControllerUserController@create');
    });
});

最后需要创建一个grpc的服务,在config/autoload/server.php目录下,在servers数组下添加一个数组。

[
            'name' => 'grpc',
            'type' => Server::SERVER_HTTP,
            'host' => '0.0.0.0',
            'port' => 9503,
            'sock_type' => SWOOLE_SOCK_TCP,
            'callbacks' => [
                SwooleEvent::ON_REQUEST => [HyperfGrpcServerServer::class, 'onRequest'],
            ],
        ],

服务层写完,开始书写服务中层。创建一个项目。

composer create-project hyperf/hyperf-skeleton user-api 

定义protoc 步骤和定义服务层一致,在此不作赘述。

定义一个client端。在App目录下新建一个Grpc目录,并且创建一个UserClient的文件,文件如下。

<?php

declare(strict_types=1);

namespace AppGrpc;

use HyperfGrpcClientBaseClient;
use PhpMicroSrvUserRequest;
use PhpMicroSrvUserResponse;
use PhpMicroSrvUserUser;

class UserClient extends BaseClient
{
    public function find(Request $argument)
    {
        return $this->simpleRequest(
            '/user.user/find',
            $argument,
            [Response::class, 'decode']
        );
    }

    public function create(User $argument)
    {
        return $this->simpleRequest(
            '/user.user/create',
            $argument,
            [Response::class, 'decode']
        );
    }
}

创建一个一个控制器UserController,如下

<?php
/**
 * Author: 陈偲
 * Date: 2019/11/14 14:40
 */
declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://doc.hyperf.io
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
 */

namespace AppController;

use AppGrpcUserClient;
use HyperfHttpServerContractRequestInterface;
use PhpMicroSrvUserRequest;
use PhpMicroSrvUserResponse;
use PhpMicroSrvUserUser;

class UserController extends AbstractController
{

    public function create(RequestInterface $request)
    {
        $username = $request->input("username");
        $password = $request->input("password");
        $phone    = $request->input("phone");
        $nickname = $request->input("nickname");

        $client = new UserClient('127.0.0.1:9503', [
            'credentials' => null,
        ]);

        $req = new User();

        $req->setUsername($username);
        $req->setNickname($nickname);
        $req->setPassword(password_hash($password,PASSWORD_DEFAULT ));
        $req->setPhone($phone);

        /**
         * @var $rsp PhpMicroSrvUserResponse
         */
        list($rsp,$status) = $client->create($req);

        if (!empty($status)) {
            return [
                'code' => 1000,
                'msg'  => "转发请求有误"
            ];
        }
        $error = $rsp->getError();
        if ($error) {
            return [
                'code' => $error->getCode(),
                'msg'  => $error->getMessage(),
            ];
        }

        /**
         * @var $user User
         */
        $user = $rsp->getUser();
        return $user->getUserId();

    }

    public function index()
    {
        $client = new UserClient('127.0.0.1:9503', [
            'credentials' => null,
        ]);


        $req = new Request();

        $req->setType(0);

        $req->setUserId(1);

        /**
         * @var $rsp PhpMicroSrvUserResponse
         */
        list($rsp,$status) = $client->find($req);

        if (!empty($status)) {
            return [
                'code' => 1000,
                'msg'  => "转发请求有误"
            ];
        }

        /**
         * @var $user User
         */
        $user = $rsp->getUser();

        return $user->getUsername();

    }
}

由于两个服务端口号一致,user-api这个服务中层的端口号该改成9502。

然后设置好路由。

Router::addRoute(['GET', 'POST', 'HEAD'], '/user', 'AppControllerUserController@index');
Router::addRoute(['GET', 'POST', 'HEAD'], '/create', 'AppControllerUserController@create');

启动两个服务,请求一下192.168.10.100:9502/user看看结果。

在postman执行一下,然后去数据库看看。

curl -X POST 
  http://192.168.10.100:9502/create 
  -H 'cache-control: no-cache' 
  -H 'content-type: application/json' 
  -d '{
	"username":"苏格拉低",
	"password":"123456",
	"phone":"18026975219",
	"email":"741001560@qq.com",
	"nickname":"木小撇"
}'

下一篇写利用consul做服务发现和健康检查。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值