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

RabbitMQ实战宝典:从新手到专家的全面探索

前言

在当今分布式系统架构中,消息队列已成为不可或缺的一部分,而RabbitMQ作为其中的佼佼者,凭借其强大的功能和灵活性,广泛应用于各种规模的应用场景中。本文将带你从基础概念出发,深入探讨RabbitMQ的核心特性,通过实战案例与Java代码示例,引领你踏上成为RabbitMQ大师的旅程。

第一章:启程——初识RabbitMQ

1.1 RabbitMQ简介

RabbitMQ是一个开源的消息代理和队列服务器,它遵循AMQP(Advanced Message Queuing Protocol)协议,支持多种编程语言,包括Java。RabbitMQ的核心价值在于解耦应用程序、提高系统扩展性和容错能力。

1.2 交换机类型及实战

RabbitMQ提供了多种交换机类型,以满足不同场景的需求:

DirectExchange:最简单直接的路由,适合一对一消息传递。
FanoutExchange:实现发布/订阅模式,任何绑定到此交换机的队列都会接收到消息。
TopicExchange:基于模式匹配的路由,提供了极其灵活的消息路由方式。

实战案例:假设我们有一个系统需要在用户注册后,通过邮件和短信通知用户。我们可以使用FanoutExchange,为邮件服务和短信服务各创建一个队列,并让这两个队列都绑定到同一个FanoutExchange上。

// java示例代码
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare("registration_notifications", BuiltinExchangeType.FANOUT);
String queueNameEmail = channel.queueDeclare().getQueue();
String queueNameSMS = channel.queueDeclare().getQueue();
channel.queueBind(queueNameEmail, "registration_notifications", "");
channel.queueBind(queueNameSMS, "registration_notifications", "");
// 发布消息
channel.basicPublish("registration_notifications", "", null, "User registered!".getBytes());

1.3 消息模型与工作流程

RabbitMQ支持多种消息模型,其中最常用的是发布/订阅模型(Pub/Sub)、路由模型(Routing)和主题模型(Topics)。每种模型都对应着不同的消息传递需求和业务场景。

发布/订阅模型

在上述实战案例中,我们已经见识了发布/订阅模型的威力。这种模型允许消息生产者(发布者)发送消息到一个交换机,然后由交换机负责将消息复制并发送给所有绑定到该交换机的队列。这非常适合一对多的通知场景,比如新闻推送、系统事件广播等。

路由模型

直接交换机(DirectExchange)体现了路由模型的特点,它根据消息携带的路由键(routing key)将消息精确地路由到与之匹配的队列。这种模型适用于需要根据特定条件分发消息的场景,比如订单处理系统中的不同商品类别处理。

主题模型

TopicExchange是主题模型的实现,它通过模式匹配的方式路由消息,允许队列通过通配符订阅多个路由键。这种灵活性使得主题模型在处理复杂且动态变化的路由规则时尤为有效,例如日志收集系统,可以根据不同的日志级别和来源配置不同的处理队列。

1.4 安装与配置

RabbitMQ可以在多种操作系统上运行,包括WindowsLinuxmacOS。最便捷的安装方式是通过包管理器(如Homebrewapt-getyum),或者直接从官方网站下载预编译的二进制文件。安装完成后,RabbitMQ会默认启动,并可通过Web管理界面http://localhost:15672进行访问和管理。

配置方面,RabbitMQ提供了丰富的配置选项,包括队列声明、交换机类型、权限控制、集群部署等,这些都可以通过配置文件、命令行参数或是管理界面来完成。对于复杂的部署需求,还可以利用插件系统进行功能扩展,如使用rabbitmq_management插件增强管理界面的功能。

1.5 安全与监控

确保消息系统的安全是至关重要的。RabbitMQ支持用户认证、权限控制和SSL/TLS加密传输,以保护消息在传输过程中的安全。管理员可以通过定义不同的用户角色和权限,细粒度地控制对队列、交换机和绑定的操作权限。

至于监控,RabbitMQ提供了一系列内置的监控和诊断工具,如上面提到的Web管理界面可以直观地展示队列状态、消息速率、节点健康状况等。此外,还可以集成第三方监控系统,利用AMQP协议的管理API获取更详细的指标数据,以便于进行性能调优和故障排查。

第二章:稳如磐石——消息可靠性保障

确保消息的可靠性是构建健壮消息驱动系统的基础。通过消息持久化、手动ACK机制、发布确认、镜像队列、死信处理与重试机制、以及网络分区的处理策略,RabbitMQ为开发者提供了一整套工具来保障消息在各种情况下的可靠性。结合正确的配置和最佳实践,可以最大限度减少消息丢失的风险,提高系统的整体稳定性。随着业务需求的增长和复杂度的提升,深入理解和应用这些可靠性策略,将对提升应用的容错能力和用户体验起到关键作用。

2.1 消息持久化

为了确保消息不因服务器故障而丢失,RabbitMQ提供了消息和队列的持久化机制。通过设置消息和队列的delivery_modedurable属性,可以在服务重启后恢复消息。

2.2 手动ACK机制

消费者通过手动确认(ACK)机制告诉RabbitMQ消息已被成功处理,这样即使消费者崩溃,消息也不会丢失。

channel.basicConsume(queueName, false, (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println("[x] Received '" + message + "'");// 处理消息逻辑...// 手动确认channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}, consumerTag -> {});

2.3 发布确认(Publisher Confirmations)

除了消费者端的ACK机制,RabbitMQ还支持发布确认(Publisher Confirmations),允许生产者确认消息是否成功到达交换机。这为消息的生产端也提供了可靠性保障。

channel.confirmSelect();try {for (int i = 0; i < messageCount; i++) {String message = "Message " + i;channel.basicPublish("", queueName, null, message.getBytes(StandardCharsets.UTF_8));}boolean waitForConfirms = channel.waitForConfirms();if (waitForConfirms) {System.out.println("All messages confirmed.");} else {System.out.println("Some messages were not confirmed.");}
} catch (Exception e) {e.printStackTrace();
}

2.4 镜像队列(Mirrored Queues)

镜像队列是一种高级的高可用性策略,它可以将队列中的消息复制到集群中的其他节点上,确保即使某个节点发生故障,队列的数据也不会丢失。配置镜像队列需要通过策略设置,指定队列的镜像级别,如以下命令行操作:

rabbitmqctl set_policy HA '^(?!amq\.).*' '{"ha-mode":"all","ha-sync-mode":"automatic"}' --apply-to queues

这段命令设置了一个名为HA的策略,应用于所有不以amq.开头的队列,确保这些队列的数据在所有节点上都有镜像。

2.5 死信处理与重试机制

RabbitMQ允许通过死信交换机(Dead Letter Exchange, DLX)来处理无法正常消费的消息。当消息达到最大重试次数或符合特定条件时,可以被重新路由到DLX,从而进入死信队列,便于后续分析或重试。

channel.queueDeclare("DLQ", true, false, false, null);
channel.queueBind("DLQ", "myDeadLetterExchange", "#");Map<String, Object> args = new HashMap<>();
args.put("x-dead-letter-exchange", "myDeadLetterExchange");
channel.queueDeclare("myQueue", true, false, false, args);

这里,myQueue配置了一个死信交换机myDeadLetterExchange,当消息变为死信时,会被重新发送到这个交换机,并根据路由键最终到达死信队列DLQ

2.6 网络分区处理与仲裁队列

在分布式系统中,网络分区可能导致部分节点与其他节点失去联系,RabbitMQ提供了网络分区检测与处理机制。当检测到网络分区时,可以根据配置策略决定队列的可写性,避免数据不一致。仲裁队列(Quorum Queues)是RabbitMQ 3.8版本引入的新特性,相比经典队列,它在分布式环境中提供了更好的耐久性和可用性,特别是在面对网络分区时,通过多数节点同意的机制保证数据一致性。

第三章:进阶探索——高级特性与最佳实践

本章深入探讨了RabbitMQ的高级特性与最佳实践,从灵活的消息路由、消息重复消费的处理,到性能优化、安全加固、自动化运维等多个维度,为开发者提供了全面的指南。通过合理运用这些策略和技巧,可以显著提升基于RabbitMQ构建的应用系统的稳定性和效率。面对日益复杂和规模化的应用环境,深入理解和实践这些高级特性,是每位消息中间件使用者必备的能力。未来,随着技术的不断进步和业务需求的演变,RabbitMQ及其生态系统将继续提供更为强大和灵活的解决方案,助力开发者构建更加高效、可靠的分布式系统。

3.1 TopicExchange的灵活运用

利用TopicExchange,可以实现消息的灵活路由。通过通配符模式,可以实现复杂的消息过滤逻辑。以下示例展示了如何配置TopicExchange以及消费者如何根据不同的通配符订阅消息:

// 声明TopicExchange
channel.exchangeDeclare("topicExchange", BuiltinExchangeType.TOPIC);// 声明两个队列并绑定到TopicExchange
channel.queueDeclare("queueNews", true, false, false, null);
channel.queueBind("queueNews", "topicExchange", "*.news.*");channel.queueDeclare("queueSports", true, false, false, null);
channel.queueBind("queueSports", "topicExchange", "*.sports.*");// 发布消息到TopicExchange
channel.basicPublish("topicExchange", "uk.news.weather", null, "Weather update UK".getBytes());
channel.basicPublish("topicExchange", "us.sports.football", null, "Football match results US".getBytes());// 消费者代码示例
String queueNameNews = "queueNews";
String queueNameSports = "queueSports";channel.basicConsume(queueNameNews, true, (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println("[News Queue] Received '" + message + "'");
}, consumerTag -> {});channel.basicConsume(queueNameSports, true, (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println("[Sports Queue] Received '" + message + "'");
}, consumerTag -> {});

在这个例子中,queueNews绑定了通配符*.news.*,意味着它将接收所有包含.news.的消息,如uk.news.weather。同样,queueSports绑定了*.sports.*,会接收所有与体育相关的消息,如us.sports.football。这样,通过灵活的通配符订阅,TopicExchange能够有效地根据消息主题将消息路由到感兴趣的消费者,满足复杂的消息过滤和分发需求。

3.2 避免消息重复消费

消息重复消费是分布式系统中常见的问题。采用全局唯一ID与Redis结合,可以有效避免重复。

Jedis jedis = new Jedis("localhost");
long result = jedis.setnx("messageId:" + messageId, "processing");
if (result == 1) {// 消费消息// ...jedis.del("messageId:" + messageId); // 消费成功后删除标识
} else {// 检查消息状态,决定是否需要重新消费
}

3.3 使用TTL和Dead Letter Exchange优化消息生命周期管理

消息的生存时间(Time-To-Live, TTL)特性允许为消息或队列设置过期时间,过期后消息可被自动删除或转发至死信队列,从而实现消息的生命周期管理。

channel.queueDeclare("myQueue", true, false, false, new HashMap<String, Object>() {{put("x-message-ttl", 60000); // 设置队列消息TTL为60秒put("x-dead-letter-exchange", "dlxExchange"); // 设置死信交换机}}
);channel.exchangeDeclare("dlxExchange", "direct");
channel.queueDeclare("dlxQueue", true, false, false, null);
channel.queueBind("dlxQueue", "dlxExchange", "routingKeyForDeadLetter");

这段代码展示了如何为队列myQueue设置消息的TTL,并指定了一个死信交换机dlxExchange。当消息过期后,将会被路由到dlxQueue,实现消息的生命周期管理。

3.4 高并发下的性能优化

在高并发场景下,可以通过预取(Prefetch)设置、批量发布和消费、以及合理的队列和交换机设计来提升性能。通过调整预取值,可以平衡消息的处理速度和系统负载,避免单个消费者占用过多资源,提高整体处理效率:

channel.basicQos(100); // 设置消费者预取值为100,即每次最多发送给消费者100条未确认消息

3.5 使用RabbitMQ的延迟队列特性

RabbitMQ通过插件支持延迟队列,允许消息在特定时间后才被投递,这对于定时任务、订单超时处理等场景非常有用。例如:安装并启用RabbitMQ延迟消息插件(rabbitmq_delayed_message_exchange)后,可以创建带有延迟特性的交换机:

channel.exchangeDeclare("delayedExchange", "x-delayed-message", true, false, new HashMap<String, Object>() {{put("x-delayed-type", "direct");}}
);channel.basicPublish("delayedExchange", "routingKey", new AMQP.BasicProperties.Builder().expiration("5000").build(), // 设置消息延迟5秒"This message will be delayed for 5 seconds".getBytes());

这段代码展示了如何发布一个将在5秒后被投递的消息到延迟交换机。

3.6 插件扩展与自定义行为

RabbitMQ的强大之处还在于其丰富的插件生态。开发者可以利用现有插件如Management UIShovelFederation等来增强监控、数据迁移和集群互联功能,甚至开发自定义插件以满足特定业务需求。例如安装和启用RabbitMQ Management插件,以增强监控能力:

rabbitmq-plugins enable rabbitmq_management

通过浏览器访问http://localhost:15672即可查看管理界面。

3.7 安全加固:权限管理与TLS加密

确保RabbitMQ的安全不仅限于网络层面,还包括严格的权限管理和数据传输加密。通过配置用户角色、vhost访问控制以及启用TLS/SSL加密,可以有效保护敏感信息和防止未经授权的访问。如下示例配置RabbitMQ的用户权限和TLS加密:

# 创建用户并分配权限
rabbitmqctl add_user username password
rabbitmqctl set_permissions -p / username ".*" ".*" ".*"# 启用TLS
rabbitmq-plugins enable rabbitmq_management_agent rabbitmq_web_stomp
rabbitmqctl set_listener_tcp_tls [-p VhostName] port [certfile] [keyfile] [cacertfile]

确保使用证书和密钥文件配置TLS监听,以加密客户端与RabbitMQ之间的通信。

3.8 监控与日志分析

利用RabbitMQ Management UI和各类监控工具(如Prometheus+GrafanaELK Stack)对消息队列的性能指标进行实时监控,结合日志分析,能够快速定位并解决潜在的性能瓶颈和异常状况。例如集成Prometheus监控RabbitMQ:

  1. 安装rabbitmq_prometheus监控插件:
rabbitmq-plugins enable rabbitmq_prometheus
  1. 配置Prometheus抓取数据:
- job_name: 'rabbitmq'static_configs:- targets: ['localhost:15692']

通过Grafana展示监控图表,及时发现并解决问题。

3.9 自动化运维与持续集成

将RabbitMQ的部署、配置和升级纳入自动化运维流程,结合持续集成/持续部署(CI/CD)实践,可以提高系统的稳定性和迭代效率。使用Docker容器化部署、Ansible自动化配置管理等技术,简化运维复杂度。使用Ansible自动化配置RabbitMQ实例:

- name: Ensure RabbitMQ is installedapt:name: rabbitmq-serverstate: present- name: Configure RabbitMQcommand: rabbitmqctl set_policy ha-all "^queue\." '{"ha-mode":"all","ha-sync-mode":"automatic"}'

结合GitLab CI/CD pipeline,自动化测试和部署RabbitMQ配置更改。

3.10 案例研究:大规模分布式系统中的消息模式设计

通过分析实际案例,探讨在大规模分布式系统中如何设计高效、可扩展的消息模式。比如如何利用发布/订阅模式实现事件驱动架构,或如何结合RPC模式处理跨服务的异步请求响应,都是深入理解RabbitMQ在复杂应用场景中的关键。例如考虑一个事件驱动架构的电商系统,使用发布/订阅模式处理订单状态变更事件:

channel.exchangeDeclare("orderEvents", "fanout");
channel.queueDeclare("emailNotifications", true, false, false, null);
channel.queueBind("emailNotifications", "orderEvents", "");channel.queueDeclare("smsNotifications", true, false, false, null);
channel.queueBind("smsNotifications", "orderEvents", "");// 发布订单状态变更事件
channel.basicPublish("orderEvents", "", null, "Order status changed".getBytes());

此例中,当订单状态变更时,通过orderEvents交换机发布消息,同时emailNotificationssmsNotifications两个队列作为订阅者,分别处理电子邮件和短信通知,实现了消息的解耦和高效处理。

第四章:运维的艺术——命令行管理

4.1 用户管理的艺术

高效运维RabbitMQ离不开对rabbitmqctl命令行工具的熟练掌握。在用户管理方面,以下是一些核心命令:

# {username} 表示用户名; {password}表示用户密码
# 该命令将创建一个 non-administrative 用户
rabbitmqctl add_user {username} {password}# 表示删除一个用户,该命令将指示RabbitMQ broker去删除指定的用户
rabbitmqctl delete_user {username}# 表示修改指定的用户的密码
rabbitmqctl change_password {username} {newpassword}# 表示清除指定用户的密码
# 执行此操作后的用户,将不能用密码登录,但是可能通过已经配置的SASL EXTERNAL的方式登录。
rabbitmqctl clear_password {username}# 表示指引RabbitMQ broker认证该用户和密码
rabbitmqctl authenticate_user {username} {password}# 表示设置用户的角色,{tag}可以是零个,一个,或者是多个。并且已经存在的tag也将会被移除。
# rabbitmqctl set_user_tags tonyg administrator 该命令表示指示RabbitMQ broker确保用户tonyg为一个管理员角色。
# 上述命令在用户通过AMQP方式登录时,不会有任何影响;但是如果通过其他方式,例如管理插件方式登录时,就可以去管理用户、vhost 和权限。
rabbitmqctl set_user_tags {username} {tag ...}# 表示列出所有用户名信息
rabbitmqctl list_users

4.2 虚拟主机(VHost)的操控

虚拟主机是RabbitMQ中消息通道的逻辑隔离单元,管理它们同样重要:

# {vhost} 表示待创建的虚拟主机项的名称
rabbitmqctl add_vhost {vhost}# 表示删除一个vhost。删除一个vhost将会删除该vhost的所有exchange、queue、binding、用户权限、参数和策略。
rabbitmqctl delete_vhost {vhost}# 表示列出所有的vhost。其中 {vhostinfoitem} 表示要展示的vhost的字段信息,展示的结果将按照 {vhostinfoitem} 指定的字段顺序展示。这些字段包括: name(名称) 和 tracing (是否为此vhost启动跟踪)。
# 如果没有指定具体的字段项,那么将展示vhost的名称。
rabbitmqctl list_vhosts {vhostinfoitem ...}# 表示设置用户权限。 {vhost} 表示待授权用户访问的vhost名称,默认为 "/"; {user} 表示待授权反问特定vhost的用户名称; {conf}表示待授权用户的配置权限,是一个匹配资源名称的正则表达式; {write} 表示待授权用户的写权限,是一个匹配资源名称的正则表达式; {read}表示待授权用户的读权限,是一个资源名称的正则表达式。
# rabbitmqctl set_permissions -p myvhost tonyg "^tonyg-.*" ".*" ".*"
# 例如上面例子,表示授权给用户 "tonyg" 在vhost为 `myvhost` 下有资源名称以 "tonyg-" 开头的 配置权限;所有资源的写权限和读权限。
rabbitmqctl set_permissions [-p vhost] {user} {conf} {write} {read}# 表示设置用户拒绝访问指定指定的vhost,vhost默认值为 "/"
rabbitmqctl clear_permissions [-p vhost] {username}# 表示列出具有权限访问指定vhost的所有用户、对vhost中的资源具有的操作权限。默认vhost为 "/"。
# 注意,空字符串表示没有任何权限。
rabbitmqctl list_permissions [-p vhost]# 表示列出指定用户的权限vhost,和在该vhost上的资源可操作权限。
rabbitmqctl list_user_permissions {username}

4.3 图形化界面的启停自如

rabbitmq_management插件提供了一个强大的Web管理界面,其启用与禁用操作如下:

# 启用管理界面:
rabbitmq-plugins enable rabbitmq_management# 停用管理界面:
rabbitmq-plugins disable rabbitmq_management

4.4 进程管理

# 以前台进程的方式启动RabbitMQ
rabbitmq-server# 以后台进程的方式启动RabbitMQ
rabbitmq-server -detached# 查看并杀死进程
ps -ef | grep erlang# 查看服务是否启动
lsof -i:5672# 查看服务的详细状态
rabbitmqctl status

结语

RabbitMQ的学习与掌握是一个持续探索的过程。通过本指南的介绍,相信你已经掌握了从RabbitMQ的基础配置到高级特性的应用,以及如何在Java项目中集成RabbitMQ并确保消息的可靠传递。接下来,将理论知识应用于实际项目,不断优化你的消息队列设计,逐步迈向RabbitMQ大师的行列。在实战中成长,让消息驱动的架构助你一臂之力,构建更加健壮、可扩展的应用系统。

相关文章:

RabbitMQ实战宝典:从新手到专家的全面探索

前言 在当今分布式系统架构中&#xff0c;消息队列已成为不可或缺的一部分&#xff0c;而RabbitMQ作为其中的佼佼者&#xff0c;凭借其强大的功能和灵活性&#xff0c;广泛应用于各种规模的应用场景中。本文将带你从基础概念出发&#xff0c;深入探讨RabbitMQ的核心特性&#…...

6月21日(周五)AH股总结:沪指失守3000点,恒生科技指数跌近2%,多只沪深300ETF午后量能显著放大

内容提要 沪指全天围绕3000点关口来回拉锯&#xff0c;收盘跌破3000点。白酒及光刻机概念集体走低&#xff0c;中芯国际港股跌超2%。CRO医药概念及水利股逆势走强。 A股低开低走 沪指全天围绕3000点关口来回拉锯&#xff0c;收盘跌破3000点&#xff0c;跌0.24%。深成指跌0.04…...

双非本,3年时间从外包到阿里P6(Android岗),看我是怎么逆袭成功的?

而在小公司&#xff0c;因为我也在小公司呆过&#xff0c;所以我有最直接的感受。整个部门技术人员没几个&#xff0c;我又大学刚毕业&#xff0c;带我的人&#xff0c;问啥啥不会&#xff0c;只有一个大佬&#xff0c;跳槽来的&#xff0c;是我们技术总监&#xff0c;有问题谁…...

前端面试题(基础篇七)

一、谈谈你对webpack的看法 webpack是一个模块打包工具&#xff0c;我们可以使用webpack管理我们的模块依赖&#xff0c;编译输出模块所需的静态文件。它可以很好的管理、打包web开发中所需的html、css、JavaScript以及其他各种静态文件&#xff08;使用的图片、字体图标等&am…...

ARM架构简明教程

目录 一、ARM架构 1、RISC指令集 2、ARM架构数据类型的约定 2.1 ARM-v7架构数据类型的约定 2.2 ARM-v8架构数据类型的约定 3、CPU内部寄存器 4、特殊寄存器 4.1 SP寄存器 4.2 LR寄存器 4.3 PC寄存器 二、汇编 1、汇编指令&#xff08;常用&#xff09; 2、C函数的…...

DWG转PDF字体研究记录

1.前言 最近需要对PDF中的符合业务规则的文字进行提取&#xff0c;发现有些文字不是文字信息形式存储&#xff0c;而是polyline形式表达&#xff0c;意味着仅仅有形体上的表达&#xff0c;丢失了原本的文字信息。 经过沟通得知&#xff0c;这些PDF是AutoCAD软件导出的&#xf…...

Java中如何处理日期和时间?

Java中如何处理日期和时间&#xff1f; 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将探讨如何在Java中处理日期和时间&#xff0c;这是开发中非常常…...

Kubernetes之Pod详解

如何更好的使用好Pod&#xff1f;本文尝试从Pod组成、Namespace共享、控制器实现原理及Pod设计原则4个方面对Pod的使用进行详细阐述&#xff0c;希望对您 一、 Kubernetes Pod介绍 在 Kubernetes 中&#xff0c;Pod 是最小的可部署单元&#xff0c;包含一个或多个容器。Pod 提…...

长亭谛听教程部署和详细教程

PPT 图片先挂着 挺概念的 谛听的能力 hw的时候可能会问你用过的安全产品能力能加分挺重要 溯源反制 反制很重要感觉很厉害 取证分析 诱捕牵制 其实就是蜜罐 有模板直接爬取某些网页模板进行伪装 部署要求 挺低的 对linux内核版本有要求 需要root 还有系统配置也要修改 …...

修复漏洞Windows 2012 Server R2(CVE-2016-2183)、(CVE-2015-2808)、(CVE-2013-2566)

修复漏洞 漏洞风险等级评定标准主机风险等级评定标准漏洞概括利用注册表修复漏洞查看修复后的漏洞漏洞风险等级评定标准 危险程度危险值区域危险程度说明高7 <=漏洞风险值<= 10攻击者可以远程执行任意命令或者代码,或对系统进行远程拒绝服务攻击。中4 <=漏洞风险值&l…...

Linux的基本指令第二篇

1.cat - 查看文件 语法&#xff1a;cat [选项] [文件] 功能&#xff1a; 查看目标文件的内容 -b 对非空输出行编号 -n对输出的所有行编号 -s不输出多行空行 现有一个文件test.c cat -n test.c cat -b test.c cat -s test.c 创建一个新文件 加入源文件的内容 || …...

php百度云账户余额查询API示例

1、官方文档地址&#xff1a;账户余额查询 请求结构 POST /v{version}/finance/cash/balance HTTP/1.1 Host: billing.baidubce.com ContentType: application/json; charsetutf-8 Content-Length: <Content_Length> Authorization: authorization string 响应参数 …...

自动化开发任务:在PHP框架中实现自定义命令

在现代Web开发中&#xff0c;自动化是提高开发效率和减少重复工作的关键。PHP框架&#xff0c;如Laravel、Symfony等&#xff0c;提供了强大的自定义命令功能&#xff0c;允许开发者创建自己的artisan命令来执行各种自动化任务。本文将详细介绍如何在PHP框架中实现自定义命令&a…...

如何在Java中实现数据加密与解密?

如何在Java中实现数据加密与解密&#xff1f; 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将探讨如何在Java中实现数据加密与解密&#xff0c;这是保…...

Nginx日志管理之日志分析

Nginx 通常被置于服务器访问的入口&#xff0c;其访问日志可以全局记录用户访问的来源、响应时间&#xff0c;以及用户行为热点等数据&#xff0c;通过对访问日志的分析&#xff0c;可以清晰地了解用户来源、用户行为习惯及自身服务器性能等情况。借助 ELK 的高性能处理能力&am…...

利用 Microsoft ChatGPT 和 OPC UA 改变工业格局

在本文中&#xff0c;我们将探讨开放性在工业物联网中的作用&#xff0c;以及Microsoft为创建基于OPC UA的开放平台所做的努力。我们将讨论 Microsoft 开放战略的四大支柱&#xff0c;以及标准化信息模型以实现互操作性的重要性。此外&#xff0c;我们将深入探讨传统接口和数据…...

力扣-两数之和

文章目录 题目题解方法1-暴力方法2-哈希 题目 原题链接&#xff1a;两数之和 题解 方法1-暴力 我最先想到的方法就是暴力&#xff0c;两层for循环&#xff0c;也能通过。&#xff08;拿到算法题在没有思路的时候暴力就是思路&#xff0c;哈哈哈&#xff09; public class T…...

基于CDMA的多用户水下无线光通信(3)——解相关多用户检测

继续上一篇博文&#xff0c;本文将介绍基于解相关的多用户检测算法。解相关检测器的优点是因不需要估计各个用户的接收信号幅值而具有抗远近效应的能力。常规的解相关检测器有运算量大和实时性差的缺点&#xff0c;本文针对异步CDMA的MAI主要来自干扰用户的相邻三个比特周期的特…...

哔哩哔哩视频URL解析原理

哔哩哔哩视频URL解析原理 视频网址解析视频的原理通常涉及以下几个步骤&#xff1a; 1、获取视频页面源代码&#xff1a;通过HTTP请求获取视频所在网页的HTML源代码。这一步通常需要处理反爬虫机制&#xff0c;如验证码或用户登录。 2、解析页面源代码&#xff1a;分析HTML源代…...

个人成长的利器:复盘教你如何避免重蹈覆辙

前言 &#x1f4eb; 大家好&#xff0c;我是南木元元&#xff0c;热爱技术和分享&#xff0c;欢迎大家交流&#xff0c;一起学习进步&#xff01; &#x1f345; 个人主页&#xff1a;南木元元 最近忙着学习和工作&#xff0c;更新比较少&#xff0c;期间一直在思考如何才能快速…...

2025秋招NLP算法面试真题(一)-史上最全Transformer面试题

史上最全Transformer面试题 Transformer为何使用多头注意力机制&#xff1f;&#xff08;为什么不使用一个头&#xff09;Transformer为什么Q和K使用不同的权重矩阵生成&#xff0c;为何不能使用同一个值进行自身的点乘&#xff1f; &#xff08;注意和第一个问题的区别&#…...

基于STM32的智能家居安防系统

目录 引言环境准备智能家居安防系统基础代码实现&#xff1a;实现智能家居安防系统 4.1 数据采集模块4.2 数据处理与分析4.3 控制系统实现4.4 用户界面与数据可视化应用场景&#xff1a;智能家居安防管理与优化问题解决方案与优化收尾与总结 1. 引言 智能家居安防系统通过使…...

React+TS前台项目实战(十二)-- 全局常用组件Toast封装,以及rxjs和useReducer的使用

文章目录 前言Toast组件1. 功能分析2. 代码详细注释&#xff08;1&#xff09;建立一个reducer.ts文件&#xff0c;用于管理状态数据&#xff08;2&#xff09;自定义一个清除定时器的hook&#xff08;3&#xff09;使用rxjs封装全局变量管理hook&#xff08;4&#xff09;在to…...

總結光學(完)

參考: 陈曦<<光学讲义>>http://ithatron.phys.tsinghua.edu.cn/downloads/optics.pdf 1 波动光学 最简单的一种波是平面波。........... 一个波的波前是指相位相同的点构成的面。波的传播方向垂直于波面。 我们在此将讨论的光波特指波长远大于原子尺度又远小于…...

线程C++

#include <thread> #include <chrono> #include <cmath> #include <mutex> #include <iostream> using namespace std;mutex mtx; void threadCommunicat() {int ans 0;while (ans<3){mtx.lock();//上锁cout << "ans" <…...

DAMA学习笔记(二)-数据治理

1.引言 数据治理&#xff08;Data Governance&#xff0c;DG&#xff09;的定义是在管理数据资产过程中行使权力和管控&#xff0c;包括计划、监控和实施。在所有组织中&#xff0c;无论是否有正式的数据治理职能&#xff0c;都需要对数据进行决策。建立了正式的数据治理规程及…...

07-appium常用操作

一、press_keycode 1&#xff09;方法说明 press_keycode方法是appium的键盘相关函数&#xff0c;可以实现键盘的相关操作&#xff0c;比如返回、按键、音量调节等等。也可以使用keyevent方法&#xff0c;功能与press_keycode方法类似。 常见按键编码&#xff1a;https://www.…...

使用lua开发apisix自定义插件并发布

接到老大需求&#xff1a;需要对cookie进行操作&#xff0c;遂查询apisix的自带插件&#xff0c;发现有&#xff0c;但不满足&#xff0c;于是自己开发了一个插件并部署&#xff0c;把开发部署流程写在这里打个日志怕以后忘掉。 一、需求 插件很简单&#xff0c;就是在reques…...

43 mysql insert select 的实现

前言 我们这里 来探讨一下 insert into $fields select $fields from $table; 的相关实现, 然后 大致来看一下 为什么 他能这么快 按照 我的思考, 应该里里面有 批量插入才对, 但是 调试结果 发现令我有一些意外 呵呵 果然 只有调试才是唯一的真理 测试数据表如下 CREATE…...

趣味学Python,快速上手神奇的itertools库!

大家好&#xff0c;我是菜哥&#xff01; 在学习Python编程的过程中&#xff0c;我们经常会使用到一些非常有用的标准库&#xff0c;它们不仅可以让我们的代码更加简洁高效&#xff0c;还能帮我们解决很多复杂的问题。Python标准库为我们提供了大量实用的工具和模块&#xff0c…...