【后端开发】go-zero微服务框架实践(goland框架对比,go-zero开发实践,文件上传问题优化等等)
【后端开发】go-zero微服务框架实践(goland框架对比,go-zero开发实践,文件上传问题优化等)
文章目录
- 1、go框架对比介绍
- 2、go-zero 微服务开发实践
- 3、go-zero 文件上传问题优化
1、go框架对比介绍
国内开源goland框架对比 1
- go-zero,2020开源,30kstar:
整体上做为一个稍重的微服务框架,提供了微服务框架需要具备的通用能力,同时也只带一部分的强约束,例如针对web和rpc服务需要按照其定义的DSL的协议格式进行定义,日志配置、服务配置、apm配置等都要按照框架定义的最佳实践来走。 - go-kratos,2019开源,23kstar:
整体上做为一个轻量级的微服务框架,B站开源项目; web和rpc服务的 DSL协议直接采用protobuf和grpc进行定义,采用wire做依赖注入、自动生成代码。 框架定位于解决微服务的核心诉求。 - tarsgo,2018开源,3kstar:
做为tars这个大的C++重量级微服务框架下的go语言服务框架,腾讯开源项目; 对于有个好爹的这个事情,总是喜忧参半的;好处在于很多能力不用从头开始做起,直接依托母体;劣势就是独立性相对较差,要选用这个tarsgo的前提,就是要先选用tars这个大的框架。 - dubbo go,2019开源,4kstar
做为dubbo这个大的Java重量级微服务框架下的go语言服务框架,阿里开源项目;优劣基本跟tarsgo一样 - jupiter,2020开源,4kstar
重量级的微服务框架,斗鱼开源项目;整体思路上跟tars和dubbo力图提供一个大一统的框架,更确切的说是一个微服务平台,也带类似tars和dubbo那样的管理控制台,提供各种控制和metric的继承,这也无形中给选用此框架带来了不少代价。 - go-mirco,2015开源,22kstar
一个轻量级的微服务框架,做为一个在2015年就开源的项目,在当时那个市面上开源的微服务框架稀少的年代,它是为数不多的选择。 - go-kit,2015开源,26kstar
从严格意义上来说,并不能做为一个微服务框架,而应该是一个微服务的工具集,其官方定义上也是这么说,提供各种选项让你自由选择。做为一个在2015年就开源的项目,也是当时很多go项目为数不多的选择之一。 - 综上所属,选型时选择go-zero
go-zero介绍 1, 2 云原生go-zero微服务框架设计思考
- go-zero 是一个集成了各种工程实践的 web 和 rpc 框架。通过弹性设计保障了大并发服务端的稳定性,经受了充分的实战检验。
go-zero 包含极简的 API 定义和生成工具 goctl,可以根据定义的 api 文件一键生成 Go, iOS, Android, Kotlin, Dart, TypeScript, JavaScript 代码,并可直接运行。 - 框架设计
轻松获得支撑千万日活服务的稳定性,内建级联超时控制、限流、自适应熔断、自适应降载等微服务治理能力,无需配置和额外代码,微服务治理中间件可无缝集成到其它现有框架使用,极简的 API 描述,一键生成各端代码,自动校验客户端请求参数合法性,大量微服务治理和并发工具包。 - 框架特点
强大的工具支持,尽可能少的代码编写,极简的接口,完全兼容 net/http,支持中间件,方便扩展,高性能,面向故障编程,弹性设计,内建服务发现、负载均衡,内建限流、熔断、降载,且自动触发,自动恢复,API 参数自动校验,超时级联控制,自动缓存控制,链路跟踪、统计报警等,高并发支撑,稳定保障了疫情期间每天的流量洪峰。



2、go-zero 微服务开发实践
1、数据库和数据表设计
- 微服务进行服务拆分一个最好理解并且最基本的原则就是:每个服务对应一个单独的数据库。做到服务与服务之间的解耦,划清边界。 1
- 这就要求我们明确项目(服务)需求之后,做好表结构设计。
- 我们后续项目中用到的model、proto、甚至api层的结构体都可以通过工具根据数据库生成,所以数据库的设计至关重要
- 这部分所有微服务都是一样的,在这里就不再赘述
- 部分设计规范可参考 1, 2, 3
- 最佳实践
范式设计:遵循数据库范式原则,最少达到第三范式,以减少数据冗余。
分区考虑:对大数据量表采取分区设计,以提高查询效率。
索引:为常用查询字段添加索引,以加速数据库查询。
规范命名:使用统一的命名规范(如小写字母加下划线)来提高可读性。
外键约束:适当设置外键以确保数据的完整性与关联性。


2、使用工具生成model
- 使用goctl中的model命令生成,1
- 为了进一步提高效率,我们对此进行了封装,方便我们更快更好的生成model
比如在model文件夹里保留建表的sql文件,用后缀_gen,_script等补充更多功能性的查询函数。 - 注意事项:
生成代码后,手动检查是否符合业务逻辑,尤其是验证函数。
定期更新模型代码,保持与数据库的同步。
自定义字段类型:如果有特殊数据类型,考虑自定义字段类型以保证数据正确性。
3、开发api层
- 先定义xxx.api文件,可以参考 api demo
- 使用goctl生成代码:goctl api go -api main.api -dir …/ --style=goZero
- 配置生成代码中的config目录以及yaml文件,弄清它们两者之间的联系
- 配置生成代码svc目录中的文件(比如jwt之类的中间件)
- 最佳实践
RESTful 设计原则:遵循 RESTful API 设计规范,确保接口的可理解性和一致性。
参数验证:对输入参数进行严格验证,使用中间件处理错误和异常。
使用 Swagger:集成 Swagger 将 API 接口文档化,便于开发和调试。 - 注意事项:
设计清晰的错误返回结构,方便前端处理。
避免过于复杂的路由,保持路由设计的简洁性。
4、开发rpc层
- 使用goctl生成pb.go文件:goctl rpc protoc lottery.proto --go_out=…/ --go-grpc_out=…/ --zrpc_out=…/ --style=goZero
- 配置svc,注册model
- 编写logic,调用model,写业务代码
- 最佳实践:
Protocol Buffers:使用 Protocol Buffers 作为序列化方式,以提高传输效率。
接口隔离原则:为不同的服务定义清晰且独立的接口,减少各服务间的耦合。 - 注意事项:
在开发过程中使用本地模拟服务进行测试,确保 RPC 调用的稳定性。
定义通用的错误处理机制,以便各个服务能够统一处理错误。
5、在api层注册rpc服务,调用rpc方法,对外提供接口
- api层配置svc,注册rpc客户端
- 调用rpc方法
- 返回restful api
- 最佳实践:
API与RPC解耦:保证 API 层与 RPC 层之间的解耦,便于后期修改和扩展。
服务发现:在微服务架构中,使用服务注册和发现机制(如 Consul 或 Nacos)来管理服务地址。 - 注意事项:
在服务注册时确保服务的健康检查设置,及时发现并替换故障服务。
关注 RPC 服务的性能监控,避免因服务调用导致的性能瓶颈。
6、生成接口文档
- 虽然goctl不直接支持生成swagger,但是goctl的插件支持。- goctl-swagger 通过 api 文件生成 swagger 文档
- 安装好goctl-swagger插件之后,我们就可以在api层的xxx.api同级目录下生成swagger了
- 参考命令如下:其中main.api是我在api层的desc目录中定义的,我们也在同级目录执行goctl命令即可:
- goctl api plugin -plugin goctl-swagger=“swagger -filename main.json” -api main.api -dir .
- 执行之后,就会出现如下图所示的main.json,这就是swagger文件
- 你可以直接使用swagger进行测试,也可以导入到其他工具中
- 注意事项:
定期审查和维护接口文档,确保其准确性与时效性。
对于较复杂的业务逻辑,提供详细的说明和使用场景,增强文档的可读性。
更多微服务开发最佳实践
-
项目结构管理-分层架构
规范目录结构,遵循行业最佳实践,提供可预见的目录结构,方便团队协作,保持代码的清晰和可维护性
避免将所有代码放在同一目录中,防止代码杂乱无章。注重模块之间的低耦合、高内聚设计。
apis, etc, catch, gen, pkg, config, handle, logic, middleware, rpchelper, svc, types, pkg, convert, etcd, constvalue, util, test等等 -
错误处理与日志记录
统一错误处理机制:定义通用的错误类型和处理函数,提高错误处理的可维护性。
结构化日志:使用结构化日志工具(如 Logrus 或 Zap)来记录 API 调用和服务事件,便于后续分析。
定期审查和分析日志,寻找潜在的性能瓶颈和异常。
避免在生产环境记录敏感信息,确保日志安全。 -
安全性
身份认证与授权:使用 JWT 或 OAuth 2.0 实现用户身份认证与授权,增强 API 的安全性。
数据加密:保护敏感数据,包括数据库存储的敏感信息和 API 请求的传输安全。
定期更新认证和授权机制,以适应新的安全威胁。
关注服务间通讯的安全性,尤其是在多服务间的 RPC 调用中。 -
性能优化
缓存策略:利用 Redis 等缓存机制来减轻数据库负担,提高数据访问速度。
异步处理:使用消息队列(如 Kafka 或 RabbitMQ)处理不需要实时响应的任务,实现异步化。
进行性能测试,确定程序瓶颈点并进行针对性优化。
定期评估 Cache 的失效策略和更新机制,以避免缓存污染。 -
服务监控与运维
监控和报警:使用 Prometheus 和 Grafana 等工具监控微服务的性能指标,并设置报警规则,以便实时响应。
健康检查:实现定期健康检查,确保服务的可用性。
监控数据的采集和存储应考虑存储成本和数据的清理策略。
对于重要的服务,建议引入熔断和重试机制,以提升系统的鲁棒性。 -
持续集成与持续交付 (CI/CD)
自动化测试:为 API 和 RPC 层编写单元测试和集成测试,确保代码质量。
CI/CD 工具:使用 Jenkins、GitLab CI 或 GitHub Actions 等工具,实现代码的自动构建、测试和部署。
保持 CI/CD 流程的可用性和高效性,定期审查构建和部署的效率。
确保每次代码提交都能触发 CI 流程,及时反馈问题。 -
文档与知识共享
维护开发文档:记录开发过程中遇到的问题及解决方案,形成知识库。
代码评审:开展代码评审活动,促进团队成员间的学习和知识共享。
定期更新文档,确保其与实际开发保持一致。
鼓励团队成员共享经验与最佳实践,共同提升团队的整体水平
3、go-zero 文件上传问题优化
背景与问题
- 使用go-zero框架,在定义请求消息的时候默认没有支持file类型的types,1 2
- 项目实现不方便换成gin框架(成本高)
- request中body请求信息有一个参数需要file类型,用于支持上传文件的场景, 上传代码 1

api
type (
UploadFileReq { }
UploadFileRes {Code int64 `json:"code"`Msg string `json:"msg"`Data string `json:"data"`
}
service file-upload {@handler uploadFilepost /uploadFile (UploadFileReq) returns (UploadFileRes)
}
handler
func UploadFileHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {// 解析表单fileData, handler, err := r.FormFile("file")if err != nil {httpx.Error(w, err)return}// 关闭文件数据defer fileData.Close()// 文件上传filename := handler.Filenamel := file.NewUploadFileLogic(r.Context(), svcCtx)resp, err := l.UploadFile(&fileData, filename)}
}
service
package fileimport ("encoding/csv""fmt""github.com/xuri/excelize/v2""io""log""mime/multipart""strings"
)func (l *UploadFileLogic) UploadFile(data *multipart.File, fileName string) (resp *types.UploadFileResp, err error) {// 上传对象存储ossConfig := l.svcCtx.Config.OssConfigfilePath := fmt.Sprintf("uploads/%s", fileName)err = file.UploadFile(*data, filePath, file.OssConfig{AccessKeyId: ossConfig.AccessKeyId,AccessKeySecret: ossConfig.AccessKeySecret,BucketName: ossConfig.BucketName,Endpoint: ossConfig.Endpoint,BucketDoMan: ossConfig.BucketDoMan,})if err != nil {l.Logger.Errorf("上传文件失败, err:%s", err.Error())return nil, err}// 解析文件内容fileType := strings.ToLower(fileName[strings.LastIndex(fileName, ".")+1:])switch fileType {case "csv":// 解析 CSV 文件csvData, err := l.parseCSVFile(*data)if err != nil {l.Logger.Errorf("解析 CSV 文件失败, err:%s", err.Error())return nil, err}l.Logger.Infof("解析到的 CSV 数据: %v", csvData)case "xlsx", "xls":// 解析 Excel 文件excelData, err := l.parseExcelFile(*data)if err != nil {l.Logger.Errorf("解析 Excel 文件失败, err:%s", err.Error())return nil, err}l.Logger.Infof("解析到的 Excel 数据: %v", excelData)default:return nil, fmt.Errorf("不支持的文件类型: %s", fileType)}// 构造返回值resp = &types.UploadFileResp{FilePath: filePath,FileName: fileName,}return resp, nil
}// 解析 CSV 文件
func (l *UploadFileLogic) parseCSVFile(file multipart.File) ([][]string, error) {reader := csv.NewReader(file)records, err := reader.ReadAll()if err != nil {return nil, fmt.Errorf("读取 CSV 文件失败: %w", err)}return records, nil
}// 解析 Excel 文件
func (l *UploadFileLogic) parseExcelFile(file multipart.File) ([][]map[string]string, error) {excel := excelize.NewFile()defer func() {if err := excel.Close(); err != nil {log.Printf("关闭 Excel 文件失败: %s", err.Error())}}()// 读取 Excel 文件内容err := excel.ImportFromReader(file)if err != nil {return nil, fmt.Errorf("导入 Excel 文件失败: %w", err)return parsedData, nil
}
相关文章:
【后端开发】go-zero微服务框架实践(goland框架对比,go-zero开发实践,文件上传问题优化等等)
【后端开发】go-zero微服务框架实践(goland框架对比,go-zero开发实践,文件上传问题优化等) 文章目录 1、go框架对比介绍2、go-zero 微服务开发实践3、go-zero 文件上传问题优化 1、go框架对比介绍 国内开源goland框架对比 1 go-…...
C#程序加密与解密Demo程序示例
目录 一、加密程序功能介绍 1、加密用途 2、功能 3、程序说明 4、加密过程 5、授权的注册文件保存方式 二、加密程序使用步骤 1、步骤一 编辑2、步骤二 3、步骤三 4、步骤四 三、核心代码说明 1、获取电脑CPU 信息 2、获取硬盘卷标号 3、机器码生成 3、 生成…...
小程序事件系统 —— 33 事件传参 - data-*自定义数据
事件传参:在触发事件时,将一些数据作为参数传递给事件处理函数的过程,就是事件传参; 在微信小程序中,我们经常会在组件上添加一些自定义数据,然后在事件处理函数中获取这些自定义数据,从而完成…...
深入解析 JavaScript 原型与原型链:从原理到应用
原型和原型链是 JavaScript 中实现对象继承和属性查找的核心机制。为了更深入地理解它们,我们需要从底层原理、实现机制以及实际应用等多个角度进行分析。 1. 原型(Prototype) 1.1 什么是原型? 每个 JavaScript 对象(…...
关于AI数据分析可行性的初步评估
一、结论:可在部分环节嵌入,无法直接处理大量数据 1.非本地部署的AI应用处理非机密文件没问题,内部文件要注意数据安全风险。 2.AI(指高规格大模型)十分适合探索性研究分析,对复杂报告无法全流程执行&…...
回归预测 | Matlab实现GWO-BP-Adaboost基于灰狼算法优化BP神经网络结合Adaboost思想的回归预测
回归预测 | Matlab实现GWO-BP-Adaboost基于灰狼算法优化BP神经网络结合Adaboost思想的回归预测 目录 回归预测 | Matlab实现GWO-BP-Adaboost基于灰狼算法优化BP神经网络结合Adaboost思想的回归预测回归效果基本介绍GWO-BP-Adaboost:基于灰狼算法优化BP神经网络结合Adaboost思想…...
ARM Cortex-M 内存映射详解:如何基于寄存器直接读写 寄存器映射方式编码程序 直接操作硬件寄存器来控制 MCU
ARM Cortex-M 的系统映射空间 在 STM32 等 ARM Cortex-M 系列 MCU 中,内存地址空间按照 存储功能 进行了严格划分,包括 Flash(程序存储)、RAM(数据存储)、外设寄存器(GPIO、UART、SPI 等&am…...
深度学习实战车辆目标跟踪与计数
本文采用YOLOv8作为核心算法框架,结合PyQt5构建用户界面,使用Python3进行开发。YOLOv8以其高效的实时检测能力,在多个目标检测任务中展现出卓越性能。本研究针对车辆目标数据集进行训练和优化,该数据集包含丰富的车辆目标图像样本…...
django中视图作用和视图功能 以及用法
在 Django REST Framework(DRF)中,视图(View)是处理 HTTP 请求并返回响应的核心组件。DRF 提供了多种视图类,适用于不同的场景和需求。以下是 DRF 中常见的视图类及其作用、使用方法的详细说明: 一、DRF 视图的分类 DRF 的视图可以分为以下几类: 基于函数的视图(Func…...
【每日学点HarmonyOS Next知识】输入框自动获取焦点、JS桥实现方式、Popup设置全屏蒙版、鼠标事件适配、Web跨域
1、HarmonyOS TextInput或TextArea如何自动获取焦点? 可以使用 focusControl.requestFocus 对需要获取焦点的组件设置焦点,具体可以参考文档: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attribut…...
【学习思维模型】
学习思维模型 一、理解类模型二、记忆类模型三、解决问题类模型四、结构化学习模型五、效率与习惯类模型六、高阶思维模型七、实践建议八、新增学习思维模型**1. 波利亚问题解决四步法****2. 主动回忆(Active Recall)****3. 鱼骨图(因果图/Ishikawa Diagram)****4. MECE原则…...
MyBatis-Plus分页控件使用及使用过程发现的一个坑
最近维护一个旧项目的时候,出现了一个BUG,经排查后发现是Mybatis-plus分页控件使用的时候需要注意的一个问题,故在本地使用MybatisPlus模拟出现了一下这个问题。 首先,先说一下MyBatis-Plus的使用: 1)引入…...
STM32的APB1和APB2的区别
STM32微控制器中的APB1和APB2的区别 STM32微控制器中的APB1和APB2是两种不同的外设总线,主要区别在于时钟速度、连接的外设以及用途。以下是它们的详细对比: 1. 时钟速度 APB1 (Advanced Peripheral Bus 1): 低速总线,时钟频率通常为系统时钟…...
JS一些小知识点
一、|| 运算符 plain this.ctx.body { type: type || 0, // ||在此处用法用于默认值填充,判断是否传参或该值是否存在,如果不存在就使用||后买你的值作为默认值 code: code || 0, msg: msg || SUCCESS, data: data || {}, ...others }; 二、trim() 方…...
手写Tomcat:实现基本功能
首先,Tomcat是一个软件,所有的项目都能在Tomcat上加载运行,Tomcat最核心的就是Servlet集合,本身就是HashMap。Tomcat需要支持Servlet,所以有servlet底层的资源:HttpServlet抽象类、HttpRequest和HttpRespon…...
C#变量与变量作用域详解
一、变量基础 1. 声明与初始化 声明语法:<数据类型> <变量名>(如 int age; string name)初始化要求: 1、 类或结构体中的字段变量(全局变量)无需显式初始化,默认值…...
SV学习笔记——数组、队列
一、定宽数组 定宽数组是静态变量,编译时便已经确定其大小,其可以分为压缩定宽数组和非压缩定宽数组:压缩数组是定义在类型后面,名字前面;非压缩数组定义在名字后面。Bit [7:0][3:0] name; bit[7:0] name [3:0]; 1.1定宽数组声明 数组的声…...
API调试工具的无解困境:白名单、动态IP与平台设计问题
引言 你是否曾经在开发中遇到过这样的尴尬情形:你打开了平台的API调试工具,准备一番操作,结果却发现根本无法连接到平台?别急,问题出在调试工具本身。今天我们要吐槽的就是那些神奇的开放平台API调试工具,…...
Git清理本地残留的、但已经在服务器上被删除的分支
要筛选出已经被服务器删除的本地分支,并在本地删除这些分支,可以按照以下步骤进行操作: 步骤 1: 获取远程分支信息,确保本地的远程分支信息是最新的: git fetch -p步骤 2: 列出本地分支和远程分支: git …...
HTTPS实现内容加密的逻辑
加密过程 使用非对称加密,网站生成公钥和私钥浏览器获取到网站公钥(通过验证和解析CA证书),随即生成一串字符串,然后使用公钥加密,发送给网站。网站用私钥将加密内容解析,然后使用这串字符串对…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...
