## 編寫一個微服務
通過編寫一個微服務,讓我們快速了解框架的使用,編寫一個微服務非常簡單,其實就是啟動一個命令行程序,在程序中啟動一個 gRPC Server,然后將 Service 注冊到 Server 中即可。
## 定義 API
我們使用 protobuf 文件來定義服務 API 接口。這是一種非常方便的方式來嚴格定義 API 并為服務器和客戶端提供具體的類型。
這是一個示例定義。
greeter.proto
~~~
syntax = "proto3";
package php.micro.grpc.greeter;
service Say {
rpc Hello(Request) returns (Response) {}
}
message Request {
string name = 1;
}
message Response {
string msg = 1;
}
~~~
在這里,我們定義了名為 php.micro.grpc.greeter 的服務,服務中定義了 Say.Hello 方法。
## 生成 API 接口
我們將上面的 .proto 文件保存到 [/protos](https://github.com/mix-php/mix-micro-skeleton/tree/master/protos) 目錄,使用代碼生成工具生成 Server/Client 代碼,工具的安裝見 “安裝說明->微服務開發” 章節。
```
protoc --php_out=. --mix_out=. greeter.proto
```
執行后將生成以下文件:
```
├── GPBMetadata
│?? └── Greeter.php
├── Php
│?? └── Micro
│?? └── Grpc
│?? └── Greeter
│?? ?? ├── Request.php
│?? ?? ├── Response.php
│?? ?? ├── SayClient.php
│?? ?? └── SayInterface.php
└── greeter.proto
```
其中 Request.php、Response.php 為 `--php_out` 生成,SayClient.php SayInterface.php 由 `--mix_out` 生成。
接下來我們將生成的文件加入到 composer autoload 中,我們修改 composer.json:
```
"autoload-dev": {
"psr-4": {
"GPBMetadata\\": "protos/GPBMetadata/",
"Php\\": "protos/Php/"
}
}
```
修改后執行 `composer dump-autoload` 使其生效。
## 實現處理程序
編寫一個服務類,實現 protoc-gen-mix 生成的 SayInterface 接口:
~~~
<?php
namespace App\Grpc\Services\Greeter;
use Mix\Context\Context;
use Php\Micro\Grpc\Greeter\Response;
use Php\Micro\Grpc\Greeter\SayInterface;
/**
* Class SayService
* @package App\Grpc\Services\Greeter
*/
class SayService implements SayInterface
{
/**
* Hello
* @param Context $context
* @param \Php\Micro\Grpc\Greeter\Request $request
* @return Response
*/
public function Hello(Context $context, \Php\Micro\Grpc\Greeter\Request $request): Response
{
$response = new Response();
$response->setMsg(sprintf('hello, %s', $request->getName()));
return $response;
}
}
~~~
骨架中提供了 `StartCommand.php` 的通用啟動命令,里面包含:
- Server 啟動/停止:[StartCommand.php#L63](https://github.com/mix-php/mix-micro-skeleton/blob/master/app/Grpc/Commands/StartCommand.php#L63)
- 微服務注冊:[StartCommand.php#L95](https://github.com/mix-php/mix-micro-skeleton/blob/master/app/Grpc/Commands/StartCommand.php#L95)
- 處理程序注冊到 Server 中:創建一個 [GreeterCommand.php#L19](https://github.com/mix-php/mix-micro-skeleton/blob/master/app/Grpc/Commands/GreeterCommand.php#L18) 繼承 `StartCommand::class` 并實現 init 方法。
- 在命令配置中配置 `GreeterCommand::class` 啟動命令:[commands/grpc.php#L5](https://github.com/mix-php/mix-micro-skeleton/blob/master/manifest/commands/grpc.php#L5)
## 運行服務
~~~
$ php bin/mix.php grpc:greeter
____
______ ___ _____ ___ _____ / /_ _____
/ __ `__ \/ /\ \/ /__ / __ \/ __ \/ __ \
/ / / / / / / /\ \/ _ / /_/ / / / / /_/ /
/_/ /_/ /_/_/ /_/\_\ / .___/_/ /_/ .___/
/_/ /_/
Server Name: mix-grpc
System Name: darwin
PHP Version: 7.3.12
Swoole Version: 4.5.0RC1
Framework Version: 2.2.2
[2020-05-19 18:49:21] GRPC.INFO: Server started [0.0.0.0:57249]
[2020-05-19 18:49:21] GRPC.INFO: Register service [php.micro.grpc.greeter-6593b8aa-99be-11ea-8195-000057bdb82e]
~~~
## 寫一個客戶端
通常我們在 API、Web 模塊中調用 gRPC 服務:
~~~
// 通過服務名稱撥號一個連接
$dialer = new \Mix\JsonRpc\Client\Dialer([
'registry' => new \Mix\Micro\Etcd\Registry('http://127.0.0.1:2379/v3'),
]);
$conn = $dialer->dialFromService('php.micro.grpc.greeter');
// 通過連接創建客戶端
$client = new \Php\Micro\Grpc\Greeter\SayClient($conn);
// 發送請求
$request = new \Php\Micro\Grpc\Greeter\Request();
$request->setName('xiaoming');
$response = $client->Hello($request);
// 打印結果
var_dump($response->getMsg());
~~~
- 查看客戶端調用實例:[SayController.php#L54](https://github.com/mix-php/mix-micro-skeleton/blob/master/app/Api/Controllers/Greeter/SayController.php#L54)
- 歡迎使用 MixPHP
- 安裝說明
- 全棧開發
- 微服務開發
- Phar 開發
- 如何部署
- 獨立部署
- Nginx
- Supervisord
- 新手教程
- 命令行常識
- 進程管理
- 熱更新
- 全局變量
- 調試程序
- 入門須知
- 命名空間
- 自動加載
- 入口文件
- 增改應用
- 自動補全 IDE
- 核心功能
- 配置 (manifest.php)
- 依賴注入
- 事件調度
- 驗證器
- 驗證器定義
- 驗證規則
- 靜態調用
- 日志 Monolog
- 緩存
- 協程
- 什么是協程
- 開啟協程
- Runtime
- 簡介
- 創建協程 xgo + Channel
- 創建協程 xgo + WaitGroup
- xgo
- xdefer
- Channel
- WaitGroup
- Timer + Ticker
- Signal
- Select
- Context
- WorkerPool
- 數據庫
- Database
- Database
- Connection
- QueryBuilder
- ExecutedEvent
- Redis
- Redis
- Connection
- CalledEvent
- 命令行
- 簡介
- Application
- 創建命令
- 命令參數
- 打印與顏色
- 守護進程
- 后臺運行
- Web/API 應用
- 簡介
- 編寫一個接口
- 服務器
- 路由 FastRoute
- 中間件
- 請求
- 響應
- 文件上傳
- 控制器
- 視圖
- Auth
- Session
- Guzzle
- HTTP 404/500
- 安全建議
- WebSocket 應用
- 簡介
- 服務器
- 客戶端
- Client
- JavaScript
- Swoole
- nginx代理
- 60s無消息斷線
- Micro 微服務
- 簡介
- 編寫一個微服務
- Mix Micro
- Go Micro
- gRPC
- JSON-RPC
- 服務注冊
- 配置中心
- 熔斷與降級
- 調用鏈追蹤
- 服務限流
- Sync Invoke 同步調用
- 簡介
- 服務器
- 客戶端
- TCP 應用
- 簡介
- 服務器
- 客戶端
- Telnet
- PHP
- Swoole
- UDP 應用
- 簡介
- 服務器
- 客戶端
- NC
- Swoole
- 第三方接入
- EasyWeChat
- Sentry
- Doctrine Cache
- 常見問題
- 如何利用 CPU 多核
- 連接多個數據庫
- 如何設置跨域
- form-data 上傳文件失敗
- 輸出大于 2M 的文件失敗