我们用一个系列来讲解从需求到上线、从代码到k8s部署、从日志到监控等各个方面的微服务完整实践。

整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中间件,所用到的技术栈基本是go-zero项目组的自研组件,基本是go-zero全家桶了。

实战项目地址:https://github.com/Mikaelemmmm/go-zero-looklook

1、民宿服务业务架构图

2、依赖关系

travel-api(民宿api) 依赖 travel-rpc(民宿rpc)、usercenter-rpc(用户中心rpc)

usercenter-rpc(用户中心rpc)依赖 identity-rpc(授权中心rpc)

travel分为几个业务

  • homestay :民宿房源
// 民宿模块v1版本的接口
@server(
prefix: travel/v1
group: homestay
)
service travel {
@doc "民宿列表(为你优选)"
@handler homestayList
post /homestay/homestayList (HomestayListReq) returns (HomestayListResp) @doc "房东所有民宿列表"
@handler businessList
post /homestay/businessList (BusinessListReq) returns (BusinessListResp) @doc "猜你喜欢民宿列表"
@handler guessList
post /homestay/guessList (GuessListReq) returns (GuessListResp) @doc "民宿详情"
@handler homestayDetail
post /homestay/homestayDetail (HomestayDetailReq) returns (HomestayDetailResp)
}
  • homestayBusiness : 民宿店家
// 店铺模块v1版本的接口
@server(
prefix: travel/v1
group: homestayBussiness
)
service travel {
@doc "最佳房东"
@handler goodBoss
post /homestayBussiness/goodBoss (GoodBossReq) returns (GoodBossResp) @doc "店铺列表"
@handler homestayBussinessList
post /homestayBussiness/homestayBussinessList (HomestayBussinessListReq) returns (HomestayBussinessListResp) @doc "房东信息"
@handler homestayBussinessDetail
post /homestayBussiness/homestayBussinessDetail (HomestayBussinessDetailReq) returns (HomestayBussinessDetailResp)
}
  • homestayComment : 民宿评论
// 民宿评论模块v1版本的接口
@server(
prefix: travel/v1
group: homestayComment
)
service travel {
@doc "民宿评论列表"
@handler commentList
post /homestayComment/commentList (CommentListReq) returns (CommentListResp)
}

3、举例:民宿列表(为你优选)

1、api服务

1、写api接口文件

app/travel/cmd/api/desc/homestay/homestay.api

type (
HomestayListReq {
LastId int64 `json:"lastId"`
PageSize int64 `json:"pageSize"`
RowType string `json:"rowType"` //preferredHomestay:优选民宿
}
HomestayListResp {
List []Homestay `json:"list"`
}
)

app/travel/cmd/api/desc/travel.api

import (
"homestay/homestay.api"
....
) // 民宿模块v1版本的接口
@server(
prefix: travel/v1
group: homestay
)
service travel {
@doc "民宿列表(为你优选)"
@handler homestayList
post /homestay/homestayList (HomestayListReq) returns (HomestayListResp)
......
}

2、goctl生成api代码

1)命令行进入app/travel/cmd/api/desc目录下。

2)去项目目录下deploy/script/gencode/gen.sh中,复制如下一条命令,在命令行中执行(命令行要切换到app/travel/cmd目录)

$ goctl api go -api *.api -dir ../  -style=goZero

3、打开app/travel/cmd/api/internal/logic/homestay/homestayListLogic.go

因为我们的推荐是在后台配置的,所以我们创建了一个活动表(这里你也可以选择配置到redis中),总之我们就是先从活动表中拿到配置的推荐民宿id,然后再通过id去获取对应民宿信息列表。

2【小技巧】 mapreduce

这里可以看到,我拿到了id集合之后,不是普通的foreach一个个获取,而是使用了go-zero为我们封装好了的mapreduce获取数据,这样就可以并发去获取数据,而不是要去取一个完成之后再取下一个,时间上大大缩短了,这里只是想给搭建展示这样一个功能,有的同学非要较真,可以传递一个id slice或者id arr到rpc,然后在rpc中在去并发获取每个,这样也没什么不好,我这里只是给大家展示这个功能

3、rpc服务

定义protobuf文件

app/travel/cmd/rpc/pb/travel.proto

// model
message Homestay {
int64 id = 1;
string title = 2;
string subTitle = 3;
string banner = 4;
string info = 5;
int64 peopleNum = 6; // 容纳人的数量
int64 homestayBusinessId = 7; // 店铺id
int64 userId = 8; // 房东id
int64 rowState = 9; // 0:下架 1:上架
int64 rowType = 10; // 售卖类型0:按房间出售 1:按人次出售
string foodInfo = 11; // 餐食标准
int64 foodPrice = 12; // 餐食价格(分)
int64 homestayPrice = 13; // 民宿价格(分)
int64 marketHomestayPrice = 14; // 民宿市场价格(分)
} // req 、resp
message HomestayDetailReq {
int64 id = 1;
}
message HomestayDetailResp {
Homestay homestay = 1;
} // service
service travel {
// 民宿详情
rpc homestayDetail(HomestayDetailReq) returns(HomestayDetailResp);
}
  • 使用goctl生成代码,这里不需要自己手动敲

    1)命令行进入app/travel/cmd/rpc/pb目录下。

    2)去项目目录下deploy/script/gencode/gen.sh中,复制如下两条命令,在命令行中执行(命令行要切换到app/travel/cmd目录)

    $ goctl rpc protoc *.proto --go_out=../ --go-grpc_out=../  --zrpc_out=../
    $ sed -i "" 's/,omitempty//g' *.pb.go
  • 打开app/travel/cmd/rpc/internal/logic/homestayDetailLogic.go写逻辑代码

    这里没什么逻辑,查询Findone,然后返回给api,因为api那边是通过id传递过来的,然后可以看到我们这边又一次使用了前一章提到的gorm作者提供的另外一款神器copier,上一节是在api中使用,将rpc的proto文件的数据copy到api文件 , 这里可以看到,我们把model返回的数据copy给proto的数据同样可以用,怎么样是不是很方便。

4、【小技巧】 model cache、singleflight

在这里为什么我们不去findlist,是因为我们在findone方法中有缓存,我们一个个根据id查询数据时候,只有第一次会命中db,其他时间基本都是命中的redis cache,这样不仅速度快,就算流量激增的时候,也不会全部打到db上,而是都在redis上,这样会大大提高我们系统的访问速度以及db支撑能力。

一般我们自己维护db cache会写的零零散散,但是go-zero使用了配套内置工具goctl生成的model,自带sqlc+sqlx实现的代码,实现了自动缓存管理,我们根本不需要去管理缓存,只需要用sqlx写 sql数据,sqlc会自动帮我们管理缓存,并且是通过singleflight ,也就是说即使缓存在某个时间失效,在失效那一刻同时有大量并发请求进来时,go-zero在查询db时候也只会放行一个线程进来,其他线程是在等待,当这个线程从数据库拿数据回来之后将该数据缓存到redis同时所有之前等待线程共享此数据返回,后续在进来的线程查相同数据时,就只会进入到redis中而不会进入到db。

这样rpc拿到所有数据之后,就可以返回给前端显示了。

4、小结

其他的几个服务没有业务什么逻辑性的这里就不再一一说明,看api文档基本都知道是什么了,根据上面例子代码自行查看即可,后面有牵扯业务复杂的地方会逐一说明

项目地址

https://github.com/zeromicro/go-zero

欢迎使用 go-zerostar 支持我们!

微信交流群

关注『微服务实践』公众号并点击 交流群 获取社区群二维码。

微服务从代码到k8s部署应有尽有系列(五、民宿服务)的更多相关文章

  1. 微服务从代码到k8s部署应有尽有系列(十三、服务监控)

    我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...

  2. 微服务从代码到k8s部署应有尽有系列(一)

    从本篇文章开始,我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 实战项目地址:https://github.com/Mikaelemmmm/go-zer ...

  3. 微服务从代码到k8s部署应有尽有系列(二、网关)

    我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...

  4. 微服务从代码到k8s部署应有尽有系列(三、鉴权)

    我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...

  5. 微服务从代码到k8s部署应有尽有系列(四、用户中心)

    我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...

  6. 微服务从代码到k8s部署应有尽有系列(六、订单服务)

    我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...

  7. 微服务从代码到k8s部署应有尽有系列(十四、部署环境搭建)

    我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...

  8. 微服务从代码到k8s部署应有尽有系列(七、支付服务)

    我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...

  9. 微服务从代码到k8s部署应有尽有系列(八、各种队列)

    我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...

随机推荐

  1. POJ 1664 放苹果 (递推思想)

    原题链接:http://poj.org/problem?id=1664 思路:苹果m个,盘子n个.假设 f ( m , n ) 代表 m 个苹果,n个盘子有 f ( m , n ) 种放法. 根据 n ...

  2. HIVE优化学习笔记

    概述 之前写过关于hive的已经有两篇随笔了,但是作者依然还是一枚小白,现在把那些杂七杂八的总结一下,供以后查阅和总结.今天的文章介绍一下hive的优化.hive是好多公司都在使用的东西,也有好多大公 ...

  3. ADO.NET数据访问基础与综合应用2020年10月31日20:17:09学习笔记

    四.创建数据表 1.数据表的名称. 2.表中的字段名.数据类型.是否可以为空.字段的约束.必备的字段(通常会有一个ID,表示实体的唯一性:可以直接手写,也可以使用种子标识自动生成,给定起始值,给定增长 ...

  4. 五天学完MySQL打卡挑战 day01

    明天继续上传学习笔记和练习的Word文档 晚安~

  5. 12.25 补充总结-jsp标签

    注:标签引用时,需在jsp 头部添加如下语句 <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c ...

  6. 字符串工具类ToStringBuilder常用方法介绍

    一.简介与引入   1.ToStringBuilder.HashCodeBuilder.EqualsBuilder.ToStringStyle.ReflectionToStringBuilder.Co ...

  7. default和delete

    在C++中,有四类特殊的成员函数,分别为:默认构造函数,默认析构函数,默认拷贝构造函数,默认赋值运算符.他们的作用为创建.初始化.销毁.拷贝对象. 虽然在类A中什么都没有定义,但是编译会通得过,因为编 ...

  8. 多线程-其他方法-join等

    1 package multithread4; 2 3 /* 4 * toString():返回该线程的字符串表现形式,包括线程名称.优先级和线程组 5 * Thread[Thread-0,5,mai ...

  9. linux关闭防火墙与开启防火墙命令

    一:下面是red hat/CentOs7关闭防火墙的命令! 1:查看防火状态 systemctl status firewalld service iptables status 2:暂时关闭防火墙 ...

  10. Azure AD Domain Service(一)将 Azure VM 实例添加到域服务里

    一,引言 有网友提到实际项目中如何将 Azuer VM 实例加入到 Azure AD 域,那我们今天就带着整个问题开始今天的分析!首先我们得了解什么是 Azure AD 域服务,Azure AD 域服 ...