10.RabbitMQ集群

十、集群与高可用

RabbitMQ 的集群分两种模式,一种是默认集群模式,一种是镜像集群模式;

在RabbitMQ集群中所有的节点(一个节点就是一个RabbitMQ的broker服务器) 被归为两类:一类是磁盘节点,一类是内存节点;

磁盘节点会把集群的所有信息(比如交换机、绑定、队列等信息)持久化到磁盘中,而内存节点只会将这些信息保存到内存中,如果该节点宕机或重启,内存节点的数据会全部丢失,而磁盘节点的数据不会丢失;

1、默认集群模式

默认集群模式也叫 普通集群模式、或者 内置集群模式;

10.1.1、默认集群简介

(1)、元数据

队列元数据:队列名称和属性(是否可持久化,是否自动删除)

交换器元数据:交换器名称、类型和属性

绑定元数据:交换器和队列的绑定列表

vhost元数据:vhost内的相关属性,如安全属性等;

当用户访问其中任何一个RabbitMQ节点时,查询到的queue/user/exchange/vhost等信息都是相同的;

(2)、数据同步特点

RabbitMQ默认集群模式只会把交换机、队列、虚拟主机等元数据信息在各个节点同步,而具体队列中的消息内容不会在各个节点中同步,队列的具体信息数据只在队列的拥有者节点保存,其他节点只知道队列的元数据和指向该节点的指针,所以其他节点接收到不属于该节点队列的消息时会将该消息传递给该队列的拥有者节点上;

集群不复制队列内容和状态到所有节点原因

1)节省存储空间;

2)提升性能;

如果消息需要复制到集群中每个节点,网络开销不可避免,持久化消息还需要写磁盘,占用磁盘空间。

在这里插入图片描述

(3)、数据访问过程

如果有一个消息生产者或者消息消费者通过amqp-client的客户端连接到节点1进行消息的发送或接收,那么此时集群中的消息收发只与节点1相关,这个没有任何问题;

如果消息生产者所连接的是节点2或者节点3,此时队列1的完整数据不在该两个节点上,那么在发送消息过程中这两个节点主要起了一个路由转发作用,根据这两个节点上的元数据(也就是指向queue的owner node的指针)转发至节点1上,最终发送的消息还是会存储至节点1的队列1上;

同样,如果消息消费者所连接的节点2或者节点3,那这两个节点也会作为路由节点起到转发作用,将会从节点1的队列1中获取消息进行消费;

10.1.2、安装

1、安装三台RabbitMQ机器

安装过程参考前面

注意:这里先安装一台MQ,然后克隆两台就可以了

2、设置IP地址

启动并设置三台机器的IP

修改配置文件方式

图形界面方式

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3、修改主机名
sudo hostnamectl set-hostname rabbit11
4、修改/etc/hosts 文件

首先需要配置一下hosts文件,因为RabbitMQ集群节点名称是读取hosts文件得到的;

注意三台机机器都需要配置

vim /etc/hosts
192.168.1.11 rabbit11
192.168.1.12 rabbit12
192.168.1.13 rabbit13

在这里插入图片描述

5、重启网络

三台机器均重启网络,使节点名生效

sudo systemctl restart NetworkManager

低版本CentOS使用如下命令

systemctl restart network
6、重新连接xshell

重启后三台机器的xshell均退出,然后再重新连接,这样才能刷新主机的名字

7、关闭防火墙

三台机器均需关闭

systemctl stop firewalld  ##关闭防火墙
systemctl disable firewalld  ##开机不启动防火墙
systemctl status firewalld	##查看防火墙状态

在这里插入图片描述

8、修改.erlang.cookie文件

三台机器 .erlang.cookie文件保持一致

由于是clone出的三台机器,所以肯定是一样的

  • 如果使用解压缩方式安装的RabbitMQ,那么该文件会在 用户名目录下 , 也就是 {用户名}目录下,也就是 用户名目录下,也就是{用户名}/.erlang.cookie;

    在这里插入图片描述

  • 如果使用rpm安装包方式进行安装,那么这个文件会在/var/lib/rabbitmq目录下;

注意 .erlang.cookie的权限为400,目前已经是400

9、启动MQ

分别启动三台机器上的rabbitmq

rabbitmq-server -detached
10、查看集群状态
  • 查看rabbitmq状态

    rabbitmqctl status
    

    在这里插入图片描述

  • 查看集群状态

    rabbitmqctl cluster_status
    

    在这里插入图片描述

11、构建集群
  • 加入节点1

    在rabbitmq12机器上执行命令,让12的rabbitmq加入集群

    注意:一定要先停止节点,将节点重置之后才能加入集群,否则数据同步会出现混乱

    ## 先停止rabbitmq
    rabbitmqctl stop_app
    ## 重置rabbitmq
    rabbitmqctl reset
    ## 节点加入集群:rabbit@rabbit11是主节点的节点名,在集群状态中可以查看到节点名称
    rabbitmqctl join_cluster rabbit@rabbit11 --ram
    ## 启动节点
    rabbitmqctl start_app
    

    –ram 参数表示让rabbitmq12成为一个内存节点,如果不带参数默认为disk磁盘节点;

    在这里插入图片描述

  • 添加节点2

    在rabbit13节点上也执行同样的命令,使rabbit13节点也加入到集群中

    ## 先停止rabbitmq
    rabbitmqctl stop_app
    ## 重置rabbitmq
    rabbitmqctl reset
    ## 节点加入集群:rabbit@rabbit11是主节点的节点名,在集群状态中可以查看到节点名称
    rabbitmqctl join_cluster rabbit@rabbit11 --ram
    ## 启动节点
    rabbitmqctl start_app
    

    当然也可以让rabbit13作为一个磁盘节点

12、添加用户和权限

操作一个节点,添加用户和权限等

#列出用户
rabbitmqctl list_users
# 添加用户
rabbitmqctl add_user admin 123456
#查看权限
rabbitmqctl list_permissions
#设置权限
rabbitmqctl set_permissions admin ".*" ".*" ".*"
#设置角色
rabbitmqctl set_user_tags admin administrator

在这里插入图片描述

13、启动web控制台

启动web控制台插件

注意:三台机器都要启动,因为插件不属于元数据,因此需要分别启动

#进入插件目录
cd /usr/local/rabbitmq_server-4.0.7/plugins/
#启动web端插件
rabbitmq-plugins enable rabbitmq_management 

在这里插入图片描述

14、创建虚拟主机

使用web浏览器添加一个虚拟主机:longdidi

在这里插入图片描述

15、再次查看集群状态

当执行完操作以后在浏览器访问web管控台来看看效果;

随便在哪个节点打开web管控台都能看到集群环境各节点的信息;

也可以使用"rabbitmqctl cluster_status"查看集群状态;

在这里插入图片描述

以上就是RabbitMQ默认集群模式(普通集群模式)的搭建;

16、验证集群
  1. 创建队列

在这里插入图片描述

  1. 创建交换机

    在这里插入图片描述

  2. 绑定交换机与队列

    • 进入交换机

      在这里插入图片描述

    • 绑定交换机与队列

      在这里插入图片描述

  3. 发布消息

    在这里插入图片描述

  4. 查看消息

    在任意节点查看消息

    在这里插入图片描述

  5. 停止主节点rabbit@rabbit11节点

    在这里插入图片描述

  6. 再在其它节点查看消息

    在这里插入图片描述

17、删除节点

在这里插入图片描述

10.1.3、节点原理

RabbitMQ底层是通过Erlang架构来实现的,所以rabbitmqctl会启动Erlang节点,并基于Erlang节点来使用Erlang系统连接RabbitMQ节点,在连接过程中需要正确的Erlang Cookie和节点名称,Erlang节点通过交换Erlang Cookie以获得认证;

2、镜像集群模式

10.2.1、镜像模式简介

镜像模式是基于默认集群模式加上一定的配置得来的;

在默认模式下的RabbitMQ集群,它会把所有节点的交换机、绑定、队列的元数据进行复制确保所有节点都有一份相同的元数据信息

但是队列数据分为两种

  • 一种是队列的元数据信息(比如队列的最大容量,队列的名称等配置信息)
  • 一种是队列里面的消息

镜像模式则是把所有的队列数据完全同步,包括元数据信息和消息数据信息,当然这对性能肯定会有一定影响,当对数据可靠性要求较高时,可以使用镜像模式;

10.2.2、镜像模式配置

实现镜像模式也非常简单,它是在普通集群模式基础之上搭建而成的

3.X版本设置

镜像队列配置语法:

rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]
  • rabbitmqctl set_policy:固定写法

  • -p Vhost: 可选参数,设置虚拟主机的名字(针对指定vhost下的queue进行设置)

  • Name: 设置策略的名称(自己取个名字就可以)

  • Pattern: queue的匹配模式(正则表达式);^表示所有的队列都是镜像队列

  • Definition:镜像定义(json格式),包括三个部分ha-mode、ha-params、ha-sync-mode

    • ha-mode

      指明镜像队列的模式,有效值为 all/exactly/nodes

      all:表示在集群中所有的节点上进行镜像
      exactly:表示在指定个数的节点上进行镜像,节点的个数由ha-params指定
      nodes:表示在指定的节点上进行镜像,节点名称通过ha-params指定
      
    • ha-params

      ha-mode模式需要用到的参数

    • ha-sync-mode

      队列中消息的同步方式,有效值为automatic(自动向master同步数据)和manual(手动向master同步数据)

  • priority:可选参数,指的是policy策略的优先级;

在默认集群模式的基础上执行上面这个命令就可以把一个默认的集群模式变成镜像集群模式

比如想配置所有名字开头为policy_的队列进行镜像,镜像数量为2,那么命令如下(在任意节点执行如下命令):

rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]

rabbitmqctl set_policy -p longdidi my_policy "^policy_"  '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'  
(1)、同步所有数据

所有节点、所有虚拟主机、所有队列 都进行镜像

如果要在所有节点所有队列上进行镜像则在任意节点执行如下命令

语法:rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]

rabbitmqctl set_policy my-all "^"  '{"ha-mode":"all"}'   
(2)、同步指定数据

针对某个虚拟主机进行镜像

语法:rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]

rabbitmqctl set_policy -p longdidi my-all "^" '{"ha-mode": "exactly", "ha-params": 2, "ha-sync-mode": "automatic"}'

在默认集群模式的基础上执行上面这个命令就可以把一个默认的集群模式变成镜像集群模式

4.X版本设置

在这里插入图片描述

3、SpringBoot集成集群

重点连接配置

spring:rabbitmq:# 连接单台rabbitmq 服务器的地址# host: 192.168.1.101# 连接单台rabbitmq 服务器的端口# port: 5672username: adminpassword: 123456virtual-host: longdidipublisher-confirm-type: correlated # 开启生产者的确认模式,设置关联模式publisher-returns: true #开启return模式# 开启消费者手动确认listener:simple:acknowledge-mode: manualaddresses: 192.168.1.11:5672,192.168.1.12:5672,192.1.13:5672

测试模块:rabbitmq-10-cluster-01

引入依赖

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency></dependencies>

配置MQ

server:port: 8080spring:application:name: cluster-learn01rabbitmq:# 连接单台rabbitmq 服务器的地址# host: 192.168.1.101# 连接单台rabbitmq 服务器的端口# port: 5672username: adminpassword: 123456virtual-host: longdidipublisher-confirm-type: correlated # 开启生产者的确认模式,设置关联模式publisher-returns: true #开启return模式# 开启消费者手动确认listener:simple:acknowledge-mode: manualaddresses: 192.168.1.11:5672,192.168.1.12:5672,192.1.13:5672data:redis:host: 192.168.1.4port: 6379#password: 123456database: 0 # 0号数据库

定义MQ队列

package com.longdidi.config;import com.longdidi.constants.RabbitMQConstant;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class RabbitConfig {/*** 正常交换机* 使用durable()方法设置持久化** @return*/@Beanpublic DirectExchange normalExchange() {return ExchangeBuilder.directExchange(RabbitMQConstant.EXCHANGE_NAME).durable(true).build();}/*** 正常队列* durable()方法就是持久化** @return*/@Beanpublic Queue normalQueue() {return QueueBuilder.durable(RabbitMQConstant.QUEUE_NAME1).build();}/*** 正常交换机和正常队列绑定** @param normalExchange* @param normalQueue* @return*/@Beanpublic Binding bindingNormal(DirectExchange normalExchange, Queue normalQueue) {return BindingBuilder.bind(normalQueue).to(normalExchange).with(RabbitMQConstant.ROUTING_NAME1);}}

生产者

package com.longdidi.service;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.longdidi.constants.RabbitMQConstant;
import com.longdidi.vo.Orders;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;import java.math.BigDecimal;
import java.util.Date;@Service
@Slf4j
public class SendMessageService {@Resourceprivate RabbitTemplate rabbitTemplate;//这个对象可以进行序列化和反序列化(json格式)@Resourceprivate ObjectMapper objectMapper;/*** 构造方法执行后自动执行*/@PostConstructpublic void init() {//开启生产者的确定模式rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {if (!ack) {log.error("消息没有到达交换机,原因为:{}", cause);//TODO 重发消息或者记录错误日志}});rabbitTemplate.setReturnsCallback(returnedMessage -> {log.error("消息没有从交换机正确的投递(路由)到队列,原因为:{}", returnedMessage.getReplyText());//TODO 记录错误日志,给程序员发短信或者或者邮件});}public void sendMsg() throws JsonProcessingException {{//创建订单Orders orders1 = Orders.builder().orderId("order_12345").orderName("买的手机").orderMoney(new BigDecimal(2356)).orderTime(new Date()).build();//转成jsonString strOrders1 = objectMapper.writeValueAsString(orders1);MessageProperties messageProperties = new MessageProperties();//设置单条消息的持久化,默认就是持久化messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);Message message = MessageBuilder.withBody(strOrders1.getBytes()).andProperties(messageProperties).build();rabbitTemplate.convertAndSend(RabbitMQConstant.EXCHANGE_NAME, RabbitMQConstant.ROUTING_NAME1, message);}{Orders orders2 = Orders.builder().orderId("order_12345").orderName("买的手机").orderMoney(new BigDecimal(2356)).orderTime(new Date()).build();String strOrders2 = objectMapper.writeValueAsString(orders2);MessageProperties messageProperties = new MessageProperties();//设置单条消息的持久化,默认就是持久化messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);Message message = MessageBuilder.withBody(strOrders2.getBytes()).andProperties(messageProperties).build();rabbitTemplate.convertAndSend(RabbitMQConstant.EXCHANGE_NAME, RabbitMQConstant.ROUTING_NAME1, message);}log.info("消息发送完毕,发送时间为:{}", new Date());}
}

消费者

package com.longdidi.service;import com.fasterxml.jackson.databind.ObjectMapper;
import com.longdidi.constants.RabbitMQConstant;
import com.longdidi.vo.Orders;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;import java.io.IOException;import com.rabbitmq.client.Channel;@Component
@Slf4j
public class ReceiveMessageService {@Resourceprivate ObjectMapper objectMapper;@Resourceprivate StringRedisTemplate stringRedisTemplate;@RabbitListener(queues = {RabbitMQConstant.QUEUE_NAME1})public void receiveMsg(Message message, Channel channel) throws IOException {//获取消息的唯一标识long deliveryTag = message.getMessageProperties().getDeliveryTag();//使用objectmapper把字节数组反序列化成对象Orders orders = objectMapper.readValue(message.getBody(), Orders.class);try {log.info("接收到的消息为:{}", orders.toString());//如果不存在就在redis中存储Boolean setResult = stringRedisTemplate.opsForValue().setIfAbsent("idempotent:" + orders.getOrderId(), orders.getOrderId());if (setResult) {// TODO 向数据库插入订单等log.info("向数据库插入订单");}//手动确认channel.basicAck(deliveryTag, false);} catch (Exception e) {log.error("消息处理出现问题");try {channel.basicNack(deliveryTag, false, true);} catch (IOException ex) {throw new RuntimeException(ex);}throw new RuntimeException(e);}}
}

定义常量

package com.longdidi.constants;public class RabbitMQConstant {// 正常交换机public static final String EXCHANGE_NAME = "exchange.idempotent.normal.1";// 队列public static final String QUEUE_NAME1 = "queue.idempotent.normal.1";// 路由keypublic static final String ROUTING_NAME1 = "key.idempotent.normal.1";
}

定义实体类

package com.longdidi.vo;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Orders implements Serializable {private String orderId;private String orderName;private BigDecimal orderMoney;private Date orderTime; //下单时间
}

发送消息

package com.longdidi;import com.longdidi.service.SendMessageService;
import jakarta.annotation.Resource;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Rabbitmq10Cluster01Application implements ApplicationRunner {public static void main(String[] args) {SpringApplication.run(Rabbitmq10Cluster01Application.class, args);}@Resourceprivate SendMessageService sendMessageService;/*** 程序一启动就会运行该方法** @param args* @throws Exception*/@Overridepublic void run(ApplicationArguments args) throws Exception {sendMessageService.sendMsg();}
}

测试

在这里插入图片描述

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

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

相关文章

DeepSeek-R1:使用KTransformers实现高效部署指南

KTransformers作为一个开源框架&#xff0c;专门为优化大规模语言模型的推理过程而设计。它支持GPU/CPU异构计算&#xff0c;并针对MoE架构的稀疏性进行了特别优化&#xff0c;可以有效降低硬件要求&#xff0c;允许用户在有限的资源下运行像DeepSeek-R1这样庞大的模型。 硬件…

回归预测 | Matlab实现GWO-BP-Adaboost基于灰狼算法优化BP神经网络结合Adaboost思想的回归预测

回归预测 | Matlab实现GWO-BP-Adaboost基于灰狼算法优化BP神经网络结合Adaboost思想的回归预测 目录 回归预测 | Matlab实现GWO-BP-Adaboost基于灰狼算法优化BP神经网络结合Adaboost思想的回归预测回归效果基本介绍GWO-BP-Adaboost:基于灰狼算法优化BP神经网络结合Adaboost思想…

基于websocket的多用户网页五子棋 --- 测试报告

目录 功能测试自动化测试性能测试 功能测试 1.登录注册页面 2.游戏大厅页面 3.游戏房间页面 自动化测试 1.使用脑图编写web自动化测试用例 2.创建自动化项目&#xff0c;根据用例通过selenium来实现脚本 根据脑图进行测试用例的编写&#xff1a; 每个页面一个测试类&am…

JavaWeb-mysql8版本安装

下载方式 地址&#xff1a;https://www.mysql.com/cn/downloads/ 选择&#xff1a;MySQL Community (GPL) downloads 选择&#xff1a;MySQL Community Server 选择&#xff1a; 选择&#xff1a; 安装mysql &#xff08;8.0.30&#xff09; 1、以管理员身份 打开 命令行…

人工智能神经网络基本原理

MP 神经元数学模型 MP 模型是神经网络领域的早期模型&#xff0c;它模仿了神经元的基本结构和工作原理。 人工神经元是一个多输入、单输出的信息处理单元&#xff0c;是对生物神经元的建模。建模方式可以有很多种&#xff0c;不同的建模方式就意味着不同的人工神经元结构。 比…

python从入门到精通(二十六):python文件操作之Word全攻略(基于python-docx)

python文件操作之word技巧大全 word技巧基础到高级操作大全A.准备工作1. 安装python-docx库2. 导入库 B.基础操作1. 创建Word文档1.1 创建文档对象1.2 添加word标题1.3 添加word段落1.4 设置段落样式1.5 创建有序列表1.6 创建无序列表1.7添加word分页1.8 添加word图片1.9 添加w…

Android Configuration相关问题如何定位分析(中英文切换、黑夜白天模式等)

Android Configuration相关问题如何定位分析&#xff08;中英文切换、黑夜白天模式等&#xff09;. Configuration的常见问题场景&#xff1a; app的size position不正确中英文显示不正确白天黑夜模式不正确 Configuration信息如下&#xff1a; mFullConfiguration{1.0 ?mc…

SCI1区TOP:自适应学习粒子群算法SLPSO,深度解析+性能实测

目录 1.摘要2.改进策略3.自适应学习粒子群算法4.结果展示5.参考文献6.获取代码 1.摘要 粒子群算法&#xff08;PSO&#xff09;是一种基于种群的随机搜索方法&#xff0c;广泛应用于科学和工程领域的连续空间优化问题&#xff0c;并已证明其高效性和有效性。许多实际问题的往往…

kotlin协程之CoroutineScope 与 CoroutineContext 详解

前言 在使用协程时&#xff0c;不管是看协程的源码还是日常使用&#xff0c;会经常看到 CoroutineScope 和 CoroutineContext&#xff0c; 这两个到底是什么东西呢&#xff1f;作用是什么&#xff1f; 本篇文章我们就来深入的理解一下 CoroutineScope 和 CoroutineContext。 …

win11编译llama_cpp_python cuda128 RTX30/40/50版本

Geforce 50xx系显卡最低支持cuda128&#xff0c;llama_cpp_python官方源只有cpu版本&#xff0c;没有cuda版本&#xff0c;所以自己基于0.3.5版本源码编译一个RTX 30xx/40xx/50xx版本。 1. 前置条件 1. 访问https://developer.download.nvidia.cn/compute/cuda/12.8.0/local_…

正向代理与反向代理

代理: 通常称为代理、代理服务器或 Web 代理&#xff0c;代理一般是指正向代理&#xff0c;是位于一组客户端计算机之前的服务器。当这些计算机向 Internet 上的站点和服务发出请求时&#xff0c;代理服务器将拦截这些请求&#xff0c;然后代表客户端与 Web服务器进行通信&…

Vue _总结

文章目录 一 Vue介绍1 什么是Vue.js2 MVVM二 第一个例子1 引入vue2 html中用法3 创建vue实例对象三 Vue基本语法1 v-text2 v-bind3 v-on4 v-model5 v-if6 v-for7 计算属性8 组件化全局注册本地注册9 生命周期10 员工程序使用vue.js重构list.htmladd.htmlupdate.html四 使用vue-…

理解梯度下降、链式法则、梯度消失/爆炸

第一章&#xff1a;人工智能之不同数据类型及其特点梳理 第二章&#xff1a;自然语言处理(NLP)&#xff1a;文本向量化从文字到数字的原理 第三章&#xff1a;循环神经网络RNN&#xff1a;理解 RNN的工作机制与应用场景(附代码) 第四章&#xff1a;循环神经网络RNN、LSTM以及GR…

笔记四:C语言中的文件和文件操作

Faye&#xff1a;只要有正确的伴奏&#xff0c;什么都能变成好旋律。 ---------《寻找天堂》 目录 一、文件介绍 1.1程序文件 1.2 数据文件 1.3 文件名 二、文件的打开和关闭 2.1 文件指针 2.2.文件的打开和关闭 2.3 文件读取结束的判定 三、 文件的顺序读写 3.1 顺序读写…

mysql下载与安装、关系数据库和表的创建

一、mysql下载&#xff1a; MySQL获取&#xff1a; 官网&#xff1a;www.mysql.com 也可以从Oracle官方进入&#xff1a;https://www.oracle.com/ 下载地址&#xff1a;https://downloads.mysql.com/archives/community/ 选择对应的版本和对应的操作系统&#xff…

(数据结构)双向链表

(数据结构)带头双向循环链表 前言 前面链表部分&#xff0c;咱们着重讲解了不带头单向不循环链表&#xff0c;简称单链表。那么链表其实也分很多种类适用于各种各样的场景。通过单链表的学习&#xff0c;其实我们已经大致了解了链表的绝大多数的内容&#xff0c;所以接下来我通…

考研英语语法全攻略:从基础到长难句剖析​

引言 在考研英语的备考之旅中,语法犹如一座灯塔,为我们在浩瀚的英语知识海洋中指引方向。无论是阅读理解中复杂长难句的解读,还是写作时准确流畅表达的需求,扎实的语法基础都起着至关重要的作用。本文将结合有道考研语法基础入门课的相关内容,为大家全面梳理考研英语语法…

【计算机网络入门】应用层

目录 1.网络应用模型 1.1 C/S模型&#xff08;客户端服务器模型&#xff09; 1.2 P2P模型&#xff08;对等模型&#xff09; 2. DNS系统 2.1 域名 2.2 域名解析流程 3. FTP文件传输协议 4. 电子邮件系统 4.1 SMTP协议 4.2 pop3协议 4.3 IMAP协议 4.4 基于万维网的电…

【GoTeams】-3:构建api、重构错误码

本文目录 1. 构建api梳理调用关系api包的作用路由梳理注册Register代码语法 2. 重构错误码 1. 构建api 首先复制project-user&#xff0c;改名为project-api&#xff0c;放在总的路径下&#xff0c;然后在工作区中进行导入。 运行命令go work use .\project-api\新建工作区之…

游戏引擎学习第145天

仓库:https://gitee.com/mrxiao_com/2d_game_3 今天的计划 目前&#xff0c;我们正在完成遗留的工作。当时我们已经将声音混合器&#xff08;sound mixer&#xff09;集成到了 SIMD 中&#xff0c;但由于一个小插曲&#xff0c;没有及时完成循环内部的部分。这个小插曲主要是…