• 一、背景
  • 二、需求描述
  • 三、构建proto文件
  • 四、网关
  • 五、微服务server端

一、背景

  • 在单体应用时代,客户端向后端服务器发起请求来获取数据。负载均衡器将请求路由给后端的集群服务的某一个,然后后端服务器程序会从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 mainimport ("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, _ := metadata.FromContext(ctx)fmt.Printf("[Log Wrapper] ctx: %v service: %s method: %s\n", md, req.Service(), req.Endpoint())return logWrapper.Client.Call(ctx, req, rsp)
}func NewLogWrapper(c client.Client) client.Client {return &LogWrapper{c}
}func main() {server := micro.NewService(micro.Name("user.client"),micro.Registry(etcd.NewRegistry(registry.Addrs("127.0.0.1:2379"),)),micro.WrapClient(NewLogWrapper),)userServiceClient := Models.NewUserCommonService("user.server", server.Client())httpServer := web.NewService(web.Name("http.server"),web.Address("127.0.0.1:9000"),web.Handler(wepApp.NewRouter(userServiceClient)))httpServer.Run()}
  • Gin路由:此处将rpc service 的 Client入口通过中间件传入Gin的Handle方法中
package webimport ("github.com/gin-gonic/gin"Models "go-micro-service/models""go-micro-service/web/handlers""go-micro-service/web/middlewares"
)func NewRouter(userListService Models.UserCommonService) *gin.Engine {ginRouter := gin.Default()ginRouter.Use(middlewares.UserMiddleware(userListService))ginRouter.Handle("GET", "/users/:size", handlers.GetUsersHandler)ginRouter.Handle("GET", "/user/:userId", handlers.GetUserDetailHandler)return ginRouter
}
  • 中间件:传入User服务相关的 rpc 服务
package middlewaresimport ("github.com/gin-gonic/gin"Models "go-micro-service/models"
)func UserMiddleware(userService Models.UserCommonService) gin.HandlerFunc {// 此处传入 rpc 业务服务return func(ctx *gin.Context) {ctx.Keys = make(map[string]interface{})ctx.Keys["userService"] = userServicectx.Next()}
}
  • Gin Handler:此处调用rpc服务
package handlersimport ("context""github.com/gin-gonic/gin"Models "go-micro-service/models""strconv"
)func GetUsersHandler(ctx *gin.Context) {userService := ctx.Keys["userService"].(Models.UserCommonService)var req Models.UsersRequestsize, _ := strconv.ParseInt(ctx.Param("size"), 10, 32)req = Models.UsersRequest{Size: int32(size)}resp, err := userService.GetUserList(context.Background(), &req)if err != nil {ctx.JSON(500, gin.H{"status": err.Error()})} else {ctx.JSON(200, gin.H{"data": resp.Data})}
}func GetUserDetailHandler(ctx *gin.Context) {userService := ctx.Keys["userService"].(Models.UserCommonService)var req Models.UsersRequestuserId, _ := strconv.ParseInt(ctx.Param("userId"), 10, 32)req = Models.UsersRequest{UserID: int32(userId)}resp, err := userService.GetUserDetail(context.Background(), &req)if err != nil {ctx.JSON(500, gin.H{"status": err.Error()})} else {ctx.JSON(200, gin.H{"data": resp.Data})}
}

五、微服务server端

  • 服务main函数
package mainimport ("github.com/micro/go-micro/v2""github.com/micro/go-micro/v2/registry""github.com/micro/go-micro/v2/registry/etcd"Models "go-micro-service/models""go-micro-service/service"
)func main() {reg := etcd.NewRegistry(registry.Addrs("127.0.0.1:2379"),)server := micro.NewService(micro.Name("user.server"),micro.Registry(reg),)Models.RegisterUserCommonServiceHandler(server.Server(), new(service.UserService))server.Init()server.Run()
}
  • service 业务逻辑单元
package serviceimport ("context""go-micro-service/models""strconv"
)type UserService struct {}func NewUser(id int32, name string) *Models.UserModel {return &Models.UserModel{UserID: id, Name: name}
}func NewUserDetail(id int32) *Models.UserModel {// Sex 1 男  0 女// Role user 普通用户  admin 管理端用户return &Models.UserModel{UserID: id, Name: "Lee" + strconv.FormatInt(int64(id), 10),Sex: "1", Address: "地址" + strconv.FormatInt(int64(id), 10), Role: "user",}
}func NewUserList(size int32) []*Models.UserModel {ret := make([]*Models.UserModel, 0)for i := int32(0); i < size; i++ {ret = append(ret, NewUser(i, "user"+strconv.FormatInt(int64(i), 10)))}return ret
}func (*UserService) GetUserList(ctx context.Context, UserListReq *Models.UsersRequest, UserListResp *Models.UserListResponse) error {UserListResp.Data = NewUserList(UserListReq.Size)return nil
}func (*UserService) GetUserDetail(ctx context.Context, UserDetailReq *Models.UsersRequest, UserDetailResp *Models.UserDetailResponse) error {UserDetailResp.Data = NewUserDetail(UserDetailReq.UserID)return nil
}

微服务之Go-Micro(八)基于Gin框架的Http网关相关推荐

  1. 微服务架构之外的选择——基于服务架构

    来自ThoughtWorks的主管Neal Ford在最近的一次演讲中表达了他对企业软件系统架构转型的看法,他认为从单体架构转向基于服务的架构要比转向微服务架构来得容易.Ford在UberConf 2 ...

  2. 微服务平台(Micro Service Platform : MSP)旨在提供一个集开发、测试、运维于一体的开发者专属平台,让开发者能快速构建或使用微服务,让开发更简单,让运维更高效。...

    微服务平台(Micro Service Platform : MSP)旨在提供一个集开发.测试.运维于一体的开发者专属平台,让开发者能快速构建或使用微服务,让开发更简单,让运维更高效. MSP采用业界 ...

  3. go+vue——基于gin框架和gorm的web开发实战

    go+vue--基于gin框架和gorm的web开发实战 gin框架 视频.资料.笔记 安装Go环境, 添加环境变量(可能自动添加好) 下载 Go 环境变量 goland 报错: GOROOT is ...

  4. 通过Dapr实现一个简单的基于.net的微服务电商系统(八)——一步一步教你如何撸Dapr之链路追踪

    Dapr提供了一些开箱即用的分布式链路追踪解决方案,今天我们来讲一讲如何通过dapr的configuration来实现非侵入式链路追踪的 目录: 一.通过Dapr实现一个简单的基于.net的微服务电商 ...

  5. 牌类游戏使用微服务重构笔记(八): 游戏网关服务器

    网关服务器 所谓网关,其实就是维持玩家客户端的连接,将玩家发的游戏请求转发到具体后端服务的服务器,具有以下几个功能点: 长期运行,必须具有较高的稳定性和性能 对外开放,即客户端需要知道网关的IP和端口 ...

  6. .Net Core with 微服务 - 使用 AgileDT 快速实现基于可靠消息的分布式事务

    前面对于分布式事务也讲了好几篇了(可靠消息最终一致性分布式事务 - TCC分布式事务 - 2PC.3PC https://github.com/kklldog/AgileDT 开源不易,大家多多 ✨✨ ...

  7. JeecgBoot 2.4 微服务正式版发布,基于SpringBoot的低代码平台

    项目介绍 JeecgBoot 是一款基于代码生成器的低代码平台!前后端分离架构 SpringBoot2.x,SpringCloud,Ant Design&Vue,Mybatis-plus,Sh ...

  8. 微服务开发及部署_基于 Kubernetes 的微服务部署即代码

    在基于 Kubernetes 的基础设施即代码一文中,我概要地介绍了基于 Kubernetes 的 .NET Core 微服务和 CI/CD 动手实践工作坊使用的基础设施是如何使用代码描述的,以及它的 ...

  9. 一、微服务基本介绍-背景(基于电商项目)

    一.微服务架构图 二.项目背景介绍 1>电商模式 市面上5种常见的模式: 1.B2B模式(Business to Business): 是指商家与商家建立的商业关系.:例如:阿里巴巴. 2.B2 ...

  10. Gavin老师Transformer直播课感悟 - Rasa项目实战之银行金融Financial Bot智能业务对话机器人业务功能微服务解析与调试(八十九)

    本文继续围绕工业级业务对话平台和框架Rasa,对Rasa项目实战之银行金融Financial Bot智能业务对话机器人的主要业务功能所使用的微服务进行解析,并通过Rasa Interactive的调试 ...

最新文章

  1. 正则表达式--检查颜色值
  2. 青龙羊毛——闪电世界(合集篇)
  3. 研磨设计模式之 策略模式--转
  4. 14c语言课程设计题目,2011级数据库课程设计任务书
  5. latex 多行公式_Markdown中输入多行并列的公式
  6. 计算机多媒体设计徽章,酷毙了:Hackaday将会议徽章设计成一台可编程的电脑
  7. MySQL入门之select、from、join、where子句及基本匹配符
  8. 光电雷达智能跟踪平台
  9. Vue图片上传删除预览操作
  10. GridView中添加自动编号,以及鼠标经过时行背景色变和删除时提示。
  11. JAVA绘制拼音有问题
  12. VS2017适配版的 VA 安装教程
  13. CISSP重点知识总结1
  14. 商业智能知识分享:BI的4大核心技术
  15. RabbitMQ问题解决:TCP connection succeeded but Erlang distribution failed
  16. JVM_0.5_小故事
  17. 使用freemarker导出Word文档(含图片)
  18. 渗透测试 ( 3 ) --- Metasploit Framework ( MSF )
  19. 北京旅游管理PPT计算机二级,计算机二级PPT真题:制作北京景点介绍PPT
  20. Bursuite暴力破解实践

热门文章

  1. 用python玩转数据mooc答案_中国大学慕课mooc用Python玩转数据章节测试答案
  2. excel正在等待某个应用程序以完成对象链接与嵌入操作_ES32 嵌入式开发从这里开始...
  3. 贵州省二级分类土地利用数据(矢量)
  4. 数论入门基础(同余定理/费马小定理/扩展欧几里德算法/中国剩余定理)
  5. mysql 修改root密码 修改账户登录host
  6. vector 详解(C++)
  7. 机器学习:激活函数的作用和原理
  8. linux定时器王贤才,《linux内核设计与实现》 学习笔记(十七)---设备和模块
  9. 如何卸载mingw_minGW在windows安装 | 学步园
  10. git log和reflog