Golang微服务框架Kratos使用问题总结

简介: 官方默认的 layout 目录已其实已经包含第三方包,但proto 文件仍然会出现红色波浪线,如`import "google/api/annotations.proto";`,以 VS Code 为例,只需要添加如下文件及配置:

Kratos 项目结构图

  1. 官方默认的 layout 目录已其实已经包含第三方包,但proto 文件仍然会出现红色波浪线,如import "google/api/annotations.proto";,以 VS Code 为例,只需要添加如下文件及配置:

    .vscode/settings.json

    {
      "protoc": {
        "options": [
          "--proto_path=${workspaceRoot}/third_party",
        ]
      }
    }
  2. 在 protobuf文件中添加的验证规则未生效

    首先要确保在 protoc 命令中添加参数:

    --validate_out=paths=source_relative,lang=go:. \

    其次在grpc.gohttp.go文件(取决于你使用的服务)中应加入validate.Validator中间件

    import "github.com/go-kratos/kratos/v2/middleware/validate"
    ....
            http.Middleware(
                recovery.Recovery(),
                validate.Validator(),
            ),
    ....
  3. unsupported Scan, storing driver.Value type []uint8 into type *time.Time\
    这个错误与 Kratos 无关,顺便记录在此,大概率你不会碰到这个问题,因为对 MySQL的配置一般都会怼上charset=utf8mb4&parseTime=True&loc=Local,万一出现这个报错,那就是缺少parseTime所致。
  4. 成功及错误响应值格式可通过http.ResponseEncoderhttp.ErrorEncode进行定制
  5. Kratos 默认返回的错误消息同时反馈在 HTTP状态码中(在kratos/v2/error中还内置了多个方法,如BadRequestUnAuthorized等),设计者应该是觉得HTTP状态码的语义更为前端所熟悉,但目前大多使用axios库来发起 HTTP请求,这样默认service.interceptors.response.use的拦截会直接进入error部分,那返回的消息体岂不是毫无价值了?原因从axios源码可以找到:
validateStatus: function validateStatus(status) {
  return status >= 200 && status < 300;
}
一种方式是修改`Kratos`中的错误处理或者一律返回200到300之间的状态码,但这便辜负了框架的**精妙设计**,另一种自然就是从前端下手,比如假定简单粗暴地将500以下的状态码都视为正常,错误消息在`response`由前端处理,可以使用如下配置:

```
const service = axios.create({
  validateStatus: (status)=>{
    return status < 500
  },
...
}
```
  1. Protobuf和OpenAPI关于变量的使用方式有点烦,如果使用camelCase,一切太平,但如果使用snake_case,就开始麻烦了,你会发现接口本身字段没有问题,但 OpenAPI 开始作妖,文档里会显示为camelCase,那如何让文档里也显示为snake_case呢?那就还要再加一个注解,比如:
string captcha_id = 1 [json_name="captcha_id"];
顺便说一下,如果字段定义与`json_name`不统一也会出问题,这种方法的缺点是太烦琐,需要为每个字段添加注解。  
经过进一步的探索,在生成时可通过[protoc-gen-openapi](https://github.com/google/gnostic/tree/main/cmd/protoc-gen-openapi)的参数`naming=proto`来配置生成使用`Protobuf`文件定义名称的文档字段(此步骤在 Kratos 中并无必要,只需关注下面的一个配置即可,但如果将生成的 openapi.yaml拿到外面使用,比如https://editor.swagger.io/, 未加参数会显示为`camelCase`)。

```
api:
    protoc --proto_path=./api \
...
           --openapi_out=fq_schema_naming=true,naming=proto,default_response=false:. \
...
```

但如果使用Kratos直接启动swagger,需要在`server/http.go`中添加配置`generator.UseJSONNamesForFields(false)`,因其默认值为`true`:

```
openAPIhandler := openapiv2.NewHandler(
    openapiv2.WithGeneratorOptions(
        generator.UseJSONNamesForFields(false), 
        generator.EnumsAsInts(true)))
srv.HandlePrefix("/q/", openAPIhandler)
```

以上都是针对文档,实际返回字段需要对`protojson`添加`UseProtoNames`来进行序列化配置,Kratos中已暴露了相关配置(https://github.com/go-kratos/kratos/blob/main/encoding/json/json.go ),只需将其加入到 main.go 文件的`init()`中即可:

```
func init() {
    json.MarshalOptions = protojson.MarshalOptions{
        EmitUnpopulated: true,
        UseProtoNames:   true,
    }
    flag.StringVar(&flagconf, "conf", "../../configs", "config path, eg: -conf config.yaml")
}
```


  1. GRPC 不似 HTTP 那样利于调试,可以考虑使用以下工具:

    • grpcui(这个工具我在安装时出现go:linkname must refer to declared function or variable,这是本地使用的版本是 go 1.18有关,解决方案是go get -u golang.org/x/sys,如果你也有这个问题,可能像我一样克隆代码在本地编译安装)
    • bloomrpc
    • Postman,是的,Postman 也有相关支持,但要求首先注册一个账号
  1. make api时出现添加--experimental_allow_proto3_optional参数的提示是因为 在 proto中使用了optional,但在3.15.0中这个特性已经转正,所以可以直接升级解决问题,当然不愿意升级请直接对protoc命令添加该参数;那我们为什么要添加optional呢(你还会在网上看到官方不建议使用optional,并且在3.15.0之前它一直作为experimental,要额外添加参数运行)?其实这与 Go 语言对零值的处理有关,在 Go 语言中数值、字符串等类型会默认被置为零值,那么问题就来了,我们怎么值知道一个int类型的变量是未传参还是传参的值为0,这时就要使用引用类型*int,在 Protobuf 中对应的就是在定义字段时在前面添加optional。\
    补充一个知识点,使用 Vue 进行前端开发的同学很多人会使用element-ui,它也有一个坑,就是在添加clearable属性后清空字段会默认将v-model对应的变量(即使它是一个数值类型)设置为空字符串,那问题来了,传一个空字符串给后端明显类型不匹配呀!于是我们又需要再添加一个@clear="status = null"(假定变量名称为status)来进行处理。
  2. POST 等请求如何获取query string,也就说怎么获取到query1和 query2的值,一开始我以为要通过http.RequestDecoder进行自定义,其实并不需要:

      rpc Post (PostRequest) returns (google.protobuf.Empty){
        option (google.api.http) = {
          post: "/url",
          body: "body",
        };
      };
    ...
    
    message PostRequest {
      string query1 = 1;
      string query2 = 2;
      Body body = 3;
    }
    
    message Body {
    ....
    }

    这里考虑到请求体可能有多个字段,定义了一个嵌套的Body类型来接收POST请求本身提交的字段 body:"body"中第二个body为 PostRequest 中的自定义字段,如仅一个字段,自然可以直接使用 string 等类型。

相关文章
|
8天前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
46 3
|
5天前
|
Dubbo Java 应用服务中间件
Dubbo学习圣经:从入门到精通 Dubbo3.0 + SpringCloud Alibaba 微服务基础框架
尼恩团队的15大技术圣经,旨在帮助开发者系统化、体系化地掌握核心技术,提升技术实力,从而在面试和工作中脱颖而出。本文介绍了如何使用Dubbo3.0与Spring Cloud Gateway进行整合,解决传统Dubbo架构缺乏HTTP入口的问题,实现高性能的微服务网关。
|
1月前
|
Dubbo Java 应用服务中间件
微服务框架Dubbo环境部署实战
微服务框架Dubbo环境部署的实战指南,涵盖了Dubbo的概述、服务部署、以及Dubbo web管理页面的部署,旨在指导读者如何搭建和使用Dubbo框架。
160 17
微服务框架Dubbo环境部署实战
|
1月前
|
Kubernetes Java Android开发
用 Quarkus 框架优化 Java 微服务架构的设计与实现
Quarkus 是专为 GraalVM 和 OpenJDK HotSpot 设计的 Kubernetes Native Java 框架,提供快速启动、低内存占用及高效开发体验,显著优化了 Java 在微服务架构中的表现。它采用提前编译和懒加载技术实现毫秒级启动,通过优化类加载机制降低内存消耗,并支持多种技术和框架集成,如 Kubernetes、Docker 及 Eclipse MicroProfile,助力开发者轻松构建强大微服务应用。例如,在电商场景中,可利用 Quarkus 快速搭建商品管理和订单管理等微服务,提升系统响应速度与稳定性。
44 5
|
1月前
|
存储 Java Maven
从零到微服务专家:用Micronaut框架轻松构建未来架构
【9月更文挑战第5天】在现代软件开发中,微服务架构因提升应用的可伸缩性和灵活性而广受欢迎。Micronaut 是一个轻量级的 Java 框架,适合构建微服务。本文介绍如何从零开始使用 Micronaut 搭建微服务架构,包括设置开发环境、创建 Maven 项目并添加 Micronaut 依赖,编写主类启动应用,以及添加控制器处理 HTTP 请求。通过示例代码展示如何实现简单的 “Hello, World!” 功能,并介绍如何通过添加更多依赖来扩展应用功能,如数据访问、验证和安全性等。Micronaut 的强大和灵活性使你能够快速构建复杂的微服务系统。
77 5
|
1月前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
62 2
|
1月前
|
Cloud Native 安全 Java
Micronaut对决Spring Boot:谁是微服务领域的王者?揭秘两者优劣,选对框架至关重要!
【9月更文挑战第5天】近年来,微服务架构备受关注,Micronaut和Spring Boot成为热门选择。Micronaut由OCI开发,基于注解的依赖注入,内置多种特性,轻量级且启动迅速;Spring Boot则简化了Spring应用开发,拥有丰富的生态支持。选择框架需考虑项目需求、团队经验、性能要求及社区支持等因素。希望本文能帮助您选择合适的微服务框架,助力您的软件开发项目取得成功!
119 2
|
2月前
|
存储 设计模式 前端开发
|
2月前
|
Cloud Native JavaScript API
一文读懂云原生 go-zero 微服务框架
一文读懂云原生 go-zero 微服务框架
|
2月前
|
开发框架 Dubbo 应用服务中间件
微服务开发框架-----Apache Dubbo
这篇文章介绍了Apache Dubbo微服务开发框架,它提供RPC通信和微服务治理能力,支持服务发现、负载均衡和流量治理等功能,并强调了Dubbo在微服务规模化实践和企业级治理方面的优势。
微服务开发框架-----Apache Dubbo