共计 3235 个字符,预计需要花费 9 分钟才能阅读完成。
咱们用一个系列来解说从需要到上线、从代码到 k8s 部署、从日志到监控等各个方面的微服务残缺实际。
整个我的项目应用了 go-zero 开发的微服务,根本蕴含了 go-zero 以及相干 go-zero 作者开发的一些中间件,所用到的技术栈根本是 go-zero 项目组的自研组件,根本是 go-zero 全家桶了。
实战我的项目地址:https://github.com/Mikaelemmm…
1、领取服务业务架构图
2、依赖关系
payment-api(领取 api)
- order-rpc(订单 rpc)
- payment-rpc(领取 rpc)
- usercenter(用户 rpc)
payment-rpc(领取 rpc)
- mqueue-rpc(音讯队列)
order-rpc(订单 rpc)
- mqueue-rpc(音讯队列)
- travel-rpc
usercenter(用户 rpc)
- identity-rpc(受权认证 rpc)
3、微信领取举例
3.1 创立领取预处理订单
1、用户在咱们这边创立完订单之后,要去微信那边创立预领取订单
app/payment/cmd/api/desc/payment.api
// 领取服务 v1 版本的接口
@server(
prefix: payment/v1
group: thirdPayment
)
service payment {
@doc "第三方领取:微信领取"
@handler thirdPaymentwxPay
post /thirdPayment/thirdPaymentWxPay (ThirdPaymentWxPayReq) returns (ThirdPaymentWxPayResp)
...
}
app/payment/cmd/api/internal/logic/thirdPayment/thirdPaymentwxPayLogic.go
- ThirdPaymentwxPay
见下图,咱们创立微信预领取订单时候做了一次封装,因为咱们平台后续领取业务必定不止民宿领取订单,必定还会有其余的,比方咱们后续能够推出商城,推出课程等,所以在这里应用 switch 做了个业务分类,目前咱们只有民宿订单,然而除了查问业务不一样,其余都一样,咱们把一样的逻辑封装起来,所以咱们持续看封装后的办法 createWxPrePayOrder
app/payment/cmd/api/internal/logic/thirdPayment/thirdPaymentwxPayLogic.go
- createWxPrePayOrder
这里就是拿到用户的登陆 userId 去换 openid(这块咱们之前注册登陆那里有小程序注册登陆,那时候就获取了 openid),而后调用 paymentRpc 中的 CreatePayment 创立咱们本地的领取流水单号,再通过调用微信 sdk-> svc.NewWxPayClientV3(这里是我基于 go-zero 封装了一次,没啥难度都能看懂),
而后在微信端创立了一个关联咱们本地流水单号的预领取订单,返回给前端,前端通过 js 发动申请即可
3.2 微信领取回调
以后端拿着咱们给的微信预处理订单发动领取,用户输出明码领取胜利后,微信服务器会回调咱们服务器,回调地址在咱们配置中填写的
这个回调地址,肯定要填写咱们领取 api 服务中的回调解决办法, 也就是如下图的接口,这样咱们能力接管到微信回调进来,咱们才能够做后续解决。
微信回调回来之后,咱们要解决回调逻辑,咱们要调用 verifyAndUpdateState 将咱们流水单号改为已领取
咱们来看看 verifyAndUpdateState 办法,咱们要查问单号是否存在,比对回调回来的金额与创立时候金额是否统一更新流水单号即可。这里不必在校验签名了,前一步的 sdk 曾经做了解决了
这里还要给前端写一个轮训接口,前端用户领取胜利后前端不能以前端的微信返回后果为准,要通过后端提供的接口轮训,判断这个流水单是否真的是后端返回领取胜利状态,如果这个接口返回胜利才算胜利,微信前端返回的不能作为根据,因为微信前端返回的不平安,个别开发都明确不晓得的本人百度。
3.3 领取胜利发送小程序模版音讯
咱们领取回调胜利之后,会给用户发送一个入驻码,去了商家那里要展现这个码,商家通过后盾核查码,其实就是美团的样子,咱们去美团下单,美团会给你个码,用户拿着这个码去入住或者生产等。
ok,回调胜利,咱们会调用 pyamentRpc 去批改以后流水单状态胜利
咱们来看看 paymentRpc 中做了什么,
后面是校验,外围做了两件事件,第一是更新状态,第二向音讯队列发送了一条音讯,咱们看看音讯队列中对应的代码
能够看到咱们应用了 go-queue 发送了一条 kq 音讯到 kafka,而不是 asynq 提早音讯,因为咱们想让所有订阅了该领取状态的业务都能收到此音讯后做相应的解决,尽管目前咱们只有一个中央监听做解决(发送小程序模版音讯告诉用户领取胜利),所以这里就是发了一条该领取流水相干信息到 kafka 中,这里跟之前订单那里是一样的只是增加音讯到队列,没有解决,那咱们看看 order-mq 中怎么解决的。
后面 order 一节曾经介绍了整个 order-mq 的运作机制,这里不再多说了,咱们只说 kq 这里
当 order-mq 启动后,go-queue 会监听 kafka 中的音讯
咱们再来看下具体实现 , 当后面领取回调胜利增加到 kafka 中时候,order-mq 中 kafka 会承受音讯,也就是 PaymentUpdateStatusMq.Consume 会接管到 kafka 的音讯,而后反序列化数据,传递给 execService 执行具体业务,那 execService 中执行了什么呢?
能够看到下方红框内,一个是批改订单状态(非领取状态,订单也有本人状态),一个是发消息(短信、微信小程序模版音讯)给用户
app/order/cmd/mq/internal/mqs/kq/paymentUpdateStatus.go
批改订单状态的咱们就不看了,咱们能够来看看发送小程序模版音讯,下方 LiveStateDate\LiveEndDate 之前调试写死的,这个间接改成办法传递过去的工夫就好了,转换一下
【注】用户想收到小程序模版音讯,必须在前端让用户受权才行,这是小程序必须的不是咱们能管制的
这里发送音讯咱们也不是真正的调用微信 sdk 去发送音讯,也是往音讯队列 MqueueRpc 中插入模版音讯(其实这里也能够间接发),而后由 message 音讯服务从 kafka 中取出来真正发送,是想所有的短信、email、微信等音讯对立从这个服务发送进来,这个本人依据本人公司业务或者架构去灵便设计吧,不肯定非得这样。
那咱们说到这里了就间接去看看 message 音讯服务代码吧
message 业务中只有一个 mq,因为他不须要 rpc、api,只须要定时从队列去音讯发送音讯,所以它运行逻辑跟 order-mq 一样的,同样实用 serviceGroup 治理
咱们不细说了,运行逻辑能够去看订单服务那一节的 order-mq 有细说,咱们只看具体实现逻辑,go-queue 从 kafka 队列中取出每一条要发送的微信小程序模版音讯数据,而后反序列化交给 execService 去解决,咱们来看看 execService
execService 次要就是整合数据,通过小程序 sdk 的 client 发送给小程序即可,这里有个留神点,小程序是能够辨别环境的,是发送到线上小程序还是体验版小程序,在下方红色框内有做辨别,理论这样是不平安的 通过这种形式,最好搞到配置文件里,万一开发环境有人捣鬼改成 formal,轻易发给他人 openid 就出事了,这个本人能够改改哈
4、小结
到这里基本上整体我的项目服务逻辑都差不多阐明完了,后续会介绍收集日志、监控、部署等
我的项目地址
https://github.com/zeromicro/go-zero
欢送应用 go-zero
并 star 反对咱们!
微信交换群
关注『微服务实际 』公众号并点击 交换群 获取社区群二维码。