Kratos漫游指南 1 - 概览
您好,地球人,欢迎来到Kratos漫游指南。
对于刚开始研究Kratos框架的开发者来说,目前的文档有些零散,这与我们的模块化设计有一些关系,不过Don't panic,从这篇文章开始,我将试图打破这一现状,漫游指南系列将循序渐进地介绍Kratos框架,理顺框架的使用思路,使您更快上手Kratos。
同时,这个系列也会逐步整合进官方文档中,同时重新组织整个文档的结构和内容,敬请期待。
本篇是该系列的第一篇,主要介绍Kratos的整体概况。
设计哲学
Kratos是一个Go语言实现的微服务框架,说得更准确一点,它更类似于一个使用Go构建微服务的工具箱,开发者可以按照自己的习惯选用或定制其中的的组件,来打造自己的微服务。也正是由于这样的原因,Kratos并不绑定于特定的基础设施,不限定于某种注册中心,或数据库ORM等,所以您可以十分轻松地将任意库集成进项目里,与Kratos共同运作。
围绕这样的核心设计理念,我们设计了如下的项目生态:
- kratos Kratos框架核心,主要包含了基础的CLI工具,内置的HTTP/gRPC接口生成和服务生命周期管理,提供链路追踪、配置文件、日志、服务发现、监控等组件能力和相关接口定义。
- contrib 基于上述核心定义的基础接口,对配置文件、日志、服务发现、监控等服务进行具体实现所形成的一系列插件,可以直接使用它们,也可以参考它们的代码,做您需要的服务的适配,从而集成进kratos项目中来。
- aegis 我们将服务可用性相关的算法:如限流、熔断等算法放在了这个独立的项目里,几乎没有外部依赖,它更不依赖Kratos,您可以在直接在任意项目中使用。您也可以轻松将它集成到Kratos中使用,提高服务的可用性。
- layout 我们设计的一个默认的项目模板,它包含一个参考了DDD和简洁架构设计的项目结构、Makefile脚本和Dockerfile文件。但这个项目模板不是必需的,您可以任意修改它,或使用自己设计的项目结构,Kratos依然可以正常工作。框架本身不对项目结构做任何假设和限制,您可以按照自己的想法来使用,具有很强的可定制性。
- gateway 这个是我们刚刚起步,用Go开发的API Gateway,后续您可以使用它来作为您Kratos微服务的网关,用于微服务API的治理,项目正在施工中,欢迎关注。
仓库、文档和社区
GitHub仓库:https://github.com/go-kratos
文档:https://go-kratos.dev/
微信群:go-kratos 官方微信群
Discord:go-kratos
为什么v2完全重新设计
以前关注过kratos项目的可能知道,Kratos的v1版本已经开源了很久,也是个较为完善的框架。那么为什么不直接基于v1继续迭代,而是要推倒重来,推出完全重新设计的v2呢?
经验源自踩坑。
在业务不断迭代、项目不断膨胀的情况下,我们发现,过去的框架和项目结构设计,导致代码变更成本逐渐升高,而没有进行合理的抽象,导致更难进行模块的测试,也更难对第三方基础库进行适配和迁移,这在一定程度上拉低了生产力。
因此,我们参考了大量的DDD和Clean Architecture等业界先进设计理念,重新设计了微服务的项目结构,并且这个结构随着我们的后续研究,会进一步进行迭代,让它成为微服务项目结构的最佳实践。
没错,新版本的是从kratos-layout开始的。也许刚接触这个项目结构时会觉得不适应,但随着项目迭代,代码复杂度的提高,这个定义良好的结构,将使项目保持优秀的代码可读性、可测试性,以及令人满意的开发效率和可维护性。
更重要的一点是,这一次我们想面向社区来设计和开发这个框架。让更多的开发者能够使用我们的框架来提高生产力,同时参与到我们的项目中来。
所以我们把整个框架设计成为一个插座,我们希望整个框架轻量,插件化,可定制。对于几乎每一个微服务相关的功能模块,我们都设计了标准化接口,对于第三方库设计为插件,这样就能迅速把任意基础设施集成到使用Kratos的项目里,因此,无论您的公司使用何种基础设施,有何种规范,您都可以轻松将Kratos定制成与您的开发、生产环境相匹配的样子。
不破不立,v2是一次从内到外的彻底革新,我们无法在旧版本上修修补补,而是选择重新设计和开发新版本。而目前v2版本也已经在很多生产环境使用,我们也将持续迭代和完善这个框架,同时也更欢迎各位开发者参与进来,一起让它变得更好。
数据库/缓存/消息队列/...
正如前文提到的,Kratos框架不限制您使用任何第三方库来进行项目开发,因此您可以根据喜好来选择库进行集成。我们也会逐步针对更多被广泛使用的第三方库开发插件。
这里给出一些被广泛使用的库供参考:
数据库:
- database/sql 官方库
- gorm
- ent
缓存:
消息队列:
其它更多的优秀go库,可以在awesome-go这个仓库中找找。
CLI工具
kratos命令目前主要用于从模板创建项目,维护依赖包版本等。具体请参考文档
Protobuf定义API
Kratos使用Protobuf进行API定义。Protobuf是由Google开发的一种语言中立的数据序列化协议。它有结构定义清晰、可扩展性好、体积小、性能优秀等特点,在众多公司和项目被广泛使用。
在使用Kratos的项目中,您将使用如下的IDL进行您的接口定义,并且通过protoc工具生成相应的.pb.go文件,其中包含根据定义生成的的服务端和客户端代码。随后您就可以在自己的项目内部注册服务端代码使用,或引用客户端代码进行远程调用。
Kratos默认仅生成gRPC接口的代码,如果需要生成HTTP代码,请在proto文件中使用option (google.api.http)来添加HTTP部分的定义后再进行生成。默认情况下,HTTP接口将使用JSON作为序列化格式,如果想使用其它序列化格式(form,XML等),请参考文档序列化进行相应的配置即可。
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;
}
需要注意,虽然Protobuf定义的API的可靠性更强,但字段结构灵活性相对JSON要弱一些,因此如果您有诸如文件上传接口,或者某些无法对应到proto的JSON结构需要使用,我门还提供了“逃生门”,在我们的Protobuf体系之外定义这些接口,实现为普通的http.Handler并且挂载到路由上,或者用struct来定义您的字段。可以参考我们的upload例子进行实现。
元信息传递
服务之间的API调用,如果有某些元信息需要传递过去,而不是写在payload消息中,可以使用Metadata包进行字段设置和提取,具体细节参考元信息传递文档
错误处理
Kratos的errors模块提供了error的封装。框架也预定义了一系列标准错误供使用。
错误处理这一块的设计也经过了很久的讨论才定下来,主要设计理念如下:
code语义近似HTTP的Status Code(例如客户端传参数错误用400)同时也作为大类错误,在HTTP接口中的HTTP Code会使用它,好处是网关层可以根据这个code触发相应策略(重试、限流、熔断等)。reason业务的具体错误码,为可读的字符串,能够表明,在同一个服务中应该唯一。message用户可读的信息,可以在客户端(App、浏览器等)进行相应的展示给用户看。metadata为一些附加信息,可以作为补充信息使用。
在API返回的错误信息中,以HTTP接口为例,消息结构大概是长这个样子的:
{
// 错误码,跟 http-status 一致,并且在 grpc 中可以转换成 grpc-status
"code": 500,
// 错误原因,定义为业务判定错误码
"reason": "USER_NOT_FOUND",
// 错误信息,为用户可读的信息,可作为用户提示内容
"message": "invalid argument error",
// 错误元信息,为错误添加附加可扩展信息
"metadata": {"some-key": "some-value"}
}
在Kratos中您可以使用proto文件定义您的业务错误,并通过工具生成对应的处理逻辑和方法。(如使用layout中提供的make errors指令。)
错误定义:
syntax = "proto3";
package api.blog.v1;
import "errors/errors.proto";
option go_package = "github.com/go-kratos/kratos/examples/blog/api/v1;v1";
enum ErrorReason {
// 设置缺省错误码
option (errors.default_code) = 500;
// 为某个枚举单独设置错误码
USER_NOT_FOUND = 0 [(errors.code) = 404];
CONTENT_MISSING = 1 [(errors.code) = 400];;
}
错误创建:
// 通过 errors.New() 响应错误
errors.New(500, "USER_NAME_EMPTY", "user name is empty")
// 通过 proto 生成的代码响应错误,并且包名应替换为自己生成代码后的 package name
api.ErrorUserNotFound("user %s not found", "kratos")
// 传递metadata
err := errors.New(500, "USER_NAME_EMPTY", "user name is empty")
err = err.WithMetadata(map[string]string{
"foo": "bar",
})
错误断言:
err := wrong()
// 通过 errors.Is() 断言
if errors.Is(err,errors.BadRequest("USER_NAME_EMPTY","")) {
// do something
}
// 通过判断 *Error.Reason 和 *Error.Code
e := errors.FromError(err)
if e.Reason == "USER_NAME_EMPTY" && e.Code == 500 {
// do something
}
// 通过 proto 生成的代码断言错误,并且包名应替换为自己生成代码后的 package name
if api.IsUserNotFound(err) {
// do something
})
配置文件
Kratos提供了统一的接口,支持配置文件的加载和变更订阅。
通过实现Source 和 Watcher即可实现任意配置源(本地或远程)的配置文件加载和变更订阅。
已经实现了下列插件:
- file 本地文件加载,Kratos内置
- apollo
- etcd
- kubernetes
- nacos
服务注册&服务发现
Kratos定义了统一的注册接口,通过实现Registrar和Discovery,您可以很轻松地将Kratos接入到您的注册中心中。
您也可以直接使用我们已经实现好的插件:
日志
Kratos的日志模块由两部分组成:
- Logger:底层日志接口,用于快速适配各种日志库到框架中来,仅提供一个最简单的Log方法。
- Helper:高级日志接口,提供了一系列带有日志等级和格式化方法的帮助函数,通常业务逻辑中建议使用这个,能够简化日志代码。
我们已经实现好的插件用于适配目前一些日志库,您也可以参考它们的代码来实现自己需要的日志库的适配:
监控
监控告警方面,您可以通过实现metrics相关接口将服务的统计数据上报给监控平台。
也可以直接使用我们已经实现好的插件:
链路追踪
Kratos使用OpenTelemetry作为分布式链路追踪所使用的标准,您可以通过对client和server配置tracing来将服务接入到链路追踪平台(如jaeger等),从而对服务的接口调用关系,耗时,错误等进行追踪。
负载均衡
Kratos内置了若干种负载均衡算法,如Weighted round robin(默认)、P2C,Random等,您可以通过在client初始化时配置来使用他们。
限流熔断
Kratos提供了限流ratelimit和熔断circuitbreaker中间件,用于微服务出现异常故障时自动对流量进行限制,提升服务的健壮性,避免雪崩。这两个中间件使用的算法,也可以在我们的可用性算法仓库aegis中找到,独立于Kratos直接使用。
中间件
您可以通过Kratos的middleware机制,统一微服务接口的某些共同逻辑。上面提到的功能插件,您可以通过实现Middleware编写Kratos能够使用的中间件。
同时在仓库的middleware目录下,我们也提供了一系列中间件供您使用。
插件
除了上述提到的插件外,我们还提供了一些其它插件,完整的插件列表请参考文档社区插件
示例代码
如果您看过文档后,对某些功能的使用仍有疑惑,或者是希望寻找一些用Kratos写项目的灵感,在仓库的examples目录下我们提供了很多代码供参考。
您也可以通过文档中的示例代码清单页面来查阅有哪些示例。
小结
使用Kratos在一般开发过程中用到大部分常用功能点,在本文已经做了简单介绍,相信您对本框架的情况已经有了大致的了解。限于篇幅原因,无法在一篇文章中涵盖到Kratos的全部细节,比如layout这个相对复杂的项目结构具体是怎么用的,我将在后续的文章中,继续对Kratos的框架设计思想和使用方法做更加详细的介绍,并且会结合具体的项目实例,介绍使用Kratos开发的完整流程。
文章转自


Kratos漫游指南 1 - 概览的更多相关文章
- Java 8并发工具包漫游指南
Java 8并发工具包简介 Java 8并发工具包由3个包组成,分别是java.util.concurrent.java.util.concurrent.atomic和java.util.concur ...
- WatchKit编程指南:概览--Watch应用的体系结构
Apple Watch应用程序包含两个部分:Watch应用和WatchKit应用扩展.Watch应用驻留在用户的Apple Watch中,只含有故事板和资源文件,要注意它并不包含任何代码.而Watch ...
- github上最全的资源教程-前端涉及的所有知识体系
前面分享了前端入门资源汇总,今天分享下前端所有的知识体系. 个人站长对个人综合素质要求还是比较高的,要想打造多拉斯自媒体网站,不花点心血是很难成功的,学习前端是必不可少的一个环节, 当然你不一定要成为 ...
- 前端资料QQ群交流
转:https://github.com/jsfront/src/blob/master/qq.md 这本来是我QQ群内部的一份公共约定的日常交流规则,后来得到大伙的一致认可,并用实际行动来捍卫它,使 ...
- 快速构建Windows 8风格应用27-漫游应用数据
原文:快速构建Windows 8风格应用27-漫游应用数据 本篇博文主要介绍漫游应用数据概览.如何构建漫游应用数据.构建漫游应用数据最佳实践. 一.漫游应用数据概览 1.若应用当中使用了漫游应用数据, ...
- [搬运] DotNetAnywhere:可供选择的 .NET 运行时
原文 : DotNetAnywhere: An Alternative .NET Runtime 作者 : Matt Warren 译者 : 张很水 我最近在收听一个名为DotNetRock 的优质播 ...
- 【JavaScript&jQuery】前端资源大全
综合类 综合类 地址 前端知识体系 http://www.cnblogs.com/sb19871023/p/3894452.html 前端知识结构 https://github.com/Jackson ...
- JavaScript资源分享
一. 资源教程: 综合类 前端知识体系 前端知识结构 Web前端开发大系概览 Web前端开发大系概览-中文版 Web Front-end Stack v2.2 En类资源汇总 免费的编程中文书籍索引 ...
- DotNetAnywhere
DotNetAnywhere:可供选择的 .NET 运行时 原文 : DotNetAnywhere: An Alternative .NET Runtime作者 : Matt Warren译者 : ...
随机推荐
- Kafka 部署完在服务器端可以访问,而在外部其它电脑访问不了
Kafka 部署完在服务器端可以访问,而在外部其它电脑访问不了 原因:config/server.properties的listeners和advertised.listeners 不配置的话默认的l ...
- ooday06 内部类
笔记: 成员内部类:应用率低,了解 类中套类,外面的称为外部类,里面的称为内部类 内部类通常只服务于外部类,对外不具备可见性 内部类对象只能在外部类中创建 内部类中可以直接访问外部类的成员(包括私有的 ...
- 面试题:Java中为什么只有值传递?
作者:小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功.JAVA底层.面试相关资料等更多精彩文章在公众号「小牛呼噜噜 」 目录 经典的问题 形参&实参 Java是 ...
- JAVA语言基础组成(1)
JAVA语言基础组成 关键字 关键字的定义和特点 定义:被Java语言赋予了特殊含义的单词 特点:关键字中所有字母都为小写 用于定义数据类型的关键字 class interface byte int ...
- 美女 Committer 手把手教你部署 Apache DolphinScheduler 单机版
还在为如何部署Apache DolphinScheduler 发愁么?自上篇<美女 Committer 手把手教你使用海豚调度>的视频发布后,受到社区伙伴们的热烈欢迎.但个别小伙伴在部署这 ...
- 用好JAVA中的函数式接口,轻松从通用代码框架中剥离掉业务定制逻辑
大家好,又见面了. 今天我们一起聊一聊JAVA中的函数式接口.那我们首先要知道啥是函数式接口.它和JAVA中普通的接口有啥区别?其实函数式接口也是一个Interface类,是一种比较特殊的接口类,这个 ...
- List的同步类比较
TL;NRs CopyOnWriteArrayList类在多线程顺序读取上有很大的优势,但在随机读取上反而有较大的劣势,且在写入方面性能极差. Vector类在顺序读取方面性能较差,但在随机读取方面有 ...
- Magicodes.Pay已支持Volo Abp
Magicodes.Pay已支持Volo Abp 简介 Magicodes.Pay希望打造一个统一支付库,相关库均使用.NET标准库编写,支持.NET Framework以及.NET Core.目前已 ...
- 人人都能看懂的卡西欧fx991cnx玩机指南,手把手教你如何利用计算器的漏洞爆机
专业术语说明 你是VerB还是VerC 别人问你这个问题的时候不要慌,帮你看你的计算器是Ver几: 同时按住shift.7.开机键 9 5次shift 第一行后半句即是 紧接着可以顺便看看计算器的序列 ...
- uniapp+.net core 小程序获取手机号
获取手机号 从基础库 2.21.2 开始,对获取手机号的接口进行了安全升级,以下是新版本接口使用指南.(旧版本接口目前可以继续使用,但建议开发者使用新版本接口,以增强小程序安全性) 因为需要用户主动触 ...