RabbitMQ运维
RabbitMQ运维
- 一.集群
- 1.简单介绍
- 2.集群的作用
- 二.搭建集群
- 1.多机多节点
- 搭建步骤
- 2.单机单节点
- 搭建步骤
- 3.宕机演示
- 三.仲裁队列
- 1.简单介绍
- 2.Raft协议
- Raft基本概念
- 主节点选举
- 选举过程
- 3.仲裁队列的使用
- 四.HAProxy负载均衡
- 1.安装HAProxy
- 2.HAProxy的使用
一.集群
1.简单介绍
RabbitMQ 集群是 RabbitMQ 实现高可用性(HA)、负载均衡和横向扩展的核心机制。
2.集群的作用
RabbitMQ集群允许消费者和生产者在RabbitMQ单个节点崩溃的情况下继续运,它可以通过添加更多的节点来线性地扩展消息通信的吞吐量。
当失去⼀个RabbitMQ节点时,客户端能够重新连接到集群中的任何其他节点并继续生产或者消费.
二.搭建集群
1.多机多节点
RabbitMQ集群对延迟非常敏感,所以搭建RabbitMQ集群时,多个节点应当在同⼀个局域网内。
因为需要多台机器进行演示,所以学生党(不宽裕)的话就不要去搞这个了,成本有点高,在网上认识一下就好了。
搭建步骤
使用3台局域网的云服务器进行搭建
- 3台机器都将RabbitMQ进行安装(安装都是一样的)
- 配置每个节点的hosts文件
- 配置Erlang Cookie
- 构建集群
这里不详细对多机多节点进行介绍,毕竟吃拼好饭的我,怎么留得住多台云服务器。
2.单机单节点
需要注意的是,单机单节点是通过伪集群的方式,如果机器挂了,就全部挂了,生产环境是不会使用这个的。
搭建步骤
- RabbitMQ的安装(已安装,不懂的可以去RabbitMQ简单介绍和安装)
- 单机启动两个节点
| Node name | AMQP协议端口号 | Web管理界面端口 |
|---|---|---|
| rabbit2 | 5673 | 15673 |
| rabbit3 | 5672 | 15674 |
启动命令:
RABBITMQ_NODE_PORT=5673 RABBITMQ_SERVER_START_ARGS=“-rabbitmq_management
listener [{port,15673}]” RABBITMQ_NODENAME=rabbit2 rabbitmq-server -detached
RABBITMQ_NODE_PORT=5674 RABBITMQ_SERVER_START_ARGS=“-rabbitmq_management
listener [{port,15674}]” RABBITMQ_NODENAME=rabbit3 rabbitmq-server -detached
- 停止服务器并重置
rabbitmqctl -n rabbit2 stop_app
rabbitmqctl -n rabbit2 reset
rabbitmqctl -n rabbit3 stop_app
rabbitmqctl -n rabbit3 reset
- 把节点加入到集群当中
rabbitmqctl -n rabbit2 join_cluster rabbit@node Name
主节点的node Name,可以通过 rabbitmqctl status 查询
rabbitmqctl -n rabbit3 join_cluster rabbit@node Name
- 重启rabbit2和rabbit3
rabbitmqctl -n rabbit2 start_app
rabbitmqctl -n rabbit3 start_app

- 查看集群的状态
rabbitmqctl cluster_status -n rabbit
3.宕机演示
节点关闭之前:

节点关闭之后:
关闭节点的命令:rabbitmqctl -n rabbit stop_app
此时关闭节点的集群已经不在运行了,并且消息也丢失了。


三.仲裁队列
1.简单介绍
RabbitMQ 的仲裁队列是⼀种基于 Raft ⼀致性算法实现的持久化、复制的FIFO队列。仲裁队列提供队列复制的能力,保障数据的高可用和安全性。使用仲裁队列可以在RabbitMQ节点间进行队列数据的复制,从而达到在⼀个节点宕机时,队列仍然可以提供服务的效果。
2.Raft协议
Raft 是⼀种用于管理和维护分布式系统⼀致性的协议,它是⼀种共识算法,旨在实现高可用性和数据的持久性。
Raft通过在节点间复制数据来保证分布式系统中的⼀致性,即使在节点故障的情况下也能保证数据不会丢失。
共识算法(Consensus Algorithm)能够保证多个副本之间的⼀致性,它允许多个分布式节点就某个值或⼀系列值达成⼀致性协议。即使在⼀些节点发生故障,网络分区或其他问题的情况下,共识算法也能保证系统的⼀致性和数据的可靠性。
共识算法
- Paxos: ⼀种经典的共识算法,基于解决分布式系统中的⼀致性问题。
- Raft:⼀种较新的共识算法,Paxos不易实现,raft是对Paxos算法的简化和改进,旨在易于理解和实现。
- Zab:ZooKeeper使用的共识算法,基于Paxos算法,大部分和Raft相同,主要区别是对于Leader的任期,Raft叫做term,Zab叫做epoch,状态复制的过程中,raft的心跳从Leader向Follower发送,而ZAB则相反。
- Gossip:Gossip算法每个节点都是对等的,即没有角色之分。Gossip算法中的每个节点都会将数据改动告诉其他节点(类似传八卦)
Raft基本概念
Raft使⽤Quorum机制来实现共识和容错,我们将对Raft集群的操作必须得到大多数(>N/2)节点的同意才能提交。
Raft集群读写操作内部发生的情况
Raft集群必须存在⼀个主节点(Leader),客户端向集群发起的所有操作都必须经由主节点处理。所以Raft核心算法中的第⼀部分就是选主(Leader election)。没有主节点集群就无法工作,先选出⼀个主节点,再考虑其它事情。
主节点会负责接收客户端发过来的操作请求,将操作包装为日志同步给其它节点,在保证⼤部分节点都同步了本次操作后,就可以安全地给客户端回应响应了。这⼀部分工作在Raft核心算法中叫日志复制(Log replication).
因为主节点的责任非常大,所以只有符合条件的节点才可以当选主节点。为了保证集群对外展现的⼀致性,主节点在处理操作日志时,也⼀定要谨慎,这部分在Raft核心算法中叫
安全性(Safety).
Raft算法将⼀致性问题分解为三个子问题: Leader选举,日志复制和安全性.
主节点选举
在Raft算法中,每个节点都处于以下三种角色之⼀
- Leader(领导者):负责处理所有客户请求,并将这些请求作为日志项复制到所有Follower。Leader定期向所有Follower发送心跳消息,以维持其领导者地位,防止Follower进入选举过程。
- Follower(跟随者) :接收来自Leader的日志条目,并在本地应用这些条目。跟随者不直接处理客户请求。
- Candidate(候选者) 当跟随者在⼀段时间内没有收到来自Leader的心跳消息时,它会变得不确定Leader是否仍然可用。在这种情况下,跟随者会转变角色成为Candidate,并开始尝试通过投票过程成为新的Leader。
在正常情况下,集群中只有⼀个Leader,剩下的节点都是follower,下图展示了这些状态和它们之间的转换关系:

可以看出所有节点在启动时,都是follow状态,在⼀段时间内如果没有收到来自leader的心跳,从follower切换到candidate,发起选举。如果收到多数派(majority)的投票(含自己的⼀票)则切换到leader状态。Leader⼀般会⼀直工作直到它发生异常为止。
任期
Raft将时间划分成任意长度的任期(term)。每⼀段任期从⼀次选举开始,在这个时候会有⼀个或者多个candidate尝试去成为leader。在成功完成⼀次leaderelection之后,⼀个leader就会⼀直节管理集群直到任期结束。
在某些情况下,⼀次选举无法选出leader,这个时候这个任期会以没有leader而结束。同时⼀个新的任期(包含⼀次新的选举)会很快重新开始。

Term更像是⼀个逻辑时钟(logic clock)的作用,有了它,就可以发现哪些节点的状态已经过期。每⼀个节点都保存⼀个current term,在通信时带上这个term的值。
每⼀个节点都存储着⼀个当前任期号(current term number)。该任期号会随着时间单调递增。
节点之间通信的时候会交换当前任期号,如果⼀个节点的当前任期号比其他节点小,那么它就将自己的任期号更新为较大的那个值,如果⼀个candidate或者leader发现自己的任期号过期了,它就会立刻回到follower状态。
如果⼀个节点接收了⼀个带着过期的任期号的请求,那么它会拒绝这次请求。Raft算法中服务器节点之间采⽤RPC进行通信,主要有两类RPC请求:
- RequestVoteRPCs:请求投票,由candidate在选举过程中发出。
- AppendEntriesRPCs:追加条目,由leader发出用来做日志复制和提供心跳机制
选举过程
Raft采用⼀种心跳机制来触发leader选举,当服务器启动的时候,都是follow状态。如果follower在electiontimeout内没有收到来自leader的心跳(可能没有选出leader,也可能leader挂了,或者leader与follower之间网络故障),则会主动发起选举。
所有节点处于follower状态:
- 率先超时的节点,自增当前任期号然后切换为candidate态,并投自己⼀票。
- 以并行的放式发送一个RequestVote RPCs 给集群中的其他服务器节点(企图得到它们的投票)
- 等待其他节点的回复

S3节点率先超时,把任期号改成2,切换为candidate状态,发起投票请求,并给自己投一票

- 赢得选举成为Leader(包括自己的⼀票)
- 其他节点赢得了选举,它自行切换到follower
- ⼀段时间内没有收到majority投票,保持candidate状态,重新发出选举
投票要求:
• 每⼀个服务器节点会按照先来先服务原则(first-come-first-served)只投给⼀个 candidate.
• 候选人知道的信息不能比自己的少
第1种情况: 赢得了选举之后,新的leader会立刻给所有节点发消息,广而告之,避免其余节点触发新的选举。
S3节点应赢得多数投票,广而告之:

第2种情况: 比如有三个节点A B C, A B同时发起选举,而A的选举消息先到达C,C给A投了⼀票,当B的消息到达C时,已经不能满足上面提到的第⼀个约束,即C不会给B投票,这时候A就胜出了。
A胜出之后,会给B,C发⼼跳消息,节点B发现节点A的term不低于自己的term,知道有已经有Leader了,于是把自己转换成follower.
S1收到S3的心跳信息,发现S3的term不低于自己,就知道已经有leader了,将自己切换成follower:

第3种情况: 没有任何节点获得majority投票。比如所有的follower同时变成candidate,然后它们都将票投给自己,那这样就没有candidate能得到超过半数的投票了。
当这种情况发生的时候,每个candidate都会进行一次超时响应,然后通过自增任期号来开启⼀轮新的选举,并启动另⼀轮的RequestVoteRPCs。如果没有额外的措施,这种无结果的投票可能会无限重复下去。
S1-S5都在参与选举,每个节点都投给自己,如果超时,会重复发起新一轮的选举

为了解决上述问题,Raft采用随机选举超时时间(randomized election timeouts)来确保很少产⽣无结果的投票,并且就算发⽣了也能很快地解决。
为了防止选票⼀开始就被瓜分,选举超时时间是从⼀个固定的区间(比如,150-300ms)中随机选择。
这样可以把服务器分散开来以确保在⼤多数情况下会只有⼀个服务器率先结束超时,那么这个时候,它就可以赢得选举并在其他服务器结束超时之前发送⼼跳。
Raft动画演示在线地址
日志复制
每个仲裁队列都有多个副本,它包含⼀个主和多个从副本。replication factor 为 5的仲裁队列将会有1个
主副本和4个从副本。
每个副本都在不同的RabbitMQ节点上客户端(生产者和消费者)只会与主副本进行交互,主副本再将这些命令复制到从副本。当主副本所在的节点下线,其中一个从副本会被选举成为主副本,继续提供服务。

消息复制和主副本选举的操作,需要超过半数的副本同意。当生产者发送⼀条消息,需要超过半数的队列副本都将消息写入磁盘以后才会向生产者进行确认,这意味着少部分比较慢的副本不会影响整个队列的性能。
3.仲裁队列的使用
- 使用Spring框架创建仲裁队列
Producer
@RequestMapping("/quorum")public String quorum() {rabbitTemplate.convertAndSend("","quorum.queue","quorum test....");return "quorum is ok!";}
Configuration
@Configuration
public class OpsConfiguration {@Bean("quorumQueue")public Queue quorumQueue() {return QueueBuilder.durable("quorum.queye").quorum().build();}
}


- 在管理页面创建仲裁队列
Node是leader



此时停止其中一个主节点,此时消息还是存在,不会直接消失,并且会重新选举leader:
先给queue2中创建一个消息:



重新启动原来的leader后,就会有2个follower了:

仲裁队列,是RabbitMQ从3.8.0版本引⼊的新的队列类型,Quorum相比Classic在分布式环境下对消息的可靠性保障更高。
普通队列只会存放在集群中的⼀个节点上,虽然通过其它节点也可以访问普通队列,但是其它节点只是把请求转发到队列所在的节点进行操作。⼀旦队列所在节点宕机,队列中的消息就会丢失,因此普通集群只是提高了并发能⼒力,并未实现高可用。
仲裁队列可以极大的保障RabbitM集群对接的高可用。
四.HAProxy负载均衡
这时候就存在两个问题:
- 如果我们访问的是node1,但是node1挂了,咱们的程序也会出现问题,所以最好是有⼀个统⼀的入口,⼀个节点故障时,流量可以及时转移到其他节点。
- 如果所有的客户端都与node1建议连接,那么node1的网络负载必然会大大增加,而其他节点又由于没有那么多的负载而造成硬件资源的浪费,这时候负载均衡显得尤其重要。

这里主要讨论的是如何有效地对RabbitMQ集群使⽤软件负载均衡技术,目前主流的方式有在客户端内
部实现负载均衡,或者使用HAProxy、LVS等负载均衡有软件来实现。这里讲⼀下使用HAProxy来实现负载均衡。
1.安装HAProxy
HAProxy(High Availability Proxy)是⼀个开源的负载均衡器和TCP/HTTP应用程序的代理服务器,它被设计用来提供高可用性,负载均衡和代理功能。HAProxy主要用于分发网络流量到多个后端服务器,以提高网络的可靠性和性能。
-
更新数据包sudo apt-get update

-
查找HAProxy:sudo apt list|grep haproxy

-
安装HAProxy:sudo apt-get install haproxy

-
验证状态:

-
查看版本:haproxy -v

-
需要Proxy服务器自启动则使用:sudo systemctl enable haproxy

-
通过vi /etc/haproxy/haproxy.cfg修改haproxy.cfg文件:
#haproxy web 管理界⾯
listen stats #设置⼀个监听器, 统计HAProxy的统计信息
bind *:8100 #指定了监听器绑定到的IP地址和端⼝
mode http #监听器的⼯作模式为HTTP
stats enable #启⽤统计⻚⾯
stats realm Haproxy\ Statistics
stats uri /
stats auth admin:admin #haproxy登录账号和密码
#配置负载均衡
listen rabbitmq #设置监听器
bind *:5670 #监听器绑定到的IP地址和端⼝, 也就是集群前端IP, 供producer和consumer
来进⾏选择,由于5672端⼝已经默认使⽤, 这⾥选择5670端⼝
mode tcp #由于RabbitMQ使⽤AMQP协议,它是⼀个基于TCP的协议,所以这⾥使⽤TCP模
balance roundrobin #指定负载均衡策略为轮询
#负载均衡中的集群节点配置,这⾥选择的rabbit节点
server rabbitmq1 127.0.0.1:5672 check inter 5000 rise 2 fall 3
server rabbitmq2 127.0.0.1:5673 check inter 5000 rise 2 fall 3
server rabbitmq3 127.0.0.1:5674 check inter 5000 rise 2 fall 3
- 配置完后,重启HAProxy:sudo systemctl restart haproxy
页面:

2.HAProxy的使用
yml文件的配置

Configuration
@Bean("clusterQueue")public Queue clusterQueue() {return QueueBuilder.durable("cluster.queye").quorum().build();}
Producer
@RequestMapping("/cluster")public String cluster() {rabbitTemplate.convertAndSend("","cluster.queue","cluster test....");return "cluster is ok!";}
相关文章:
RabbitMQ运维
RabbitMQ运维 一.集群1.简单介绍2.集群的作用 二.搭建集群1.多机多节点搭建步骤 2.单机单节点搭建步骤 3.宕机演示 三.仲裁队列1.简单介绍2.Raft协议Raft基本概念主节点选举选举过程 3.仲裁队列的使用 四.HAProxy负载均衡1.安装HAProxy2.HAProxy的使用 一.集群 1.简单介绍 Ra…...
Ansible 实战:Roles,运维的 “魔法函数”
一、介绍 你现在已经学过tasks和handlers,那么,最好的playbook组织方式是什么呢?答案很简单:使用roles!roles基于一种已知的文件结构,能够自动加载特定的vars_files、tasks以及handlers。通过roles对内容进…...
CVAT安装和使用(Windows)
必要组件安装 WSL2 Docker Git Chrome Install WSL2 (Windows subsystem for Linux) refer to this official guide. WSL2 requires Windows 10, version 2004 or higher. After installing WSL2, install a Linux Distribution of your choice. 安装 WSL2(适用…...
Spring 中的 bean 生命周期
🌱 一、什么是 Bean 生命周期? 在 Spring 容器中,一个 Bean 从“创建 → 初始化 → 使用 → 销毁”,经历了完整的生命周期。 Spring 提供了 多个扩展点 让你可以在这些阶段做事情,比如注入资源、日志记录、连接资源、清…...
关于JVM和OS中的指令重排以及JIT优化
关于JVM和OS中的指令重排以及JIT优化 前言: 这东西应该很重要才对,可是大多数博客都是以讹传讹,全是错误,尤其是JVM会对字节码进行重排都出来了,明明自己测一测就出来的东西,写出来误人子弟… 研究了两天&…...
微软推出首款量子计算芯片Majorana 1
全球首款拓扑架构量子芯片问世,2025年2月20日,经过近20年研究,微软推出了首款量子计算芯片Majorana 1,其宣传视频如本文末尾所示。 微软表示,开发Majorana 1需要创造一种全新的物质状态,即所谓的“拓扑体”…...
数组练习题总结
一、求出数组中的最大值let arr [1, 2, 5, 7];let max 0;for (i 0; i < arr.length; i) {// console.log(max);if (max < arr[i]) {max arr[i];}}console.log(max); 首先生成一个数组,设一个变量为保存最大值,写一个循环,在循环里写…...
Kotlin 中的 `reified` 关键字全解析:保留类型信息 + 优化高阶函数的双重魔法
在使用 Kotlin 编写泛型函数时,你是否遇到过这样的尴尬:你想判断某个对象是不是泛型类型 T,结果却发现代码根本编译不过?这是因为 Kotlin 和 Java 一样,泛型在运行时会被类型擦除。 为了解决这个问题,Kotl…...
在CPU服务器上部署Ollama和Dify的过程记录
在本指南中,我将详细介绍如何在CPU服务器上安装和配置Ollama模型服务和Dify平台,以及如何利用Docker实现这些服务的高效部署和迁移。本文分为三大部分:Ollama部署、Dify环境配置和Docker环境管理,适合需要在本地或私有环境中运行A…...
【计网】TCP 协议详解 与 常见面试题
三次握手、四次挥手的常见面试题 不用死记,只需要清楚三次握手,四次挥手的流程,回答的时候心里要记住,假设网络是不可靠的 问题(1):为什么关闭连接时需要四次挥手,而建立连接却只要三次握手? 关…...
Java 基础-31-枚举-认识枚举
在Java编程语言中,枚举(Enum)是一种特殊的类,它允许一组固定的常量。它们非常适合用来表示一组固定的值,比如星期几、季节、颜色等。枚举自Java 5开始引入,为定义常量提供了一种更强大和方便的方式。本文将…...
7.4 SVD 的几何背景
一、SVD 的几何解释 SVD 将矩阵分解成三个矩阵的乘积: ( 正交矩阵 ) ( 对角矩阵 ) ( 正交矩阵 ) (\pmb{正交矩阵})\times(\pmb{对角矩阵})(\pmb{正交矩阵}) (正交矩阵)(对角矩阵)(正交矩阵),用几何语言表述其几何背景: ( 旋转 ) ( 伸缩 )…...
低延迟云网络的核心技术
低延迟云网络通过架构优化、协议创新、硬件加速等多维度技术手段,将数据传输延迟降低至毫秒级甚至微秒级。 1. 网络架构优化 1.1 扁平化网络Leaf-Spine 架构 减少网络层级,缩短数据转发路径(如数据中心内部一跳可达)。 扁平化网络Leaf-Spine(叶子-脊椎)架构是一种现代…...
C++的多态-上
目录 多态的概念 多态的定义及实现 1.虚函数 2. 多态的实现 2.1.多态构成条件 2.2.虚函数重写的两个例外 (1)协变(基类与派生类虚函数返回值类型不同) (2)析构函数的重写(基类与派生类析构函数的名字不同) 2.3.多态的实现 2.4.多态在析构函数中的应用 2.5.多态构成条…...
内存与显存:从同根生到殊途异路的科技演进
在现代计算机的世界里,内存和显存是两个不可或缺的硬件组件。它们看似功能相近,却在发展历程中逐渐分道扬镳,各自服务于不同的计算需求。今天,我们将从一根内存条和一块显卡入手,深入探讨内存与显存的异同,…...
手搓多模态-04 归一化介绍
在机器学习中,归一化是一个非常重要的工具,它能帮助我们加速训练的速度。在我们前面的SiglipVisionTransformer 中,也有用到归一化层,如下代码所示: class SiglipVisionTransformer(nn.Module): ##视觉模型的第二层&am…...
【C++】第八节—string类(上)——详解+代码示例
hello,又见面了! 云边有个稻草人-CSDN博客 C_云边有个稻草人的博客-CSDN博客——C专栏(质量分高达97!) 菜鸟进化中。。。 目录 一、为什么要学习string类? 1.1 C语言中的字符串 1.2 面试题(暂不做讲解) …...
Java 数组与 ArrayList 核心区别解析:从源码到实战!!!
🌟 Java 数组与 ArrayList 核心区别解析:从源码到实战 💡 Java 开发者必读! 数组(Array)和 ArrayList 是 Java 中最常用的数据存储结构,但它们的底层设计、性能表现和适用场景差异显著。本文通…...
【易飞】易飞批量选择品号处理方法,工作效率提升300%
开窗选择品号方式要么手动输入,要么以什么开头、包含、从A物料到B物料查询后返回的有规律的品号。对于没有规律且大量品号的处理方式是否有便捷的方法呢? 尤其在通常在查询多阶材料清单,查询库存明细表,整批变更元件等如品号无规律情况下,只能一个个选择,无法通过EXCEL方…...
【最新版】啦啦外卖v64系统独立版源码+全部小程序APP端+安装教程
一.系统介绍 啦啦外卖跑腿平台独立版,使用的都知道该系统功能非常强大,应该说是目前外卖平台功能最全的一套系统。主要是功能非常多,拿来即用,包括客户端小程序、配送端小程序、商户端小程序,还有对应四个端的APP源码…...
iproute2 工具集使用详解
目录 一、iproute2 核心命令:ip二、常用功能详解1. 管理网络接口(link 对象)2. 管理 IP 地址(address 对象)3. 管理路由表(route 对象)4. 管理 ARP 和邻居缓存(neigh 对象࿰…...
项目总结之常问的一些问题
1.项目功能介绍,重难点 重难点: mock工具使用(涉及到的三方接口过多,由于网络等原因无法调通,所以测试的时候,采用mock工具来模拟返回接口真正调用后响应数据) 2.项目负责哪部分?…...
C语言查漏补缺:占位符篇
占位符篇 1. 整数类型2. 字符类型3. 浮点数类型4. 指针类型5. 字符串6. 修饰符 1. 整数类型 %d / %i:用于 int(有符号十进制整数)。int num -42; printf("%d", num); // 输出: -42%u:用于 unsigned int(无…...
cut命令用法
cut 是 Linux/Unix 系统中一个用于按列提取文本内容的命令,常用于处理结构化文本(如 CSV、日志、配置文件等)。它通过分隔符、字符位置或字节位置来切割文本,提取指定部分。 核心功能 按字段(列)提取&#…...
java 正则表达式优化
1,什么是正则表达式 正则表达式使用一些特定的元字符来检索、匹配以及替换符合规则的字符串。 构造正则表达式语法的元字符,由普通字符、标准字符、限定字符(量词)、定位字符(边界字符)组成 普通字符 字母[…...
AD(Altium Designer)更换PCB文件的器件封装
一、确定是否拥有想换的器件PCB封装 1.1 打开现有的原理图 1.2 确定是否拥有想换的器件PCB文件 1.2.1 如果有 按照1.3进行切换器件PCB封装 1.2.2 如果没有 按照如下链接进行添加 AD(Altium Designer)已有封装库的基础上添加器件封装-CSDN博客https://blog.csdn.net/XU15…...
【文献研究】含硼钢中BN表面偏析对可镀性的影响
《B 添加钢的溶融 Zn めっき性に及ぼす BN 表面析出の影響》由JFE公司田原大輔等人撰写。研究聚焦 B 添加钢在低露点退火时 BN 形成对镀锌性的影响,对汽车用高强度钢镀锌工艺优化意义重大。通过多组对比实验,结合多种分析手段,明确了相关因素…...
React学习-css
W3Schools Tryit Editor CSS 教程 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明: p { /* 这是个注释 */ color:red; text-align:center; }选择器 CSS Id: #para1{ text-align:center; color:red; } Class: .center {text-align:center;} p…...
AIP-215 API特定proto
编号215原文链接AIP-215: API-specific protos状态批准创建日期2018-10-01更新日期2018-10-01 API通常使用API特定proto定义,偶尔依赖通用组件。保持API相互隔离可以避免版本问题和客户端库打包问题。 指南 所有特定于某个API的protos 必须 位于带有主版本号的包…...
C++ 获取一整行(一行)字符串并转换为数字
代码很简单,主要是自己总是忘记,记录一下: #include <iostream> #include <cstdlib> #include <cstring>#include <string> #include <vector> #include <sstream>using namespace std;void print_int_…...





