背景
- 在单体应用时代,客户端向后端服务器发起请求来获取数据。负载均衡器将请求路由给后端的集群服务的某一个,然后后端服务器程序会从DB获取数据返回给客户端。微服务架构下,单体应用被切割成多个微服务,如果将多个微服务直接对外暴露,肯定会出现诸多问题
- 客户端的请求报文和微服务暴露的API不匹配,协议可能都不一样,有的是二进制的rpc,也可能使用某种消息传递协议
- 微服务难以重构,为了满足需求合并或者重构服务势必导致开发成本
- 因此,微服务网关应运而生
需求描述
- 客户端向基于Gin框架构建Http网关发起请求
- 在网关处通过rpc客户端调用rpc服务端获取相关业务数据
- 获取用户列表
- 获取用户详细信息
- 源码地址
构建proto文件
- Users.proto 存放实体模型
syntax = "proto3";
package Models;
option go_package = "./;Models";
message UserModel {
// @inject_tag: json:"uid"
int32 UserID = 1;
// @inject_tag: json:"name"
string Name = 2;
// @inject_tag: json:"addr"
string Address = 3;
// @inject_tag: json:"sex"
string Sex = 4;
// @inject_tag: json:"role"
string Role = 5;
}
- UserService.proto 存放微服务的请求响应模型
syntax = "proto3";
package Models;
option go_package = "./;Models";
import "Users.proto";
message UsersRequest {
int32 size = 1;
// @inject_tag: uri:"uid" json:"uid"
int32 UserID = 2;
}
message UserListResponse {
repeated UserModel data=1;
}
message UserDetailRequest {
int32 userId = 1;
}
message UserDetailResponse {
UserModel data=1;
}
service UserCommonService {
rpc GetUserList(UsersRequest) returns (UserListResponse);
rpc GetUserDetail(UsersRequest) returns (UserDetailResponse);
}
- 通过 protoc 生成 rpc相关的go 模型文件
网关
- RPC client端
package main
import (
"context"
"fmt"
"github.com/micro/go-micro/v2"
"github.com/micro/go-micro/v2/client"
"github.com/micro/go-micro/v2/metadata"
"github.com/micro/go-micro/v2/registry"
"github.com/micro/go-micro/v2/registry/etcd"
"github.com/micro/go-micro/v2/web"
Models "go-micro-service/models"
wepApp "go-micro-service/web"
)
type LogWrapper struct {
client.Client
}
func (logWrapper *LogWrapper) Call(ctx context.Context, req client.Request, rsp interface{
}, opts ...client.CallOption) error {
md, _ :=