RocketMQ 集群的搭建部署 以及rocketmq-console-ng仪表台的安装部署
在 RocketMQ 主要的组件如下。
NameServer
NameServer 集群,Topic 的路由注册中心,为客户端根据 Topic 提供路由服务,
从而引导客户端向 Broker 发送消息。NameServer 之间的节点不通信。
路由信息在 NameServer 集群中数据一致性采取的最终一致性。
Broker
消息存储服务器,分为两种角色:
Master 与 Slave,
在 RocketMQ 中,主服务承担读写操作,从服务器作为一个备份,当主服务器存在压力时,
从服务器可以承担读服务(消息消费)。所有 Broker,包含 Slave 服务器每隔 30s 会向 NameServer 发送心跳包,
心跳包中会包含存在在 Broker 上所有的 Topic 的路由信息。
Client
消息客户端,包括 Producer(消息发送者)和 Consumer(消费消费者)。
客户端在同一时间只会连接一台 NameServer,只有在连接出现异常时才会向尝试连接另外一台。
客户端每隔 30s 向 NameServer 发起 Topic 的路由信息查询。
温馨提示:NameServer 是在内存中存储 Topic 的路由信息,持久化 Topic 路由信息的地方是在 Broker 中,
即 ${ROCKETMQ_HOME}/store/config/topics.json。
在 RocketMQ 4.5.0 版本后引入了多副本机制,即一个复制组(m-s)可以演变为基于 Raft 协议的复制组,
复制组内部使用 Raft 协议保证 Broker 节点数据的强一致性,该部署架构在金融行业用的比较多。
消息订阅模型
在 RocketMQ 的消息消费模式采用的是发布与订阅模式。
Topic:一类消息的集合,消息发送者将一类消息发送到一个主题中,
例如订单模块将订单发送到 order_topic 中,而用户登录时,将登录事件发送到 user_login_topic 中。
ConsumerGroup:消息消费组,一个消费单位的“群体”,
消费组首先在启动时需要订阅需要消费的 Topic。一个 Topic 可以被多个消费组订阅,
同样一个消费组也可以订阅多个主题。一个消费组拥有多个消费者。
消费模式
在 RocketMQ 中支持广播模式与集群模式。
广播模式:一个消费组内的所有消费者每一个都会处理 Topic 中的每一条消息,通常用于刷新内存缓存。
集群模式:一个消费组内的所有消费者共同消费一个 Topic 中的消息,即分工协作,一个消费者消费一部分数据,启动负载均衡。
集群模式是非常普遍的模式,符合分布式架构的基本理念,即横向扩容,当前消费者如果无法快速及时处理消息时,
可以通过增加消费者的个数横向扩容,快速提高消费能力,及时处理挤压的消息。
在 MQ 领域有一个不成文的约定:同一个消费者同一时间可以分配多个队列,但一个队列同一时间只会分配给一个消费者。
RocketMQ 提供了众多的队列负载算法,其中最常用的两种平均分配算法。
AllocateMessageQueueAveragely:平均分配
AllocateMessageQueueAveragelyByCircle:轮流平均分配
温馨提示:如果 Topic 的队列个数小于消费者的个数,那有些消费者无法分配到消息。
在 RocketMQ 中一个 Topic 的队列数直接决定了最大消费者的个数,但 Topic 队列个数的增加对 RocketMQ 的性能不会产生影响。
Linux 常用的端口命令:
修改主机名:
vim /etc/hostname
修改IP地址:
cd /etc/sysconfig/network-scripts/
vim ifcfg-ens33 修改IP
# 关闭防火墙
systemctl stop firewalld.service
# 查看防火墙的状态
firewall-cmd --state
# 禁止firewall开机启动
systemctl disable firewalld.service
# 开放name server默认端口
firewall-cmd --remove-port=9876/tcp --permanent
# 开放master默认端口
firewall-cmd --remove-port=10911/tcp --permanent
# 开放slave默认端口 (当前集群模式可不开启)
firewall-cmd --remove-port=11011/tcp --permanent
# 重启防火墙
firewall-cmd --reload
在官网下载rocketmq 的二进制包,并上传至虚拟机
https://rocketmq.apache.org/release_notes/release-notes-4.9.3
RocketMQ服务搭建
下载RocketMQ源码 : Apache Download Mirrors
解压 :rocketmq-all-4.9.2-bin-release.zip
unzip rocketmq-all-4.9.2-bin-release.zip
如果没有 unzip 命令 安装 yum install unzip
进入机器a的目录
cd /usr/local/bin/rocketmq-all-4.9.3-bin-release/conf/2m-2s-sync
在机器a上配置broker-a的master节点
vim broker-a.properties
内容:
#所属集群名字
brokerClusterName=rocketmq-cluster
#broker名字,注意此处不同的配置文件填写的不一样
brokerName=broker-a
#0 表示 Master,>0 表示 Slave
brokerId=0
#nameServer地址,分号分割
namesrvAddr=rocketmq-nameserver1:9876;rocketmq-nameserver2: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/bin/rocketmq/store/broker-a
#commitLog 存储路径
storePathCommitLog=/usr/local/bin/rocketmq/store/broker-a/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/usr/local/bin/rocketmq/store/broker-a/consumerqueue
#消息索引存储路径
storePathIndex=/usr/local/bin/rocketmq/store/broker-a/index
#checkpoint 文件存储路径
storeCheckpoint=/usr/local/bin/rocketmq/store/broker-a/checkpoint
#abort 文件存储路径
abortFile=/usr/local/bin/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
brokerIP1=192.168.178.128
在机器a上配置broker-b的slave节点
vim broker-b-s.properties
#所属集群名字
brokerClusterName=rocketmq-cluster
#broker名字,注意此处不同的配置文件填写的不一样
brokerName=broker-b
#0 表示 Master,>0 表示 Slave
brokerId=1
#nameServer地址,分号分割
namesrvAddr=rocketmq-nameserver1:9876;rocketmq-nameserver2:9876
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#Broker 对外服务的监听端口
listenPort=11011
#删除文件时间点,默认凌晨 4点
deleteWhen=04
#文件保留时间,默认 48 小时
fileReservedTime=120
#commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#destroyMapedFileIntervalForcibly=120000
#redeleteHangedFileInterval=120000
#检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
#存储路径
storePathRootDir=/usr/local/bin/rocketmq/store/broker-b
#commitLog 存储路径
storePathCommitLog=/usr/local/bin/rocketmq/store/broker-b/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/usr/local/bin/rocketmq/store/broker-b/consumerqueue
#消息索引存储路径
storePathIndex=/usr/local/bin/rocketmq/store/broker-b/index
#checkpoint 文件存储路径
storeCheckpoint=/usr/local/bin/rocketmq/store/broker-b/checkpoint
#abort 文件存储路径
abortFile=/usr/local/bin/rocketmq/store/broker-b/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
brokerIP1=192.168.178.128
在机器b上配置broker-b 的master 节点
#所属集群名字
brokerClusterName=rocketmq-cluster
#broker名字,注意此处不同的配置文件填写的不一样
brokerName=broker-b
#0 表示 Master,>0 表示 Slave
brokerId=0
#nameServer地址,分号分割
namesrvAddr=rocketmq-nameserver1:9876;rocketmq-nameserver2: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/bin/rocketmq/store/broker-b
#commitLog 存储路径
storePathCommitLog=/usr/local/bin/rocketmq/store/broker-b/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/usr/local/bin/rocketmq/store/broker-b/consumerqueue
#消息索引存储路径
storePathIndex=/usr/local/bin/rocketmq/store/broker-b/index
#checkpoint 文件存储路径
storeCheckpoint=/usr/local/bin/rocketmq/store/broker-b/checkpoint
#abort 文件存储路径
abortFile=/usr/local/bin/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
brokerIP1=192.168.178.129
在机器b上配置broker-a 的slave节点
#所属集群名字
brokerClusterName=rocketmq-cluster
#broker名字,注意此处不同的配置文件填写的不一样
brokerName=broker-a
#0 表示 Master,>0 表示 Slave
brokerId=1
#nameServer地址,分号分割
namesrvAddr=rocketmq-nameserver1:9876;rocketmq-nameserver2:9876
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#Broker 对外服务的监听端口
listenPort=11011
#删除文件时间点,默认凌晨 4点
deleteWhen=04
#文件保留时间,默认 48 小时
fileReservedTime=120
#commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#destroyMapedFileIntervalForcibly=120000
#redeleteHangedFileInterval=120000
#检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
#存储路径
storePathRootDir=/usr/local/bin/rocketmq/store/broker-a
#commitLog 存储路径
storePathCommitLog=/usr/local/bin/rocketmq/store/broker-a/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/usr/local/bin/rocketmq/store/broker-a/consumerqueue
#消息索引存储路径
storePathIndex=/usr/local/bin/rocketmq/store/broker-a/index
#checkpoint 文件存储路径
storeCheckpoint=/usr/local/bin/rocketmq/store/broker-a/checkpoint
#abort 文件存储路径
abortFile=/usr/local/bin/rocketmq/store/broker-a/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
brokerIP1=192.168.178.129
分别在a和b两台机器上修改jvm启动参数
修改 runbroker.sh 中的jvm初始堆内存,最大堆内存,年轻代的大小
JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m"
修改 runserver.sh
JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
开始启动nameServer
分别在a ,b两台机器运行
cd /usr/local/bin/rocketmq-all-4.5.0-bin-release/bin
nohup sh mqnamesrv &
在机器a上启动broker-a的master节点
cd /usr/local/bin/rocketmq-all-4.5.0-bin-release/bin
nohup sh mqbroker -c /usr/local/bin/rocketmq-all-4.5.0-bin-release/conf/2m-2s-sync/broker-a.properties &
在机器a上启动broker-b的slave节点
nohup sh mqbroker -c /usr/local/bin/rocketmq-all-4.5.0-bin-release/conf/2m-2s-sync/broker-b-s.properties &
13.在机器b上启动broker-b的master节点
nohup sh mqbroker -c /usr/local/bin/rocketmq-all-4.5.0-bin-release/conf/2m-2s-sync/broker-b.properties &
在机器b上启动broker-a的slave节点
nohup sh mqbroker -c /usr/local/bin/rocketmq-all-4.5.0-bin-release/conf/2m-2s-sync/broker-a-s.properties &
查看是否启动成功了:
jps
到此 2主两从的节点就启动完成了
rocketmq-console-ng仪表台
下载安装
https://github.com/apache/rocketmq-externals/tree/release-rocketmq-console-1.0.0
修改配置文件:
server.address=0.0.0.0
# =============修改端口为19876=============
server.port=19876
### SSL setting
#server.ssl.key-store=classpath:rmqcngkeystore.jks
#server.ssl.key-store-password=rocketmq
#server.ssl.keyStoreType=PKCS12
#server.ssl.keyAlias=rmqcngkey
#spring.application.index=true
spring.application.name=rocketmq-console
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
logging.level.root=INFO
logging.config=classpath:logback.xml
#if this value is empty,use env value rocketmq.config.namesrvAddr NAMESRV_ADDR | now, you can set it in ops page.default localhost:9876
# =============修改namesrv地址,如果是多个请以分号;分隔(此处修改成你自己安装的rocket namesrv地址ip即可)=============
rocketmq.config.namesrvAddr=10.211.55.11:9876
#if you use rocketmq version < 3.5.8, rocketmq.config.isVIPChannel should be false.default true
rocketmq.config.isVIPChannel=
#rocketmq-console's data path:dashboard/monitor
rocketmq.config.dataPath=/tmp/rocketmq-console/data
#set it false if you don't want use dashboard.default true
rocketmq.config.enableDashBoardCollect=true
#set the message track trace topic if you don't want use the default one
rocketmq.config.msgTrackTopicName=
rocketmq.config.ticketKey=ticket
#Must create userInfo file: ${rocketmq.config.dataPath}/users.properties if the login is required
# =============开启控制台账户密码登录(为true表示开启,为false表示关闭)=============
rocketmq.config.loginRequired=true
#set the accessKey and secretKey if you used acl
#rocketmq.config.accessKey=
#rocketmq.config.secretKey=
修改 users.properties 内容如下(每次修改完记得重新编译打包):
# This file supports hot change, any change will be auto-reloaded without Console restarting.
# Format: a user per line, username=password[,N] #N is optional, 0 (Normal User); 1 (Admin)
# Define Admin
# =============用户名和密码规则「用户名=密码,权限」,这里的权限为1表示管理员,为0表示普通用户=============
# 例如:admin=admin123,1
这是用户名=这是密码,1
# Define Users
# =============屏蔽下边两个账户=============
#user1=user1
#user2=user2
放开console控制台的监控参数配置
默认的rocketmq-console将此功能注释掉了,修改文件:
~/rocketmq-console/src/resources/static/view/pages/consumer.html,将如下图所示的代码放开即可。
开启定时任务监控,扫描实时数据,做阈值判断,告警提示
默认情况下,rocketmq-console只定义了定时任务入口,具体的策略没有任何处理,我们需要根据自己的需求加入自身的告警方式,比如:邮箱,钉钉,短信,微信等等。
其预留的定时任务实现类为:
org.apache.rocketmq.console.task.MonitorTask
定时任务的扫描频率可根据自身系统要求考量设置。
简单的介绍面板
https://wenku.baidu.com/view/bada131113661ed9ad51f01dc281e53a5902514a.html
参考文档:
ttps://learn.lianglianglee.com/专栏/RocketMQ%20实战与进阶(完)/03%20消息发送%20API%20详解与版本变迁说明.md
ttps://blog.csdn.net/luanlouis/article/details/88078657
https://rocketmq.apache.org/docs/quick-start/
https://www.sunjs.com/article/detail/a44ed76899194d1fa1cc883c70b99c1f.html
RocketMQ 集群的搭建部署 以及rocketmq-console-ng仪表台的安装部署的更多相关文章
- RocketMq 集群方式搭建 步骤教学包教包会
mq集群方式搭建 有段时间没写这些技术文章了, 今天抽空写一点,不然自己都快忘记了 这篇文章记录了rocketmq 集群方式搭建的过程, 也是自己半天的成果记录吧! 感兴趣的朋友点个赞在走呗! 好了, ...
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十一)NIFI1.7.1安装
一.nifi基本配置 1. 修改各节点主机名,修改/etc/hosts文件内容. 192.168.0.120 master 192.168.0.121 slave1 192.168.0.122 sla ...
- RocketMQ之三:RocketMQ集群环境搭建
1.初步理解Producer/Consumer Group 在安装RocketMQ之前我们先来理解Group概念,在RocketMQ中Group是很重要的.通过Group机制,让RocketMQ天然的 ...
- rocketmq 集群环境搭建配置
rocketmq环境搭建配置: 一. 搭建三主集群,环境:centos-64 7.4 + RocketMQ-4.3.2 Master01: 192.168.102.68 Master02: 192 ...
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十七):kafka manager安装
一.kafka-manager简介 为了简化开发者和服务工程师维护Kafka集群的工作,yahoo构建了一个叫做Kafka管理器的基于Web工具,叫做 Kafka Manager.这个管理工具可以很容 ...
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十九)ES6.2.2 安装Ik中文分词器
注: elasticsearch 版本6.2.2 1)集群模式,则每个节点都需要安装ik分词,安装插件完毕后需要重启服务,创建mapping前如果有机器未安装分词,则可能该索引可能为RED,需要删除后 ...
- hadoop集群环境搭建之zookeeper集群的安装部署
关于hadoop集群搭建有一些准备工作要做,具体请参照hadoop集群环境搭建准备工作 (我成功的按照这个步骤部署成功了,经实际验证,该方法可行) 一.安装zookeeper 1 将zookeeper ...
- Solr集群的搭建以及使用(内涵zookeeper集群的搭建指南)
1 什么是SolrCloud SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud.当一个系统的索引数据量少的时候 ...
- RocketMq 集群搭建 部署
原文链接:https://blog.csdn.net/weixin_40533111/article/details/84451219 作者小太阳^_^,转载请注明出处,谢谢 前言本文基于最新版roc ...
随机推荐
- 2021.08.03 BZOJ 疯狂的馒头(并查集)
2021.08.03 BZOJ 疯狂的馒头(并查集) 疯狂的馒头 - 题目 - 黑暗爆炸OJ (darkbzoj.tk) 重点: 1.并查集的神奇运用 2.离线化 题意: 给一个长为n的序列,进行m次 ...
- Vue_transition动画
1 <!DOCTYPE html> 2 <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml ...
- js实现图片懒加载原理
原理 图片懒加载是前端页面优化的一种方式,在页面中有很多图片的时候,图片加载就需要很多时间,很耗费服务器性能,不仅影响渲染速度还会浪费带宽,为了解决这个问题,提高用户体验,所以就出现了懒加载这种方式来 ...
- 深度长文:深入理解Ceph存储架构
点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 本文是一篇Ceph存储架构技术文章,内容深入到每个存储特 ...
- 【总结】2022GDOI普及组 没得游记
因为是线上,所以没得游记 Day -3 学校安排去7班上课,好耶! 上午全是主科,有一节生物 被你七班捧上天了 被你七班造谣说我暴踩Everyone,还传到九班,给我玩阴的是吧 下午模拟赛,初一第一 ...
- 一款高速的NET版的离线免费OCR
PaddleOCR.Onnx 一款基于Paddle的OCR,项目使用ONNX模型,速度更快.本项目同时支持X64和X86的CPU上使用.本项目是一个基于PaddleOCR的C++代码修改并封装的.NE ...
- 使用 AgileConfig 动态配置 NLog
NLog 是我们在 .NET 领域使用非常广泛的日志组件.它默认使用 xml 来维护它的配置.最近有几个同学问我当使用 AgileConfig 的时候如何配置 NLog .因为 AgileConfig ...
- 438. Find All Anagrams in a String - LeetCode
Question 438. Find All Anagrams in a String Solution 题目大意:给两个字符串,s和p,求p在s中出现的位置,p串中的字符无序,ab=ba 思路:起初 ...
- 345. Reverse Vowels of a String - LeetCode
Question 345. Reverse Vowels of a String Solution 思路:交换元音,第一次遍历,先把出现元音的索引位置记录下来,第二遍遍历元音的索引并替换. Java实 ...
- 【Java面试】如何理解Spring Boot中的Starter?
一个工作了3年的Java程序员,遇到一个Spring Boot的问题. 他对这个问题有一些了解,但是回答得不是很好,希望参考我的高手回答. 这个问题是:"如何理解Spring Boot中的S ...