RabbitMQ--04--Spring Cloud Stream(消息驱动)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 1.Spring Cloud Stream
    • 1. 基本介绍
          • https://spring.io/projects/spring-cloud-stream#overview
    • 2.Spring Cloud Stream 解决的痛点问题
    • 3.设计思想
      • Stream为什么可以统一底层差异
      • 绑定器Binder的说明:
      • Stream的工作流程
    • 4.核心概念
    • 5. 常用注解
  • 基础案例1
    • 1.pom依赖
    • 2.yml配置文件
    • 3.生产着
    • 4.消费者
        • ==@StreamListener注解==
    • 5.测试,启动7001,8801,8802
    • 6.分组消费与持久化
  • 案例2----自定义消息通道
    • 1.生产者
    • 2.消费者
    • 3.测试
  • 案例3----自定义消息通道
    • 1.生产着
    • 2.消费者


1.Spring Cloud Stream

1. 基本介绍

官方定义 Spring Cloud Stream 是一个构建消息驱动微服务的框架

https://spring.io/projects/spring-cloud-stream#overview

在这里插入图片描述

Spring Cloud Stream 中,提供了一个微服务和消息中间件之间的一个粘合剂,这个粘合剂叫做Binder,Binder 负责与消息中间件进行交互。而我们开发者则通过 inputs 或者 outputs 这样的消息通道与 Binder 进行交互。

目前仅支持RabbitMQ、Kafka

  • 应用程序通过 inputs 或者 outputs 来与 Spring Cloud Stream中binder对象交互。
  • 通过我们配置来binding(绑定) ,而 Spring Cloud Stream 的 binder对象负责与消息中间件交互。
  • 所以,我们只需要搞清楚如何与 Spring Cloud Stream 交互就可以方便使用消息驱动的方式。

2.Spring Cloud Stream 解决的痛点问题

MQ消息中间件广泛应用在应用解耦合、异步消息处理、流量削峰等场景中。

  • 不同的MQ消息中间件内部机制包括使用方式都会有所不同,比如RabbitMQ中有Exchange(交换机/交换器)这一概念,kafka有Topic、Partition分区这些概念,MQ消息中间件的差异性不利于我们上层的开发应用,当我们的系统希望从原有的RabbitMQ切换到Kafka时,我们会发现比较困难,很多要操作可能重来(因为应用程序和具体的某⼀款MQ消息中间件耦合在⼀起了)。
  • Spring Cloud Stream进行了很好的上层抽象,可以让我们与具体消息中间件解耦合,屏蔽掉了底层具体MQ消息中间件的细节差异,就像Hibernate屏蔽掉了具体数据库(Mysql/Oracle一样)。如此⼀来,我们学习、开发、维护MQ都会变得轻松。目前Spring Cloud Stream支持RabbitMQ和Kafka。

本质:屏蔽掉了底层不同MQ消息中间件之间的差异,统一了MQ的编程模型,降低了学习、开发、维护MQ的成本

3.设计思想

Spring Cloud Stream 是⼀个构建消息驱动微服务的框架。应用程序通过inputs(相当于消息消费者consumer)或者outputs(相当于消息生产者producer)来与Spring Cloud Stream中的binder对象交互,而Binder对象是用来屏蔽底层MQ细节的,它负责与具体的消息中间件交互。

  • 说白了:对于我们来说,只需要知道如何使⽤Spring Cloud Stream与Binder对象交互即可

在这里插入图片描述

Spring Cloud Stream 通过使用Spring Integration来连接消息代理中间件以实现消息事件驱动,为流行的消息中间件产品(Spring Cloud Stream 原生默认支持RabbitMQ,Kafka。阿里在官方基础上提供了RocketMQ的支持

提供了个性化的自动化配置实现,引用了发布-订阅模式,消费组,分区的三大核心概念。

Stream中的消息通信方式遵循了发布-订阅模式

通常的mq的实现思想

  • 生产者/消费者之间靠消息媒介传递信息内容—Message
  • 消息必须走特定的通道—消息通道MessageChannel
  • 消息通道里的消息如何被消费呢,谁负责收发处理----消息通道MessageChannel的子接口SubscribableChannel,由MessageHandler消息处理器所订阅

Stream为什么可以统一底层差异

在没有绑定器这个概念的情况下,我们的SpringBoot应用要直接与消息中间件进行信息交互的时候,由于各消息中间件构建的初衷不同,它们的实现细节上会有较大的差异性

  • 通过定义绑定器作为中间层,完美地实现了应用程序与消息中间件细节之间的隔离。
  • 通过向应用程序暴露统一的Channel通道,使得应用程序不需要再考虑各种不同的消息中间件实现。
  • 通过定义绑定器Binder作为中间层,实现了应用程序与消息中间件细节之间的隔离。

绑定器Binder的说明:

在没有绑定器这个概念的情况下,Spring Boot应用要直接与消息中间件进行信息交互的时候,由于各消息中间件构建的初衷不同,它们的实现细节上会有较大的差异性。通过定义绑定器作为中间层,可以完美地实现应用程序与消息中间件细节之间的隔离。Stream对消息中间件的进一步封装,可以做到代码层面对中间件的无感知,甚至于动态的切换中间件,实现微服务和具体消息中间件的解耦,使得微服务可以关注更多自己的业务流程。一个集成Spring Cloud Stream 程序的框架示意图,如下图所示:
在这里插入图片描述
在这里插入图片描述
Binder中的INPUT和OUTPUT针对Binder本身而言,INPUT对应于消费者,OUTPUT对应于生产者。 INPUT接收消息生产者发送的消息,OUTPUT发送消息给到消息消费者消费。

Stream的工作流程

在这里插入图片描述

  • binder: 目标绑定器,目标指的是 kafka 还是 RabbitMQ,绑定器就是封装了目标中间件的包。如果操作的是 kafka
    就使用 kafka binder ,如果操作的是 RabbitMQ 就使用 rabbitmq binder。
  • Source和Sink:可理解为参照对象是Spring Cloud Stream自身,从Stream发布消息就是输出,接收消息就是输入。Source用于获取数据(要发送到MQ的数据),Sink用于提供数据(要接收MQ发送的数据,提供数据给消息消费者)
  • Channel:通道,是队列Queue的一种抽象,在消息通讯系统中就是实现存储和转发的媒介。用于存放source接收到的数据,或者是存放binder拉取的数据。
  • Message:一种规范化的数据结构,生产者和消费者基于这个数据结构通过外部消息系统与目标绑定器和其他应用程序通信。

4.核心概念

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5. 常用注解

在这里插入图片描述

基础案例1

1.pom依赖

  • 核心组件
    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-stream-rabbit</artifactId></dependency>
  • 项目依赖
<dependencies><!--stream rabbit --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-stream-rabbit</artifactId></dependency><!--eureka client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--监控--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--热部署--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>

2.yml配置文件

server:port: 8801spring:application:name: cloud-stream-providerrabbitmq:host: 112.124.16.82  # RabbitMQ在本机的用localhost,在服务器的用服务器的ip地址port: 5673username: guestpassword: guestcloud:stream:binders: # 在此处配置要绑定的rabbitmq的服务信息defaultRabbit: # 表示定义的名称,用于binding整合type: rabbit # 消息组件类型bindings: # 服务的整合处理output: # 这个名字是一个通道的名称destination: studyExchange # 表示要使用的Exchange名称content-type: application/json # 设置消息类型,本次为json,本文要设置为“text/plain”binder: defaultRabbit # 设置要绑定的消息服务的具体设置(爆红不影响使用,位置没错)eureka:client:service-url:defaultZone: http://localhost:7001/eurekainstance:lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30S)lease-expiration-duration-in-seconds: 5 # 如果超过5S间隔就注销节点 默认是90sinstance-id: send-8801.com # 在信息列表时显示主机名称prefer-ip-address: true # 访问的路径变为IP地址

3.生产着

  • 新建service.IMessageProvider接口
public interface IMessageProvider {public String send();
}
  • 在service下新建impl.IMessageProviderImpl实现类
package service.impl;import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.MessageChannel;
import service.IMessageProvider;import javax.annotation.Resource;
import java.util.UUID;@EnableBinding(Source.class)    // 定义消息的推送管道(Source是spring的)
public class IMessageProviderImpl implements IMessageProvider {@Resourceprivate MessageChannel output;  // 消息发送管道@Overridepublic String send() {String serial = UUID.randomUUID().toString();// MessageBuilder是spring的integration.support.MessageBuilderoutput.send(MessageBuilder.withPayload(serial).build());    System.out.println("*******serial: " + serial);return null;}
}

消息发送管道 MessageChannel

在这里插入图片描述

MessageBuilder是spring的integration.support.MessageBuilder

在这里插入图片描述

  • 新建controller.SendMessageController
package com.IT.springcloud.controller;import com.IT.springcloud.service.IMessageProvider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController
public class SendMessageController {@Resourceprivate IMessageProvider iMessageProvider;@GetMapping("/sendMessage")public String sendMessage(){return iMessageProvider.send();}}

4.消费者

  • pom文件与8801相同
  • yml文件
server:port: 8802spring:application:name: cloud-stream-consumerrabbitmq:host: 112.124.16.82  # RabbitMQ在本机的用localhost,在服务器的用服务器的ip地址port: 5673username: guestpassword: guestcloud:stream:binders: # 在此处配置要绑定的rabbitmq的服务信息defaultRabbit: # 表示定义的名称,用于binding整合type: rabbit # 消息组件类型bindings: # 服务的整合处理input: # 这个名字是一个通道的名称destination: studyExchange # 表示要使用的Exchange名称content-type: application/json # 设置消息类型,本次为json,本文要设置为“text/plain”binder: defaultRabbit # 设置要绑定的消息服务的具体设置(爆红不影响使用,位置没错)eureka:client:service-url:defaultZone: http://localhost:7001/eurekainstance:lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30S)lease-expiration-duration-in-seconds: 5 # 如果超过5S间隔就注销节点 默认是90sinstance-id: send-8802.com # 在信息列表时显示主机名称prefer-ip-address: true # 访问的路径变为IP地址
  • 新建controller.ReceiveMessageListenerController
@StreamListener注解

@StreamListener注解的作用是将被修饰的方法注册为消息中间件上数据流的事件监听器,注解中的属性值对应了监听的消息通道名。

package com.IT.springcloud.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Controller;@EnableBinding(Sink.class)
@Controller
public class ReceiveMessageListenerController {@Value("${server.port}")private String serverPort;@StreamListener(Sink.INPUT) // 监听public void input(Message<String> message){System.out.println("消费者1号------>收到的消息:" + message.getPayload() + "\t port:" + serverPort);}}

5.测试,启动7001,8801,8802

浏览器地址栏输入:localhost:8801/sendMessage

  • 发送方8801

在这里插入图片描述

  • 接收方8802

在这里插入图片描述

6.分组消费与持久化

  1. 按照8802克隆一个新模块8803

  2. 将8802/8803实现轮询分组,每次只有一个消费者收到消息,也就是说,8801发出一条消息,只能被8802和8803中的其中一个接收到,不能同时被接收,这样就可以避免重复消费,只需要在8802和8803的yml文件中:bindings/input下设置为同一个分组即可

bindings: # 服务的整合处理input: # 这个名字是一个通道的名称destination: studyExchange # 表示要使用的Exchange名称content-type: application/json # 设置消息类型,本次为json,本文要设置为“text/plain”binder: defaultRabbit # 设置要绑定的消息服务的具体设置(爆红不影响使用,位置没错)group: ITA # 设置分组
  1. 测试,现在我们发送两条消息
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

案例2----自定义消息通道

1.生产者

创建 StreamClient 接口,通过 @Input和 @Output注解定义输入通道和输出通道

  • @Input 和 @Output 注解都还有一个 value 属性,该属性可以用来设置消息通道的名称,这里指定的消息通道名称分别是 myInput 和 myOutput。如果直接使用两个注解而没有指定具体的 value 值,则会默认使用方法名作为消息通道的名称。
public interface StreamClient {String INPUT = "myInput";String OUTPUT = "myOutput";@Input(StreamClient.INPUT)SubscribableChannel input();@Output(StreamClient.OUTPUT)MessageChannel output();
}
  • SubscribableChannel
    定义输入通道时,需要返回 SubscribableChannel 接口对象,该接口集成自 MessageChannel 接口,它定义了维护消息通道订阅者的方法。
    在这里插入图片描述

  • MessageChannel
    当定义输出通道的时候,需要返回 MessageChannel 接口对象,该接口定义了向消息通道发送消息的方
    在这里插入图片描述

  • 创建一个接口用于测试发送消息


@RestController
public class IMessageProvider{@Autowiredprivate StreamClient streamClient;@GetMapping("/send")public void send() {streamClient.output().send(MessageBuilder.withPayload("Hello World...").build());}}

2.消费者

在完成了消息通道绑定的定义后,这些用于定义绑定消息通道的接口则可以被 @EnableBinding 注解的 value 参数指定,从而在应用启动的时候实现对定义消息通道的绑定,Spring Cloud Stream 会为其创建具体的实例,而开发者只需要通过注入的方式来获取这些实例并直接使用即可。下面就来创建用于接收来自 RabbitMQ 消息的消费者 StreamReceiver## 3.验证

  • 创建用于接收来自 RabbitMQ 消息的消费者 StreamReceiver 类
@Component
@EnableBinding(value = {StreamClient.class})
public class StreamReceiver {private Logger logger = LoggerFactory.getLogger(StreamReceiver.class);@StreamListener(StreamClient.INPUT)public void receive(String message) {logger.info("StreamReceiver: {}", message);}
}

3.测试

启动 StreamApplication,访问 http://localhost:9898/send 接口发送消息,通过控制台,可以看到,消息已成功被接收
在这里插入图片描述

案例3----自定义消息通道

1.生产着

import  org.springframework.cloud.stream.annotation.Input;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.SubscribableChannel;/*** 事件主题流引擎处理**/
public interface EventTopicStreams {/*** 事件合并监听方法** @return 监听通道*/@Input(TopicConst.EVENT_TOPIC_INPUT)SubscribableChannel eventInput();/*** 事件合并发送方法** @return 发送渠道*/@Output(TopicConst.EVENT_TOPIC_OUTPUT)MessageChannel eventOutput();}
@Component
@Slf4j
@EnableBinding(EventTopicStreams.class)
public class EventTopicProducer {private final EventTopicStreams eventTopicStreams;public EventTopicProducer(EventTopicStreams eventTopicStreams) {this.eventTopicStreams = eventTopicStreams;}/*** 发送事件合并消息** @param audienceMergeReqDTO 源档案audid和目标档案audid*/public void sendEventMergeMsg(AudienceMergeReqDTO audienceMergeReqDTO) {eventTopicStreams.eventOutput().send(MessageBuilder.withPayload(audienceMergeReqDTO).setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON).build());}}

2.消费者

@Component
@Slf4j
@EnableBinding(EventTopicStreams.class)
public class EventTopicListener {private final EventEsService eventEsService;public EventTopicListener(EventEsService eventEsService) {this.eventEsService = eventEsService;}@StreamListener(TopicConst.EVENT_TOPIC_INPUT)public void receive(@Payload String payload) {eventEsService.disposeEventMergeMqMsg(payload);}}

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

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

相关文章

2024网络安全-自学笔记

前言 一、什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防…

新火种AI|国产手机抢滩“AI+折叠屏”赛道,行业洗牌大战就此开启?

作者&#xff1a;小岩 编辑&#xff1a;彩云 从2023年到2024年&#xff0c;随着新一波人工智能浪潮的加速&#xff0c;消费电子产品也迎来了全新的话题——AI。更重要的是&#xff0c;这场战争看似没有硝烟&#xff0c;但各大厂商都已经暗自角力了许久&#xff0c;特别是手机…

Windows 11 鼠标右键可选择 cmd 命令行选项

** Windows 11 鼠标右键可选择 cmd 命令行选项 ** 在文件夹内打开命令行&#xff0c;只能使用 Windows 自带的 PowerShell &#xff0c; 作为一个 cmd 重度使用用户来说很是折磨&#xff0c;需要打开 cmd 然后切换盘符再 cd 。。。 现在咱们自己创建一个可以打开 cmd 的方法…

Qt调用内置图标

int IconIndex0; QIcon icon QApplication::style()->standardIcon((QStyle::StandardPixmap)IconIndex);按以上代码可以调用Qt内置的71个图标&#xff0c;只要变换IconIndex就可以了&#xff0c;IconIndex为[0,70]。显示如下&#xff1a;图标index名称。

图论中的最小生成树:Kruskal与Prim算法深入解析

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;アンビバレント—Uru 0:24━━━━━━️&#x1f49f;──────── 4:02 &#x1f504; ◀️ ⏸ ▶️ ☰ …

西井科技与安通控股签署战略合作协议 共创大物流全新生态

2024年3月21日&#xff0c;西井科技与安通控股在“上海硅巷”新象限空间正式签署战略合作框架协议。双方基于此前在集装箱物流的成功实践与资源优势&#xff0c;积极拓展在AI数字化产品、新能源自动驾驶解决方案和多场景应用&#xff0c;以及绿色物流链等领域的深度探索、强强联…

视频号下载助手失效了?如何解决下载视频问题!

在刷短视频的时候难免会遇到部分的视频号视频下载不下来&#xff0c;那我们该如何解决视频号下载问题呢&#xff1f; 视频号下载助手解决方案 视频号下载助手失效分为两种情况! 1、可以解析&#xff0c;但不能下载 根据使用视频号下载助手常见的问题&#xff0c;我们发现会有…

Linux本地部署TeslaMate结合内网穿透实现公网访问内网车辆信息

文章目录 1. Docker部署TeslaMate2. 本地访问TeslaMate3. Linux安装Cpolar4. 配置TeslaMate公网地址5. 远程访问TeslaMate6. 固定TeslaMate公网地址7. 固定地址访问TeslaMate TeslaMate是一个开源软件&#xff0c;可以通过连接特斯拉账号&#xff0c;记录行驶历史&#xff0c;统…

YOLOv3学习

YOLOv3仅使用卷积层&#xff0c;使其成为一个全卷积网络&#xff08;FCN&#xff09;。文章中&#xff0c;作者提出一个新的特征提取网络&#xff0c;Darknet-53。正如其名&#xff0c;它包含53个卷积层&#xff0c;每个后面跟随着batch normalization层和leaky ReLU层。没有池…

【网络原理】HTTP 请求 (Request)详解

文章目录 &#x1f38d;请求格式&#x1f384;认识URL&#x1f338;query string&#x1f338;关于 URL encode &#x1f340;认识 “方法” (method)&#x1f338;GET方法&#x1f338;POST 方法&#x1f338;GET 和 POST 的区别 &#x1f332;认识请求 “报头” (header)&…

权限管理系统-0.5.0

六、审批管理模块 审批管理模块包括审批类型和审批模板&#xff0c;审批类型如&#xff1a;出勤、人事、财务等&#xff0c;审批模板如&#xff1a;加班、请假等具体业务。 6.1 引入依赖 在项目中引入activiti7的相关依赖&#xff1a; <!--引入activiti的springboot启动器…

Git进阶命令-reset

一、reset命令使用场景 有时候我们提交了一些错误的或者不完善的代码&#xff0c;需要回退到之前的某个稳定的版本,面对这种情况有两种解决方法: 解决方法1&#xff1a;修改错误内容&#xff0c;再次commit一次 解决方法2&#xff1a;使用git reset 命令撤销这一次错误的com…

汽车KL15、KL30、ACC的区别

文章目录 前言一、KL30是什么&#xff1f;二、KL15是什么&#xff1f;KL15信号的演变 三、为啥用KL15、KL30呢&#xff1f; 前言 相信刚接触汽车电子的伙伴都会有一个疑惑&#xff0c;什么是KL15?什么是KL30? 内心一脸懵逼…… KL是德语Klemme的缩写&#xff0c;指的是ECU的…

RCE漏洞

RCE漏洞概述 远程命令执行/代码注入漏洞&#xff0c;英文全称为Reote Code/CommandExecute&#xff0c;简称RCE漏洞。PHPJava等Web开发语言包含命令执行和代码执行函数,攻击者可以直接向后台服务器远程执行操作系统命今或者运行注入代码&#xff0c;进而获取系统信息、控制后台…

2023年五级区划省市县乡镇行政村社区边界数据

行政区划数据是重要的基础地理信息数据&#xff0c;根据国家统计局公布的数据&#xff0c;行政区划共分为五级&#xff0c;分别为省级、地级、县级、乡镇/街道级、村/社区级。 该套数据以2020-2023年国家基础地理信息数据中的县区划数据作为矢量基础&#xff0c;辅以高德行政区…

Spring Security源码

WebSecurityConfigurerAdapter已废弃&#xff0c;官方推荐使用HttpSecurity 或WebSecurity。 都继承了SecurityBuilder public interface SecurityBuilder<O> {O build() throws Exception;}亮点&#xff1a;通过这种方式很容易知道知道自己构建的Object HttpSecurit…

Shell脚本学习-if循环

最小化的if语句 无实际用途 if [ ] ;then echo fi 脚本解释 if 判断 [ ] 里面的条件是否成立 后面跟then&#xff0c;代表条件成立 如果在一行则使用分号隔离&#xff08;;&#xff09; 如果不在一行使用则直接在下一行驶入then即可。 如果条件成立则输出echo 后面…

IT管理备考TOGAF10证书有哪些好处?

现今&#xff0c;随着信息技术的快速发展&#xff0c;企业对于高效的IT管理需求日益增长。而TOGAF10证书作为全球公认的企业架构管理标准&#xff0c;成为了IT管理者的必备工具。本文将为您详细介绍TOGAF10证书的好处&#xff0c;以助您更好地了解和利用这一强大的工具。 首先&…

大模型主流微调训练方法总结 LoRA、Adapter、Prefix-tuning、P-tuning、Prompt-tuning 并训练自己的数据集

大模型主流微调训练方法总结 LoRA、Adapter、Prefix-tuning、P-tuning、Prompt-tuning 概述 大模型微调(finetuning)以适应特定任务是一个复杂且计算密集型的过程。本文训练测试主要是基于主流的的微调方法:LoRA、Adapter、Prefix-tuning、P-tuning和Prompt-tuning,并对…

金蝶云星空——单据附件上传

文章目录 概要技术要点代码实现小结 概要 单据附件上传 技术要点 单据附件上传金蝶是有提供标准的上传接口&#xff1a; http://[IP]/K3Cloud/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.AttachmentUpLoad.common.kdsvc 参数说明 参数类型必填说明FileName字符是…