陕西专业网站开发联系电话,有做国外网站推广吗,如何做免费网站制作,某某公司网站建设论文【后端开发】go-zero微服务框架实践#xff08;goland框架对比#xff0c;go-zero开发实践#xff0c;文件上传问题优化等#xff09; 文章目录 1、go框架对比介绍2、go-zero 微服务开发实践3、go-zero 文件上传问题优化 1、go框架对比介绍
国内开源goland框架对比 1
go-…【后端开发】go-zero微服务框架实践goland框架对比go-zero开发实践文件上传问题优化等 文章目录 1、go框架对比介绍2、go-zero 微服务开发实践3、go-zero 文件上传问题优化 1、go框架对比介绍
国内开源goland框架对比 1
go-zero2020开源30kstar 整体上做为一个稍重的微服务框架提供了微服务框架需要具备的通用能力同时也只带一部分的强约束例如针对web和rpc服务需要按照其定义的DSL的协议格式进行定义日志配置、服务配置、apm配置等都要按照框架定义的最佳实践来走。go-kratos2019开源23kstar 整体上做为一个轻量级的微服务框架B站开源项目 web和rpc服务的 DSL协议直接采用protobuf和grpc进行定义采用wire做依赖注入、自动生成代码。 框架定位于解决微服务的核心诉求。tarsgo2018开源3kstar 做为tars这个大的C重量级微服务框架下的go语言服务框架腾讯开源项目 对于有个好爹的这个事情总是喜忧参半的好处在于很多能力不用从头开始做起直接依托母体劣势就是独立性相对较差要选用这个tarsgo的前提就是要先选用tars这个大的框架。dubbo go2019开源4kstar 做为dubbo这个大的Java重量级微服务框架下的go语言服务框架阿里开源项目优劣基本跟tarsgo一样jupiter2020开源4kstar 重量级的微服务框架斗鱼开源项目整体思路上跟tars和dubbo力图提供一个大一统的框架更确切的说是一个微服务平台也带类似tars和dubbo那样的管理控制台提供各种控制和metric的继承这也无形中给选用此框架带来了不少代价。go-mirco2015开源22kstar 一个轻量级的微服务框架做为一个在2015年就开源的项目在当时那个市面上开源的微服务框架稀少的年代它是为数不多的选择。go-kit2015开源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 …/ --stylegoZero配置生成代码中的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…/ --stylegoZero配置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类型的types1 2项目实现不方便换成gin框架成本高request中body请求信息有一个参数需要file类型用于支持上传文件的场景 上传代码 1 api
type (
UploadFileReq { }
UploadFileRes {Code int64 json:codeMsg string json:msgData 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/csvfmtgithub.com/xuri/excelize/v2iologmime/multipartstrings
)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
}