微服务从代码到k8s部署应有尽有系列(五、民宿服务)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 微服务从代码到k8s部署应有尽有系列(五、民宿服务)

我们用一个系列来讲解从需求到上线、从代码到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

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
1月前
|
运维 Kubernetes Docker
利用Docker和Kubernetes构建微服务架构
利用Docker和Kubernetes构建微服务架构
|
15天前
|
关系型数据库 MySQL Docker
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
75 24
|
8天前
|
存储 Kubernetes 容器
K8S部署nexus
该配置文件定义了Nexus 3的Kubernetes部署,包括PersistentVolumeClaim、Deployment和服务。PVC请求20Gi存储,使用NFS存储类。Deployment配置了一个Nexus 3容器,内存限制为6G,CPU为1000m,并挂载数据卷。Service类型为NodePort,通过30520端口对外提供服务。所有资源位于`nexus`命名空间中。
|
17天前
|
关系型数据库 MySQL Docker
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
96 6
|
1月前
|
Kubernetes Cloud Native 微服务
云原生入门与实践:Kubernetes的简易部署
云原生技术正改变着现代应用的开发和部署方式。本文将引导你了解云原生的基础概念,并重点介绍如何使用Kubernetes进行容器编排。我们将通过一个简易的示例来展示如何快速启动一个Kubernetes集群,并在其上运行一个简单的应用。无论你是云原生新手还是希望扩展现有知识,本文都将为你提供实用的信息和启发性的见解。
|
29天前
|
Kubernetes Cloud Native 持续交付
容器化、Kubernetes与微服务架构的融合
容器化、Kubernetes与微服务架构的融合
47 1
|
1月前
|
监控 安全 持续交付
构建高效的微服务架构:从设计到部署
构建高效的微服务架构:从设计到部署
25 1
|
1月前
|
监控 持续交付 Docker
Docker 容器化部署在微服务架构中的应用有哪些?
Docker 容器化部署在微服务架构中的应用有哪些?
|
1月前
|
监控 持续交付 Docker
Docker容器化部署在微服务架构中的应用
Docker容器化部署在微服务架构中的应用
|
1月前
|
安全 持续交付 Docker
微服务架构和 Docker 容器化部署的优点是什么?
微服务架构和 Docker 容器化部署的优点是什么?