乐趣区

关于golang:微服务从代码到k8s部署应有尽有系列一

从本篇文章开始,咱们用一个系列来解说从需要到上线、从代码到 k8s 部署、从日志到监控等各个方面的微服务残缺实际。

实战我的项目地址:https://github.com/Mikaelemmm…

一、我的项目简介

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

我的项目目录构造如下:

  • app:所有业务代码蕴含 api、rpc 以及 mq(音讯队列、提早队列、定时工作)
  • common:通用组件 error、middleware、interceptor、tool、ctxdata 等
  • data:该我的项目蕴含该目录依赖所有中间件 (mysql、es、redis、grafana 等) 产生的数据,此目录下的所有内容应该在 git 疏忽文件中,不须要提交。
  • deploy:

    • filebeat: docker 部署 filebeat 配置
    • go-stash:go-stash 配置
    • nginx: nginx 网关配置
    • prometheus:prometheus 配置
    • script:

      • gencode:生成 api、rpc,以及创立 kafka 语句,复制粘贴应用
      • mysql:生成 model 的 sh 工具
    • goctl: 该我的项目 goctl 的 template,goctl 生成自定义代码模版,tempalte 用法可参考 go-zero 文档,复制到家目录下.goctl 即可,
      该我的项目用到 goctl 版本是 v1.3.0
  • doc : 该我的项目系列文档

二、用到技术栈

  • go-zero
  • nginx 网关
  • filebeat
  • kafka
  • go-stash
  • elasticsearch
  • kibana
  • prometheus
  • grafana
  • jaeger
  • go-queue
  • asynq
  • asynqmon
  • dtm
  • docker
  • docker-compose
  • mysql
  • redis

三、我的项目架构图

四、业务架构图

五、我的项目环境搭建

本我的项目采纳 air 热加载功即时批改代码及时失效,并且不须要每次都要重启,改了代码主动就在容器中从新加载了,本地不须要启动服务,本地装置的 sdk 就是写代码主动提醒应用的,理论运行是以来容器中 cosmtrek/air 的 golang 环境。所以应用 goland、vscode 都一样

1、clone 代码 & 更新依赖

$ git clone git@github.com:Mikaelemmmm/go-zero-looklook.git
$ go mod tidy

2、启动我的项目所依赖的环境

$ docker-compose -f docker-compose-env.yml up -d

jaeger: http://127.0.0.1:16686/search

asynq(延时、定时音讯队列): http://127.0.0.1:8980/

kibana: http://127.0.0.1:5601/

Elastic search: http://127.0.0.1:9200/

Prometheus: http://127.0.0.1:9090/

Grafana: http://127.0.0.1:3001/

Mysql: 自行客户端工具 (Navicat、Sequel Pro) 查看

  • host : 127.0.0.1
  • port : 33069
  • username : root
  • pwd : PXDN93VRKUm8TeE7

Redis: 自行工具(redisManager)查看

  • host : 127.0.0.1
  • port : 63799
  • pwd : G62m50oigInC30sf

Kafka: 自行客户端工具查看

  • host : 127.0.0.1
  • port : 9092

3、拉取我的项目依赖镜像

因为本我的项目是用 air 热加载的,所以是在 air+golang 镜像中运行,间接 docker-compose 也能够,然而思考依赖可能会比拟大,会影响启动我的项目,所以最好先把这个镜像拉取下来再去启动我的项目,拉取 air+golang 我的项目依赖的镜像命令如下

$ docker pull cosmtrek/air:latest

4、导入 mysql 数据

创立数据库 looklook_order && 导入 deploy/sql/looklook_order.sql 数据

创立数据库 looklook_payment && 导入 deploy/sql/looklook_payment.sql 数据

创立数据库 looklook_travel && 导入 deploy/sql/looklook_travel.sql 数据

创立数据库 looklook_usercenter && 导入 looklook_usercenter.sql 数据

5、启动我的项目

$ docker-compose up -d 

【注】依赖的是我的项目根目录下的 docker-compose.yml 配置

6、查看我的项目运行状况

拜访 http://127.0.0.1:9090/,点击下面菜单“Status”,在点击 Targets , 蓝色的就是启动成了,红色就是没启动胜利

【注】如果是第一次拉取我的项目,每个我的项目容器第一次构建拉取依赖,这个看网络状况,可能会比较慢有的服务,所以会导致我的项目启动失败或者被依赖的服务启动失败本人也启动失败了,这个很失常,如果碰到我的项目启动不起来的状况,比方 order-api,这时候咱们去看下日志就能够

$ docker logs -f order-api 

很显著是因为 order-rpc 启动工夫太久了,而 order-api 始终等他启动,order-rpc 肯定工夫内没有启动胜利,order-api 没急躁了(超时了),就算前面 order-rpc 启动起来,它也不论了,这时候再去重启一次 order-api 就能够了,这个只是第一次创立容器会这样,之后只有不销毁容器就不会,咱们去到我的项目根目录下重启一下

$ docker-compose restart order-api

【留神】肯定要去到我的项目根目录下重启,因为 docker-compose.yml 在我的项目根目录

而后咱们在看一下,这里咱们应用 docker logs 看了

  __    _   ___  
 / /\  | | | |_) 
/_/--\ |_| |_| \_ , built with Go 1.17.6

mkdir /go/src/github.com/looklook/app/order/cmd/api/tmp
watching .
watching desc
watching desc/order
watching etc
watching internal
watching internal/config
watching internal/handler
watching internal/handler/homestayOrder
watching internal/logic
watching internal/logic/homestayOrder
watching internal/svc
watching internal/types
!exclude tmp
building...
running...

能够看到 order-api 曾经胜利了,再去 prometheus 看一下

能够看到 prometheus 也显示胜利了,同理把其余的也排查一次,启动胜利就能够了

7、拜访我的项目

因为咱们应用 nginx 做的网关,nginx 网关配置在 docker-compose 中,也是配置在 docker-compose 中,nignx 对外裸露端口是 8888,所以咱们通过 8888 端口拜访

$ curl  -X POST "http://127.0.0.1:8888/usercenter/v1/user/register" -H "Content-Type: application/json" -d "{\"mobile\":\"18888888888\",\"password\":\"123456\"}" 

返回:
{"code":200,"msg":"OK","data":{"accessToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NzM5NjY0MjUsImlhdCI6MTY0MjQzMDQyNSwiand0VXNlcklkIjo1fQ.E5-yMF0OvNpBcfr0WyDxuTq1SRWGC3yZb9_Xpxtzlyw","accessExpire":1673966425,"refreshAfter":1658198425}}

【注】如果是拜访 nginx 失败,拜访胜利能够疏忽,可能是 nginx 依赖后端服务,之前因为后端服务没启动起来,nginx 这里没启动起来,重启一次 nginx 即可, 我的项目根目录下重启

$ docker-compose restart nginx

六、日志收集

将我的项目日志收集到 es(filebeat 收集日志 ->kafka -> go-stash 生产 kafka 日志 -> 输入到 es 中, kibana 查看 es 数据)

所以咱们要提前在 kafka 中创立日志的 topic

进入 kafka 容器

$ docker exec -it kafka /bin/sh

创立 log 的 topic

$ cd /opt/kafka/bin
$ ./kafka-topics.sh --create --zookeeper zookeeper:2181 --replication-factor 1 -partitions 1 --topic looklook-log

拜访 kibana http://127.0.0.1:5601/,创立日志索引

点击左上角菜单(三个横线那个东东),找到 Analytics – > 点击 discover

而后在以后页面,Create index pattern-> 输出 looklook-* -> Next Step -> 抉择 @timestamp->Create index pattern

而后点击左上角菜单,找到 Analytics-> 点击 discover,日志都显示了(如果不显示,就去排查 filebeat、go-stash,应用 docker logs -f filebeat 查看)

七、本我的项目镜像介绍

所有服务启动胜利,应该是如下这些,自行比照

  • nginx : 网关(nginx->api->rpc)
  • cosmtrek/air : 咱们业务代码开发依赖的环境镜像,之所以用这个是因为 air 热加载,写代码实时编译太不便了,这个镜像是 air+golang,实际上咱们启咱们本人的业务服务后,咱们的业务服务是运行在此镜像中的
  • wurstmeister/kafka:业务应用的 kafka
  • wurstmeister/zookeeper:kafka 依赖的 zookeeper
  • redis:业务应用的 redis
  • mysql: 业务应用的数据库
  • prom/prometheus:监控业务
  • grafana/grafana:prometheus 的 ui 很难看,用来显示 prometheus 收集来的数据
  • elastic/filebeat:收集日志到 kafka
  • go-stash : 生产 kafka 中日志,脱敏、过滤而后输入到 es
  • docker.elastic.co/elasticsearch/elasticsearch:存储收集的日志
  • docker.elastic.co/kibana/kibana:显示 elasticsearch
  • jaegertracing/jaeger-query、jaegertracing/jaeger-collector、jaegertracing/jaeger-agent:链路追踪
  • go-stash : filebeat 收集日志到 kafka 后,go-stash 去生产 kafka 进行数据脱敏、过滤日志中内容,最初输入到 es 中

八、我的项目开发倡议

  • app 下放所有业务服务代码
  • common 放所有服务的公共根底库
  • data 我的项目依赖中间件产生的数据,理论开发中应该在 git 中疏忽此目录以及此目录下产生的数据
  • 生成 api、rpc 代码:

个别咱们在生成 api,rpc 代码时候手动去敲 goctl 的命令比拟长,也记不住,所以咱们间接去 deploy/script/gencode/gen.sh 中复制代码即可。比方我在 usercenter 服务中新减少了一个业务,批改明码,写完 api 文件之后,进入到 usercenter/cmd/api/desc 目录下,间接复制 deploy/script/gencode/gen.sh 中的生成 api 命令运行即可

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

生成 rpc 也一样,在写完 proto 文件后,间接粘复制 deploy/script/gencode/gen.sh 中的生成 rpc 命令运行即可

goctl >= 1.3 进入 ” 服务 /cmd/rpc/pb” 目录下,执行上面命令

$ goctl rpc protoc *.proto --go_out=../ --go-grpc_out=../  --zrpc_out=../
$ sed -i ""'s/,omitempty//g' *.pb.go

goctl < 1.3 进入 ” 服务 /cmd” 目录下,执行上面命令

$  goctl rpc proto -src rpc/pb/*.proto -dir ./rpc -style=goZero
$  sed -i ""'s/,omitempty//g'  ./rpc/pb/*.pb.go

【注】倡议在生成 rpc 文件时候,在多执行一次上面那个命令,把 protobuf 生成的 omitempty 给删除掉,不然字段为 nil 就不返回了

  • 生成 kafka 代码:
    因为本我的项目应用了 go-queue 的 kq 做音讯队列,kq 又依赖的 kafka,理论就是应用了 kafka 做音讯队列,然而 kq 默认是须要咱们提前把 topic 建好的,不许默认主动生成,所以命令也筹备好了,间接复制 deploy/script/gencode/gen.sh 中的创立 kafka 的 topic 代码即可

     kafka-topics.sh --create --zookeeper zookeeper:2181 --replication-factor 1 -partitions 1 --topic {topic}
  • 生成 model 代码,间接运行 deploy/script/mysql/genModel.sh 参数
  • api 我的项目中的.api 文件咱们做了拆分,对立放到每个 api 的 desc 文件夹下,因为如果所有内容都写在 api 中可能不便于查看,所以做了拆分,把所有办法写到一个 api 中,其余的实体以及 req、rep 对立放到一个文件夹独自定义比拟清晰
  • 生成 model、错误处理时候应用了 template 从新定义,该我的项目用到的自定义的 goctl 的模版在我的项目 data/goctl 下

九、后续

因为我的项目中因为波及到的技术栈略微有点多,将分章节一步一步解说,敬请关注。

我的项目地址

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

欢送应用 go-zerostar 反对咱们!

微信交换群

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

退出移动版