早年,如果使用go来做微服务,可选框架只有
go-zero
、go-micro
、go-kit
等。但随着Golang的发展,社区也涌现出了一些新型的微服务框架,国内公司也开源了不少微服务框架,本文就主要介绍下哔哩哔哩的kratos
与字节跳动的hertz
。
hertz与kratos介绍
hertz
简介
Hertz
[həːts] 是一个 Golang 微服务 HTTP 框架,在设计之初参考了其他开源框架 fasthttp
、gin
、echo
的优势, 并结合字节跳动内部的需求,使其具有高易用性、高性能、高扩展性等特点,目前在字节跳动内部已广泛使用。 如今越来越多的微服务选择使用 Golang,如果对微服务性能有要求,又希望框架能够充分满足内部的可定制化需求,Hertz 会是一个不错的选择。
架构设计
框架特点
- 高易用性
在开发过程中,快速写出来正确的代码往往是更重要的。因此,在 Hertz 在迭代过程中,积极听取用户意见,持续打磨框架,希望为用户提供一个更好的使用体验,帮助用户更快的写出正确的代码。
- 高性能
Hertz 默认使用自研的高性能网络库 Netpoll,在一些特殊场景相较于 go net,Hertz 在 QPS、时延上均具有一定优势。关于性能数据,可参考下图 Echo 数据。
四个框架的对比:
Performance
三个框架的对比:
从hertz官方压测数据看,Gin完全打不过hertz啊喂。Gin已经算是go http框架里面性能佼佼者了。
关于详细的性能数据,可参考 https://github.com/cloudwego/hertz-benchmark。
- 高扩展性
Hertz 采用了分层设计,提供了较多的接口以及默认的扩展实现,用户也可以自行扩展。同时得益于框架的分层设计,框架的扩展性也会大很多。目前仅将稳定的能力开源给社区,更多的规划参考 RoadMap。
- 多协议支持
Hertz 框架原生提供 HTTP1.1、ALPN 协议支持。除此之外,由于分层设计,Hertz 甚至支持自定义构建协议解析逻辑,以满足协议层扩展的任意需求。
- 网络层切换能力
Hertz 实现了 Netpoll 和 Golang 原生网络库 间按需切换能力,用户可以针对不同的场景选择合适的网络库,同时也支持以插件的方式为 Hertz 扩展网络库实现。
kratos
简介
Kratos
一套轻量级 Go 微服务框架,包含大量微服务相关框架及工具。
名字来源于:《战神》游戏以希腊神话为背景,讲述奎托斯(Kratos)由凡人成为战神并展开弑神屠杀的冒险经历。
架构设计
特性
- APIs:协议通信以 HTTP/gRPC 为基础,通过 Protobuf 进行定义;
- Errors:通过 Protobuf 的 Enum 作为错误码定义,以及工具生成判定接口;
- Metadata:在协议通信 HTTP/gRPC 中,通过 Middleware 规范化服务元信息传递;
- Config:支持多数据源方式,进行配置合并铺平,通过 Atomic 方式支持动态配置;
- Logger:标准日志接口,可方便集成三方 log 库,并可通过 fluentd 收集日志;
- Metrics:统一指标接口,可以实现各种指标系统,默认集成 Prometheus;
- Tracing:遵循 OpenTelemetry 规范定义,以实现微服务链路追踪;
- Encoding:支持 Accept 和 Content-Type 进行自动选择内容编码;
- Transport:通用的 HTTP/gRPC 传输层,实现统一的 Middleware 插件支持;
- Registry:实现统一注册中心接口,可插件化对接各种注册中心;
kratos-layout方案
kratos官方提供了一套目录结构方案
.
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── api // 下面维护了微服务使用的proto文件以及根据它们所生成的go文件
│ └── helloworld
│ └── v1
│ ├── error_reason.pb.go
│ ├── error_reason.proto
│ ├── error_reason.swagger.json
│ ├── greeter.pb.go
│ ├── greeter.proto
│ ├── greeter.swagger.json
│ ├── greeter_grpc.pb.go
│ └── greeter_http.pb.go
├── cmd // 整个项目启动的入口文件
│ └── server
│ ├── main.go
│ ├── wire.go // 我们使用wire来维护依赖注入
│ └── wire_gen.go
├── configs // 这里通常维护一些本地调试用的样例配置文件
│ └── config.yaml
├── generate.go
├── go.mod
├── go.sum
├── internal // 该服务所有不对外暴露的代码,通常的业务逻辑都在这下面,使用internal避免错误引用
│ ├── biz // 业务逻辑的组装层,类似 DDD 的 domain 层,data 类似 DDD 的 repo,而 repo 接口在这里定义,使用依赖倒置的原则。
│ │ ├── README.md
│ │ ├── biz.go
│ │ └── greeter.go
│ ├── conf // 内部使用的config的结构定义,使用proto格式生成
│ │ ├── conf.pb.go
│ │ └── conf.proto
│ ├── data // 业务数据访问,包含 cache、db 等封装,实现了 biz 的 repo 接口。我们可能会把 data 与 dao 混淆在一起,data 偏重业务的含义,它所要做的是将领域对象重新拿出来,我们去掉了 DDD 的 infra层。
│ │ ├── README.md
│ │ ├── data.go
│ │ └── greeter.go
│ ├── server // http和grpc实例的创建和配置
│ │ ├── grpc.go
│ │ ├── http.go
│ │ └── server.go
│ └── service // 实现了 api 定义的服务层,类似 DDD 的 application 层,处理 DTO 到 biz 领域实体的转换(DTO -> DO),同时协同各类 biz 交互,但是不应处理复杂逻辑
│ ├── README.md
│ ├── greeter.go
│ └── service.go
└── third_party // api 依赖的第三方proto
├── README.md
├── google
│ └── api
│ ├── annotations.proto
│ ├── http.proto
│ └── httpbody.proto
└── validate
├── README.md
└── validate.proto
hertz与kratos比较
hertz
比对项 | 内容 |
---|---|
框架名 | hertz |
维护公司 | 字节跳动 |
项目地址 | https://github.com/cloudwego/hertz |
star数 | 2.6k |
开源时间 | 6个月 |
服务治理 | 服务注册/发现、负载均衡、熔断、限流、重试、监控、链路跟踪、日志、诊断等 |
服务发现拓展支持 | nacos、consul、etcd、eureka、polaris、servicecomb、zookeeper |
传输协议 | 仅支持HTTP,如果想支持RPC的话,可以接入字节跳动的Kitex框架 |
API定义 | 支持Protobuf、thrift、传统http.req |
框架原则特点 | 高易用性、高性能、高扩展性、多协议支持、网络层切换能力 |
使用总结
- 该框架可轻可重,你可以把hertz当成一个类似Gin的简单http框架,也可以构建为一个功能丰富的微服务框架。
- 如果你需要使用一些扩展服务特性,学习成本是比kratos高的。同时编码自由度也会降低,你必须学习它,按它的规范来写代码。
- 可以基于 thrift 和 protobuf 的 IDL 生成 Hertz 项目的脚手架,感兴趣的可以试试
kratos
比对项 | 内容 |
---|---|
框架名 | kratos |
维护公司 | Bilibli |
项目地址 | https://github.com/go-kratos/kratos |
star数 | 19.3k |
开源时间 | 2年 |
服务治理 | 服务注册/发现、负载均衡、熔断、限流、异常恢复、监控、链路跟踪、日志等 |
传输协议 | gRPC、HTTP |
服务发现拓展支持 | nacos、consul、etcd、polaris、kubernetes、discovery、zookeeper |
API定义 | 仅支持Protobuf |
框架原则特点 | 简单、通用、高效、稳定、健壮、高性能、扩展性、容错性、工具链 |
使用总结
- 上手较快,官方提供的文档与示例代码比较丰富,而且还提供了一套项目结构模板kratos-layout
- 编程与工程化思想可以学习
- Kratos仅支持使用Protobuf进行API定义。从其它框架迁移过来可能比较困难
比如定义一个路由为
/helloworld/{name}
,请求method
为GET
的接口需要定义如下proto
结构
syntax = "proto3";
package helloworld.v1;
import "google/api/annotations.proto";
option go_package = "github.com/go-kratos/kratos-layout/api/helloworld/v1;v1";
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/helloworld/{name}"
};
}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
总结
- 两个框架各有特色,很多地方都值得我们去学习了解。
Hertz
最主要的特性其实就是它的性能与稳定性,比较直观的就是抖音每日的海量请求。- 总体来说
Hertz
的学习成本是高于kratos
的,这是由社区活跃性与框架决定的。 kratos
提供了一个kratos-layout
,可以帮助用户规范一个合理的项目结构。- 由于
Hertz
开源时间相对较短,所以用户比较少,官方支持也没有kratos
活跃,导致能找到的学习使用资料也比较少。 - 两者的微服务支持大同小异,具体请详细阅读官方文档。
- 建议大家都真实上手使用一下这两款框架,只有深入使用才能了解到它们的设计理念与精髓。
评论(0)