千家信息网

企业项目迁移go-zero的方法教程

发表于:2025-02-21 作者:千家信息网编辑
千家信息网最后更新 2025年02月21日,这篇文章主要介绍"企业项目迁移go-zero的方法教程",在日常操作中,相信很多人在企业项目迁移go-zero的方法教程问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"企
千家信息网最后更新 2025年02月21日企业项目迁移go-zero的方法教程

这篇文章主要介绍"企业项目迁移go-zero的方法教程",在日常操作中,相信很多人在企业项目迁移go-zero的方法教程问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"企业项目迁移go-zero的方法教程"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

gateway service

gateway 中我做了一些自定义,在端请求我们后台接口情况下,虽然多数情况是不需要关心错误码的,但是避免不了要某些场景还是需要根据固定错误码去做特殊处理,我自己定义了一个错误类,这个错误类只在 gateway 中使用:

err.go:

package xerrimport "fmt"type CodeError struct {   errCode int   errMsg  string}// 属性func (e *CodeError) GetErrCode() int {   return e.errCode}func (e *CodeError) GetErrMsg() string {   return e.errMsg}func (e *CodeError) Error() string {   return fmt.Sprintf("ErrCode:%d,ErrMsg:%s", e.errCode, e.errMsg)}func New(errCode int, errMsg string) *CodeError {   return &CodeError{errCode: errCode, errMsg: errMsg}}func NewErrCode(errCode int) *CodeError {   return &CodeError{errCode: errCode, errMsg: MapErrMsg(errCode)}}func NewErrMsg(errMsg string) *CodeError {   return &CodeError{errCode: BAD_REUQEST_ERROR, errMsg: errMsg}}

errmsg.go

package xerrvar message map[int]stringfunc init()  {   message = make(map[int]string)   message[OK] = "SUCCESS"   message[BAD_REUQEST_ERROR] = "服务器繁忙,请稍后再试"   message[REUQES_PARAM_ERROR] = "参数错误"   message[USER_NOT_FOUND] = "用户不存在"}func MapErrMsg(errcode int) string {   if msg, ok := message[errcode]; ok {      return msg   } else {      return "服务器繁忙,请稍后再试"   }}

errcode.go

package xerr// 成功返回const OK = 200// 全局错误码// 前3位代表业务,后三位代表具体功能const BAD_REUQEST_ERROR = 100001const REUQES_PARAM_ERROR = 100002// 用户模块const USER_NOT_FOUND = 200001

我将三个文件统一放在 lib/xerr 目录

有了错误码还不行,还要定义统一返回http的结果,goctl 生成的默认的是挺好的,但是没法符合我这种返回自定义错误码需求,于是我自己有写了一个统一返回结果的文件:

httpresult:

package xhttpimport (   "fishtwo/lib/xerr"   "fmt"   "github.com/tal-tech/go-zero/core/logx"   "github.com/tal-tech/go-zero/rest/httpx"   "google.golang.org/grpc/status"   "net/http"   "github.com/pkg/errors")// http方法func HttpResult(r *http.Request,w http.ResponseWriter,resp interface{},err error)  {   if err == nil {      // 成功返回      r:= Success(resp)      httpx.WriteJson(w, http.StatusOK, r)   } else {      // 错误返回      errcode := xerr.BAD_REUQEST_ERROR      errmsg := "服务器繁忙,请稍后再试"      if e,ok := err.(*xerr.CodeError);ok{         // 自定义CodeError         errcode = e.GetErrCode()         errmsg = e.GetErrMsg()      } else {         originErr := errors.Cause(err) // err类型         if gstatus, ok := status.FromError(originErr);ok{            // grpc err错误            errmsg = gstatus.Message()         }      }      logx.WithContext(r.Context()).Error("【GATEWAY-SRV-ERR】 : %+v ",err)      httpx.WriteJson(w, http.StatusBadRequest, Error(errcode,errmsg))   }}// http参数错误返回func ParamErrorResult(r *http.Request,w http.ResponseWriter,err error)  {   errMsg := fmt.Sprintf("%s ,%s", xerr.MapErrMsg(xerr.REUQES_PARAM_ERROR), err.Error())   httpx.WriteJson(w, http.StatusBadRequest, Error(xerr.REUQES_PARAM_ERROR,errMsg))}

responsebean

package xhttptype (   NullJson struct {}   ResponseSuccessBean struct {      Code int         `json:"code"`      Msg  string      `json:"msg"`      Data interface{} `json:"data"`   })func Success(data interface{}) *ResponseSuccessBean {   return &ResponseSuccessBean{200, "OK", data}}type ResponseErrorBean struct {   Code int         `json:"code"`   Msg  string      `json:"msg"`}func Error(errCode int,errMsg string) *ResponseErrorBean {   return &ResponseErrorBean{errCode, errMsg}}

放在 lib/xhttp下

然后改造了internal/handler/下通过goctl生成的代码:

当然你会说,每次生成完都要手动去改,好麻烦!

当当当当~~~ goctltemplate 来咯 https://www.yuque.com/tal-tech/go-zero/mkpuit

然后修改 ~/.goctl/api/handler.tpl:

package handlerimport (         "net/http"         {{.ImportPackages}})func {{.HandlerName}}(ctx *svc.ServiceContext) http.HandlerFunc {   return func(w http.ResponseWriter, r *http.Request) {      {{if .HasRequest}}var req types.{{.RequestType}}      if err := httpx.Parse(r, &req); err != nil {         xhttp.ParamErrorResult(r,w,err)         return      }{{end}}      l := logic.New{{.LogicType}}(r.Context(), ctx)      resp, err := l.Login(req)      xhttp.HttpResult(r,w,resp,err)   }}

在重新生成看看,是不是就 beautiful 了,哈哈

然后在说我们的 gateway log,如果眼神好的用户,在上面的 httpresult.go 中已经看到了 log 的身影:

是的是的,这样处理就可以啦,这样只要有错误就会打印日志了,go-zero 已经把 trace-id 带进去了,啥?trace-id 不知道是啥?嗯,其实就是把一次请求通过此 id 串联起来,比如你 user-api 调用 user->srv 或者其他 srv,那要把他们这一次请求都串联起来,需要一个唯一标识别,这个 id 就是做这个,做链路追踪有很多,比如 jaegerzipkin

RPC service

modelrpc 服务中,官方文档推荐是将 model 放在 services 目录下,与每个 rpc 服务一层,但是个人感觉每个 model 对应一张表,一张表只能由一个服务去控制,哪个服务控制这张表就哪个服务拥有控制这个 model 权利,其他服务想访问就要通过 grpc,这是个人的想法,所以我把每个服务自己管控的 model 放在了 internal

enum:另外我在服务下加了 enum 枚举目录,因为其他 rpc 服务或者 api 服务会调用这个枚举去比对,我就放在 internal 外部

到此,关于"企业项目迁移go-zero的方法教程"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0