项目架构
业务
在idl/srv_name新建proto 新建app/srv_name生成单个HTTP服务
export ROOT_MOD=github.com/cloudwego/biz-demo/gomall
//生成http
cd app/frontend && cwgo server --type HTTP
--service frontend
--module ${ROOT_MOD}/app/frontend
-I ../../idl --idl ../../idl/frontend/auth_page.proto
//生成服务端
//-pass将传递这个更底层命令,即使用kitex去生成,其中-use使用指定模块,只生成服务端代码
cd app/user && cwgo server --type RPC
--service user
--module ${ROOT_MOD}/app/user
--pass "-use ${ROOT_MOD}/rpc_gen/kitex_gen"
-I ../../idl --idl ../../idl/user.proto
//生成客户端rpc
cd rpc_gen && cwgo client --type RPC
--service user
--module ${ROOT_MOD}/rpc_gen
--I ../idl --idl ../idl/user.proto
在biz下面 在handler/home中调用服务,相当于controller的作用 业务逻辑实习在service中
app/Fronted
用户login、register,写入session, 商品search_product/get_product/categories /biz /dal:mysql,redis初始化 /handler /home: proto生成的文件 home() /auth: proto生成的文件 Login()/Register()/Logout() /service /home: Run(): 展示具体图片 /login: 身份管理:用户身份确认(邮箱密码)/用户浏览器鉴权(确认身份)/鉴权/权限管理 session(session_id)/jwt(保存在服务端中)/paseto(隐私性好)/keyauth(token库) Run(): 登录(调用rpc.UserClient.Login),添加session:session.Save() /logout: Run(): 清空Session /Register: Run(): 注册(调用rpc.UserClient.Register),session.Save() /search_product:rpc.ProductClient.SearchProducts /get_product:rpc.ProductClient.GetProduct /categories:rpc.ProductClient.ListProducts /middleware /middleware.go: Register(): 使用hz注册下面的中间件 /auth.go: 从session中获取相关信息放到context里面 /infra /rpc client.go: 先从consul里面找地址,再调用使用到的rpc.UserClient /utils function.go:放经常会用的返回值,例如userId constant.go: /conf conf.go:在hz下面新增配置 /main.go 初始化metric:mtl.InitMtl() 加载env 注册中间件
app/User
给frontend提供login、register这样的接口 先去idl下面新建proto,再生成代码到rpc_gen中 /biz /dal:mysql,redis初始化 /model: 定义user表,并且创建表以及实现一些数据库逻辑 /service /login: 完成业务逻辑,具体的参数校验 /Register: Run(): 保存到数据库,session.Save() /main.go 初始化kitex,注册到consul
app/Product
商品列表、商品查询、商品 /biz /model product-category /service get_product search_product list_product
app/Cart
/biz/service 因为往购物车添加商品需要调用:AddItem 清空购物车:EmptyCart 返回购物车里的内容:GetCart /infra/rpc:因为往购物车添加商品需要调用 以下将kitex项目集中到promethues /conf
//conf.go:在kitex结构体下面新增
MetricsPort string `yaml:"metrics_port"`
//conf.yaml:在kitex下面新加
metrics_port: ":9993"
main.go 在项目启动时,初始化metric mtl.InitMetric(serviceName, conf.GetConf().Kitex.MetricsPort, conf.GetConf().Registry.RegistryAddress[0]) 在初始kitex的过程中,将原本添加opts []server.Option var serviceName = conf.GetConf().Kitex.Service 添加到opts中:opts = append(opts, server.WithServiceAddr(addr)) 同时
app/Order
创建订单:PlaceOrder 返回订单列表:ListOrder
app/Payment
卡支付(模拟卡信息,校验卡),校验之后就创建支付日志:Charge
app/Checkout
biz/service 先rpc.CartClient.GetCart,再找到购物车内容, 再遍历找到每个商品信息rpc.ProductClient.GetProduct 再创建订单rpc.OrderClient.PlaceOrder 结算rpc.PaymentClient.Charge 结算成功后邮件通知 定义消息内容data := proto.Marshal(&email.EmailReq{}) 发送消息msg := &nats.Msg{Subject: "email", Data: data} _ = mq.Nc.PublishMsg(msg) infra mq/nats.go:连接nats rpc/client.go:调用其他服务
app/Email
nats: 消息中间件 /biz /consumer:监听是否要通过邮件发消息 /email email.go: 订阅消息主题“email”,将消息发送:notify.NewNoopEmail.Send() 关闭服务前,取消订阅 consumer.go:启动消费者 /infra /mq:连接nats /notify:模拟邮件发送
/idl
放proto文件,用来生成的依据 /frontend /common.proto:将重复的message部分抽成common /home.proto:主页 /auth_page.proto:登录成功后跳转到别的页面 /product_page.proto:放返回商品列表的展示 /user.proto /product.proto
/rpc_gen
放生成的客户端 /rpc /user /product
/db
运行代码前先创建:建库语句
可观测性
指标:prometheus
架构
![[Pasted image 20241116202247.png]] prometheus_server: 收集监控数据,定时拉取应用&其他组件的指标 将收集数据写到本地磁盘(TSDB)/远程写入(influxDB) 服务发现:通过consul/k8s这样的方式去获取服务的地址 push_gateway: 一些定时任务/批处理将指标主动推送 Grafana: 提供面板去监控server收集到的数据 Alertmanager: 通知那些不符合预定义的行为
实现
/common:外层公用组件 /mtl metrics.go 先定义一个公共Registry,注册指标:prometheus.NewRegistry() 再注册一个服务到consul中,地址就是prometheus_server运行的信息 服务关闭下线信息:server.RegisterShutdownHook 启动这样一个metric_server:http.Handle("/metrics", promhttp.HandlerFor(Registry, promhttp.HandlerOpts{})) 再异步起动一个server供promethues拉取指标:go http.ListenAndServe(metricsPort, nil) tracing.go 初始化(关闭ot指标功能) /serversuite/serversuite.go metric 包装上面的server:WithTracer(prometheus.NewServerTrace) 将原本所有服务都注册到consul的部分抽象到serversuite中 抽象成一个属性CommonServerSuite trace WithSuite(tracing.NewServerSuite()) /clientsuite/clientsuite.go metric 将所有服务中有client.go,需要进行服务发现的部分抽象出来 抽象成属性CommonGrpcClientSuite trace client.WithSuite(tracing.NewClientSuite()), /deploy/config promethues.yml:通过consul获取到promethues,寻找下面的服务
监控
打开grafana 导入prom运行json 添加prom运行端口