马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
go zero RPC和ETCD
在现实的开发中,微服务通常是分布式的,每个服务运行在独立的历程中,乃至大概在差别的服务器上。RPC答应这些服务以透明的方式相互调用方法,就像在当地调用一样,从而简化了服务间的通讯。
RPC使调用者不须要关注服务的实现细节,只需知道接口,更方便协作编程 ,多数RPC框架可以大概根据服务界说主动天生客户端代码,淘汰了人为错误并加速了开发过程。
RPC可以比传统的HTTP/REST更快地举行数据互换,这在须要高性能和低耽误的微服务体系中尤为告急
一、API和RPC
1.API 和 RPC 的关系
API和RPC是两种差别的服务交互模式,分别用于处理处罚HTTP哀求和服务间的远程调用。
- API(应用步伐编程接口):
- API通常用于袒露微服务的HTTP接口,答应客户端(如前端应用)通过HTTP哀求与微服务举行交互。
- API重要处理处罚用户哀求,举行输入验证、路由、HTTP状态码处理处罚等。
- RPC(远程过程调用):
- RPC用于微服务之间的直接调用,通常通过协议(如gRPC)举行通讯。
- RPC更得当于内部服务之间的高效交互,特殊是在须要低耽误和高吞吐量的场景中。
2.API 文件与 Proto 文件的约定
在项目开发中,API界说和RPC界说应保持肯定的约定,以确保服务的同等性和可维护性:
- 接口界说同等性:
- API层和RPC层应只管保持同等的接口,比如在API层界说的哀求和相应布局体,RPC层也应使用类似或相似的布局体。这有助于低落服务侵入和明白本钱。
- 数据布局的映射:
- 当API哀求到达时,通常须要将HTTP哀求参数映射到RPC调用的参数。此时,可以界说一个公共的哀求和相应数据布局,以淘汰重复界说和维护本钱。
- 错误处理处罚同等性:
- 在API和RPC之间应保持类似的错误处理处罚逻辑,以便在发生错误时可以大概提供同等的错误相应。
3.示例约定
- **API 文件(.api)**示例:
- # 文件: user.api
- service user-api {
-
-
- @server(
- rest: {
-
-
- path: /users,
- method: POST
- }
- )
- register(req RegisterRequest) returns (RegisterResponse);
- @server(
- rest: {
-
-
- path: /users/{
-
- id},
- method: GET
- }
- )
- getUser(id int64) returns (GetUserResponse);
- }
- message RegisterRequest {
-
-
- string name = 1;
- int32 age = 2;
- }
- message RegisterResponse {
-
-
- int64 id = 1;
- }
- message GetUserResponse {
-
-
- string name = 1;
- int32 age = 2;
- }
复制代码
- **Proto 文件(.proto)**示例:
- ```protobuf
- syntax = "proto3";
- package user;
- service UserService {
-
-
- rpc Register(RegisterRequest) returns (RegisterResponse);
- rpc GetUser(GetUserRequest) returns (GetUserResponse);
- }
- message RegisterRequest {
-
-
- string name = 1;
- int32 age = 2;
- }
- message RegisterResponse {
-
-
- int64 id = 1;
- }
- message GetUserRequest {
-
-
- int64 id = 1; // 请求者根据ID获取用户信息
- }
- message GetUserResponse {
-
-
- string name = 1;
- int32 age = 2;
- }
复制代码 下面我将通过一个简朴的示例,分析怎样使用go zero框架和 Protocol Buffers 界说 RPC 服务。
二、天生 RPC代码
在这个教程中,我们根据user.api文件,来编写一个user.proto 文件,创建一个用户管理的 RPC 服务.
1.回顾user.api
go zero的 API 文件通常界说 HTTP 接口,包罗哀求和相应的格式。它重要用于 RESTful API 的界说。
我们先来回顾下之前的user.api文件
- type (
- RegisterRequest {
-
-
- Username string `json:"username" validate:"required"` // 注册请求,用户名
- Password string `json:"password" validate:"required"` // 注册请求,密码
- }
- RegisterResponse {
-
-
- Message string `json:"message"` // 响应消息
- }
- )
- type (
- LoginRequest {
-
-
- Username string `json:"username" validate:"required"` // 登录请求,用户名
- Password string `json:"password" validate:"required"` // 登录请求,密码
- }
- LoginResponse {
-
-
- Token string `json:"token"` // 登录响应,JWT token
- }
- )
- @server (
- group: user // 代表当前 service 代码块下的路由生成代码时都会被放到 user 目录下
- prefix: /v1 //定义路由前缀为 "/v1"
- )
- // 微服务名称为 user-ap,生成的代码目录和配置文件将和 user 值相关
- service user-api {
-
-
- //用户注册
- @handler RegisterHandler
- //提交post请求 RegisterRequest为请求体 RegisterResponse为响应体
- post /register (RegisterRequest) returns (RegisterResponse)
- //用户登录
- @handler LoginHandler
- post /login (LoginRequest) returns (LoginResponse)
- }
- //因为我们想要通过jwt来传递数据,所以我们不需求请求信息
- type (
- GetInfoResponse {
-
-
- Username string `json:"username" `
- Password string `json:"password" `
- }
- )
- //更新数据我们就简单修改下密码
- type (
- UpdataRequest {
-
-
- Password string `json:"password" ` // 更新请求,新的密码
- }
- UpdataResponse {
-
-
- Message string `json:"message"` // 更新响应消息
- }
- )
- @server (
- group: user
- prefix: /v1
- jwt: Auth //开启jwt
- )
- service user-api {
-
-
- @handler GetInfoHandler
- // 不需要请求信息
- post /getinfo returns (GetInfoResponse)
- @handler UpdataHandler
- post /updata (UpdataRequest) returns (UpdataResponse)
- }
复制代码 2. 创建user.proto 文件
Proto 文件,用于界说 gRPC 服务和消息格式。它重要用于远程过程调用(RPC),使用 Protocol Buffers 举行数据序列化。
根据user.api文件创建user.proto文件:
- syntax = "proto3"; //声明使用 Protocol Buffers 的版本为 3
- //proto 包名
- package pb;
- //生成 golang 代码后的包名
- option go_package ="./pb"; //必须要有“./” 这样的路径
- //指定生成的 Go 代码的包名为 pb,在同一目录下创建一个名为 pb 的包
- //定义用户消息结构
- message Users {
-
-
- int64
复制代码 |