[Go 微服务] Kratos 使用的简单总结

news2024/11/23 8:07:21

文章目录

      • 1.Kratos 简介
      • 2.传输协议
      • 3.日志
      • 4.错误处理
      • 5.配置管理
      • 6.wire

1.Kratos 简介

Kratos并不绑定于特定的基础设施,不限定于某种注册中心,或数据库ORM等,所以您可以十分轻松地将任意库集成进项目里,与Kratos共同运作。

在这里插入图片描述
API -> Service(wire) -> DB

  1. 可以看到kratos将整个服务大体分为了3层,API / Service / DB。
  2. 左侧标注了在 Service和DB层,使用依赖注入(DI)进行实现,工具名称为Wire。
  3. 可以看到Wire这个工具几乎贯穿Kratos架构始终,是一个大角色。

2.传输协议

支持http + grpc两种调用方式,通过编写proto文件来实现。

一般,http开放给外部调用,可以使用restful风格定义。grpc面向内部微服务之间进行调用。

在这里插入图片描述

​ 在项目中,会以这样的结构出现,并且可以对不同协议进来的请求进行处理,添加处理的中间件,如权限校验、熔断限流等等。

3.日志

在kratos中,可以自定义日志框架选型,设置日志格式和输出内容,然后将logger对象以依赖注入的方式,分配给server中的grpc server和http server,这样就可以实现每次收到请求后的日志打印。

将logger对象以依赖注入的方式,注入到业务层,就可以在业务层中统一使用logger进行输出。

4.错误处理

在grpc中,比较通用的一种错误处理方式就是直接通过 proto 预定义定义错误码,然后通过 proto-gen-go 生成帮助代码,直接返回 error。

{
    // 错误码,跟 http-status 一致,并且在 grpc 中可以转换成 grpc-status
    "code": 500,
    // 错误原因,定义为业务判定错误码
    "reason": "USER_NOT_FOUND",
    // 错误信息,为用户可读的信息,可作为用户提示内容
    "message": "invalid argument error",
    // 错误元信息,为错误添加附加可扩展信息
    "metadata": {
      "foo": "bar"
    }
}

这里可以发现,为了兼容grpc,在http的返回结果中,code也无法自定义,只能跟随httpcode。所以这里客户端或者第三方去处理错误时,需要判断reason字段。

5.配置管理

使用proto文件定义配置和生成struct,然后将yaml中的内容读取到对应struct 字段中进行使用。

在这里我们可以注意到,在kratos中,除了传输格式使用了proto进行定义之外,错误处理和配置管理,也使用了proto来进行。可以说,一切皆proto。

6.wire

Wire 是一个灵活的依赖注入工具(需要安装),通过自动生成代码的方式在编译期完成依赖注入。通过 Wire 进行初始化代码,可以很好地解决组件之间的耦合,以及提高代码维护性。

打开Kratos的示例项目,从main入口看,有一处调用了wireApp方法,这里就是一切的源头(万恶之源)。

这个方法调用的是main同目录的wire文件中的wireApp方法,同目录的wire_gen.go实现了此方法。

wire_gen中去实例化不同service和组建的对象,用于调用。关系图如下:

在这里插入图片描述

在这里插入图片描述

server -> service -> biz -> data

main.go -> wire.go(wire_gen.go)

在这里插入图片描述

wire.go 中有用到ProviderSet

package main

import (
	"kratos-demo03/internal/biz"
	"kratos-demo03/internal/conf"
	"kratos-demo03/internal/data"
	"kratos-demo03/internal/server"
	"kratos-demo03/internal/service"

	"github.com/go-kratos/kratos/v2"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/google/wire"
)

// wireApp init kratos application.
func wireApp(*conf.Server, *conf.Data, log.Logger) (*kratos.App, func(), error) {
	panic(wire.Build(server.ProviderSet, data.ProviderSet, biz.ProviderSet, service.ProviderSet, newApp))
}

main.go 有用到App和Config

package main

import (
	"flag"
	"os"

	"kratos-demo03/internal/conf"

	"github.com/go-kratos/kratos/v2"
	"github.com/go-kratos/kratos/v2/config"
	"github.com/go-kratos/kratos/v2/config/file"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/go-kratos/kratos/v2/middleware/tracing"
	"github.com/go-kratos/kratos/v2/transport/grpc"
	"github.com/go-kratos/kratos/v2/transport/http"

	_ "go.uber.org/automaxprocs"
)

// go build -ldflags "-X main.Version=x.y.z"
var (
	// Name is the name of the compiled software.
	Name string
	// Version is the version of the compiled software.
	Version string
	// flagconf is the config flag.
	flagconf string

	id, _ = os.Hostname()
)

func init() {
	flag.StringVar(&flagconf, "conf", "../../configs", "config path, eg: -conf config.yaml")
}

func newApp(logger log.Logger, gs *grpc.Server, hs *http.Server) *kratos.App {
	return kratos.New(
		kratos.ID(id),
		kratos.Name(Name),
		kratos.Version(Version),
		kratos.Metadata(map[string]string{}),
		kratos.Logger(logger),
		kratos.Server(
			gs,
			hs,
		),
	)
}

func main() {
	flag.Parse()
	logger := log.With(log.NewStdLogger(os.Stdout),
		"ts", log.DefaultTimestamp,
		"caller", log.DefaultCaller,
		"service.id", id,
		"service.name", Name,
		"service.version", Version,
		"trace.id", tracing.TraceID(),
		"span.id", tracing.SpanID(),
	)
	c := config.New(
		config.WithSource(
			file.NewSource(flagconf),
		),
	)
	defer c.Close()

	if err := c.Load(); err != nil {
		panic(err)
	}

	var bc conf.Bootstrap
	if err := c.Scan(&bc); err != nil {
		panic(err)
	}

	app, cleanup, err := wireApp(bc.Server, bc.Data, logger)
	if err != nil {
		panic(err)
	}
	defer cleanup()

	// start and wait for stop signal
	if err := app.Run(); err != nil {
		panic(err)
	}
}

在每个模块中,只需要一个 ProviderSet 提供者集合,就可以在 wire 中进行依赖注入。

有一个数据库连接对象,service需要操作数据库,依赖数据库连接对象。这时候我们可以声明数据库连接对象在ProviderSet集合,然后在service对象处声明,我需要一个数据库连接对象。 然后我们使用wire工具,就可以自动帮我们生成依赖注入的代码。

这里的依赖注入让代码间的依赖关系一目了然。只需要查看wire_gen.go代码就可以了解依赖关系。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1876813.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《mysql篇》--查询(进阶)

目录 将查询结果作为插入数据 聚合查询 聚合函数 count sum group by子句 having 联合查询 笛卡尔积 多表查询 join..on实现多表查询 内连接 外连接 自连接 子查询 合并查询 将查询结果作为插入数据 Insert into 表2 select * from 表1//将表1的查询数据插入…

【UE 网络】专用服务器和多个客户端加入游戏会话的过程,以及GameMode、PlayerController、Pawn的创建流程

目录 0 引言1 多人游戏会话1.1 Why?为什么要有这个1.2 How?怎么使用? 2 加入游戏会话的流程总结 🙋‍♂️ 作者:海码007📜 专栏:UE虚幻引擎专栏💥 标题:【UE 网络】在网络…

爬坑之 [‘NODE_ENV‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。]

在package.json中配置如下: 执行npm run dev启动 报错: 实际上, NODE_ENVdevelopment webpack-dev-server 这条脚本会合并为两条命令执行, 分别为: NODE_EVNdevelopment webpack-dev-server 这种写法在cmd中是不被支持的 解决…

Bootstrap更改默认的“请在电子邮件地址中包含@”

摘要: 今天开发一个外贸系统,必须全部英文的,但是使用到bootatrp 4的input标签的type"email"输入没有含“”符号时会提示:“请在电子邮件地址中包含”中文提示!一开始以为是中国下载的谷歌是浏览器自带的提示…

计算机网络知识整理笔记

目录 1.对网络协议的分层? 2.TCP/IP和UDP之间的区别? 3.建立TCP连接的三次握手? 4.断开TCP连接的四次挥手? 5.TCP协议如何保证可靠性传输? 6.什么是TCP的拥塞控制? 7.什么是HTTP协议? 8…

停车场智能化管理:车位引导系统实现车位资源优化与数据分析

随着城市汽车保有量的不断增长,停车难问题日益凸显。尤其是在高峰时段,寻找停车位和取车成为了许多车主的头疼问题。为了解决这一难题,维小帮智能车位引导系统应运而生,它利用先进的技术手段,帮助车主快速找到停车位&a…

【计算机图形学】期末考试知识点汇总

文章目录 第一章计算机图形学概述计算机图形学的定义计算机图形学的应用计算机图形学 vs 图像处理 vs模式识别图形显示器的发展及工作原理理解三维渲染管线 第二章 基本图元的扫描转换扫描转换直线的扫描转换DDA算法Bresenham算法中点画线算法圆的扫描转换中点画圆算法反走样 第…

2024steam夏促商店打不开、steam活动加载不了解决方法一览

今年的夏促终于开始了!目前可以看到很多精品小游戏在促销列表内,活动正式开启后还不知道又会是怎样的一幅场景。因为每年夏促都会有不少刚高考完的新手加入,遇到常见的steam商店打不开、活动页面不加载等问题不知道怎么解决。所以这里给大家准备了几种常…

从零创建深度学习张量库,支持gpu并行与自动微分

多年来,我一直在使用 PyTorch 构建和训练深度学习模型。尽管我已经学会了它的语法和规则,但总有一些东西激起了我的好奇心:这些操作内部发生了什么?这一切是如何运作的? 如果你已经到这里,你可能也有同样的…

mybatis的高级映射

mybatis的高级映射(重点) 表与表之间的关系: 一对一关系: 栗子:一个人对应一个身份证号 一对多关系: 栗子:一个用户可以有多个订单 1. 分析需求&…

权限维持-域环境单机版---粘滞键屏保登录

免责声明;本文仅做技术交流与学习,,, 目录 粘滞键: 粘滞键位置: 屏保&登录: 1、WinLogon配合无文件落地上线 结合ps命令: 2、屏幕保护生效后执行后门 粘滞键: Windows维权之粘滞键项维权-腾讯云开发者社区-腾讯云 (tencent.com) 系统自带的辅助功能进行替…

LNBxx21的功能

LNBxx21功能: LNBxx21 家族是为卫星LNB模块供电/连接LNB块与接收机的集成化解决方案。LNBxx21的很多功能可以让LNB电源/接口符合国际标准,此外,模块内还包括一个I2C总线接口,因为集成了一个升压直流-直流控制器,所以可…

MySQL InnoDB支持几种行格式

数据库表的行格式决定了一行数据是如何进行物理存储的,进而影响查询和DML操作的性能。 在InnoDB中,常见的行格式有4种: 1、COMPACT:是MySQL 5.0之前的默认格式,除了保存字段值外,还会利用空值列表保存null…

zabbix-agent2启动失败报错Unit zabbix-agent2.service entered failed state.

文章目录 1,用systemctl status zabbix-agent2查看报错状态2,用journalctl -xe查看一下报错日志3,再看一下zabbix的日志。4,错误修改5, 再次重启zabbix-agent2 1,用systemctl status zabbix-agent2查看报错…

【漏洞复现】Atlassian Confluence RCE(CVE-2023-22527)

产品简介 Atlassian Confluence 是一款由Atlassian开发的企业团队协作和知识管理软件,提供了一个集中化的平台,用于创建、组织和共享团队的文档、知识库、项目计划和协作内容。是面向大型企业和组织的高可用性、可扩展性和高性能版本。 0x02 漏洞概述 …

综合布线实训室建设可行性报告

1、 建设综合布线实训室的目的和意义 1.1 响应国家职业教育政策 在国家对职业教育的高度重视和政策支持下,综合布线实训室的建设不仅是对国家教育方针的积极响应,也是对技术教育改革的有力推动。通过这一平台,我们旨在培育出一批具有强烈实…

全面体验ONLYOFFICE 8.1版本桌面编辑器

ONLYOFFICE官网 在当今的数字化办公环境中,选择合适的文档处理工具对于提升工作效率和团队协作至关重要。ONLYOFFICE 8.1版本桌面编辑器,作为一款集成了多项先进功能的办公软件,为用户提供了全新的办公体验。今天,我们将深入探索…

[linux]sed命令基础入门详解

sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这…

imx6ull/linux应用编程学习(5)FrameBuffer的应用编程

什么是FrameBuffer? Frame 是帧的意思, buffer 是缓冲的意思,所以 Framebuffer 就是帧缓冲, 这意味着 Framebuffer 就是一块内存,里面保存着一帧图像。帧缓冲(framebuffer)是 Linux 系统中的一种…

泰迪智能科技携手广州番禺职业技术学院共建上进双创工作室

为充分发挥校企双方的优势,促进产教融合,发挥职业教育为社会、行业、企业服务的作用,为企业培养更多高素质、高技能的应用型人才的同时也为学生实习、就业提供更大空间。6月26日,“泰迪广州番禺职业技术学院上进双创工作室签约授牌…