前言
FilterServerManager 负责维护过滤服务器长连接 与 过滤服务器信息映射关系,并且内部有定时调度线程,不断检查过滤服务器实际数量和配置数量是否一致,如果不一致,就根据配置构建命令行命令,执行命令启动 FilterServer 过滤服务器进程。
过滤服务器实例,是RockerMQ的高级功能,复制支持更复杂的过滤条件。
源码版本:4.9.3
源码架构图
核心数据结构
java
// 过滤服务器管理组件
public class FilterServerManager {
// 过滤服务器最大空闲时间,30秒
public static final long FILTER_SERVER_MAX_IDLE_TIME_MILLS = 30000;
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME);
// 过滤服务器长连接 与 过滤服务器信息映射关系
private final ConcurrentMap<Channel, FilterServerInfo> filterServerTable =
new ConcurrentHashMap<Channel, FilterServerInfo>(16);
private final BrokerController brokerController;
// 过滤服务器定时调度线程池
private ScheduledExecutorService scheduledExecutorService = Executors
.newSingleThreadScheduledExecutor(new ThreadFactoryImpl("FilterServerManagerScheduledThread"));
}
java
static class FilterServerInfo {
// 过滤服务器地址
private String filterServerAddr;
// 最后更新时间戳
private long lastUpdateTimestamp;
}
核心行为方法
java
// 过滤服务器管理组件
public class FilterServerManager {
// 过滤服务器最大空闲时间,30秒
public static final long FILTER_SERVER_MAX_IDLE_TIME_MILLS = 30000;
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME);
// 过滤服务器长连接 与 过滤服务器信息映射关系
private final ConcurrentMap<Channel, FilterServerInfo> filterServerTable =
new ConcurrentHashMap<Channel, FilterServerInfo>(16);
private final BrokerController brokerController;
// 过滤服务器定时调度线程池
private ScheduledExecutorService scheduledExecutorService = Executors
.newSingleThreadScheduledExecutor(new ThreadFactoryImpl("FilterServerManagerScheduledThread"));
public FilterServerManager(final BrokerController brokerController) {
this.brokerController = brokerController;
}
public void start() {
// 注册调度任务,每隔30秒扫描一次过滤服务器
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
FilterServerManager.this.createFilterServer();
} catch (Exception e) {
log.error("", e);
}
}
}, 1000 * 5, 1000 * 30, TimeUnit.MILLISECONDS);
}
// 创建过滤服务器
public void createFilterServer() {
int more =
this.brokerController.getBrokerConfig().getFilterServerNums() - this.filterServerTable.size();
String cmd = this.buildStartCommand();
for (int i = 0; i < more; i++) {
// 启动过滤服务器
FilterServerUtil.callShell(cmd, log);
}
}
// 构建过滤服务器启动命令
private String buildStartCommand() {
String config = "";
if (BrokerStartup.configFile != null) {
config = String.format("-c %s", BrokerStartup.configFile);
}
if (this.brokerController.getBrokerConfig().getNamesrvAddr() != null) {
config += String.format(" -n %s", this.brokerController.getBrokerConfig().getNamesrvAddr());
}
if (RemotingUtil.isWindowsPlatform()) {
return String.format("start /b %s\\bin\\mqfiltersrv.exe %s",
this.brokerController.getBrokerConfig().getRocketmqHome(),
config);
} else {
return String.format("sh %s/bin/startfsrv.sh %s",
this.brokerController.getBrokerConfig().getRocketmqHome(),
config);
}
}
public void shutdown() {
this.scheduledExecutorService.shutdown();
}
// 注册过滤服务器
public void registerFilterServer(final Channel channel, final String filterServerAddr) {
FilterServerInfo filterServerInfo = this.filterServerTable.get(channel);
if (filterServerInfo != null) {
filterServerInfo.setLastUpdateTimestamp(System.currentTimeMillis());
} else {
filterServerInfo = new FilterServerInfo();
filterServerInfo.setFilterServerAddr(filterServerAddr);
filterServerInfo.setLastUpdateTimestamp(System.currentTimeMillis());
this.filterServerTable.put(channel, filterServerInfo);
log.info("Receive a New Filter Server<{}>", filterServerAddr);
}
}
// 扫描过期的过滤服务器
public void scanNotActiveChannel() {
Iterator<Entry<Channel, FilterServerInfo>> it = this.filterServerTable.entrySet().iterator();
while (it.hasNext()) {
Entry<Channel, FilterServerInfo> next = it.next();
long timestamp = next.getValue().getLastUpdateTimestamp();
Channel channel = next.getKey();
// 过滤服务器超过30秒没有更新,则删除
if ((System.currentTimeMillis() - timestamp) > FILTER_SERVER_MAX_IDLE_TIME_MILLS) {
log.info("The Filter Server<{}> expired, remove it", next.getKey());
// 删除内存中的过滤服务器信息
it.remove();
// 关闭过滤服务器连接
RemotingUtil.closeChannel(channel);
}
}
}
// 过滤服务器连接关闭事件
public void doChannelCloseEvent(final String remoteAddr, final Channel channel) {
FilterServerInfo old = this.filterServerTable.remove(channel);
if (old != null) {
log.warn("The Filter Server<{}> connection<{}> closed, remove it", old.getFilterServerAddr(),
remoteAddr);
}
}
// 构建新的过滤服务器列表
public List<String> buildNewFilterServerList() {
List<String> addr = new ArrayList<>();
Iterator<Entry<Channel, FilterServerInfo>> it = this.filterServerTable.entrySet().iterator();
while (it.hasNext()) {
Entry<Channel, FilterServerInfo> next = it.next();
addr.add(next.getValue().getFilterServerAddr());
}
return addr;
}
static class FilterServerInfo {
// 过滤服务器地址
private String filterServerAddr;
// 最后更新时间戳
private long lastUpdateTimestamp;
public String getFilterServerAddr() {
return filterServerAddr;
}
public void setFilterServerAddr(String filterServerAddr) {
this.filterServerAddr = filterServerAddr;
}
public long getLastUpdateTimestamp() {
return lastUpdateTimestamp;
}
public void setLastUpdateTimestamp(long lastUpdateTimestamp) {
this.lastUpdateTimestamp = lastUpdateTimestamp;
}
}
}