RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ

一、RabbitMQ概述

RabbitMQ

RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布式系统和微服务架构中

异步消息处理:RabbitMQ 允许系统组件通过消息传递异步交互,提高性能和响应速度。

消息持久化:支持将消息保存到磁盘,确保消息不会因服务器故障而丢失。

灵活的路由:通过交换器(Exchanges)和队列(Queues)的组合,可以灵活地路由和分发消息。

高可用性:支持镜像队列和集群,确保消息系统的高可用性。

多种协议支持:支持 AMQP 0-9-1、STOMP、MQTT 等多种消息协议。

管理界面:提供易于使用的管理界面,方便监控和管理消息队列。

基本特点:

支持多语言客户端:RabbitMQ几乎支持所有常用的语言,比如java、Ruby、.NET等。

提供跟踪机制:RabbitMQ提供消息跟踪机制,如果消息异常,使用者可以查出发生了什么情况。

提供插件机制:RabbitMQ提供了许多插件,从多方面进行扩展,也可以编写自己的插件

Broker:就是 RabbitMQ 服务,用于接收和分发消息,接受客户端的连接,实现 AMQP 实体服务。

Virtual host:出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚拟的分组中,类似于网络中的 namespace 概念。当多个不同的用户使用同一个 RabbitMQ server 提供的服务时,可以划分出多个 vhost,每个用户在自己的 vhost 创建 exchange 或 queue 等。

Connection:连接,生产者/消费者与 Broker 之间的 TCP 网络连接。

Channel:网络信道,如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候建立连接的开销将是巨大的,效率也较低。Channel 是在 connection 内部建立的逻辑连接,如果应用程序支持多线程,通常每个 thread 创建单独的 channel 进行通讯,AMQP method 包含了 channel id 帮助客户端和 message broker 识别 channel,所以 channel 之间是完全隔离的。Channel 作为轻量级的Connection 极大减少了操作系统建立 TCP connection 的开销。

Message:消息,服务与应用程序之间传送的数据,由Properties和body组成,Properties可是对消息进行修饰,比如消息的优先级,延迟等高级特性,Body则就是消息体的内容。

Virtual Host:虚拟节点,用于进行逻辑隔离,最上层的消息路由,一个虚拟主机理由可以有若干个Exhange和Queue,同一个虚拟主机里面不能有相同名字的Exchange

Exchange:交换机,是 message 到达 broker 的第一站,用于根据分发规则、匹配查询表中的 routing key,分发消息到 queue 中去,不具备消息存储的功能。常用的类型有:direct、topic、fanout。

Bindings:exchange 和 queue 之间的虚拟连接,binding 中可以包含 routing key,Binding 信息被保存到 exchange 中的查询表中,用于 message 的分发依据。

Routing key:是一个路由规则,虚拟机可以用它来确定如何路由一个特定消息

Queue:消息队列,保存消息并将它们转发给消费者进行消费。

消息路由

直连交换机

扇形交换机

主题交换机

头交换机

二、RabbitMQ的工作模式

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.1. 简单模式

在这里插入图片描述

  • 描述:在这种模式下,生产者(P)将消息发送到一个队列中,消费者(C)从该队列中接收消息。
  • 特点:只有一个队列,一个生产者和一个消费者。消息直接从生产者传递给消费者。
2.2. 工作模式

在这里插入图片描述

  • 描述:生产者(P)将消息发送到一个队列中,多个消费者(C1, C2)可以订阅这个队列。
  • 特点:多个消费者可以共享同一个队列,消息会被轮流分配给不同的消费者,实现负载均衡。
2.3. 发布订阅模式

在这里插入图片描述

  • 描述:生产者(P)将消息发送到一个交换机(X),交换机根据路由键将消息分发到多个队列中,每个队列由一个或多个消费者(C1, C2)订阅。
  • 特点:一个消息可以被多个消费者接收,适用于广播场景。
2.4. 路由模式

在这里插入图片描述

  • 描述:生产者(P)将消息发送到一个交换机(X),交换机根据路由键将消息分发到特定的队列中,每个队列由一个或多个消费者(C1, C2)订阅。
  • 特点:通过路由键来决定消息应该发送到哪个队列,支持更灵活的消息路由。
2.5. 主题模式

在这里插入图片描述

  • 描述:生产者(P)将消息发送到一个交换机(X),交换机根据主题(通常是通配符匹配)将消息分发到多个队列中,每个队列由一个或多个消费者(C1, C2, C3)订阅。
  • 特点:使用通配符(如*#)进行灵活的主题匹配,支持更复杂的路由规则。
2.6. RPC模式

在这里插入图片描述

  • 描述:客户端(Client)发送一个请求到服务器(Server),服务器处理请求后返回响应。客户端通过一个临时队列(rpc_queue)接收响应。
  • 特点:模拟远程过程调用(RPC),客户端等待服务器的响应,适用于需要同步处理的场景。

三、RabbitMQ工作原理

连接与信道建立:

生产者和消费者分别与RabbitMQ服务器建立连接,并创建通信信道。

队列声明:

生产者声明一个或多个队列,用于存储消息。

消息发送:

生产者通过信道将消息发送到交换机。

交换机根据预定义的路由规则和绑定,将消息路由到一个或多个队列中。

消息接收与处理:

消费者订阅一个或多个队列,并从这些队列中接收消息进行处理。

消费者处理完消息后,向RabbitMQ服务器发送确认消息(ACK)。

消息删除:

RabbitMQ服务器在接收到消费者的确认消息后,从队列中删除该消息。

四、RabbitMQ应用

4.1 RabbitMQ安装和配置

官网地址https://www.rabbitmq.com/,选择版本4.1.0

在这里插入图片描述

下载Erlang

地址https://www.erlang.org/downloads

在这里插入图片描述

RabbitMQ4.1.0与Erlang的版本兼容

在这里插入图片描述

4.2 安装Erlang

在这里插入图片描述

双击点开,接着选取要安装的路径,然后一路傻瓜式安装 next 下一步,安装即可。

**【注意】**不要安装在中文或带空格的文件路径下

4.3 安装RabbitMQ

在这里插入图片描述

右键管理员运行,然后选择安装路径,接着一路 next 下一步,遇到弹窗点允许,没有弹窗则无视。

**【注意】**不要安装在中文或带空格的文件路径下

打开cmd,命令移动到sbin目录下

执行命令

rabbitmq-plugins enable rabbitmq_management

在这里插入图片描述

启动rabbitmq

使用管理员打开cmd

net start RabbitMQ

访问RabbitMQ

地址:http://127.0.0.1:15672

输入用户名guest和密码guest,进去之后如图:

在这里插入图片描述

4.3 Java访问RabbitMq工程

第一步,引入依赖

 <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.20.0</version>
</dependency>
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>2.24.3</version>
</dependency>

第二步,编写生产者

public class Producer {public static void main(String[] args) throws IOException, TimeoutException {// 创建连接工厂ConnectionFactory factory = new ConnectionFactory();factory.setUsername("guest");factory.setPassword("guest");// 设置 RabbitMQ 地址factory.setHost("localhost");factory.setVirtualHost("/");// 建立到代理服务器的连接Connection conn = factory.newConnection();// 创建信道Channel channel = conn.createChannel();// 声明交换器String exchangeName = "hello-exchange";channel.exchangeDeclare(exchangeName, "direct", true);String routingKey = "testRoutingKey";// 发布消息byte[] messageBodyBytes = "jx".getBytes();channel.basicPublish(exchangeName, routingKey, null, messageBodyBytes);channel.close();conn.close();}
}

第三步,编写消费者

public class Consumer {public static void main(String[] args) throws IOException, TimeoutException{// 创建连接工厂ConnectionFactory factory = new ConnectionFactory();factory.setUsername("guest");factory.setPassword("guest");// 设置 RabbitMQ 地址factory.setHost("localhost");factory.setVirtualHost("/");// 建立到代理服务器的连接Connection conn = factory.newConnection();// 创建信道final Channel channel = conn.createChannel();// 声明交换器String exchangeName = "hello-exchange";channel.exchangeDeclare(exchangeName, "direct", true);// 声明队列String queueName = channel.queueDeclare().getQueue();String routingKey = "testRoutingKey";// 绑定队列,通过键 testRoutingKey 将队列和交换器绑定起来channel.queueBind(queueName, exchangeName, routingKey);while (true) {// 消费消息boolean autoAck = false;String consumerTag = "";channel.basicConsume(queueName, autoAck, consumerTag, new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag,Envelope envelope,AMQP.BasicProperties properties,byte[] body) throws IOException {String routingKey = envelope.getRoutingKey();String contentType = properties.getContentType();System.out.println("消费的路由键: " + routingKey);System.out.println("消费的内容类型: " + contentType);long deliveryTag = envelope.getDeliveryTag();// 确认消息channel.basicAck(deliveryTag, false);System.out.println("消费的消息内容: ");String bodyStr = new String(body, "UTF-8");System.out.println(bodyStr);}});}}
}
4.4 Spring Boot 整合RabbitMQ工程

第一步,引入依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.1</version><relativePath/> <!-- lookup parent in repository --></parent><artifactId>spring_boot_rabbitmq_demo</artifactId><packaging>jar</packaging><name>spring_boot_rabbitmq_demo Maven Webapp</name><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

第二步,编写配置

在resources下编写application.yml

spring:rabbitmq:host: localhostport: 5672username: guestpassword: guestvirtual-host: /publisher-confirm-type: correlated # 启用发布确认publisher-return: true # 启用发布返回listener:simple:acknowledge-mode: manual # 手动确认消息prefetch: 1 # 每次只处理一个消息

第三步 编写配置类

@Configuration
public class RabbitMQConfig {// 定义交换器名称public static final String EXCHANGE_NAME = "hello-exchange";// 定义队列名称public static final String QUEUE_NAME = "hello-queue";// 定义路由键public static final String ROUTING_KEY = "testRoutingKey";@Beanpublic DirectExchange directExchange() {return new DirectExchange(EXCHANGE_NAME, true, false);}@Beanpublic Queue queue() {return new Queue(QUEUE_NAME, true);}@Beanpublic Binding binding(DirectExchange directExchange, Queue queue) {return BindingBuilder.bind(queue).to(directExchange).with(ROUTING_KEY);}
}

第四步,编写生产者

@Service
public class RabbitMQProducer {@Autowiredprivate RabbitTemplate rabbitTemplate;public void sendMessage(String message) {// 构建消息内容Message msg = new Message(message.getBytes(), new MessageProperties());// 发送消息到指定的交换器和路由键rabbitTemplate.send(RabbitMQConfig.EXCHANGE_NAME, RabbitMQConfig.ROUTING_KEY, msg);System.out.println("已发送消息: " + message);}@PostConstructpublic void init() {// 测试发送消息sendMessage("Hello, RabbitMQ!");}
}

第五步,编写消费者

@Component
public class RabbitMQConsumer {@RabbitListener(queues = RabbitMQConfig.QUEUE_NAME)public void processMessage(byte[] message,@Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag,@Header("amqp_consumerTag") String consumerTag,Channel channel) throws IOException {try {// 处理消息String messageStr = new String(message);System.out.println("接收到的消息: " + messageStr);// 手动确认消息channel.basicAck(deliveryTag, false); //是否批量确认} catch (Exception e) {e.printStackTrace();// 如果处理失败,可以选择拒绝消息或者重新入队channel.basicNack(deliveryTag, false, true);//第二是否批量 第三个是是否重新入队}}
}

第六步, 编写启动类

@SpringBootApplication
public class RabbitMQApplication{@Autowiredprivate RabbitMQProducer producer;public static void main(String[] args) {SpringApplication.run(RabbitMQApplication.class, args);}
}
4.5 实现消息向页面推送(基于4.4内容)

第一步,引入依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.1</version><relativePath/> <!-- lookup parent in repository --></parent><artifactId>spring_boot_rabbitmq_demo</artifactId><packaging>jar</packaging><name>spring_boot_rabbitmq_demo Maven Webapp</name><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

第二步,修改配置文件application.yml 添加server配置

server:port: 8080context-path: /spring:rabbitmq:host: localhostport: 5672username: guestpassword: guestvirtual-host: /publisher-confirm-type: correlated # 启用发布确认publisher-return: true # 启用发布返回listener:simple:acknowledge-mode: manual # 手动确认消息prefetch: 1 # 每次只处理一个消息

第三步,增加stomp配置类

@Configuration
@EnableWebSocketMessageBroker
public class StompConfig implements WebSocketMessageBrokerConfigurer {@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {registry.addEndpoint("/ws").setAllowedOriginPatterns("*").withSockJS();}@Overridepublic void configureMessageBroker(MessageBrokerRegistry registry) {registry.setApplicationDestinationPrefixes("/app");registry.enableSimpleBroker("/topic"); // 启用简单消息代理,订阅路径为/topic}
}

第四步,编写测试controller

@Controller
@RequestMapping("test")
public class StompController {@Autowiredprivate SimpMessagingTemplate messagingTemplate;@RequestMapping("/send")@ResponseBodypublic void send() {messagingTemplate.convertAndSend("/topic/greetings", "Hello World!");}
}

第五步,提供前端html页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>STOMP Example</title><script src="https://cdn.bootcdn.net/ajax/libs/sockjs-client/1.6.1/sockjs.min.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
</head>
<body>
<h1>STOMP Web Message Push</h1>
<button onclick="connect()">Connect</button>
<button onclick="disconnect()">Disconnect</button><script type="text/javascript">var stompClient = null;function connect() {var socket = new SockJS('http://localhost:8080/ws');// 连接到注册的STOMP端点stompClient = Stomp.over(socket);stompClient.connect({}, function (frame) {console.log('Connected: ' + frame);stompClient.subscribe('/topic/greetings', function (greeting) {alert(greeting);});});}function disconnect() {if (stompClient !== null) {stompClient.disconnect();}console.log("Disconnected");}</script>
</body>
</html>

运行效果

在这里插入图片描述

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

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

相关文章

Python Copilot【代码辅助工具】 简介

粉丝爱买鳕鱼肠深海鳕鱼肉鱼肉香肠盼盼麦香鸡味块卡乐比&#xff08;Calbee&#xff09;薯条三兄弟 独立小包美丽雅 奶茶杯一次性饮料杯好时kisses多口味巧克力糖老金磨方【黑金系列】黑芝麻丸郑新初网红郑新初烤鲜牛肉干超人毛球修剪器去球器剃毛器衣服去毛器优惠券宁之春 红黑…

VBA进度条ProgressForm1

上一章《VBA如何使用ProgressBar进度条控件》介绍了ProgressBar控件的使用方法&#xff0c;今天我给大家介绍ProgressForm1进度条的使用方法&#xff0c;ProgressForm1是集成ProgressBar控件和Label控件的窗体&#xff0c;可以同时显示进度条和百分比&#xff0c;如下图&#x…

快速部署和启动Vue3项目

快速入门Vue3 一、安装 Node.js 和 npm Vue 3 是基于 JavaScript 的框架&#xff0c;Node.js 提供了 JavaScript 运行环境&#xff0c;npm 是 Node.js 的包管理工具&#xff0c;用于安装和管理 Vue 3 及相关依赖。访问 Node.js 官方网站&#xff08;https://nodejs.org/&…

[TIP] Ubuntu 22.04 配置多个版本的 GCC 环境

问题背景 在 Ubuntu 22.04 中安装 VMware 虚拟机时&#xff0c;提示缺少 VMMON 和 VMNET 模块 编译这两个模块需要 GCC 的版本大于 12.3.0&#xff0c;而 Ubuntu 22.04 自带的 GCC 版本为 11.4.0 因此需要安装对应的 GCC 版本&#xff0c;但为了不影响其他程序&#xff0c;需…

【西门子杯工业嵌入式-4-什么是外部中断】

西门子杯工业嵌入式-4-什么是外部中断 一、中断的基本概念1. 什么是中断2. 生活中的中断示例3. MCU 中的中断机制 二、NVIC 嵌套向量中断控制器1. NVIC 简介2. NVIC 的作用3. 中断向量表 三、中断优先级机制1. 中断优先级的含义2. 抢占与响应优先级3. 优先级分组配置 四、外部中…

Blocked aria-hidden on an element because its descendant retained focus.

问题出在 Element UI 的 el-table 组件 全选功能上&#xff0c;这是一个常见的无障碍&#xff08;a11y&#xff09;问题。这个错误提示与网页 accessibility&#xff08;无障碍访问&#xff09;相关&#xff0c;涉及 aria-hidden 属性的不当使用。 问题原因分析 1. Element U…

App/uni-app 离线本地存储方案有哪些?最推荐的是哪种方案?

以下是 UniApp 离线本地存储方案的详细介绍及推荐方案分析&#xff1a; 一、UniApp 离线本地存储方案分类 1. 基于 uni.storage 系列 API&#xff08;跨端基础方案&#xff09; API 及特点&#xff1a; 提供 uni.setStorage&#xff08;异步存储&#xff09;、uni.getStorag…

数据库系统概论(十七)超详细讲解数据库规范化与五大范式(从函数依赖到多值依赖,再到五大范式,附带例题,表格,知识图谱对比带你一步步掌握)

数据库系统概论&#xff08;十七&#xff09;超详细讲解数据库规范化与五大范式&#xff08;从函数依赖到多值依赖&#xff0c;再到五大范式&#xff0c;附带例题&#xff0c;表格&#xff0c;知识图谱对比带你一步步掌握&#xff09; 前言一、为什么需要规范化1. 我们先想一个…

交互标牌——视觉货币(数字)转换器项目及源码

一、作品简介 视觉货币&#xff08;数字&#xff09;转换器是我为交互标牌创客争霸赛设计的项目&#xff0c;项目的主要功能是能将所见的数字按照设定的公式转换成新的单位量&#xff0c;这里我主要演示的是货币转换&#xff0c;直接将摄像头对准价签&#xff0c;即可显示出转换…

React 第五十四节 Router中useRevalidator的使用详解及案例分析

前言 useRevalidator 是 React Router v6.4 引入的一个强大钩子&#xff0c;用于在数据路由&#xff08;Data Router&#xff09;中手动触发路由数据的重新验证&#xff08;revalidation&#xff09;。 它在需要主动刷新数据而不改变路由位置的场景中非常有用。 一、useReval…

“一代更比一代强”:现代 RAG 架构的演进之路

编者按&#xff1a; 我们今天为大家带来的文章&#xff0c;作者的观点是&#xff1a;RAG 技术的演进是一个从简单到复杂、从 Naive 到 Agentic 的系统性优化过程&#xff0c;每一次优化都是在试图解决无数企业落地大语言模型应用时出现的痛点问题。 文章首先剖析 Naive RAG 的基…

Flask-SQLAlchemy使用小结

链表查询 join方法允许你指定两个或多个表之间的连接条件&#xff0c;并返回一个新的查询对象&#xff0c;该对象包含了连接后的结果。 内连接 from sqlalchemy import join # 使用join函数 query db.session.query(User, Order).join(Order, User.id Order.user_id) res…

【python与生活】如何构建一个解读IPO招股书的算法?

构建一个基于Python的IPO招股书解读算法需要结合自然语言处理&#xff08;NLP&#xff09;技术和大型语言模型&#xff08;LLM&#xff09;。以下是一个完整的解决方案&#xff0c;使用LangChain框架和OpenAI的GPT模型&#xff1a; import os import re import pandas as pd f…

LangChain面试内容整理-知识点1:LangChain架构与核心理念

LangChain 是一个用于构建基于大型语言模型(LLM)的应用的框架,其架构采用模块化设计,核心理念是将语言模型与外部工具、数据源相结合,以实现复杂任务的分解与执行medium.com。整个框架可以理解为一系列可组合的组件,包括链(Chain)、智能体(Agent)、工具(Tool)和LLM…

13.MySQL用户管理

13.MySQL用户管理 目录 MySQL用户管理 用户 用户信息创建用户修改用户密码删除用户 数据库的权限 MySQL中的权限给用户授权回收权限 用户 用户信息 MySQL中的用户信息存储在默认数据库mysql的user表中。这个表记录了所有用户的详细信息&#xff0c;包括用户名、登录权限…

分布式Session处理的五大主流方案解析

在分布式环境下&#xff0c;Session 处理的核心挑战是确保用户请求在不同服务器间流转时能保持会话状态一致。以下是主流解决方案及优缺点分析&#xff1a; &#x1f510; 一、集中存储方案&#xff08;主流推荐&#xff09; Redis/Memcached 存储 原理&#xff1a;将 Session…

【数据分析】什么是鲁棒性?

引言 —— 为什么我们需要“抗折腾”的系统&#xff1f; 当你乘坐的飞机穿越雷暴区时机体剧烈颠簸&#xff0c;自动驾驶汽车在暴雨中稳稳避开障碍物&#xff0c;或是手机从口袋摔落后依然流畅运行——这些场景背后&#xff0c;都藏着一个工程领域的“隐形守护者”&#xff1a;…

altium designer2024绘制stm32过程笔记x`

学习视频&#xff1a;【Altium Designer 1小时&#xff08;貌似不够&#xff09;速成&#xff08;可能不止一小时*~* 但我觉得仨小时肯定够了---来自up猪的自信!!&#xff09;】https://www.bilibili.com/video/BV17E411x7dR?p2&vd_sourcea756421e0aaa64b2bba352eabfa26ed…

Java 类型参数 T、R 、 O 、K、V 、E 、? 区别

在 Java 泛型和函数式编程中&#xff0c;T、R 和 O 都是类型参数&#xff08;Type Parameters&#xff09;&#xff0c;它们的主要区别在于命名约定和上下文含义&#xff0c;而不是语言层面的区别。它们可以互换使用&#xff0c;但通常遵循一定的命名习惯以提高代码可读性。 1.…

Komiko 视频到视频功能炸裂上线!

Komiko 平台作为行业的创新先锋&#xff0c;近日宣布推出全新的视频到视频&#xff08;Video-to-Video&#xff09;功能&#xff0c;这一举措犹如一颗重磅炸弹&#xff0c;瞬间在漫画、动画和插画创作的世界里掀起了惊涛骇浪&#xff0c;进一步巩固了其作为 AI 驱动的一体化创作…