当前位置: 首页 > news >正文

【后端开发】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 对象&#xff08…...

关于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. ‌声明与初始化‌ 声明语法‌&#xff1a;<数据类型> <变量名>&#xff08;如 int age; string name&#xff09;‌初始化要求‌&#xff1a; 1、 类或结构体中的字段变量&#xff08;全局变量&#xff09;‌无需显式初始化‌&#xff0c;默认值…...

SV学习笔记——数组、队列

一、定宽数组 定宽数组是静态变量&#xff0c;编译时便已经确定其大小&#xff0c;其可以分为压缩定宽数组和非压缩定宽数组:压缩数组是定义在类型后面&#xff0c;名字前面;非压缩数组定义在名字后面。Bit [7:0][3:0] name; bit[7:0] name [3:0]; 1.1定宽数组声明 数组的声…...

API调试工具的无解困境:白名单、动态IP与平台设计问题

引言 你是否曾经在开发中遇到过这样的尴尬情形&#xff1a;你打开了平台的API调试工具&#xff0c;准备一番操作&#xff0c;结果却发现根本无法连接到平台&#xff1f;别急&#xff0c;问题出在调试工具本身。今天我们要吐槽的就是那些神奇的开放平台API调试工具&#xff0c;…...

Git清理本地残留的、但已经在服务器上被删除的分支

要筛选出已经被服务器删除的本地分支&#xff0c;并在本地删除这些分支&#xff0c;可以按照以下步骤进行操作&#xff1a; 步骤 1: 获取远程分支信息&#xff0c;确保本地的远程分支信息是最新的&#xff1a; git fetch -p步骤 2: 列出本地分支和远程分支&#xff1a; git …...

HTTPS实现内容加密的逻辑

加密过程 使用非对称加密&#xff0c;网站生成公钥和私钥浏览器获取到网站公钥&#xff08;通过验证和解析CA证书&#xff09;&#xff0c;随即生成一串字符串&#xff0c;然后使用公钥加密&#xff0c;发送给网站。网站用私钥将加密内容解析&#xff0c;然后使用这串字符串对…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 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&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;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的列编号是这样的&#xff1a;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 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 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 插件详为例&#xff0c;Webpack.config.js它可能的配置和含义如下&#xff1a; 前言 Module Federation 的Webpack.config.js核心配置包括&#xff1a; name filename&#xff08;定义应用标识&#xff09; remotes&#xff08;引用远程模块&#xff0…...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...