提交 5440b1c4 编写于 作者: D duhenglucky

Add slow consumer process service for push model

上级 2be22d2f
...@@ -39,10 +39,12 @@ import org.apache.rocketmq.remoting.interceptor.InterceptorFactory; ...@@ -39,10 +39,12 @@ import org.apache.rocketmq.remoting.interceptor.InterceptorFactory;
import org.apache.rocketmq.remoting.interceptor.InterceptorGroup; import org.apache.rocketmq.remoting.interceptor.InterceptorGroup;
import org.apache.rocketmq.snode.client.ClientHousekeepingService; import org.apache.rocketmq.snode.client.ClientHousekeepingService;
import org.apache.rocketmq.snode.client.ClientManager; import org.apache.rocketmq.snode.client.ClientManager;
import org.apache.rocketmq.snode.client.SlowConsumerService;
import org.apache.rocketmq.snode.client.SubscriptionGroupManager; import org.apache.rocketmq.snode.client.SubscriptionGroupManager;
import org.apache.rocketmq.snode.client.SubscriptionManager; import org.apache.rocketmq.snode.client.SubscriptionManager;
import org.apache.rocketmq.snode.client.impl.ConsumerManagerImpl; import org.apache.rocketmq.snode.client.impl.ConsumerManagerImpl;
import org.apache.rocketmq.snode.client.impl.ProducerManagerImpl; import org.apache.rocketmq.snode.client.impl.ProducerManagerImpl;
import org.apache.rocketmq.snode.client.impl.SlowConsumerServiceImpl;
import org.apache.rocketmq.snode.client.impl.SubscriptionManagerImpl; import org.apache.rocketmq.snode.client.impl.SubscriptionManagerImpl;
import org.apache.rocketmq.snode.config.SnodeConfig; import org.apache.rocketmq.snode.config.SnodeConfig;
import org.apache.rocketmq.snode.offset.ConsumerOffsetManager; import org.apache.rocketmq.snode.offset.ConsumerOffsetManager;
...@@ -77,10 +79,8 @@ public class SnodeController { ...@@ -77,10 +79,8 @@ public class SnodeController {
private NnodeService nnodeService; private NnodeService nnodeService;
private ExecutorService consumerManagerExecutor; private ExecutorService consumerManagerExecutor;
private ScheduledService scheduledService; private ScheduledService scheduledService;
// private ProducerManager producerManager; private ClientManager producerManager;
// private ConsumerManager consumerManager; private ClientManager consumerManager;
private ClientManager producerManagerImpl;
private ClientManager consumerManagerImpl;
private SubscriptionManager subscriptionManager; private SubscriptionManager subscriptionManager;
private ClientHousekeepingService clientHousekeepingService; private ClientHousekeepingService clientHousekeepingService;
private SubscriptionGroupManager subscriptionGroupManager; private SubscriptionGroupManager subscriptionGroupManager;
...@@ -94,6 +94,7 @@ public class SnodeController { ...@@ -94,6 +94,7 @@ public class SnodeController {
private InterceptorGroup sendMessageInterceptorGroup; private InterceptorGroup sendMessageInterceptorGroup;
private PushService pushService; private PushService pushService;
private ClientService clientService; private ClientService clientService;
private SlowConsumerService slowConsumerService;
private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl( private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl(
"SnodeControllerScheduledThread")); "SnodeControllerScheduledThread"));
...@@ -172,9 +173,10 @@ public class SnodeController { ...@@ -172,9 +173,10 @@ public class SnodeController {
this.pushService = new PushServiceImpl(this); this.pushService = new PushServiceImpl(this);
this.clientService = new ClientServiceImpl(this); this.clientService = new ClientServiceImpl(this);
this.subscriptionManager = new SubscriptionManagerImpl(); this.subscriptionManager = new SubscriptionManagerImpl();
this.producerManagerImpl = new ProducerManagerImpl(); this.producerManager = new ProducerManagerImpl();
this.consumerManagerImpl = new ConsumerManagerImpl(this); this.consumerManager = new ConsumerManagerImpl(this);
this.clientHousekeepingService = new ClientHousekeepingService(this.producerManagerImpl, this.consumerManagerImpl); this.clientHousekeepingService = new ClientHousekeepingService(this.producerManager, this.consumerManager);
this.slowConsumerService = new SlowConsumerServiceImpl(this);
} }
public SnodeConfig getSnodeConfig() { public SnodeConfig getSnodeConfig() {
...@@ -257,18 +259,10 @@ public class SnodeController { ...@@ -257,18 +259,10 @@ public class SnodeController {
this.pushService.shutdown(); this.pushService.shutdown();
} }
// public ProducerManager getProducerManager() {
// return producerManager;
// }
public RemotingServer getSnodeServer() { public RemotingServer getSnodeServer() {
return snodeServer; return snodeServer;
} }
// public ConsumerManager getConsumerManager() {
// return consumerManager;
// }
public SubscriptionGroupManager getSubscriptionGroupManager() { public SubscriptionGroupManager getSubscriptionGroupManager() {
return subscriptionGroupManager; return subscriptionGroupManager;
} }
...@@ -326,20 +320,20 @@ public class SnodeController { ...@@ -326,20 +320,20 @@ public class SnodeController {
this.remotingServerInterceptorGroup = remotingServerInterceptorGroup; this.remotingServerInterceptorGroup = remotingServerInterceptorGroup;
} }
public ClientManager getProducerManagerImpl() { public ClientManager getProducerManager() {
return producerManagerImpl; return producerManager;
} }
public void setProducerManagerImpl(ClientManager producerManagerImpl) { public void setProducerManager(ClientManager producerManager) {
this.producerManagerImpl = producerManagerImpl; this.producerManager = producerManager;
} }
public ClientManager getConsumerManagerImpl() { public ClientManager getConsumerManager() {
return consumerManagerImpl; return consumerManager;
} }
public void setConsumerManagerImpl(ClientManager consumerManagerImpl) { public void setConsumerManager(ClientManager consumerManager) {
this.consumerManagerImpl = consumerManagerImpl; this.consumerManager = consumerManager;
} }
public SubscriptionManager getSubscriptionManager() { public SubscriptionManager getSubscriptionManager() {
...@@ -357,4 +351,12 @@ public class SnodeController { ...@@ -357,4 +351,12 @@ public class SnodeController {
public void setClientService(ClientService clientService) { public void setClientService(ClientService clientService) {
this.clientService = clientService; this.clientService = clientService;
} }
public SlowConsumerService getSlowConsumerService() {
return slowConsumerService;
}
public void setSlowConsumerService(SlowConsumerService slowConsumerService) {
this.slowConsumerService = slowConsumerService;
}
} }
...@@ -53,9 +53,7 @@ public class Client { ...@@ -53,9 +53,7 @@ public class Client {
if (o == null || getClass() != o.getClass()) if (o == null || getClass() != o.getClass())
return false; return false;
Client client = (Client) o; Client client = (Client) o;
return heartbeatInterval == client.heartbeatInterval && return version == client.version &&
lastUpdateTimestamp == client.lastUpdateTimestamp &&
version == client.version &&
clientRole == client.clientRole && clientRole == client.clientRole &&
Objects.equals(groupId, client.groupId) && Objects.equals(groupId, client.groupId) &&
Objects.equals(clientId, client.clientId) && Objects.equals(clientId, client.clientId) &&
...@@ -65,7 +63,7 @@ public class Client { ...@@ -65,7 +63,7 @@ public class Client {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(clientRole, groupId, clientId, remotingChannel, heartbeatInterval, lastUpdateTimestamp, version, language); return Objects.hash(clientRole, groupId, clientId, remotingChannel, version, language);
} }
public String getGroupId() { public String getGroupId() {
...@@ -123,4 +121,19 @@ public class Client { ...@@ -123,4 +121,19 @@ public class Client {
public void setLanguage(LanguageCode language) { public void setLanguage(LanguageCode language) {
this.language = language; this.language = language;
} }
@Override public String toString() {
return "Client{" +
"clientRole=" + clientRole +
", groupId='" + groupId + '\'' +
", clientId='" + clientId + '\'' +
", remotingChannel=" + remotingChannel +
", heartbeatInterval=" + heartbeatInterval +
", lastUpdateTimestamp=" + lastUpdateTimestamp +
", version=" + version +
", language=" + language +
'}';
}
} }
...@@ -52,9 +52,9 @@ public class ClientHousekeepingService implements ChannelEventListener { ...@@ -52,9 +52,9 @@ public class ClientHousekeepingService implements ChannelEventListener {
private ClientRole clientRole(RemotingChannel remotingChannel) { private ClientRole clientRole(RemotingChannel remotingChannel) {
if (remotingChannel instanceof NettyChannelImpl) { if (remotingChannel instanceof NettyChannelImpl) {
Channel channel = ((NettyChannelImpl) remotingChannel).getChannel(); Channel channel = ((NettyChannelImpl) remotingChannel).getChannel();
Attribute<ClientRole> clientRoleAttribute = channel.attr(SnodeConstant.NETTY_CLIENT_ROLE_ATTRIBUTE_KEY); Attribute<Client> clientAttribute = channel.attr(SnodeConstant.NETTY_CLIENT_ATTRIBUTE_KEY);
if (clientRoleAttribute != null) { if (clientAttribute != null) {
return clientRoleAttribute.get(); return clientAttribute.get().getClientRole();
} }
} }
log.warn("RemotingChannel type error: {}", remotingChannel.getClass()); log.warn("RemotingChannel type error: {}", remotingChannel.getClass());
......
...@@ -20,5 +20,6 @@ import org.apache.rocketmq.remoting.RemotingChannel; ...@@ -20,5 +20,6 @@ import org.apache.rocketmq.remoting.RemotingChannel;
public interface SlowConsumerService { public interface SlowConsumerService {
boolean isSlowConsumer(long latestLogicOffset, String topic, String queueId, RemotingChannel remotingChannel); boolean isSlowConsumer(long latestLogicOffset, String topic, int queueId, RemotingChannel remotingChannel,
String enodeName);
} }
...@@ -16,8 +16,6 @@ ...@@ -16,8 +16,6 @@
*/ */
package org.apache.rocketmq.snode.client; package org.apache.rocketmq.snode.client;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import org.apache.rocketmq.common.DataVersion; import org.apache.rocketmq.common.DataVersion;
...@@ -26,20 +24,15 @@ import org.apache.rocketmq.common.constant.LoggerName; ...@@ -26,20 +24,15 @@ import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig; import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig;
import org.apache.rocketmq.logging.InternalLogger; import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory; import org.apache.rocketmq.logging.InternalLoggerFactory;
import org.apache.rocketmq.remoting.serialize.RemotingSerializable;
import org.apache.rocketmq.snode.SnodeController; import org.apache.rocketmq.snode.SnodeController;
public class SubscriptionGroupManager { public class SubscriptionGroupManager {
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.BROKER_LOGGER_NAME); private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.SNODE_LOGGER_NAME);
private final ConcurrentMap<String, SubscriptionGroupConfig> subscriptionGroupTable = private final ConcurrentMap<String, SubscriptionGroupConfig> subscriptionGroupTable = new ConcurrentHashMap<>(1024);
new ConcurrentHashMap<>(1024);
private final DataVersion dataVersion = new DataVersion(); private final DataVersion dataVersion = new DataVersion();
private transient SnodeController snodeController;
public SubscriptionGroupManager() { private transient SnodeController snodeController;
this.init();
}
public SubscriptionGroupManager(SnodeController snodeController) { public SubscriptionGroupManager(SnodeController snodeController) {
this.snodeController = snodeController; this.snodeController = snodeController;
...@@ -47,51 +40,6 @@ public class SubscriptionGroupManager { ...@@ -47,51 +40,6 @@ public class SubscriptionGroupManager {
} }
private void init() { private void init() {
{
SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig();
subscriptionGroupConfig.setGroupName(MixAll.TOOLS_CONSUMER_GROUP);
this.subscriptionGroupTable.put(MixAll.TOOLS_CONSUMER_GROUP, subscriptionGroupConfig);
}
{
SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig();
subscriptionGroupConfig.setGroupName(MixAll.FILTERSRV_CONSUMER_GROUP);
this.subscriptionGroupTable.put(MixAll.FILTERSRV_CONSUMER_GROUP, subscriptionGroupConfig);
}
{
SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig();
subscriptionGroupConfig.setGroupName(MixAll.SELF_TEST_CONSUMER_GROUP);
this.subscriptionGroupTable.put(MixAll.SELF_TEST_CONSUMER_GROUP, subscriptionGroupConfig);
}
{
SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig();
subscriptionGroupConfig.setGroupName(MixAll.ONS_HTTP_PROXY_GROUP);
subscriptionGroupConfig.setConsumeBroadcastEnable(true);
this.subscriptionGroupTable.put(MixAll.ONS_HTTP_PROXY_GROUP, subscriptionGroupConfig);
}
{
SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig();
subscriptionGroupConfig.setGroupName(MixAll.CID_ONSAPI_PULL_GROUP);
subscriptionGroupConfig.setConsumeBroadcastEnable(true);
this.subscriptionGroupTable.put(MixAll.CID_ONSAPI_PULL_GROUP, subscriptionGroupConfig);
}
{
SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig();
subscriptionGroupConfig.setGroupName(MixAll.CID_ONSAPI_PERMISSION_GROUP);
subscriptionGroupConfig.setConsumeBroadcastEnable(true);
this.subscriptionGroupTable.put(MixAll.CID_ONSAPI_PERMISSION_GROUP, subscriptionGroupConfig);
}
{
SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig();
subscriptionGroupConfig.setGroupName(MixAll.CID_ONSAPI_OWNER_GROUP);
subscriptionGroupConfig.setConsumeBroadcastEnable(true);
this.subscriptionGroupTable.put(MixAll.CID_ONSAPI_OWNER_GROUP, subscriptionGroupConfig);
}
} }
public void updateSubscriptionGroupConfig(final SubscriptionGroupConfig config) { public void updateSubscriptionGroupConfig(final SubscriptionGroupConfig config) {
...@@ -133,32 +81,7 @@ public class SubscriptionGroupManager { ...@@ -133,32 +81,7 @@ public class SubscriptionGroupManager {
return subscriptionGroupConfig; return subscriptionGroupConfig;
} }
public String encode() {
return this.encode(false);
}
public void decode(String jsonString) {
if (jsonString != null) {
SubscriptionGroupManager obj = RemotingSerializable.fromJson(jsonString, SubscriptionGroupManager.class);
if (obj != null) {
this.subscriptionGroupTable.putAll(obj.subscriptionGroupTable);
this.dataVersion.assignNewOne(obj.dataVersion);
this.printLoadDataWhenFirstBoot(obj);
}
}
}
public String encode(final boolean prettyFormat) {
return RemotingSerializable.toJson(this, prettyFormat);
}
private void printLoadDataWhenFirstBoot(final SubscriptionGroupManager sgm) {
Iterator<Entry<String, SubscriptionGroupConfig>> it = sgm.getSubscriptionGroupTable().entrySet().iterator();
while (it.hasNext()) {
Entry<String, SubscriptionGroupConfig> next = it.next();
log.info("load exist subscription group, {}", next.getValue().toString());
}
}
public ConcurrentMap<String, SubscriptionGroupConfig> getSubscriptionGroupTable() { public ConcurrentMap<String, SubscriptionGroupConfig> getSubscriptionGroupTable() {
return subscriptionGroupTable; return subscriptionGroupTable;
......
...@@ -35,9 +35,9 @@ public interface SubscriptionManager { ...@@ -35,9 +35,9 @@ public interface SubscriptionManager {
Subscription getSubscription(String groupId); Subscription getSubscription(String groupId);
void registerPush(Set<SubscriptionData> subscriptionDataSet, RemotingChannel remotingChannel, String groupId); void registerPushSession(Set<SubscriptionData> subscriptionDataSet, RemotingChannel remotingChannel, String groupId);
void removePush(RemotingChannel remotingChannel); void removePushSession(RemotingChannel remotingChannel);
Set<RemotingChannel> getPushableChannel(String topic, Integer queueId); Set<RemotingChannel> getPushableChannel(String topic, Integer queueId);
} }
...@@ -122,6 +122,7 @@ public abstract class ClientManagerImpl implements ClientManager { ...@@ -122,6 +122,7 @@ public abstract class ClientManagerImpl implements ClientManager {
} }
oldClient.setLastUpdateTimestamp(System.currentTimeMillis()); oldClient.setLastUpdateTimestamp(System.currentTimeMillis());
} }
log.debug("Register client role: {}, group: {}, last: {}", client.getClientRole(), client.getGroupId(), client.getLastUpdateTimestamp());
onRegister(client.getGroupId(), client.getRemotingChannel()); onRegister(client.getGroupId(), client.getRemotingChannel());
return updated; return updated;
} }
......
...@@ -39,12 +39,12 @@ public class ConsumerManagerImpl extends ClientManagerImpl { ...@@ -39,12 +39,12 @@ public class ConsumerManagerImpl extends ClientManagerImpl {
@Override @Override
public void onClosed(String groupId, RemotingChannel remotingChannel) { public void onClosed(String groupId, RemotingChannel remotingChannel) {
this.snodeController.getClientService().notifyConsumer(groupId); this.snodeController.getClientService().notifyConsumer(groupId);
this.snodeController.getSubscriptionManager().removePush(remotingChannel); this.snodeController.getSubscriptionManager().removePushSession(remotingChannel);
} }
@Override @Override
public void onUnregister(String groupId, RemotingChannel remotingChannel) { public void onUnregister(String groupId, RemotingChannel remotingChannel) {
this.snodeController.getClientService().notifyConsumer(groupId); this.snodeController.getClientService().notifyConsumer(groupId);
this.snodeController.getSubscriptionManager().removePush(remotingChannel); this.snodeController.getSubscriptionManager().removePushSession(remotingChannel);
} }
} }
...@@ -16,14 +16,45 @@ ...@@ -16,14 +16,45 @@
*/ */
package org.apache.rocketmq.snode.client.impl; package org.apache.rocketmq.snode.client.impl;
import io.netty.channel.Channel;
import io.netty.util.Attribute;
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
import org.apache.rocketmq.remoting.RemotingChannel; import org.apache.rocketmq.remoting.RemotingChannel;
import org.apache.rocketmq.remoting.netty.NettyChannelImpl;
import org.apache.rocketmq.snode.SnodeController;
import org.apache.rocketmq.snode.client.Client;
import org.apache.rocketmq.snode.client.SlowConsumerService; import org.apache.rocketmq.snode.client.SlowConsumerService;
import org.apache.rocketmq.snode.constant.SnodeConstant;
public class SlowConsumerServiceImpl implements SlowConsumerService { public class SlowConsumerServiceImpl implements SlowConsumerService {
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.SNODE_LOGGER_NAME);
private final SnodeController snodeController;
public SlowConsumerServiceImpl(SnodeController snodeController) {
this.snodeController = snodeController;
}
@Override @Override
public boolean isSlowConsumer(long latestLogicOffset, String topic, String queueId, public boolean isSlowConsumer(long latestLogicOffset, String topic, int queueId,
RemotingChannel remotingChannel) { RemotingChannel remotingChannel, String enodeName) {
Client client = null;
if (remotingChannel instanceof NettyChannelImpl) {
Channel channel = ((NettyChannelImpl) remotingChannel).getChannel();
Attribute<Client> clientAttribute = channel.attr(SnodeConstant.NETTY_CLIENT_ATTRIBUTE_KEY);
if (clientAttribute != null) {
client = clientAttribute.get();
}
}
if (client != null) {
long ackedOffset = this.snodeController.getConsumerOffsetManager().queryOffset(enodeName, client.getGroupId(), topic, queueId);
if (latestLogicOffset - ackedOffset > snodeController.getSnodeConfig().getSlowConsumerThreshold()) {
log.warn("[SlowConsumer] group: {}, lastAckedOffset:{} nowOffset:{} ", client.getGroupId(), ackedOffset, latestLogicOffset);
return true;
}
}
return false; return false;
} }
} }
...@@ -52,7 +52,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { ...@@ -52,7 +52,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
} }
@Override @Override
public void registerPush(Set<SubscriptionData> subscriptionDataSet, RemotingChannel remotingChannel, public void registerPushSession(Set<SubscriptionData> subscriptionDataSet, RemotingChannel remotingChannel,
String groupId) { String groupId) {
Set<String> prevSubSet = this.clientSubscriptionTable.get(remotingChannel); Set<String> prevSubSet = this.clientSubscriptionTable.get(remotingChannel);
Set<String> keySet = new HashSet<>(); Set<String> keySet = new HashSet<>();
...@@ -89,7 +89,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { ...@@ -89,7 +89,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
} }
@Override @Override
public void removePush(RemotingChannel remotingChannel) { public void removePushSession(RemotingChannel remotingChannel) {
Set<String> subSet = this.clientSubscriptionTable.get(remotingChannel); Set<String> subSet = this.clientSubscriptionTable.get(remotingChannel);
if (subSet != null) { if (subSet != null) {
for (String key : subSet) { for (String key : subSet) {
......
...@@ -284,4 +284,11 @@ public class SnodeConfig { ...@@ -284,4 +284,11 @@ public class SnodeConfig {
return remotingServerInterceptorPath; return remotingServerInterceptorPath;
} }
public int getSlowConsumerThreshold() {
return slowConsumerThreshold;
}
public void setSlowConsumerThreshold(int slowConsumerThreshold) {
this.slowConsumerThreshold = slowConsumerThreshold;
}
} }
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
package org.apache.rocketmq.snode.constant; package org.apache.rocketmq.snode.constant;
import io.netty.util.AttributeKey; import io.netty.util.AttributeKey;
import org.apache.rocketmq.snode.client.Client;
import org.apache.rocketmq.snode.client.impl.ClientRole; import org.apache.rocketmq.snode.client.impl.ClientRole;
public class SnodeConstant { public class SnodeConstant {
...@@ -30,10 +31,5 @@ public class SnodeConstant { ...@@ -30,10 +31,5 @@ public class SnodeConstant {
public static final AttributeKey<ClientRole> NETTY_CLIENT_ROLE_ATTRIBUTE_KEY = AttributeKey.valueOf("netty.client.role"); public static final AttributeKey<ClientRole> NETTY_CLIENT_ROLE_ATTRIBUTE_KEY = AttributeKey.valueOf("netty.client.role");
public static final String NETTY_PRODUCER_ROLE_ATTRIBUTE_VALUE = "Producer"; public static final AttributeKey<Client> NETTY_CLIENT_ATTRIBUTE_KEY = AttributeKey.valueOf("netty.client");
public static final String NETTY_CONSUMER_ROLE_ATTRIBUTE_VALUE = "Consumer";
public static final String NETTY_IOT_ROLE_ATTRIBUTE_VALUE = "IOTGroup";
} }
...@@ -39,7 +39,7 @@ public class ConsumerOffsetManager { ...@@ -39,7 +39,7 @@ public class ConsumerOffsetManager {
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.SNODE_LOGGER_NAME); private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.SNODE_LOGGER_NAME);
private static final String TOPIC_GROUP_SEPARATOR = "@"; private static final String TOPIC_GROUP_SEPARATOR = "@";
private ConcurrentMap<String/* topic@group */, ConcurrentMap<Integer, Long>> offsetTable = private ConcurrentMap<String/* Enode@Topic@Group */, ConcurrentMap<Integer, Long>> offsetTable =
new ConcurrentHashMap<>(512); new ConcurrentHashMap<>(512);
private transient SnodeController snodeController; private transient SnodeController snodeController;
...@@ -88,11 +88,10 @@ public class ConsumerOffsetManager { ...@@ -88,11 +88,10 @@ public class ConsumerOffsetManager {
return result; return result;
} }
public void commitOffset(final String enodeName, final String clientHost, final String group, final String topic, public void commitOffset(final String enodeName, final String clientHost, final String group, final String topic,
final int queueId, final int queueId,
final long offset) { final long offset) {
// topic@group // Topic@group
String key = buildKey(enodeName, topic, group); String key = buildKey(enodeName, topic, group);
this.commitOffset(clientHost, key, queueId, offset); this.commitOffset(clientHost, key, queueId, offset);
} }
...@@ -101,12 +100,13 @@ public class ConsumerOffsetManager { ...@@ -101,12 +100,13 @@ public class ConsumerOffsetManager {
ConcurrentMap<Integer, Long> map = this.offsetTable.get(key); ConcurrentMap<Integer, Long> map = this.offsetTable.get(key);
if (null == map) { if (null == map) {
map = new ConcurrentHashMap<>(32); map = new ConcurrentHashMap<>(32);
ConcurrentMap<Integer, Long> prev = this.offsetTable.putIfAbsent(key, map);
map = prev != null ? prev : map;
map.put(queueId, offset); map.put(queueId, offset);
this.offsetTable.put(key, map);
} else { } else {
Long storeOffset = map.put(queueId, offset); Long storeOffset = map.put(queueId, offset);
if (storeOffset != null && offset < storeOffset) { if (storeOffset != null && offset < storeOffset) {
log.warn("[NOTIFYME]update consumer offset less than store. clientHost={}, key={}, queueId={}, requestOffset={}, storeOffset={}", clientHost, key, queueId, offset, storeOffset); log.warn("[NOTIFYME]update consumer offset less than store. clientHost: {}, key: {}, queueId: {}, requestOffset: {}, storeOffset: {}", clientHost, key, queueId, offset, storeOffset);
} }
} }
} }
...@@ -123,18 +123,6 @@ public class ConsumerOffsetManager { ...@@ -123,18 +123,6 @@ public class ConsumerOffsetManager {
return -1; return -1;
} }
public String encode() {
return this.encode(false);
}
public void decode(String jsonString) {
if (jsonString != null) {
ConsumerOffsetManager obj = RemotingSerializable.fromJson(jsonString, ConsumerOffsetManager.class);
if (obj != null) {
this.offsetTable = obj.offsetTable;
}
}
}
public String encode(final boolean prettyFormat) { public String encode(final boolean prettyFormat) {
return RemotingSerializable.toJson(this, prettyFormat); return RemotingSerializable.toJson(this, prettyFormat);
......
...@@ -126,7 +126,7 @@ public class ConsumerManageProcessor implements RequestProcessor { ...@@ -126,7 +126,7 @@ public class ConsumerManageProcessor implements RequestProcessor {
(GetConsumerListByGroupRequestHeader) request (GetConsumerListByGroupRequestHeader) request
.decodeCommandCustomHeader(GetConsumerListByGroupRequestHeader.class); .decodeCommandCustomHeader(GetConsumerListByGroupRequestHeader.class);
List<String> clientIds = this.snodeController.getConsumerManagerImpl().getAllClientId(requestHeader.getConsumerGroup()); List<String> clientIds = this.snodeController.getConsumerManager().getAllClientId(requestHeader.getConsumerGroup());
if (!clientIds.isEmpty()) { if (!clientIds.isEmpty()) {
GetConsumerListByGroupResponseBody body = new GetConsumerListByGroupResponseBody(); GetConsumerListByGroupResponseBody body = new GetConsumerListByGroupResponseBody();
body.setConsumerIdList(clientIds); body.setConsumerIdList(clientIds);
......
...@@ -63,47 +63,41 @@ public class HeartbeatProcessor implements RequestProcessor { ...@@ -63,47 +63,41 @@ public class HeartbeatProcessor implements RequestProcessor {
private RemotingCommand register(RemotingChannel remotingChannel, RemotingCommand request) { private RemotingCommand register(RemotingChannel remotingChannel, RemotingCommand request) {
HeartbeatData heartbeatData = HeartbeatData.decode(request.getBody(), HeartbeatData.class); HeartbeatData heartbeatData = HeartbeatData.decode(request.getBody(), HeartbeatData.class);
Channel channel; Channel channel = null;
ClientRole role = null; Attribute<Client> clientAttribute = null;
Attribute<ClientRole> clientRoleAttribute = null;
if (remotingChannel instanceof NettyChannelHandlerContextImpl) { if (remotingChannel instanceof NettyChannelHandlerContextImpl) {
channel = ((NettyChannelHandlerContextImpl) remotingChannel).getChannelHandlerContext().channel(); channel = ((NettyChannelHandlerContextImpl) remotingChannel).getChannelHandlerContext().channel();
clientRoleAttribute = channel.attr(SnodeConstant.NETTY_CLIENT_ROLE_ATTRIBUTE_KEY); clientAttribute = channel.attr(SnodeConstant.NETTY_CLIENT_ATTRIBUTE_KEY);
} }
Client client = new Client(); Client client = new Client();
client.setClientId(heartbeatData.getClientID()); client.setClientId(heartbeatData.getClientID());
client.setRemotingChannel(remotingChannel); client.setRemotingChannel(remotingChannel);
for (ProducerData producerData : heartbeatData.getProducerDataSet()) { for (ProducerData producerData : heartbeatData.getProducerDataSet()) {
role = ClientRole.Producer;
client.setGroupId(producerData.getGroupName()); client.setGroupId(producerData.getGroupName());
client.setClientRole(role); client.setClientRole(ClientRole.Producer);
this.snodeController.getProducerManagerImpl().register(client); this.snodeController.getProducerManager().register(client);
} }
for (ConsumerData data : heartbeatData.getConsumerDataSet()) { for (ConsumerData data : heartbeatData.getConsumerDataSet()) {
client.setGroupId(data.getGroupName()); client.setGroupId(data.getGroupName());
role = ClientRole.Consumer; client.setClientRole(ClientRole.Consumer);
client.setClientRole(role); boolean channelChanged = this.snodeController.getConsumerManager().register(client);
boolean channelChanged = this.snodeController.getConsumerManagerImpl().register(client);
boolean subscriptionChanged = this.snodeController.getSubscriptionManager().subscribe(data.getGroupName(), boolean subscriptionChanged = this.snodeController.getSubscriptionManager().subscribe(data.getGroupName(),
data.getSubscriptionDataSet(), data.getSubscriptionDataSet(),
data.getConsumeType(), data.getConsumeType(),
data.getMessageModel(), data.getMessageModel(),
data.getConsumeFromWhere()); data.getConsumeFromWhere());
if (data.getConsumeType() == ConsumeType.CONSUME_PUSH) { if (data.getConsumeType() == ConsumeType.CONSUME_PUSH) {
NettyChannelImpl nettyChannel = new NettyChannelImpl(((NettyChannelHandlerContextImpl)remotingChannel).getChannelHandlerContext().channel()); NettyChannelImpl nettyChannel = new NettyChannelImpl(channel);
this.snodeController.getSubscriptionManager().registerPush(data.getSubscriptionDataSet(), nettyChannel, data.getGroupName()); this.snodeController.getSubscriptionManager().registerPushSession(data.getSubscriptionDataSet(), nettyChannel, data.getGroupName());
} }
if (subscriptionChanged || channelChanged) { if (subscriptionChanged || channelChanged) {
this.snodeController.getClientService().notifyConsumer(data.getGroupName()); this.snodeController.getClientService().notifyConsumer(data.getGroupName());
} }
} }
if (role != null) {
log.debug("Set channel attribute value: {}", role);
clientRoleAttribute.setIfAbsent(role);
}
clientAttribute.setIfAbsent(client);
RemotingCommand response = RemotingCommand.createResponseCommand(null); RemotingCommand response = RemotingCommand.createResponseCommand(null);
response.setCode(ResponseCode.SUCCESS); response.setCode(ResponseCode.SUCCESS);
response.setRemark(null); response.setRemark(null);
...@@ -118,13 +112,13 @@ public class HeartbeatProcessor implements RequestProcessor { ...@@ -118,13 +112,13 @@ public class HeartbeatProcessor implements RequestProcessor {
final String producerGroup = requestHeader.getProducerGroup(); final String producerGroup = requestHeader.getProducerGroup();
if (producerGroup != null) { if (producerGroup != null) {
this.snodeController.getProducerManagerImpl().unRegister(producerGroup, remotingChannel); this.snodeController.getProducerManager().unRegister(producerGroup, remotingChannel);
} }
final String consumerGroup = requestHeader.getConsumerGroup(); final String consumerGroup = requestHeader.getConsumerGroup();
if (consumerGroup != null) { if (consumerGroup != null) {
this.snodeController.getConsumerManagerImpl().unRegister(consumerGroup, remotingChannel); this.snodeController.getConsumerManager().unRegister(consumerGroup, remotingChannel);
this.snodeController.getSubscriptionManager().removePush(remotingChannel); this.snodeController.getSubscriptionManager().removePushSession(remotingChannel);
this.snodeController.getClientService().notifyConsumer(consumerGroup); this.snodeController.getClientService().notifyConsumer(consumerGroup);
} }
......
...@@ -75,7 +75,7 @@ public class SendMessageProcessor implements RequestProcessor { ...@@ -75,7 +75,7 @@ public class SendMessageProcessor implements RequestProcessor {
} }
remotingChannel.reply(data); remotingChannel.reply(data);
if (data.getCode() == ResponseCode.SUCCESS && isNeedPush) { if (data.getCode() == ResponseCode.SUCCESS && isNeedPush) {
this.snodeController.getPushService().pushMessage(topic, queueId, message, data); this.snodeController.getPushService().pushMessage(enodeName, topic, queueId, message, data);
} }
} else { } else {
if (this.snodeController.getSendMessageInterceptorGroup() != null) { if (this.snodeController.getSendMessageInterceptorGroup() != null) {
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.snode.service;
public class ConsumerOffsetService {
}
...@@ -20,10 +20,8 @@ import org.apache.rocketmq.remoting.protocol.RemotingCommand; ...@@ -20,10 +20,8 @@ import org.apache.rocketmq.remoting.protocol.RemotingCommand;
public interface PushService { public interface PushService {
void pushMessage(final String topic, final Integer queueId, final byte[] message, void pushMessage(final String enodeName, final String topic, final Integer queueId, final byte[] message,
final RemotingCommand response); final RemotingCommand response);
void start();
void shutdown(); void shutdown();
} }
...@@ -42,7 +42,7 @@ public class ClientServiceImpl implements ClientService { ...@@ -42,7 +42,7 @@ public class ClientServiceImpl implements ClientService {
SubscriptionGroupConfig subscriptionGroupConfig = snodeController.getSubscriptionGroupManager().findSubscriptionGroupConfig(group); SubscriptionGroupConfig subscriptionGroupConfig = snodeController.getSubscriptionGroupManager().findSubscriptionGroupConfig(group);
boolean notifyConsumer = subscriptionGroupConfig.isNotifyConsumerIdsChangedEnable(); boolean notifyConsumer = subscriptionGroupConfig.isNotifyConsumerIdsChangedEnable();
if (notifyConsumer) { if (notifyConsumer) {
List<RemotingChannel> remotingChannels = snodeController.getConsumerManagerImpl().getChannels(group); List<RemotingChannel> remotingChannels = snodeController.getConsumerManager().getChannels(group);
if (remotingChannels != null && snodeController.getSubscriptionGroupManager().getSubscriptionGroupTable().get(group).isNotifyConsumerIdsChangedEnable()) { if (remotingChannels != null && snodeController.getSubscriptionGroupManager().getSubscriptionGroupTable().get(group).isNotifyConsumerIdsChangedEnable()) {
for (RemotingChannel remotingChannel : remotingChannels) { for (RemotingChannel remotingChannel : remotingChannels) {
NotifyConsumerIdsChangedRequestHeader requestHeader = new NotifyConsumerIdsChangedRequestHeader(); NotifyConsumerIdsChangedRequestHeader requestHeader = new NotifyConsumerIdsChangedRequestHeader();
......
...@@ -58,13 +58,15 @@ public class PushServiceImpl implements PushService { ...@@ -58,13 +58,15 @@ public class PushServiceImpl implements PushService {
private final Integer queueId; private final Integer queueId;
private final String topic; private final String topic;
private final RemotingCommand response; private final RemotingCommand response;
private final String enodeName;
public PushTask(final String topic, final Integer queueId, final byte[] message, public PushTask(final String topic, final Integer queueId, final byte[] message,
final RemotingCommand response) { final RemotingCommand response, final String enodeName) {
this.message = message; this.message = message;
this.queueId = queueId; this.queueId = queueId;
this.topic = topic; this.topic = topic;
this.response = response; this.response = response;
this.enodeName = enodeName;
} }
@Override @Override
...@@ -79,11 +81,16 @@ public class PushServiceImpl implements PushService { ...@@ -79,11 +81,16 @@ public class PushServiceImpl implements PushService {
RemotingCommand pushMessage = RemotingCommand.createRequestCommand(RequestCode.SNODE_PUSH_MESSAGE, pushMessageHeader); RemotingCommand pushMessage = RemotingCommand.createRequestCommand(RequestCode.SNODE_PUSH_MESSAGE, pushMessageHeader);
pushMessage.setBody(message); pushMessage.setBody(message);
Set<RemotingChannel> consumerTable = snodeController.getSubscriptionManager().getPushableChannel(topic, queueId); Set<RemotingChannel> consumerTable = snodeController.getSubscriptionManager().getPushableChannel(topic, queueId);
log.info("Push message to consumerTable: {}", consumerTable);
if (consumerTable != null) { if (consumerTable != null) {
for (RemotingChannel remotingChannel : consumerTable) { for (RemotingChannel remotingChannel : consumerTable) {
if (remotingChannel.isWritable()) { if (remotingChannel.isWritable()) {
log.info("Push message to remotingChannel: {}", remotingChannel.remoteAddress()); boolean slowConsumer = snodeController.getSlowConsumerService().isSlowConsumer(sendMessageResponseHeader.getQueueOffset(), topic, queueId, remotingChannel, enodeName);
if (slowConsumer) {
log.warn("[SlowConsumer]: {} closed as slow consumer", remotingChannel);//TODO metrics
remotingChannel.close();
continue;
}
log.debug("Push message to remotingChannel: {}", remotingChannel.remoteAddress());
snodeController.getSnodeServer().push(remotingChannel, pushMessage, SnodeConstant.DEFAULT_TIMEOUT_MILLS); snodeController.getSnodeServer().push(remotingChannel, pushMessage, SnodeConstant.DEFAULT_TIMEOUT_MILLS);
} else { } else {
log.warn("Remoting channel is not writable: {}", remotingChannel.remoteAddress()); log.warn("Remoting channel is not writable: {}", remotingChannel.remoteAddress());
...@@ -107,21 +114,17 @@ public class PushServiceImpl implements PushService { ...@@ -107,21 +114,17 @@ public class PushServiceImpl implements PushService {
} }
@Override @Override
public void pushMessage(final String topic, final Integer queueId, final byte[] message, public void pushMessage(final String enodeName, final String topic, final Integer queueId, final byte[] message,
final RemotingCommand response) { final RemotingCommand response) {
Set<RemotingChannel> pushableChannels = this.snodeController.getSubscriptionManager().getPushableChannel(topic, queueId); Set<RemotingChannel> pushableChannels = this.snodeController.getSubscriptionManager().getPushableChannel(topic, queueId);
if (pushableChannels != null) { if (pushableChannels != null) {
PushTask pushTask = new PushTask(topic, queueId, message, response); PushTask pushTask = new PushTask(topic, queueId, message, response, enodeName);
pushMessageExecutorService.submit(pushTask); pushMessageExecutorService.submit(pushTask);
} else { } else {
log.info("Topic: {} QueueId: {} no need to push", topic, queueId); log.info("Topic: {} QueueId: {} no need to push", topic, queueId);
} }
} }
@Override
public void start() {
}
@Override @Override
public void shutdown() { public void shutdown() {
this.pushMessageExecutorService.shutdown(); this.pushMessageExecutorService.shutdown();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册