1. 各角色介绍

Producer:消息的发送者;举例:发信者

Consumer:消息接收者;举例:收信者

Broker:暂存和传输信息;举例:邮局

NameServer:管理Broker;举例:各个邮局的管理机构

Topic:区分消息的种类;一个发送者可以发送消息给一个或多个Topic;一个接收者可以订阅一个或多个Topic消息

Message Queue:相当于是Topic的分区;用于并行发送和接收消息

2. 集群搭建方式

2.1 集群特点

NameServer是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。

Broker部署相对复杂,Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master,Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。Master也可以部署多个。每个Broker与NameServer集群中的所有节点建立长连接,定时注册Topic信息到所有NameServer。

Producer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可集群部署。

Consumer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker配置决定。

2.2 集群模式

2.2.1 单Master模式

这种方式风险较大,一旦Broker重启或者宕机时,会导致整个服务不可用。不建议线上环境使用,可以用于本地测试。

上一篇采用的就是这种方式部署的:1 - 【RocketMQ 系列】CentOS 7.6 安装部署RocketMQ

https://note.youdao.com/s/9DXcH2gh

2.2.2 多Master模式

一个集群无Slave,全是Master,例如2个Master或者3个Master,这种模式的优缺点如下:

优点:配置简单,单个Master宕机或重启维护对应用无影响,在磁盘配置为RAID10时,即使机器宕机不可恢复情况下,由于RAID10磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢),性能最高;

缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到影响。

2.2.3 多Master多Slave模式-异步复制

每个Master配置一个Slave,有多对Master-Slave,HA采用异步复制方式,主备有短暂消息延迟(毫秒级),这种模式的优缺点如下:

优点:即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,同时Master宕机后,消费者仍然可以从Slave消费,而且此过程对应用透明,不需要人工干预,性能同多Master模式几乎一样;

缺点:Master宕机,磁盘损坏情况下会丢失少量消息。

2.2.4 多Master多Slave模式-同步双写

每个Master配置一个Slave,有多对Master-Slave,HA采用同步双写方式,即只有主备都写成功,才向应用返回成功,这种模式的优缺点如下:

优点:数据与服务都无单点故障,Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高;

缺点:性能比异步复制模式略低(大约低10%左右),发送单个消息的RT会略高,且目前版本在主节点宕机后,备机不能自动切换为主机。(4.5版本之后提供DLedger多副本模式可实现主从自动切换)

2.3 双主双从集群搭建

2.3.1 总体架构

消息高可用采用2m-2s(同步双写)方式

2.3.2 集群工作流程

启动NameServer,NameServer起来后监听端口,等待Broker、Producer、Consumer连上来,相当于一个路由控制中心。

Broker启动,跟所有的NameServer保持长连接,定时发送心跳包。心跳包中包含当前Broker信息(IP+端口等)以及存储所有Topic信息。注册成功后,NameServer集群中就有Topic跟Broker的映射关系。

收发消息前,先创建Topic,创建Topic时需要指定该Topic要存储在哪些Broker上,也可以在发送消息时自动创建Topic。

Producer发送消息,启动时先跟NameServer集群中的其中一台建立长连接,并从NameServer中获取当前发送的Topic存在哪些Broker上,轮询从队列列表中选择一个队列,然后与队列所在的Broker建立长连接从而向Broker发消息。

Consumer跟Producer类似,跟其中一台NameServer建立长连接,获取当前订阅Topic存在哪些Broker上,然后直接跟Broker建立连接通道,开始消费消息。

2.3.3 服务器环境

序号

IP(外/内)

角色

架构模式

1

81.71.157.232

172.16.0.8

nameserver、brokerserver

Master1、Slave2

2

106.55.35.2

172.16.0.2

nameserver、brokerserver

Master2、Slave1

服务器准备好了按照我上个教程配置好基础环境(安装 jdk1.8 、Maven 3.8.6 、RocketMQ 4.9.4)

https://note.youdao.com/s/9DXcH2gh

2.3.4 Host添加信息

vim /etc/hosts

在末尾加上配置内容如下:

# nameserver

81.71.157.232 rocketmq-nameserver1 # 9876

106.55.35.2 rocketmq-nameserver2 # 9876

# broker

81.71.157.232 rocketmq-master1 # 10910

81.71.157.232 rocketmq-slave2 # 10921

106.55.35.2 rocketmq-master2 # 10920

106.55.35.2 rocketmq-slave1 # 10911

配置完成后,重启网卡

systemctl restart network

2.3.5 安全组配置

为了安全只开放特定的端口号:9876(NameServer1 和 NameServer2)、10910(Master1)、10920(Master2)、10911(Slave1)、10921(Slave2)

2.3.6 环境变量配置

vim /etc/profile

在profile文件的末尾加入如下内容

# rocketmq

ROCKETMQ_HOME=/usr/local/rocketmq

PATH=$PATH:$ROCKETMQ_HOME/bin

export ROCKETMQ_HOME PATH

ESC 之后 输入 :wq! 回车保存并退出,再输入以下命令使得配置立刻生效:

source /etc/profile

2.3.7 创建消息存储路径

1号服务器:81.71.157.232

mkdir -p /usr/local/rocketmq/store/broker-a/commitlog

mkdir -p /usr/local/rocketmq/store/broker-a/consumequeue

mkdir -p /usr/local/rocketmq/store/broker-a/index

mkdir -p /usr/local/rocketmq/store/broker-b-s/commitlog

mkdir -p /usr/local/rocketmq/store/broker-b-s/consumequeue

mkdir -p /usr/local/rocketmq/store/broker-b-s/index

2号服务器 :106.55.35.2

mkdir -p /usr/local/rocketmq/store/broker-b/commitlog

mkdir -p /usr/local/rocketmq/store/broker-b/consumequeue

mkdir -p /usr/local/rocketmq/store/broker-b/index

mkdir -p /usr/local/rocketmq/store/broker-a-s/commitlog

mkdir -p /usr/local/rocketmq/store/broker-a-s/consumequeue

mkdir -p /usr/local/rocketmq/store/broker-a-s/index

2.3.8 broker配置文件

分别在2台服务器上执行以下命令,编辑 broker.conf 文件,红框部分改成对应服务器的外网IP

vim /usr/local/rocketmq/conf/broker.conf

2.3.8.1 master1

服务器:81.71.157.232 、172.16.0.8

vim /usr/local/rocketmq/conf/2m-2s-sync/broker-a.properties

修改配置如下:

#Broker服务地址

brokerIP1=81.71.157.232

#所属集群名字

brokerClusterName=rocketmq-cluster

#broker名字,注意此处不同的配置文件填写的不一样

brokerName=broker-a

#0 表示 Master,>0 表示 Slave

brokerId=0

#nameServer地址,分号分割

namesrvAddr=81.71.157.232:9876;106.55.35.2:9876

#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数

defaultTopicQueueNums=4

#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭

autoCreateTopicEnable=true

#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭

autoCreateSubscriptionGroup=true

#Broker 对外服务的监听端口

listenPort=10910

#删除文件时间点,默认凌晨 4点

deleteWhen=04

#文件保留时间,默认 48 小时

fileReservedTime=120

#commitLog每个文件的大小默认1G

mapedFileSizeCommitLog=1073741824

#ConsumeQueue每个文件默认存30W条,根据业务情况调整

mapedFileSizeConsumeQueue=300000

#destroyMapedFileIntervalForcibly=120000

#redeleteHangedFileInterval=120000

#检测物理文件磁盘空间

diskMaxUsedSpaceRatio=88

#存储路径

storePathRootDir=/usr/local/rocketmq/store/broker-a

#commitLog 存储路径

storePathCommitLog=/usr/local/rocketmq/store/broker-a/commitlog

#消费队列存储路径存储路径

storePathConsumeQueue=/usr/local/rocketmq/store/broker-a/consumequeue

#消息索引存储路径

storePathIndex=/usr/local/rocketmq/store/broker-a/index

#checkpoint 文件存储路径

storeCheckpoint=/usr/local/rocketmq/store/broker-a/checkpoint

#abort 文件存储路径

abortFile=/usr/local/rocketmq/store/broker-a/abort

#限制的消息大小

maxMessageSize=65536

#flushCommitLogLeastPages=4

#flushConsumeQueueLeastPages=2

#flushCommitLogThoroughInterval=10000

#flushConsumeQueueThoroughInterval=60000

#Broker 的角色

#- ASYNC_MASTER 异步复制Master

#- SYNC_MASTER 同步双写Master

#- SLAVE

brokerRole=SYNC_MASTER

#刷盘方式

#- ASYNC_FLUSH 异步刷盘

#- SYNC_FLUSH 同步刷盘

flushDiskType=SYNC_FLUSH

#checkTransactionMessageEnable=false

#发消息线程池数量

#sendMessageThreadPoolNums=128

#拉消息线程池数量

#pullMessageThreadPoolNums=128

2.3.8.2 slave2

服务器:81.71.157.232 、172.16.0.8

vim /usr/local/rocketmq/conf/2m-2s-sync/broker-b-s.properties

修改配置如下:

#Broker服务地址

brokerIP1=81.71.157.232

#所属集群名字

brokerClusterName=rocketmq-cluster

#broker名字,注意此处不同的配置文件填写的不一样

brokerName=broker-b

#0 表示 Master,>0 表示 Slave

brokerId=1

#nameServer地址,分号分割

namesrvAddr=81.71.157.232:9876;106.55.35.2:9876

#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数

defaultTopicQueueNums=4

#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭

autoCreateTopicEnable=true

#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭

autoCreateSubscriptionGroup=true

#Broker 对外服务的监听端口

listenPort=10921

#删除文件时间点,默认凌晨 4点

deleteWhen=04

#文件保留时间,默认 48 小时

fileReservedTime=120

#commitLog每个文件的大小默认1G

mapedFileSizeCommitLog=1073741824

#ConsumeQueue每个文件默认存30W条,根据业务情况调整

mapedFileSizeConsumeQueue=300000

#destroyMapedFileIntervalForcibly=120000

#redeleteHangedFileInterval=120000

#检测物理文件磁盘空间

diskMaxUsedSpaceRatio=88

#存储路径

storePathRootDir=/usr/local/rocketmq/store/broker-b-s

#commitLog 存储路径

storePathCommitLog=/usr/local/rocketmq/store/broker-b-s/commitlog

#消费队列存储路径存储路径

storePathConsumeQueue=/usr/local/rocketmq/store/broker-b-s/consumequeue

#消息索引存储路径

storePathIndex=/usr/local/rocketmq/store/broker-b-s/index

#checkpoint 文件存储路径

storeCheckpoint=/usr/local/rocketmq/store/broker-b-s/checkpoint

#abort 文件存储路径

abortFile=/usr/local/rocketmq/store/broker-b-s/abort

#限制的消息大小

maxMessageSize=65536

#flushCommitLogLeastPages=4

#flushConsumeQueueLeastPages=2

#flushCommitLogThoroughInterval=10000

#flushConsumeQueueThoroughInterval=60000

#Broker 的角色

#- ASYNC_MASTER 异步复制Master

#- SYNC_MASTER 同步双写Master

#- SLAVE

brokerRole=SLAVE

#刷盘方式

#- ASYNC_FLUSH 异步刷盘

#- SYNC_FLUSH 同步刷盘

flushDiskType=ASYNC_FLUSH

#checkTransactionMessageEnable=false

#发消息线程池数量

#sendMessageThreadPoolNums=128

#拉消息线程池数量

#pullMessageThreadPoolNums=128

2.3.8.3 master2

服务器:106.55.35.2、172.16.0.2

vim /usr/local/rocketmq/conf/2m-2s-sync/broker-b.properties

修改配置如下:

#Broker服务地址

brokerIP1=106.55.35.2

#所属集群名字

brokerClusterName=rocketmq-cluster

#broker名字,注意此处不同的配置文件填写的不一样

brokerName=broker-b

#0 表示 Master,>0 表示 Slave

brokerId=0

#nameServer地址,分号分割

namesrvAddr=81.71.157.232:9876;106.55.35.2:9876

#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数

defaultTopicQueueNums=4

#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭

autoCreateTopicEnable=true

#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭

autoCreateSubscriptionGroup=true

#Broker 对外服务的监听端口

listenPort=10920

#删除文件时间点,默认凌晨 4点

deleteWhen=04

#文件保留时间,默认 48 小时

fileReservedTime=120

#commitLog每个文件的大小默认1G

mapedFileSizeCommitLog=1073741824

#ConsumeQueue每个文件默认存30W条,根据业务情况调整

mapedFileSizeConsumeQueue=300000

#destroyMapedFileIntervalForcibly=120000

#redeleteHangedFileInterval=120000

#检测物理文件磁盘空间

diskMaxUsedSpaceRatio=88

#存储路径

storePathRootDir=/usr/local/rocketmq/store/broker-b

#commitLog 存储路径

storePathCommitLog=/usr/local/rocketmq/store/broker-b/commitlog

#消费队列存储路径存储路径

storePathConsumeQueue=/usr/local/rocketmq/store/broker-b/consumequeue

#消息索引存储路径

storePathIndex=/usr/local/rocketmq/store/broker-b/index

#checkpoint 文件存储路径

storeCheckpoint=/usr/local/rocketmq/store/broker-b/checkpoint

#abort 文件存储路径

abortFile=/usr/local/rocketmq/store/broker-b/abort

#限制的消息大小

maxMessageSize=65536

#flushCommitLogLeastPages=4

#flushConsumeQueueLeastPages=2

#flushCommitLogThoroughInterval=10000

#flushConsumeQueueThoroughInterval=60000

#Broker 的角色

#- ASYNC_MASTER 异步复制Master

#- SYNC_MASTER 同步双写Master

#- SLAVE

brokerRole=SYNC_MASTER

#刷盘方式

#- ASYNC_FLUSH 异步刷盘

#- SYNC_FLUSH 同步刷盘

flushDiskType=SYNC_FLUSH

#checkTransactionMessageEnable=false

#发消息线程池数量

#sendMessageThreadPoolNums=128

#拉消息线程池数量

#pullMessageThreadPoolNums=128

2.3.8.4 slave1

服务器:106.55.35.2、172.16.0.2

vim /usr/local/rocketmq/conf/2m-2s-sync/broker-a-s.properties

修改配置如下:

#Broker服务地址

brokerIP1=106.55.35.2

#所属集群名字

brokerClusterName=rocketmq-cluster

#broker名字,注意此处不同的配置文件填写的不一样

brokerName=broker-a

#0 表示 Master,>0 表示 Slave

brokerId=1

#nameServer地址,分号分割

namesrvAddr=81.71.157.232:9876;106.55.35.2:9876

#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数

defaultTopicQueueNums=4

#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭

autoCreateTopicEnable=true

#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭

autoCreateSubscriptionGroup=true

#Broker 对外服务的监听端口

listenPort=10911

#删除文件时间点,默认凌晨 4点

deleteWhen=04

#文件保留时间,默认 48 小时

fileReservedTime=120

#commitLog每个文件的大小默认1G

mapedFileSizeCommitLog=1073741824

#ConsumeQueue每个文件默认存30W条,根据业务情况调整

mapedFileSizeConsumeQueue=300000

#destroyMapedFileIntervalForcibly=120000

#redeleteHangedFileInterval=120000

#检测物理文件磁盘空间

diskMaxUsedSpaceRatio=88

#存储路径

storePathRootDir=/usr/local/rocketmq/store/broker-a-s

#commitLog 存储路径

storePathCommitLog=/usr/local/rocketmq/store/broker-a-s/commitlog

#消费队列存储路径存储路径

storePathConsumeQueue=/usr/local/rocketmq/store/broker-a-s/consumequeue

#消息索引存储路径

storePathIndex=/usr/local/rocketmq/store/broker-a-s/index

#checkpoint 文件存储路径

storeCheckpoint=/usr/local/rocketmq/store/broker-a-s/checkpoint

#abort 文件存储路径

abortFile=/usr/local/rocketmq/store/broker-a-s/abort

#限制的消息大小

maxMessageSize=65536

#flushCommitLogLeastPages=4

#flushConsumeQueueLeastPages=2

#flushCommitLogThoroughInterval=10000

#flushConsumeQueueThoroughInterval=60000

#Broker 的角色

#- ASYNC_MASTER 异步复制Master

#- SYNC_MASTER 同步双写Master

#- SLAVE

brokerRole=SLAVE

#刷盘方式

#- ASYNC_FLUSH 异步刷盘

#- SYNC_FLUSH 同步刷盘

flushDiskType=ASYNC_FLUSH

#checkTransactionMessageEnable=false

#发消息线程池数量

#sendMessageThreadPoolNums=128

#拉消息线程池数量

#pullMessageThreadPoolNums=128

2.3.9 服务启动

2.3.9.1 启动NameServer集群

分别在 81.71.157.232 和 106.55.35.2 启动 NameServer1 和 NameServer2

cd /usr/local/rocketmq/bin

nohup sh mqnamesrv &

jps

2.3.9.2 启动Broker集群

在 81.71.157.232 上启动 master1

在 106.55.35.2 上启动 slave1

在 106.55.35.2 上启动 master2

在 81.71.157.232 上启动 slave2

master1:

cd /usr/local/rocketmq/bin

nohup sh mqbroker -c /usr/local/rocketmq/conf/2m-2s-sync/broker-a.properties &

jps

slave1:

cd /usr/local/rocketmq/bin

nohup sh mqbroker -c /usr/local/rocketmq/conf/2m-2s-sync/broker-a-s.properties &

jps

master2:

cd /usr/local/rocketmq/bin

nohup sh mqbroker -c /usr/local/rocketmq/conf/2m-2s-sync/broker-b.properties &

jps

slave2:

cd /usr/local/rocketmq/bin

nohup sh mqbroker -c /usr/local/rocketmq/conf/2m-2s-sync/broker-b-s.properties &

jps

2.3.10 查看状态

分别在 81.71.157.232 和 106.55.35.2 执行以下命令:

jps

启动完成,分别在2台服务器查看集群信息:

sh mqadmin clusterlist -n 81.71.157.232:9876

sh mqadmin clusterlist -n 106.55.35.2:9876

或者执行以下命令:

sh mqadmin clusterlist -n localhost:9876

2.4 RocketMQ 仪表盘

按照上篇文章操作安装就行,链接地址:注意更改仪表盘端口(安全组端口开放),然后rocketmq.config.namesrvAddr配置项改成对应的外网IP

https://note.youdao.com/s/9DXcH2gh

2.4.1 访问仪表盘

http://81.71.157.232:8888/#/

http://106.55.35.2:8888/#/

到此部署完成!自启动服务可以按照我上篇文章的思路操作。https://note.youdao.com/s/9DXcH2gh

【RocketMQ 系列】 RocketMQ 双主双从(同步双写) 集群搭建的更多相关文章

  1. MySQL集群搭建(6)-双主+keepalived高可用

    双主 + keepalived 是一个比较简单的 MySQL 高可用架构,适用于中小 MySQL 集群,今天就说说怎么用 keepalived 做 MySQL 的高可用. 1 概述 1.1 keepa ...

  2. rocketmq 两主两从异步集群搭建

    1.安装JDK 需要先卸载系统默认的OPENJDK,安装 JDK1.8 64位的版本. 卸载open-jdk rpm -qa|grep java 查到open jdk的安装. 使用命令 rpm -e ...

  3. RocketMQ集群搭建(3m-3s-async)

    RocketMQ集群搭建(3m-3s-async) 各角色介绍 角色 作用 Producer 消息发送者,将消息发送到 Broker.无状态,其与NameServer集群中的一个节点建立长连接,定期从 ...

  4. RocketMQ集群搭建方式

    各角色介绍 Producer:消息的发送者:举例:发信者 Consumer:消息接收者:举例:收信者 Broker:暂存和传输消息:举例:邮局 NameServer:管理Broker:举例:各个邮局的 ...

  5. 分布式缓存技术redis学习系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  6. 大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 图文详解

    引言 在之前的大数据学习系列中,搭建了Hadoop+Spark+HBase+Hive 环境以及一些测试.其实要说的话,我开始学习大数据的时候,搭建的就是集群,并不是单机模式和伪分布式.至于为什么先写单 ...

  7. redis--主从同步,故障切换,集群搭建

    一 . redis主从同步 准备三个配置文件,实现一主两从的redis数据库结构(这三个配置文件仅仅端口不一样) # redis-6379.conf 文件, 写入下面数据: port 6379 dae ...

  8. 分布式缓存技术redis系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  9. .Net Core2.1 秒杀项目一步步实现CI/CD(Centos7.2)系列一:k8s高可用集群搭建总结以及部署API到k8s

    前言:本系列博客又更新了,是博主研究很长时间,亲自动手实践过后的心得,k8s集群是购买了5台阿里云服务器部署的,这个集群差不多搞了一周时间,关于k8s的知识点,我也是刚入门,这方面的知识建议参考博客园 ...

  10. redis系列之4----redis高级应用(集群搭建、集群分区原理、集群操作)

    文章主目录 Redis集群简介 Redis集群搭建 Redis集群分区原理 集群操作 参考文档 本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 ...

随机推荐

  1. nginx相关报错

    # openresty -s reloadnginx: [warn] conflicting server name "community-gw.xxx.cn" on 0.0.0. ...

  2. pod(四):pod的重启策略和生命周期

    目录 一.系统环境 二.前言 三.pod的重启策略 四.pod的生命周期 一.系统环境 服务器版本 docker软件版本 Kubernetes(k8s)集群版本 CPU架构 CentOS Linux ...

  3. linux下vim的使用以及高效率的技巧

    目录 一.关于vim编辑器 二.vim编辑器的模式 三.一般模式下的基础操作 四.V模式(列模式)的基础操作 五.命令模式下的基础操作 六.自定义vim环境 七.vim同时打开多个文件 八.比较两个文 ...

  4. jquery加载页面时触发事件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Linux运维面试总结

    1.Linux系统相关日志 /var/log/message:系统信息日志,包含错误信息 /var/log/secure:系统登录日志 /var/log/maillog:邮件日志 /var/log/c ...

  6. CSS操作——文本属性

    1.font-style(字体样式风格) /* 属性值: normal:设置字体样式为正体.默认值. italic:设置字体样式为斜体.这是选择字体库中的斜体字. oblique:设置字体样式为斜体. ...

  7. C#命令行参数解析库System.CommandLine介绍

    命令行参数 平常在日常的开发过程中,会经常用到命令行工具.如cmd下的各种命令. 以下为sc命令执行后的截图,可以看到,由于没有输入任何附带参数,所以程序并未执行任何操作,只是输出了描述和用法. 系统 ...

  8. ASP.NET Core SignalR 概述

    什么是 SignalR? ASP.NET Core SignalR 是一个开放源代码库,可用于简化向应用添加实时 Web 功能. 实时 Web 功能使服务器端代码能够将内容推送到客户端. 适合 Sig ...

  9. NOIP模拟91(多校24)

    T1 破门而入 解题思路 签到题(然而我数组开小直接变成暴力分...) 发现其实就是第一类斯特林数,然后 \(n^2\) 推就好了. 感觉可以用 NTT 优化成 \(nlogn\) ,但是好像并没有什 ...

  10. 【Effective C++】设计与声明——reference篇

    以pass-by-reference-to-const替换pass-by-value 缺省情况下C++以by value方式传递对象至(或来自)函数.除非你另外指定,否则函数参数都是以实际实参的复件( ...