mirror of
https://github.com/apache/rocketmq.git
synced 2026-09-01 15:47:01 +08:00
Add flow control logic
This commit is contained in:
@@ -999,7 +999,7 @@ public class BrokerController {
|
||||
}
|
||||
|
||||
public void registerServerRPCHook(RPCHook rpcHook) {
|
||||
getRemotingServer().registerRPCHook(rpcHook);
|
||||
// getRemotingServer().registerRPCHook(rpcHook);
|
||||
}
|
||||
|
||||
public RemotingServer getRemotingServer() {
|
||||
|
||||
@@ -72,7 +72,7 @@ public class BrokerOuterAPI {
|
||||
|
||||
public BrokerOuterAPI(final ClientConfig nettyClientConfig, RPCHook rpcHook) {
|
||||
this.remotingClient = RemotingClientFactory.getInstance().createRemotingClient().init(nettyClientConfig, null);
|
||||
this.remotingClient.registerRPCHook(rpcHook);
|
||||
// this.remotingClient.registerRPCHook(rpcHook);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
@@ -193,6 +193,9 @@ public class BrokerOuterAPI {
|
||||
|
||||
RemotingCommand response = this.remotingClient.invokeSync(namesrvAddr, request, timeoutMills);
|
||||
assert response != null;
|
||||
if (response == null){
|
||||
System.out.println("ssssssssssssss");
|
||||
}
|
||||
switch (response.getCode()) {
|
||||
case ResponseCode.SUCCESS: {
|
||||
RegisterBrokerResponseHeader responseHeader =
|
||||
@@ -393,6 +396,6 @@ public class BrokerOuterAPI {
|
||||
}
|
||||
|
||||
public void registerRPCHook(RPCHook rpcHook) {
|
||||
remotingClient.registerRPCHook(rpcHook);
|
||||
// remotingClient.registerRPCHook(rpcHook);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,6 +145,8 @@ import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException;
|
||||
import org.apache.rocketmq.remoting.ClientConfig;
|
||||
import org.apache.rocketmq.remoting.interceptor.Interceptor;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorGroup;
|
||||
import org.apache.rocketmq.remoting.netty.ResponseFuture;
|
||||
import org.apache.rocketmq.remoting.serialize.LanguageCode;
|
||||
import org.apache.rocketmq.remoting.protocol.RemotingCommand;
|
||||
@@ -169,13 +171,13 @@ public class MQClientAPIImpl {
|
||||
|
||||
public MQClientAPIImpl(final ClientConfig nettyClientConfig,
|
||||
final ClientRemotingProcessor clientRemotingProcessor,
|
||||
RPCHook rpcHook, final org.apache.rocketmq.client.ClientConfig clientConfig) {
|
||||
InterceptorGroup interceptorGroup, final org.apache.rocketmq.client.ClientConfig clientConfig) {
|
||||
this.clientConfig = clientConfig;
|
||||
topAddressing = new TopAddressing(MixAll.getWSAddr(), clientConfig.getUnitName());
|
||||
this.remotingClient = new NettyRemotingClient(nettyClientConfig, null);
|
||||
this.clientRemotingProcessor = clientRemotingProcessor;
|
||||
|
||||
this.remotingClient.registerRPCHook(rpcHook);
|
||||
this.remotingClient.registerInterceptorGroup(interceptorGroup);
|
||||
this.remotingClient.registerProcessor(RequestCode.CHECK_TRANSACTION_STATE, this.clientRemotingProcessor, null);
|
||||
|
||||
this.remotingClient.registerProcessor(RequestCode.NOTIFY_CONSUMER_IDS_CHANGED, this.clientRemotingProcessor, null);
|
||||
@@ -556,7 +558,7 @@ public class MQClientAPIImpl {
|
||||
}
|
||||
|
||||
public PullResult pullMessage(
|
||||
String addr,
|
||||
String addr,
|
||||
final PullMessageRequestHeader requestHeader,
|
||||
final long timeoutMillis,
|
||||
final CommunicationMode communicationMode,
|
||||
|
||||
@@ -50,7 +50,7 @@ public class MQClientManager {
|
||||
if (null == instance) {
|
||||
instance =
|
||||
new MQClientInstance(clientConfig.cloneClientConfig(),
|
||||
this.factoryIndexGenerator.getAndIncrement(), clientId, rpcHook);
|
||||
this.factoryIndexGenerator.getAndIncrement(), clientId, null);
|
||||
MQClientInstance prev = this.factoryTable.putIfAbsent(clientId, instance);
|
||||
if (prev != null) {
|
||||
instance = prev;
|
||||
|
||||
@@ -79,6 +79,8 @@ import org.apache.rocketmq.remoting.RPCHook;
|
||||
import org.apache.rocketmq.remoting.common.RemotingHelper;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingException;
|
||||
import org.apache.rocketmq.remoting.ClientConfig;
|
||||
import org.apache.rocketmq.remoting.interceptor.Interceptor;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorGroup;
|
||||
import org.apache.rocketmq.remoting.protocol.RemotingCommand;
|
||||
|
||||
public class MQClientInstance {
|
||||
@@ -121,14 +123,15 @@ public class MQClientInstance {
|
||||
this(clientConfig, instanceIndex, clientId, null);
|
||||
}
|
||||
|
||||
public MQClientInstance(org.apache.rocketmq.client.ClientConfig clientConfig, int instanceIndex, String clientId, RPCHook rpcHook) {
|
||||
public MQClientInstance(org.apache.rocketmq.client.ClientConfig clientConfig, int instanceIndex, String clientId,
|
||||
InterceptorGroup interceptorGroup) {
|
||||
this.clientConfig = clientConfig;
|
||||
this.instanceIndex = instanceIndex;
|
||||
this.nettyClientConfig = new ClientConfig();
|
||||
this.nettyClientConfig.setClientCallbackExecutorThreads(clientConfig.getClientCallbackExecutorThreads());
|
||||
this.nettyClientConfig.setUseTLS(clientConfig.isUseTLS());
|
||||
this.clientRemotingProcessor = new ClientRemotingProcessor(this);
|
||||
this.mQClientAPIImpl = new MQClientAPIImpl(this.nettyClientConfig, this.clientRemotingProcessor, rpcHook, clientConfig);
|
||||
this.mQClientAPIImpl = new MQClientAPIImpl(this.nettyClientConfig, this.clientRemotingProcessor, interceptorGroup, clientConfig);
|
||||
|
||||
if (this.clientConfig.getNamesrvAddr() != null) {
|
||||
this.mQClientAPIImpl.updateNameServerAddressList(this.clientConfig.getNamesrvAddr());
|
||||
|
||||
@@ -37,5 +37,9 @@
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>rocketmq-remoting</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
*/
|
||||
package org.apache.rocketmq.common;
|
||||
|
||||
import com.alibaba.fastjson.parser.ParserConfig;
|
||||
import com.alibaba.fastjson.util.TypeUtils;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.RuntimeMXBean;
|
||||
@@ -28,19 +31,21 @@ import java.net.NetworkInterface;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.CRC32;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
import org.apache.rocketmq.common.constant.LoggerName;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.remoting.common.RemotingHelper;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
public class UtilAll {
|
||||
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
|
||||
@@ -517,4 +522,23 @@ public class UtilAll {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T getYamlDataObject(String path, Class<T> clazz) {
|
||||
Yaml ymal = new Yaml();
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(new File(path));
|
||||
return ymal.loadAs(fis, clazz);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(String.format("The file for Plain mode was not found , paths %s", path), e);
|
||||
} finally {
|
||||
if (fis != null) {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("close transport fileInputStream Exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.common.flowcontrol;
|
||||
|
||||
import com.alibaba.csp.sentinel.SphO;
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.remoting.common.RemotingHelper;
|
||||
import org.apache.rocketmq.remoting.interceptor.ExceptionContext;
|
||||
import org.apache.rocketmq.remoting.interceptor.Interceptor;
|
||||
import org.apache.rocketmq.remoting.interceptor.RequestContext;
|
||||
import org.apache.rocketmq.remoting.interceptor.ResponseContext;
|
||||
|
||||
public abstract class AbstractFlowControlService implements Interceptor {
|
||||
private static final InternalLogger log = InternalLoggerFactory.getLogger(RemotingHelper.ROCKETMQ_REMOTING);
|
||||
private final ThreadLocal<Boolean> acquiredThreadLocal = new ThreadLocal<Boolean>();
|
||||
private final FlowControlConfig flowControlConfig;
|
||||
|
||||
public AbstractFlowControlService() {
|
||||
this.flowControlConfig = new FlowControlConfig();
|
||||
loadRules(this.flowControlConfig);
|
||||
}
|
||||
|
||||
public abstract String getResourceKey(RequestContext requestContext);
|
||||
|
||||
public abstract int getResourceCount(RequestContext requestContext);
|
||||
|
||||
public abstract String getFlowControlType();
|
||||
|
||||
public abstract void rejectRequest(RequestContext requestContext);
|
||||
|
||||
@Override
|
||||
public void beforeRequest(RequestContext requestContext) {
|
||||
String resourceKey = getResourceKey(requestContext);
|
||||
int resourceCount = getResourceCount(requestContext);
|
||||
resourceCount = resourceCount == 0 ? 1 : resourceCount;
|
||||
if (resourceKey != null) {
|
||||
boolean acquired = SphO.entry(resourceKey, resourceCount);
|
||||
if (acquired) {
|
||||
this.acquiredThreadLocal.set(true);
|
||||
} else {
|
||||
rejectRequest(requestContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterRequest(ResponseContext responseContext) {
|
||||
Boolean acquired = this.acquiredThreadLocal.get();
|
||||
if (acquired != null && acquired == true) {
|
||||
SphO.exit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(ExceptionContext exceptionContext) {
|
||||
Boolean acquired = this.acquiredThreadLocal.get();
|
||||
if (acquired != null && acquired == true) {
|
||||
SphO.exit();
|
||||
}
|
||||
}
|
||||
|
||||
public List<FlowControlRule> getRules(String moduleName, String flowControlType) {
|
||||
if (this.flowControlConfig != null) {
|
||||
Map<String, Map<String, List<FlowControlRule>>> rules = this.flowControlConfig.getPlainFlowControlRules();
|
||||
Map<String, List<FlowControlRule>> flowControlMap = rules.get(moduleName);
|
||||
if (flowControlMap != null) {
|
||||
if (flowControlMap.get(flowControlType) != null) {
|
||||
return flowControlMap.get(flowControlType);
|
||||
} else {
|
||||
log.warn("Get flow control config null by flowControlType: {} ", flowControlType);
|
||||
}
|
||||
} else {
|
||||
log.warn("Get flow control config null by moduleName: {} ", moduleName);
|
||||
}
|
||||
} else {
|
||||
log.warn("flowControlConfig is null ");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void loadRules(FlowControlConfig flowControlConfig) {
|
||||
Map<String, Map<String, List<FlowControlRule>>> rules = flowControlConfig.getPlainFlowControlRules();
|
||||
for (Map<String, List<FlowControlRule>> flowControlTypeMap : rules.values()) {
|
||||
for (List<FlowControlRule> list : flowControlTypeMap.values()) {
|
||||
for (FlowControlRule flowControlRule : list) {
|
||||
List<FlowRule> sentinelRules = new ArrayList<FlowRule>();
|
||||
FlowRule rule1 = new FlowRule();
|
||||
rule1.setResource(flowControlRule.getFlowControlResourceName());
|
||||
rule1.setCount(flowControlRule.getFlowControlResourceCount());
|
||||
rule1.setGrade(flowControlRule.getFlowControlGrade());
|
||||
rule1.setLimitApp("default");
|
||||
sentinelRules.add(rule1);
|
||||
FlowRuleManager.loadRules(sentinelRules);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.common.flowcontrol;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.apache.rocketmq.common.MixAll;
|
||||
import org.apache.rocketmq.common.UtilAll;
|
||||
import org.apache.rocketmq.common.constant.LoggerName;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
|
||||
public class FlowControlConfig {
|
||||
|
||||
private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
|
||||
|
||||
private String flowControlFileHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY, System.getenv(MixAll.ROCKETMQ_HOME_ENV));
|
||||
private static final String DEFAULT_FLOW_CONTROL_FILE = "conf/flowControl.yml";
|
||||
|
||||
private String flowControlFileName = System.getProperty("rocketmq.flow.control.file", DEFAULT_FLOW_CONTROL_FILE);
|
||||
|
||||
private List<FlowControlRule> rules;
|
||||
|
||||
public static final String defaultResourceName = "overallFlowControl";
|
||||
|
||||
private Map<String/*server name*/, Map<String/*flowControlType*/, List<FlowControlRule>>> plainFlowControlRules;
|
||||
|
||||
public FlowControlConfig() {
|
||||
loadFlowControlConfig();
|
||||
}
|
||||
|
||||
public void loadFlowControlConfig() {
|
||||
JSONObject jsonObject = UtilAll.getYamlDataObject(flowControlFileHome + File.separator + flowControlFileName,
|
||||
JSONObject.class);
|
||||
if (jsonObject != null && jsonObject.size() > 0) {
|
||||
plainFlowControlRules = new HashMap<String/*server name*/, Map<String /*flowControlType*/, List<FlowControlRule>>>();
|
||||
Set<Map.Entry<String, Object>> entries = jsonObject.entrySet();
|
||||
for (Map.Entry<String, Object> entry : entries) {
|
||||
String serverName = entry.getKey();
|
||||
Map<String /*flowControlType*/, List<FlowControlRule>> flowControlTypeMap = plainFlowControlRules.get(serverName);
|
||||
if (flowControlTypeMap == null) {
|
||||
flowControlTypeMap = new HashMap<String, List<FlowControlRule>>();
|
||||
plainFlowControlRules.put(serverName, flowControlTypeMap);
|
||||
}
|
||||
|
||||
LinkedHashMap flowControlMap = (LinkedHashMap) entry.getValue();
|
||||
Iterator iter = flowControlMap.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry tmp = (Map.Entry) iter.next();
|
||||
String flowControlType = (String) tmp.getKey();
|
||||
List jsonList = (ArrayList) tmp.getValue();
|
||||
if (jsonList != null) {
|
||||
for (Object json : jsonList) {
|
||||
Map map = (LinkedHashMap) json;
|
||||
FlowControlRule flowControlRule = JSON.parseObject(JSON.toJSONString(map), FlowControlRule.class);
|
||||
List<FlowControlRule> flowControlRules = flowControlTypeMap.get(flowControlType);
|
||||
if (flowControlRules == null) {
|
||||
flowControlRules = new ArrayList<FlowControlRule>();
|
||||
flowControlTypeMap.put(flowControlType, flowControlRules);
|
||||
}
|
||||
flowControlRules.add(flowControlRule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
log.warn("Load topic config: {}", this.plainFlowControlRules);
|
||||
}
|
||||
|
||||
public Map<String, Map<String, List<FlowControlRule>>> getPlainFlowControlRules() {
|
||||
return plainFlowControlRules;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.common.flowcontrol;
|
||||
|
||||
import org.apache.rocketmq.remoting.interceptor.Interceptor;
|
||||
|
||||
public class FlowControlRule {
|
||||
private String flowControlResourceName;
|
||||
private Integer flowControlGrade;
|
||||
private Integer flowControlBehavior;
|
||||
private double flowControlResourceCount;
|
||||
|
||||
public String getFlowControlResourceName() {
|
||||
return flowControlResourceName;
|
||||
}
|
||||
|
||||
public void setFlowControlResourceName(String flowControlResourceName) {
|
||||
this.flowControlResourceName = flowControlResourceName;
|
||||
}
|
||||
|
||||
public Integer getFlowControlGrade() {
|
||||
return flowControlGrade;
|
||||
}
|
||||
|
||||
public void setFlowControlGrade(Integer flowControlGrade) {
|
||||
this.flowControlGrade = flowControlGrade;
|
||||
}
|
||||
|
||||
public Integer getFlowControlBehavior() {
|
||||
return flowControlBehavior;
|
||||
}
|
||||
|
||||
public void setFlowControlBehavior(Integer flowControlBehavior) {
|
||||
this.flowControlBehavior = flowControlBehavior;
|
||||
}
|
||||
|
||||
public double getFlowControlResourceCount() {
|
||||
return flowControlResourceCount;
|
||||
}
|
||||
|
||||
public void setFlowControlResourceCount(double flowControlResourceCount) {
|
||||
this.flowControlResourceCount = flowControlResourceCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FlowControlRule{" +
|
||||
"flowControlResourceName='" + flowControlResourceName + '\'' +
|
||||
", flowControlGrade=" + flowControlGrade +
|
||||
", flowControlBehavior=" + flowControlBehavior +
|
||||
", flowControlResourceCount=" + flowControlResourceCount +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,6 @@ public class Consumer {
|
||||
* Launch the consumer instance.
|
||||
*/
|
||||
consumer.start();
|
||||
|
||||
System.out.printf("Consumer Started.%n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,6 +598,16 @@
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<version>2.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-core</artifactId>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.19</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
</project>
|
||||
|
||||
+10
-2
@@ -28,8 +28,8 @@
|
||||
<name>rocketmq-remoting ${project.version}</name>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.6</maven.compiler.source>
|
||||
<maven.compiler.target>1.6</maven.compiler.target>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -54,5 +54,13 @@
|
||||
<artifactId>netty-tcnative-boringssl-static</artifactId>
|
||||
<version>1.1.33.Fork26</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.apache.rocketmq.remoting.common.Pair;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorGroup;
|
||||
import org.apache.rocketmq.remoting.protocol.RemotingCommand;
|
||||
|
||||
public interface RemotingServer extends RemotingService {
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
|
||||
package org.apache.rocketmq.remoting;
|
||||
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorGroup;
|
||||
|
||||
public interface RemotingService {
|
||||
void start();
|
||||
|
||||
void shutdown();
|
||||
|
||||
void registerRPCHook(RPCHook rpcHook);
|
||||
void registerInterceptorGroup(InterceptorGroup interceptorGroup);
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.remoting.exception;
|
||||
|
||||
public class RemotingRuntimeException extends RuntimeException {
|
||||
private final int responseCode;
|
||||
private final String responseMessage;
|
||||
|
||||
public RemotingRuntimeException(int responseCode, String errorMessage) {
|
||||
this.responseCode = responseCode;
|
||||
this.responseMessage = errorMessage;
|
||||
}
|
||||
|
||||
public int getResponseCode() {
|
||||
return responseCode;
|
||||
}
|
||||
|
||||
public String getResponseMessage() {
|
||||
return responseMessage;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.rocketmq.remoting.interceptor;
|
||||
|
||||
import org.apache.rocketmq.remoting.RemotingChannel;
|
||||
import org.apache.rocketmq.remoting.protocol.RemotingCommand;
|
||||
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.rocketmq.remoting.interceptor;
|
||||
|
||||
public interface Interceptor {
|
||||
|
||||
String interceptorName();
|
||||
|
||||
void beforeRequest(RequestContext requestContext);
|
||||
|
||||
void afterRequest(ResponseContext responseContext);
|
||||
|
||||
+4
-3
@@ -15,14 +15,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.rocketmq.remoting.interceptor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class InterceptorGroup {
|
||||
private List<Interceptor> interceptors = new ArrayList<Interceptor>();
|
||||
private List<Interceptor> interceptors = new ArrayList<>();
|
||||
|
||||
public void registerInterceptor(Interceptor interceptor) {
|
||||
if (interceptor != null) {
|
||||
public synchronized void registerInterceptor(Interceptor interceptor) {
|
||||
if (interceptor != null && !interceptors.contains(interceptor)) {
|
||||
interceptors.add(interceptor);
|
||||
}
|
||||
}
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.remoting.interceptor;
|
||||
|
||||
import org.apache.rocketmq.remoting.RemotingChannel;
|
||||
import org.apache.rocketmq.remoting.protocol.RemotingCommand;
|
||||
|
||||
public class InterceptorInvoker {
|
||||
public static void invokeBeforeRequest(InterceptorGroup interceptorGroup, RemotingChannel remotingChannel,
|
||||
RemotingCommand request) {
|
||||
if (interceptorGroup != null) {
|
||||
RequestContext requestContext = new RequestContext(request, remotingChannel);
|
||||
interceptorGroup.beforeRequest(requestContext);
|
||||
}
|
||||
}
|
||||
|
||||
public static void invokeAfterRequest(InterceptorGroup interceptorGroup, RemotingChannel remotingChannel,
|
||||
RemotingCommand request, RemotingCommand response) {
|
||||
if (interceptorGroup != null) {
|
||||
ResponseContext responseContext = new ResponseContext(request, remotingChannel, response);
|
||||
interceptorGroup.afterRequest(responseContext);
|
||||
}
|
||||
}
|
||||
|
||||
public static void invokeOnException(InterceptorGroup interceptorGroup, RemotingChannel remotingChannel,
|
||||
RemotingCommand request, Throwable throwable, String remark) {
|
||||
if (interceptorGroup != null) {
|
||||
ExceptionContext exceptionContext = new ExceptionContext(request, remotingChannel, throwable, remark);
|
||||
interceptorGroup.onException(exceptionContext);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.rocketmq.remoting.interceptor;
|
||||
|
||||
import org.apache.rocketmq.remoting.RemotingChannel;
|
||||
import org.apache.rocketmq.remoting.protocol.RemotingCommand;
|
||||
|
||||
@@ -23,8 +24,8 @@ public class RequestContext {
|
||||
protected RemotingChannel remotingChannel;
|
||||
|
||||
public RequestContext(RemotingCommand request, RemotingChannel remotingChannel) {
|
||||
this.remotingChannel = remotingChannel;
|
||||
this.request = request;
|
||||
this.remotingChannel = remotingChannel;
|
||||
}
|
||||
|
||||
public RemotingCommand getRequest() {
|
||||
|
||||
+93
-24
@@ -37,20 +37,22 @@ import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.remoting.ChannelEventListener;
|
||||
import org.apache.rocketmq.remoting.InvokeCallback;
|
||||
import org.apache.rocketmq.remoting.RemotingChannel;
|
||||
import org.apache.rocketmq.remoting.RequestProcessor;
|
||||
import org.apache.rocketmq.remoting.RPCHook;
|
||||
import org.apache.rocketmq.remoting.common.Pair;
|
||||
import org.apache.rocketmq.remoting.common.RemotingHelper;
|
||||
import org.apache.rocketmq.remoting.common.SemaphoreReleaseOnlyOnce;
|
||||
import org.apache.rocketmq.remoting.common.ServiceThread;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingRuntimeException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorGroup;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorInvoker;
|
||||
import org.apache.rocketmq.remoting.protocol.RemotingCommand;
|
||||
import org.apache.rocketmq.remoting.protocol.RemotingSysResponseCode;
|
||||
import org.apache.rocketmq.remoting.util.ThreadUtils;
|
||||
@@ -194,21 +196,15 @@ public abstract class NettyRemotingAbstract {
|
||||
final Pair<RequestProcessor, ExecutorService> matched = this.processorTable.get(cmd.getCode());
|
||||
final Pair<RequestProcessor, ExecutorService> pair = null == matched ? this.defaultRequestProcessor : matched;
|
||||
final int opaque = cmd.getOpaque();
|
||||
|
||||
final InterceptorGroup interceptorGroup = NettyRemotingAbstract.this.getInterceptorGroup();
|
||||
if (pair != null) {
|
||||
Runnable run = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
RPCHook rpcHook = NettyRemotingAbstract.this.getRPCHook();
|
||||
if (rpcHook != null) {
|
||||
rpcHook.doBeforeRequest(RemotingHelper.parseChannelRemoteAddr(ctx.channel()), cmd);
|
||||
}
|
||||
|
||||
InterceptorInvoker.invokeBeforeRequest(interceptorGroup, remotingChannel, cmd);
|
||||
final RemotingCommand response = pair.getObject1().processRequest(remotingChannel, cmd);
|
||||
if (rpcHook != null) {
|
||||
rpcHook.doAfterResponse(RemotingHelper.parseChannelRemoteAddr(ctx.channel()), cmd, response);
|
||||
}
|
||||
InterceptorInvoker.invokeAfterRequest(interceptorGroup, remotingChannel, cmd, response);
|
||||
|
||||
if (!cmd.isOnewayRPC()) {
|
||||
if (response != null) {
|
||||
@@ -221,17 +217,22 @@ public abstract class NettyRemotingAbstract {
|
||||
log.error(cmd.toString());
|
||||
log.error(response.toString());
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
log.error("process request exception", e);
|
||||
} catch (Throwable throwable) {
|
||||
log.error("Process request exception", throwable);
|
||||
log.error(cmd.toString());
|
||||
|
||||
InterceptorInvoker.invokeOnException(interceptorGroup, remotingChannel, cmd, throwable, null);
|
||||
int responseCode = RemotingSysResponseCode.SYSTEM_ERROR;
|
||||
String responseMessage = RemotingHelper.exceptionSimpleDesc(throwable);
|
||||
if (!cmd.isOnewayRPC()) {
|
||||
final RemotingCommand response = RemotingCommand.createResponseCommand(RemotingSysResponseCode.SYSTEM_ERROR,
|
||||
RemotingHelper.exceptionSimpleDesc(e));
|
||||
if (throwable instanceof RemotingRuntimeException) {
|
||||
RemotingRuntimeException remotingRuntimeException = (RemotingRuntimeException) throwable;
|
||||
responseCode = remotingRuntimeException.getResponseCode();
|
||||
responseMessage = remotingRuntimeException.getResponseMessage();
|
||||
}
|
||||
final RemotingCommand response = RemotingCommand.createResponseCommand(responseCode,
|
||||
responseMessage);
|
||||
response.setOpaque(opaque);
|
||||
ctx.writeAndFlush(response);
|
||||
}
|
||||
@@ -340,11 +341,11 @@ public abstract class NettyRemotingAbstract {
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom RPC hook.
|
||||
* Custom interceptor hook.
|
||||
*
|
||||
* @return RPC hook if specified; null otherwise.
|
||||
*/
|
||||
public abstract RPCHook getRPCHook();
|
||||
public abstract InterceptorGroup getInterceptorGroup();
|
||||
|
||||
/**
|
||||
* This method specifies thread pool to use while invoking callback methods.
|
||||
@@ -407,6 +408,26 @@ public abstract class NettyRemotingAbstract {
|
||||
}
|
||||
}
|
||||
|
||||
public RemotingCommand invokeSyncWithInterceptor(final RemotingChannel remotingChannel,
|
||||
final RemotingCommand request,
|
||||
final long timeoutMillis) throws InterruptedException, RemotingSendRequestException, RemotingTimeoutException {
|
||||
InterceptorGroup interceptorGroup = getInterceptorGroup();
|
||||
InterceptorInvoker.invokeBeforeRequest(interceptorGroup, remotingChannel, request);
|
||||
Channel channel = null;
|
||||
if (remotingChannel instanceof NettyChannelImpl) {
|
||||
channel = ((NettyChannelImpl) remotingChannel).getChannel();
|
||||
}
|
||||
try {
|
||||
RemotingCommand response = invokeSyncImpl(channel, request, timeoutMillis);
|
||||
InterceptorInvoker.invokeAfterRequest(interceptorGroup, remotingChannel, request, response);
|
||||
return response;
|
||||
} catch (InterruptedException | RemotingSendRequestException | RemotingTimeoutException ex) {
|
||||
InterceptorInvoker.invokeOnException(interceptorGroup, remotingChannel, request, ex, null);
|
||||
log.error("Sync invoke error ", ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public RemotingCommand invokeSyncImpl(final Channel channel, final RemotingCommand request,
|
||||
final long timeoutMillis)
|
||||
throws InterruptedException, RemotingSendRequestException, RemotingTimeoutException {
|
||||
@@ -429,11 +450,12 @@ public abstract class NettyRemotingAbstract {
|
||||
responseTable.remove(opaque);
|
||||
responseFuture.setCause(f.cause());
|
||||
responseFuture.putResponse(null);
|
||||
log.warn("send a request command to channel <" + addr + "> failed.");
|
||||
log.warn("Send a request command to channel <" + addr + "> failed.");
|
||||
}
|
||||
});
|
||||
|
||||
RemotingCommand responseCommand = responseFuture.waitResponse(timeoutMillis);
|
||||
|
||||
if (null == responseCommand) {
|
||||
if (responseFuture.isSendRequestOK()) {
|
||||
throw new RemotingTimeoutException(RemotingHelper.parseSocketAddressAddr(addr), timeoutMillis,
|
||||
@@ -449,7 +471,26 @@ public abstract class NettyRemotingAbstract {
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected Channel getAndCreateChannel(final String addr, long timeout) throws InterruptedException;
|
||||
abstract protected RemotingChannel getAndCreateChannel(final String addr, long timeout) throws InterruptedException;
|
||||
|
||||
public void invokeAsyncWithInterceptor(
|
||||
final RemotingChannel remotingChannel,
|
||||
final RemotingCommand request,
|
||||
final long timeoutMillis,
|
||||
final InvokeCallback invokeCallback) throws InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException {
|
||||
InterceptorGroup interceptorGroup = this.getInterceptorGroup();
|
||||
InterceptorInvoker.invokeBeforeRequest(interceptorGroup, remotingChannel, request);
|
||||
Channel channel = null;
|
||||
if (remotingChannel instanceof NettyChannelImpl) {
|
||||
channel = ((NettyChannelImpl) remotingChannel).getChannel();
|
||||
}
|
||||
try {
|
||||
invokeAsyncImpl(channel, request, timeoutMillis, invokeCallback);
|
||||
} catch (InterruptedException | RemotingTooMuchRequestException | RemotingTimeoutException | RemotingSendRequestException ex) {
|
||||
InterceptorInvoker.invokeOnException(interceptorGroup, remotingChannel, request, ex, null);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public void invokeAsyncImpl(final Channel channel, final RemotingCommand request,
|
||||
final long timeoutMillis,
|
||||
@@ -488,7 +529,10 @@ public abstract class NettyRemotingAbstract {
|
||||
final String remotingAddr = RemotingHelper.parseChannelRemoteAddr(channel);
|
||||
try {
|
||||
if (channel == null) {
|
||||
channel = getAndCreateChannel(addr, timeoutMillis);
|
||||
RemotingChannel remotingChannel = getAndCreateChannel(addr, timeoutMillis);
|
||||
if (remotingChannel != null && remotingChannel instanceof NettyChannelImpl) {
|
||||
channel = ((NettyChannelImpl) remotingChannel).getChannel();
|
||||
}
|
||||
responseFuture.setProcessChannel(channel);
|
||||
}
|
||||
channel.writeAndFlush(request).addListener(new ChannelFutureListener() {
|
||||
@@ -558,6 +602,26 @@ public abstract class NettyRemotingAbstract {
|
||||
}
|
||||
}
|
||||
|
||||
public void invokeOnewayWithInterceptor(final RemotingChannel remotingChannel, final RemotingCommand request,
|
||||
final long timeoutMillis)
|
||||
throws
|
||||
InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException {
|
||||
Channel channel = null;
|
||||
|
||||
InterceptorGroup interceptorGroup = this.getInterceptorGroup();
|
||||
InterceptorInvoker.invokeBeforeRequest(interceptorGroup, remotingChannel, request);
|
||||
|
||||
if (remotingChannel instanceof NettyChannelImpl) {
|
||||
channel = ((NettyChannelImpl) remotingChannel).getChannel();
|
||||
}
|
||||
try {
|
||||
invokeOnewayImpl(channel, request, timeoutMillis);
|
||||
} catch (InterruptedException | RemotingTooMuchRequestException | RemotingTimeoutException | RemotingSendRequestException ex) {
|
||||
InterceptorInvoker.invokeOnException(interceptorGroup, remotingChannel, request, ex, null);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public void invokeOnewayImpl(final Channel channel, final RemotingCommand request, final long timeoutMillis)
|
||||
throws
|
||||
InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException {
|
||||
@@ -650,6 +714,11 @@ public abstract class NettyRemotingAbstract {
|
||||
}
|
||||
}
|
||||
|
||||
public void registerNettyProcessor(int requestCode, RequestProcessor processor, ExecutorService executor) {
|
||||
Pair<RequestProcessor, ExecutorService> pair = new Pair<>(processor, executor);
|
||||
this.processorTable.put(requestCode, pair);
|
||||
}
|
||||
|
||||
public class NettyServerHandler extends SimpleChannelInboundHandler<RemotingCommand> {
|
||||
|
||||
@Override
|
||||
|
||||
+29
-10
@@ -38,8 +38,11 @@ import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.remoting.RemotingChannel;
|
||||
import org.apache.rocketmq.remoting.common.RemotingHelper;
|
||||
import org.apache.rocketmq.remoting.common.RemotingUtil;
|
||||
import org.apache.rocketmq.remoting.netty.NettyChannelHandlerContextImpl;
|
||||
import org.apache.rocketmq.remoting.netty.NettyChannelImpl;
|
||||
import org.apache.rocketmq.remoting.netty.NettyEvent;
|
||||
import org.apache.rocketmq.remoting.netty.NettyEventType;
|
||||
import org.apache.rocketmq.remoting.netty.NettyRemotingAbstract;
|
||||
@@ -72,11 +75,21 @@ public abstract class NettyRemotingClientAbstract extends NettyRemotingAbstract
|
||||
return Math.abs(r.nextInt() % 999) % 999;
|
||||
}
|
||||
|
||||
public void closeRemotingChannel(final String addr, final RemotingChannel remotingChannel) {
|
||||
Channel channel = null;
|
||||
if (remotingChannel instanceof NettyChannelImpl) {
|
||||
channel = ((NettyChannelImpl) remotingChannel).getChannel();
|
||||
}
|
||||
if (remotingChannel instanceof NettyChannelHandlerContextImpl) {
|
||||
channel = ((NettyChannelHandlerContextImpl) remotingChannel).getChannelHandlerContext().channel();
|
||||
}
|
||||
closeChannel(addr, channel);
|
||||
}
|
||||
|
||||
public void closeChannel(final String addr, final Channel channel) {
|
||||
if (null == channel) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String addrRemote = null == addr ? RemotingHelper.parseChannelRemoteAddr(channel) : addr;
|
||||
|
||||
try {
|
||||
@@ -122,7 +135,7 @@ public abstract class NettyRemotingClientAbstract extends NettyRemotingAbstract
|
||||
this.channelTables.clear();
|
||||
}
|
||||
|
||||
public void closeChannel(final Channel channel) {
|
||||
private void closeChannel(final Channel channel) {
|
||||
if (null == channel) {
|
||||
return;
|
||||
}
|
||||
@@ -169,17 +182,23 @@ public abstract class NettyRemotingClientAbstract extends NettyRemotingAbstract
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Channel getAndCreateChannel(final String addr, long timeout) throws InterruptedException {
|
||||
protected RemotingChannel getAndCreateChannel(final String addr, long timeout) throws InterruptedException {
|
||||
Channel channel = null;
|
||||
if (null == addr) {
|
||||
return getAndCreateNameServerChannel(timeout);
|
||||
channel = getAndCreateNameServerChannel(timeout);
|
||||
} else {
|
||||
ChannelWrapper cw = this.channelTables.get(addr);
|
||||
if (cw != null && cw.isOK()) {
|
||||
channel = cw.getChannel();
|
||||
} else {
|
||||
channel = this.createChannel(addr, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
ChannelWrapper cw = this.channelTables.get(addr);
|
||||
if (cw != null && cw.isOK()) {
|
||||
return cw.getChannel();
|
||||
if (channel != null) {
|
||||
RemotingChannel remotingChannel = new NettyChannelImpl(channel);
|
||||
return remotingChannel;
|
||||
}
|
||||
|
||||
return this.createChannel(addr, timeout);
|
||||
return null;
|
||||
}
|
||||
|
||||
private Channel getAndCreateNameServerChannel(long timeout) throws InterruptedException {
|
||||
|
||||
-4
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
package org.apache.rocketmq.remoting.transport;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.timeout.IdleState;
|
||||
@@ -108,7 +107,4 @@ public abstract class NettyRemotingServerAbstract extends NettyRemotingAbstract
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected Channel getAndCreateChannel(String addr, long timeout) throws InterruptedException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+35
-49
@@ -43,6 +43,7 @@ import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.remoting.ChannelEventListener;
|
||||
import org.apache.rocketmq.remoting.InvokeCallback;
|
||||
import org.apache.rocketmq.remoting.RPCHook;
|
||||
import org.apache.rocketmq.remoting.RemotingChannel;
|
||||
import org.apache.rocketmq.remoting.RemotingClient;
|
||||
import org.apache.rocketmq.remoting.common.Pair;
|
||||
import org.apache.rocketmq.remoting.common.RemotingHelper;
|
||||
@@ -51,6 +52,10 @@ import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException;
|
||||
import org.apache.rocketmq.remoting.ClientConfig;
|
||||
import org.apache.rocketmq.remoting.interceptor.Interceptor;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorGroup;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorInvoker;
|
||||
import org.apache.rocketmq.remoting.netty.NettyChannelImpl;
|
||||
import org.apache.rocketmq.remoting.transport.rocketmq.NettyDecoder;
|
||||
import org.apache.rocketmq.remoting.transport.rocketmq.NettyEncoder;
|
||||
import org.apache.rocketmq.remoting.RequestProcessor;
|
||||
@@ -67,7 +72,7 @@ public class Http2ClientImpl extends NettyRemotingClientAbstract implements Remo
|
||||
private ExecutorService callbackExecutor;
|
||||
private ChannelEventListener channelEventListener;
|
||||
private DefaultEventExecutorGroup defaultEventExecutorGroup;
|
||||
private RPCHook rpcHook;
|
||||
private InterceptorGroup interceptorGroup;
|
||||
|
||||
public Http2ClientImpl(final ClientConfig clientConfig,
|
||||
final ChannelEventListener channelEventListener) {
|
||||
@@ -75,7 +80,7 @@ public class Http2ClientImpl extends NettyRemotingClientAbstract implements Remo
|
||||
init(clientConfig, channelEventListener);
|
||||
}
|
||||
|
||||
public Http2ClientImpl(){
|
||||
public Http2ClientImpl() {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -139,12 +144,8 @@ public class Http2ClientImpl extends NettyRemotingClientAbstract implements Remo
|
||||
public void shutdown() {
|
||||
super.shutdown();
|
||||
try {
|
||||
clearChannels();
|
||||
|
||||
for (ChannelWrapper cw : this.channelTables.values()) {
|
||||
this.closeChannel(null, cw.getChannel());
|
||||
}
|
||||
|
||||
this.channelTables.clear();
|
||||
if (this.ioGroup != null) {
|
||||
this.ioGroup.shutdownGracefully();
|
||||
}
|
||||
@@ -166,8 +167,8 @@ public class Http2ClientImpl extends NettyRemotingClientAbstract implements Remo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRPCHook(RPCHook rpcHook) {
|
||||
this.rpcHook = rpcHook;
|
||||
public void registerInterceptorGroup(InterceptorGroup interceptorGroup) {
|
||||
this.interceptorGroup = interceptorGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -178,31 +179,25 @@ public class Http2ClientImpl extends NettyRemotingClientAbstract implements Remo
|
||||
@Override
|
||||
public RemotingCommand invokeSync(String addr, final RemotingCommand request, long timeoutMillis)
|
||||
throws InterruptedException, RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException {
|
||||
final Channel channel = this.getAndCreateChannel(addr, timeoutMillis);
|
||||
if (channel != null && channel.isActive()) {
|
||||
final RemotingChannel remotingChannel = this.getAndCreateChannel(addr, timeoutMillis);
|
||||
if (remotingChannel != null && remotingChannel.isActive()) {
|
||||
try {
|
||||
if (this.rpcHook != null) {
|
||||
this.rpcHook.doBeforeRequest(addr, request);
|
||||
}
|
||||
RemotingCommand response = this.invokeSyncImpl(channel, request, timeoutMillis);
|
||||
if (this.rpcHook != null) {
|
||||
this.rpcHook.doAfterResponse(RemotingHelper.parseChannelRemoteAddr(channel), request, response);
|
||||
}
|
||||
RemotingCommand response = this.invokeSyncWithInterceptor(remotingChannel, request, timeoutMillis);
|
||||
return response;
|
||||
} catch (RemotingSendRequestException e) {
|
||||
log.warn("invokeSync: send request exception, so close the channel[{}]", addr);
|
||||
this.closeChannel(addr, channel);
|
||||
log.warn("InvokeSync: send request exception, so close the channel[{}]", addr);
|
||||
this.closeRemotingChannel(addr, remotingChannel);
|
||||
throw e;
|
||||
} catch (RemotingTimeoutException e) {
|
||||
if (nettyClientConfig.isClientCloseSocketIfTimeout()) {
|
||||
this.closeChannel(addr, channel);
|
||||
log.warn("invokeSync: close socket because of timeout, {}ms, {}", timeoutMillis, addr);
|
||||
this.closeRemotingChannel(addr, remotingChannel);
|
||||
log.warn("InvokeSync: close socket because of timeout, {}ms, {}", timeoutMillis, addr);
|
||||
}
|
||||
log.warn("invokeSync: wait response timeout exception, the channel[{}]", addr);
|
||||
log.warn("InvokeSync: wait response timeout exception, the channel[{}]", addr);
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
this.closeChannel(addr, channel);
|
||||
this.closeRemotingChannel(addr, remotingChannel);
|
||||
throw new RemotingConnectException(addr);
|
||||
}
|
||||
}
|
||||
@@ -211,20 +206,19 @@ public class Http2ClientImpl extends NettyRemotingClientAbstract implements Remo
|
||||
public void invokeAsync(String addr, RemotingCommand request, long timeoutMillis, InvokeCallback invokeCallback)
|
||||
throws InterruptedException, RemotingConnectException, RemotingTooMuchRequestException, RemotingTimeoutException,
|
||||
RemotingSendRequestException {
|
||||
final Channel channel = this.getAndCreateChannel(addr, timeoutMillis);
|
||||
if (channel != null && channel.isActive()) {
|
||||
final RemotingChannel remotingChannel = this.getAndCreateChannel(addr, timeoutMillis);
|
||||
|
||||
if (remotingChannel != null && remotingChannel.isActive()) {
|
||||
try {
|
||||
if (this.rpcHook != null) {
|
||||
this.rpcHook.doBeforeRequest(addr, request);
|
||||
}
|
||||
this.invokeAsyncImpl(channel, request, timeoutMillis, invokeCallback);
|
||||
|
||||
this.invokeAsyncWithInterceptor(remotingChannel, request, timeoutMillis, invokeCallback);
|
||||
} catch (RemotingSendRequestException e) {
|
||||
log.warn("invokeAsync: send request exception, so close the channel[{}]", addr);
|
||||
this.closeChannel(addr, channel);
|
||||
this.closeRemotingChannel(addr, remotingChannel);
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
this.closeChannel(addr, channel);
|
||||
this.closeRemotingChannel(addr, remotingChannel);
|
||||
throw new RemotingConnectException(addr);
|
||||
}
|
||||
}
|
||||
@@ -232,20 +226,17 @@ public class Http2ClientImpl extends NettyRemotingClientAbstract implements Remo
|
||||
@Override
|
||||
public void invokeOneway(String addr, RemotingCommand request, long timeoutMillis) throws InterruptedException,
|
||||
RemotingConnectException, RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException {
|
||||
final Channel channel = this.getAndCreateChannel(addr, timeoutMillis);
|
||||
if (channel != null && channel.isActive()) {
|
||||
final RemotingChannel remotingChannel = this.getAndCreateChannel(addr, timeoutMillis);
|
||||
if (remotingChannel != null && remotingChannel.isActive()) {
|
||||
try {
|
||||
if (this.rpcHook != null) {
|
||||
this.rpcHook.doBeforeRequest(addr, request);
|
||||
}
|
||||
this.invokeOnewayImpl(channel, request, timeoutMillis);
|
||||
this.invokeOnewayWithInterceptor(remotingChannel, request, timeoutMillis);
|
||||
} catch (RemotingSendRequestException e) {
|
||||
log.warn("invokeOneway: send request exception, so close the channel[{}]", addr);
|
||||
this.closeChannel(addr, channel);
|
||||
this.closeRemotingChannel(addr, remotingChannel);
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
this.closeChannel(addr, channel);
|
||||
this.closeRemotingChannel(addr, remotingChannel);
|
||||
throw new RemotingConnectException(addr);
|
||||
}
|
||||
}
|
||||
@@ -257,13 +248,8 @@ public class Http2ClientImpl extends NettyRemotingClientAbstract implements Remo
|
||||
|
||||
@Override
|
||||
public void registerProcessor(int requestCode, RequestProcessor processor, ExecutorService executor) {
|
||||
ExecutorService executorThis = executor;
|
||||
if (null == executor) {
|
||||
executorThis = this.publicExecutor;
|
||||
}
|
||||
|
||||
Pair<RequestProcessor, ExecutorService> pair = new Pair<RequestProcessor, ExecutorService>(processor, executorThis);
|
||||
this.processorTable.put(requestCode, pair);
|
||||
executor = (executor == null ? this.publicExecutor : executor);
|
||||
registerNettyProcessor(requestCode, processor, executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -277,8 +263,8 @@ public class Http2ClientImpl extends NettyRemotingClientAbstract implements Remo
|
||||
}
|
||||
|
||||
@Override
|
||||
public RPCHook getRPCHook() {
|
||||
return this.rpcHook;
|
||||
public InterceptorGroup getInterceptorGroup() {
|
||||
return this.interceptorGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+14
-11
@@ -56,6 +56,8 @@ import org.apache.rocketmq.remoting.common.RemotingHelper;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException;
|
||||
import org.apache.rocketmq.remoting.interceptor.Interceptor;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorGroup;
|
||||
import org.apache.rocketmq.remoting.netty.ChannelStatisticsHandler;
|
||||
import org.apache.rocketmq.remoting.netty.NettyChannelImpl;
|
||||
import org.apache.rocketmq.remoting.transport.rocketmq.NettyDecoder;
|
||||
@@ -79,7 +81,7 @@ public class Http2ServerImpl extends NettyRemotingServerAbstract implements Remo
|
||||
private ChannelEventListener channelEventListener;
|
||||
private ExecutorService publicExecutor;
|
||||
private int port;
|
||||
private RPCHook rpcHook;
|
||||
private InterceptorGroup interceptorGroup;
|
||||
|
||||
public Http2ServerImpl(ServerConfig nettyServerConfig, ChannelEventListener channelEventListener) {
|
||||
super(nettyServerConfig.getServerOnewaySemaphoreValue(), nettyServerConfig.getServerAsyncSemaphoreValue());
|
||||
@@ -137,12 +139,8 @@ public class Http2ServerImpl extends NettyRemotingServerAbstract implements Remo
|
||||
|
||||
@Override
|
||||
public void registerProcessor(int requestCode, RequestProcessor processor, ExecutorService executor) {
|
||||
ExecutorService executorThis = executor;
|
||||
if (null == executor) {
|
||||
executorThis = this.publicExecutor;
|
||||
}
|
||||
Pair<RequestProcessor, ExecutorService> pair = new Pair<RequestProcessor, ExecutorService>(processor, executorThis);
|
||||
this.processorTable.put(requestCode, pair);
|
||||
executor = (executor == null ? this.publicExecutor : executor);
|
||||
registerNettyProcessor(requestCode, processor, executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -242,13 +240,18 @@ public class Http2ServerImpl extends NettyRemotingServerAbstract implements Remo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRPCHook(RPCHook rpcHook) {
|
||||
this.rpcHook = rpcHook;
|
||||
public void registerInterceptorGroup(InterceptorGroup interceptorGroup) {
|
||||
this.interceptorGroup = interceptorGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RPCHook getRPCHook() {
|
||||
return this.rpcHook;
|
||||
public InterceptorGroup getInterceptorGroup() {
|
||||
return this.interceptorGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RemotingChannel getAndCreateChannel(String addr, long timeout) throws InterruptedException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+46
-41
@@ -38,15 +38,24 @@ import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.remoting.ChannelEventListener;
|
||||
import org.apache.rocketmq.remoting.InvokeCallback;
|
||||
import org.apache.rocketmq.remoting.RPCHook;
|
||||
import org.apache.rocketmq.remoting.RemotingChannel;
|
||||
import org.apache.rocketmq.remoting.RemotingClient;
|
||||
import org.apache.rocketmq.remoting.common.Pair;
|
||||
import org.apache.rocketmq.remoting.common.RemotingHelper;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingConnectException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException;
|
||||
import org.apache.rocketmq.remoting.ClientConfig;
|
||||
import org.apache.rocketmq.remoting.RequestProcessor;
|
||||
import org.apache.rocketmq.remoting.interceptor.ExceptionContext;
|
||||
import org.apache.rocketmq.remoting.interceptor.Interceptor;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorGroup;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorInvoker;
|
||||
import org.apache.rocketmq.remoting.interceptor.RequestContext;
|
||||
import org.apache.rocketmq.remoting.interceptor.ResponseContext;
|
||||
import org.apache.rocketmq.remoting.netty.NettyChannelImpl;
|
||||
import org.apache.rocketmq.remoting.netty.TlsHelper;
|
||||
import org.apache.rocketmq.remoting.protocol.RemotingCommand;
|
||||
import org.apache.rocketmq.remoting.transport.NettyRemotingClientAbstract;
|
||||
@@ -67,7 +76,7 @@ public class NettyRemotingClient extends NettyRemotingClientAbstract implements
|
||||
private ExecutorService callbackExecutor;
|
||||
private ChannelEventListener channelEventListener;
|
||||
private DefaultEventExecutorGroup defaultEventExecutorGroup;
|
||||
private RPCHook rpcHook;
|
||||
private InterceptorGroup interceptorGroup;
|
||||
|
||||
public NettyRemotingClient() {
|
||||
super();
|
||||
@@ -123,7 +132,7 @@ public class NettyRemotingClient extends NettyRemotingClientAbstract implements
|
||||
.option(ChannelOption.SO_RCVBUF, nettyClientConfig.getClientSocketRcvBufSize())
|
||||
.handler(new ChannelInitializer<SocketChannel>() {
|
||||
@Override
|
||||
public void initChannel(SocketChannel ch) throws Exception {
|
||||
public void initChannel(SocketChannel ch) {
|
||||
ChannelPipeline pipeline = ch.pipeline();
|
||||
if (nettyClientConfig.isUseTLS()) {
|
||||
if (null != sslContext) {
|
||||
@@ -165,8 +174,8 @@ public class NettyRemotingClient extends NettyRemotingClientAbstract implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRPCHook(RPCHook rpcHook) {
|
||||
this.rpcHook = rpcHook;
|
||||
public void registerInterceptorGroup(InterceptorGroup interceptorGroup) {
|
||||
this.interceptorGroup = interceptorGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -178,38 +187,35 @@ public class NettyRemotingClient extends NettyRemotingClientAbstract implements
|
||||
public RemotingCommand invokeSync(String addr, final RemotingCommand request, long timeoutMillis)
|
||||
throws InterruptedException, RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException {
|
||||
long beginStartTime = System.currentTimeMillis();
|
||||
final Channel channel = this.getAndCreateChannel(addr, timeoutMillis);
|
||||
|
||||
if (channel != null && channel.isActive()) {
|
||||
final RemotingChannel remotingChannel = this.getAndCreateChannel(addr, timeoutMillis);
|
||||
if (remotingChannel != null && remotingChannel.isActive()) {
|
||||
try {
|
||||
if (this.rpcHook != null) {
|
||||
this.rpcHook.doBeforeRequest(addr, request);
|
||||
}
|
||||
long costTime = System.currentTimeMillis() - beginStartTime;
|
||||
if (timeoutMillis < costTime) {
|
||||
throw new RemotingTimeoutException("invokeSync call timeout");
|
||||
}
|
||||
RemotingCommand response = this.invokeSyncImpl(channel, request, timeoutMillis - costTime);
|
||||
if (this.rpcHook != null) {
|
||||
this.rpcHook.doAfterResponse(RemotingHelper.parseChannelRemoteAddr(channel), request, response);
|
||||
}
|
||||
RemotingCommand response = this.invokeSyncWithInterceptor(remotingChannel, request, timeoutMillis - costTime);
|
||||
return response;
|
||||
} catch (RemotingSendRequestException e) {
|
||||
log.warn("invokeSync: send request exception, so close the channel[{}]", addr);
|
||||
this.closeChannel(addr, channel);
|
||||
throw e;
|
||||
} catch (RemotingTimeoutException e) {
|
||||
if (nettyClientConfig.isClientCloseSocketIfTimeout()) {
|
||||
this.closeChannel(addr, channel);
|
||||
log.warn("invokeSync: close socket because of timeout, {}ms, {}", timeoutMillis, addr);
|
||||
} catch (RemotingException remotingException) {
|
||||
if (remotingException instanceof RemotingSendRequestException) {
|
||||
log.warn("invokeSync: send request exception, so close the channel[{}]", addr);
|
||||
this.closeRemotingChannel(addr, remotingChannel);
|
||||
throw (RemotingSendRequestException) remotingException;
|
||||
}
|
||||
if (remotingException instanceof RemotingTimeoutException) {
|
||||
if (nettyClientConfig.isClientCloseSocketIfTimeout()) {
|
||||
this.closeRemotingChannel(addr, remotingChannel);
|
||||
log.warn("invokeSync: close socket because of timeout, {}ms, {}", timeoutMillis, addr);
|
||||
}
|
||||
log.warn("invokeSync: wait response timeout exception, the channel[{}]", addr);
|
||||
throw (RemotingTimeoutException) remotingException;
|
||||
}
|
||||
log.warn("invokeSync: wait response timeout exception, the channel[{}]", addr);
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
this.closeChannel(addr, channel);
|
||||
this.closeRemotingChannel(addr, remotingChannel);
|
||||
throw new RemotingConnectException(addr);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -217,12 +223,14 @@ public class NettyRemotingClient extends NettyRemotingClientAbstract implements
|
||||
throws InterruptedException, RemotingConnectException, RemotingTooMuchRequestException, RemotingTimeoutException,
|
||||
RemotingSendRequestException {
|
||||
long beginStartTime = System.currentTimeMillis();
|
||||
final Channel channel = this.getAndCreateChannel(addr, timeoutMillis);
|
||||
final RemotingChannel remotingChannel = this.getAndCreateChannel(addr, timeoutMillis);
|
||||
Channel channel = null;
|
||||
if (remotingChannel instanceof NettyChannelImpl) {
|
||||
channel = ((NettyChannelImpl) remotingChannel).getChannel();
|
||||
}
|
||||
|
||||
if (channel != null && channel.isActive()) {
|
||||
try {
|
||||
if (this.rpcHook != null) {
|
||||
this.rpcHook.doBeforeRequest(addr, request);
|
||||
}
|
||||
long costTime = System.currentTimeMillis() - beginStartTime;
|
||||
if (timeoutMillis < costTime) {
|
||||
throw new RemotingTooMuchRequestException("invokeAsync call timeout");
|
||||
@@ -242,20 +250,17 @@ public class NettyRemotingClient extends NettyRemotingClientAbstract implements
|
||||
@Override
|
||||
public void invokeOneway(String addr, RemotingCommand request, long timeoutMillis) throws InterruptedException,
|
||||
RemotingConnectException, RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException {
|
||||
final Channel channel = this.getAndCreateChannel(addr, timeoutMillis);
|
||||
if (channel != null && channel.isActive()) {
|
||||
final RemotingChannel remotingChannel = getAndCreateChannel(addr, timeoutMillis);
|
||||
if (remotingChannel != null && remotingChannel.isActive()) {
|
||||
try {
|
||||
if (this.rpcHook != null) {
|
||||
this.rpcHook.doBeforeRequest(addr, request);
|
||||
}
|
||||
this.invokeOnewayImpl(channel, request, timeoutMillis);
|
||||
this.invokeOnewayWithInterceptor(remotingChannel, request, timeoutMillis);
|
||||
} catch (RemotingSendRequestException e) {
|
||||
log.warn("invokeOneway: send request exception, so close the channel[{}]", addr);
|
||||
this.closeChannel(addr, channel);
|
||||
log.warn("InvokeOneway: send request exception, so close the channel[{}]", addr);
|
||||
this.closeRemotingChannel(addr, remotingChannel);
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
this.closeChannel(addr, channel);
|
||||
this.closeRemotingChannel(addr, remotingChannel);
|
||||
throw new RemotingConnectException(addr);
|
||||
}
|
||||
}
|
||||
@@ -267,7 +272,7 @@ public class NettyRemotingClient extends NettyRemotingClientAbstract implements
|
||||
executorThis = this.publicExecutor;
|
||||
}
|
||||
|
||||
Pair<RequestProcessor, ExecutorService> pair = new Pair<RequestProcessor, ExecutorService>(processor, executorThis);
|
||||
Pair<RequestProcessor, ExecutorService> pair = new Pair<>(processor, executorThis);
|
||||
this.processorTable.put(requestCode, pair);
|
||||
}
|
||||
|
||||
@@ -282,8 +287,8 @@ public class NettyRemotingClient extends NettyRemotingClientAbstract implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public RPCHook getRPCHook() {
|
||||
return this.rpcHook;
|
||||
public InterceptorGroup getInterceptorGroup() {
|
||||
return this.interceptorGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+15
-15
@@ -42,7 +42,6 @@ import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.remoting.ChannelEventListener;
|
||||
import org.apache.rocketmq.remoting.InvokeCallback;
|
||||
import org.apache.rocketmq.remoting.RPCHook;
|
||||
import org.apache.rocketmq.remoting.RemotingChannel;
|
||||
import org.apache.rocketmq.remoting.RemotingServer;
|
||||
import org.apache.rocketmq.remoting.RequestProcessor;
|
||||
@@ -53,6 +52,8 @@ import org.apache.rocketmq.remoting.common.TlsMode;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException;
|
||||
import org.apache.rocketmq.remoting.interceptor.Interceptor;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorGroup;
|
||||
import org.apache.rocketmq.remoting.netty.FileRegionEncoder;
|
||||
import org.apache.rocketmq.remoting.netty.NettyChannelImpl;
|
||||
import org.apache.rocketmq.remoting.netty.TlsHelper;
|
||||
@@ -74,9 +75,8 @@ public class NettyRemotingServer extends NettyRemotingServerAbstract implements
|
||||
private DefaultEventExecutorGroup defaultEventExecutorGroup;
|
||||
private Class<? extends ServerSocketChannel> socketChannelClass;
|
||||
|
||||
private RPCHook rpcHook;
|
||||
|
||||
private int port = 0;
|
||||
private InterceptorGroup interceptorGroup;
|
||||
|
||||
private static final String HANDSHAKE_HANDLER_NAME = "handshakeHandler";
|
||||
private static final String TLS_HANDLER_NAME = "sslHandler";
|
||||
@@ -216,24 +216,19 @@ public class NettyRemotingServer extends NettyRemotingServerAbstract implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRPCHook(RPCHook rpcHook) {
|
||||
this.rpcHook = rpcHook;
|
||||
public void registerInterceptorGroup(InterceptorGroup interceptorGroup) {
|
||||
this.interceptorGroup = interceptorGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerProcessor(int requestCode, RequestProcessor processor, ExecutorService executor) {
|
||||
ExecutorService executorThis = executor;
|
||||
if (null == executor) {
|
||||
executorThis = this.publicExecutor;
|
||||
}
|
||||
|
||||
Pair<RequestProcessor, ExecutorService> pair = new Pair<RequestProcessor, ExecutorService>(processor, executorThis);
|
||||
this.processorTable.put(requestCode, pair);
|
||||
executor = (executor == null ? this.publicExecutor : executor);
|
||||
registerNettyProcessor(requestCode, processor, executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerDefaultProcessor(RequestProcessor processor, ExecutorService executor) {
|
||||
this.defaultRequestProcessor = new Pair<RequestProcessor, ExecutorService>(processor, executor);
|
||||
this.defaultRequestProcessor = new Pair<>(processor, executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -273,8 +268,13 @@ public class NettyRemotingServer extends NettyRemotingServerAbstract implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public RPCHook getRPCHook() {
|
||||
return this.rpcHook;
|
||||
public InterceptorGroup getInterceptorGroup() {
|
||||
return this.interceptorGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RemotingChannel getAndCreateChannel(String addr, long timeout) throws InterruptedException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -72,6 +72,10 @@
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -34,6 +34,9 @@ import org.apache.rocketmq.remoting.RemotingClientFactory;
|
||||
import org.apache.rocketmq.remoting.RemotingServer;
|
||||
import org.apache.rocketmq.remoting.RemotingServerFactory;
|
||||
import org.apache.rocketmq.remoting.ServerConfig;
|
||||
import org.apache.rocketmq.remoting.interceptor.Interceptor;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorFactory;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorGroup;
|
||||
import org.apache.rocketmq.snode.client.ClientHousekeepingService;
|
||||
import org.apache.rocketmq.snode.client.ConsumerIdsChangeListener;
|
||||
import org.apache.rocketmq.snode.client.ConsumerManager;
|
||||
@@ -41,9 +44,6 @@ import org.apache.rocketmq.snode.client.DefaultConsumerIdsChangeListener;
|
||||
import org.apache.rocketmq.snode.client.ProducerManager;
|
||||
import org.apache.rocketmq.snode.client.SubscriptionGroupManager;
|
||||
import org.apache.rocketmq.snode.config.SnodeConfig;
|
||||
import org.apache.rocketmq.remoting.interceptor.Interceptor;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorFactory;
|
||||
import org.apache.rocketmq.remoting.interceptor.InterceptorGroup;
|
||||
import org.apache.rocketmq.snode.offset.ConsumerOffsetManager;
|
||||
import org.apache.rocketmq.snode.processor.ConsumerManageProcessor;
|
||||
import org.apache.rocketmq.snode.processor.HeartbeatProcessor;
|
||||
@@ -82,7 +82,8 @@ public class SnodeController {
|
||||
private ConsumerManageProcessor consumerManageProcessor;
|
||||
private SendMessageProcessor sendMessageProcessor;
|
||||
private PullMessageProcessor pullMessageProcessor;
|
||||
private HeartbeatProcessor hearbeatProcessor;
|
||||
private HeartbeatProcessor heartbeatProcessor;
|
||||
private InterceptorGroup remotingServerInterceptorGroup;
|
||||
private InterceptorGroup consumeMessageInterceptorGroup;
|
||||
private InterceptorGroup sendMessageInterceptorGroup;
|
||||
private PushService pushService;
|
||||
@@ -160,7 +161,7 @@ public class SnodeController {
|
||||
this.consumerOffsetManager = new ConsumerOffsetManager(this);
|
||||
this.consumerManageProcessor = new ConsumerManageProcessor(this);
|
||||
this.sendMessageProcessor = new SendMessageProcessor(this);
|
||||
this.hearbeatProcessor = new HeartbeatProcessor(this);
|
||||
this.heartbeatProcessor = new HeartbeatProcessor(this);
|
||||
this.pullMessageProcessor = new PullMessageProcessor(this);
|
||||
this.pushService = new PushServiceImpl(this);
|
||||
|
||||
@@ -170,19 +171,41 @@ public class SnodeController {
|
||||
return snodeConfig;
|
||||
}
|
||||
|
||||
// private void initFlowControlIntercepterGruop() {
|
||||
// this.remotingServerInterceptorGroup = new InterceptorGroup();
|
||||
// List<Interceptor> remotingServerInterceptors = InterceptorFactory.getInstance().loadInterceptors(this.snodeConfig.getRemotingServerInterceptorPath());
|
||||
// this.remotingServerInterceptorGroup.registerInterceptor(flowControlService);
|
||||
// }
|
||||
|
||||
private void initRemotingServerInterceptorGroup() {
|
||||
List<Interceptor> remotingServerInterceptors = InterceptorFactory.getInstance().loadInterceptors(this.snodeConfig.getRemotingServerInterceptorPath());
|
||||
if (remotingServerInterceptors != null && remotingServerInterceptors.size() > 0) {
|
||||
if (this.remotingServerInterceptorGroup == null) {
|
||||
this.remotingServerInterceptorGroup = new InterceptorGroup();
|
||||
}
|
||||
for (Interceptor interceptor : remotingServerInterceptors) {
|
||||
this.remotingServerInterceptorGroup.registerInterceptor(interceptor);
|
||||
log.warn("Remoting server interceptor: {} registered!", interceptor.interceptorName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean initialize() {
|
||||
this.snodeServer = RemotingServerFactory.getInstance().createRemotingServer().init(this.nettyServerConfig, this.clientHousekeepingService);
|
||||
this.registerProcessor();
|
||||
initInterceptorGroup();
|
||||
initSnodeInterceptorGroup();
|
||||
initRemotingServerInterceptorGroup();
|
||||
this.snodeServer.registerInterceptorGroup(this.remotingServerInterceptorGroup);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void initInterceptorGroup() {
|
||||
private void initSnodeInterceptorGroup() {
|
||||
List<Interceptor> consumeMessageInterceptors = InterceptorFactory.getInstance().loadInterceptors(this.snodeConfig.getConsumeMessageInterceptorPath());
|
||||
if (consumeMessageInterceptors != null && consumeMessageInterceptors.size() > 0) {
|
||||
this.consumeMessageInterceptorGroup = new InterceptorGroup();
|
||||
for (Interceptor interceptor : consumeMessageInterceptors) {
|
||||
this.consumeMessageInterceptorGroup.registerInterceptor(interceptor);
|
||||
log.warn("Consume message interceptor: {} registered!", interceptor.interceptorName());
|
||||
}
|
||||
}
|
||||
List<Interceptor> sendMessageInterceptors = InterceptorFactory.getInstance().loadInterceptors(this.snodeConfig.getSendMessageInterceptorPath());
|
||||
@@ -190,15 +213,17 @@ public class SnodeController {
|
||||
this.sendMessageInterceptorGroup = new InterceptorGroup();
|
||||
for (Interceptor interceptor : sendMessageInterceptors) {
|
||||
this.sendMessageInterceptorGroup.registerInterceptor(interceptor);
|
||||
log.warn("Send message interceptor: {} registered!", interceptor.interceptorName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void registerProcessor() {
|
||||
this.snodeServer.registerProcessor(RequestCode.SEND_MESSAGE_V2, sendMessageProcessor, this.sendMessageExecutor);
|
||||
this.snodeServer.registerProcessor(RequestCode.CONSUMER_SEND_MSG_BACK, sendMessageProcessor, this.sendMessageExecutor);
|
||||
this.snodeServer.registerProcessor(RequestCode.HEART_BEAT, hearbeatProcessor, this.heartbeatExecutor);
|
||||
this.snodeServer.registerProcessor(RequestCode.UNREGISTER_CLIENT, hearbeatProcessor, this.heartbeatExecutor);
|
||||
this.snodeServer.registerProcessor(RequestCode.HEART_BEAT, heartbeatProcessor, this.heartbeatExecutor);
|
||||
this.snodeServer.registerProcessor(RequestCode.UNREGISTER_CLIENT, heartbeatProcessor, this.heartbeatExecutor);
|
||||
this.snodeServer.registerProcessor(RequestCode.SNODE_PULL_MESSAGE, pullMessageProcessor, this.pullMessageExecutor);
|
||||
this.snodeServer.registerProcessor(RequestCode.GET_CONSUMER_LIST_BY_GROUP, consumerManageProcessor, this.consumerManageExecutor);
|
||||
this.snodeServer.registerProcessor(RequestCode.UPDATE_CONSUMER_OFFSET, consumerManageProcessor, this.consumerManageExecutor);
|
||||
@@ -287,4 +312,13 @@ public class SnodeController {
|
||||
public void setEnodeService(EnodeService enodeService) {
|
||||
this.enodeService = enodeService;
|
||||
}
|
||||
|
||||
public InterceptorGroup getRemotingServerInterceptorGroup() {
|
||||
return remotingServerInterceptorGroup;
|
||||
}
|
||||
|
||||
public void setRemotingServerInterceptorGroup(
|
||||
InterceptorGroup remotingServerInterceptorGroup) {
|
||||
this.remotingServerInterceptorGroup = remotingServerInterceptorGroup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,9 +71,13 @@ public class SnodeConfig {
|
||||
|
||||
private final String consumeMessageInterceptorPath = "META-INF/service/org.apache.rocketmq.snode.interceptor.ConsumeMessageInterceptor";
|
||||
|
||||
private final String remotingServerInterceptorPath = "META-INF/service/org.apache.rocketmq.snode.interceptor.RemotingServerInterceptor";
|
||||
|
||||
private int listenPort = 11911;
|
||||
|
||||
private double snodeQPSLimit = 10000;
|
||||
|
||||
|
||||
private boolean vipChannelEnabled = Boolean.parseBoolean(System.getProperty(SEND_MESSAGE_WITH_VIP_CHANNEL_PROPERTY, "true"));
|
||||
|
||||
public void setSnodeHeartBeatInterval(long snodeHeartBeatInterval) {
|
||||
@@ -276,4 +280,16 @@ public class SnodeConfig {
|
||||
public String getConsumeMessageInterceptorPath() {
|
||||
return consumeMessageInterceptorPath;
|
||||
}
|
||||
|
||||
public String getRemotingServerInterceptorPath() {
|
||||
return remotingServerInterceptorPath;
|
||||
}
|
||||
|
||||
public double getSnodeQPSLimit() {
|
||||
return snodeQPSLimit;
|
||||
}
|
||||
|
||||
public void setSnodeQPSLimit(double snodeQPSLimit) {
|
||||
this.snodeQPSLimit = snodeQPSLimit;
|
||||
}
|
||||
}
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.flowcontrol;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import org.apache.rocketmq.common.flowcontrol.AbstractFlowControlService;
|
||||
import org.apache.rocketmq.common.protocol.RequestCode;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
import org.apache.rocketmq.logging.InternalLoggerFactory;
|
||||
import org.apache.rocketmq.remoting.common.RemotingHelper;
|
||||
import org.apache.rocketmq.remoting.exception.RemotingRuntimeException;
|
||||
import org.apache.rocketmq.remoting.interceptor.RequestContext;
|
||||
import org.apache.rocketmq.remoting.protocol.RemotingSysResponseCode;
|
||||
|
||||
public class QPSFlowControlServiceImpl extends AbstractFlowControlService {
|
||||
private static final InternalLogger log = InternalLoggerFactory.getLogger(RemotingHelper.ROCKETMQ_REMOTING);
|
||||
|
||||
private final AtomicLong logCount = new AtomicLong(0);
|
||||
|
||||
private final String flowControlType = "countLimit";
|
||||
|
||||
public QPSFlowControlServiceImpl() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResourceKey(RequestContext requestContext) {
|
||||
if (RequestCode.HEART_BEAT == requestContext.getRequest().getCode()) {
|
||||
return null;
|
||||
}
|
||||
return requestContext.getRequest().getCode() + "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFlowControlType() {
|
||||
return this.flowControlType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rejectRequest(RequestContext requestContext) {
|
||||
if (logCount.getAndIncrement() % 100 == 0) {
|
||||
log.warn("[REJECT]exceed system flow control config QPS, start flow control for a while: requestContext: {} ", requestContext);
|
||||
}
|
||||
throw new RemotingRuntimeException(RemotingSysResponseCode.SYSTEM_BUSY, "[REJECT]exceed system flow control config QPS, start flow control for a while");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String interceptorName() {
|
||||
return "snodeQPSFlowControlInterceptor";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResourceCount(RequestContext requestContext) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -232,7 +232,7 @@ public class ConsumerOffsetManager {
|
||||
for (Entry<Integer, Long> queueEntry : map.entrySet()) {
|
||||
Integer queueId = queueEntry.getKey();
|
||||
Long offset = queueEntry.getValue();
|
||||
this.snodeController.getEnodeService().persistOffsetToEnode(enodeName, consumerGroup, topic, queueId, offset);
|
||||
this.snodeController.getEnodeService().persistOffset(enodeName, consumerGroup, topic, queueId, offset);
|
||||
}
|
||||
} else {
|
||||
log.error("Persist offset split keys error:{}", key);
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.apache.rocketmq.snode.processor;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import org.apache.rocketmq.common.constant.LoggerName;
|
||||
import org.apache.rocketmq.common.protocol.RequestCode;
|
||||
import org.apache.rocketmq.common.protocol.ResponseCode;
|
||||
import org.apache.rocketmq.common.protocol.header.ConsumerSendMsgBackRequestHeader;
|
||||
import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeaderV2;
|
||||
import org.apache.rocketmq.logging.InternalLogger;
|
||||
@@ -74,7 +75,7 @@ public class SendMessageProcessor implements RequestProcessor {
|
||||
this.snodeController.getSendMessageInterceptorGroup().afterRequest(responseContext);
|
||||
}
|
||||
remotingChannel.reply(data);
|
||||
if (isNeedPush) {
|
||||
if (data.getCode() == ResponseCode.SUCCESS && isNeedPush) {
|
||||
this.snodeController.getPushService().pushMessage(topic, queueId, message, data);
|
||||
}
|
||||
} else {
|
||||
|
||||
+2
-7
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
package org.apache.rocketmq.snode.service;/*
|
||||
* 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.
|
||||
@@ -14,11 +14,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.rocketmq.snode.service;
|
||||
|
||||
import com.google.common.util.concurrent.RateLimiter;
|
||||
import com.google.common.util.concurrent.SmoothRateLimiter;
|
||||
|
||||
public class FlowControlService {
|
||||
RateLimiter rateLimiter = SmoothRateLimiter.create()
|
||||
public interface AdminService {
|
||||
}
|
||||
@@ -44,7 +44,7 @@ public interface EnodeService {
|
||||
|
||||
boolean persistSubscriptionGroupConfig(SubscriptionGroupConfig subscriptionGroupConfig);
|
||||
|
||||
void persistOffsetToEnode(String enodeName, String groupName, String topic, int queueId, long offset);
|
||||
void persistOffset(String enodeName, String groupName, String topic, int queueId, long offset);
|
||||
|
||||
RemotingCommand loadOffset(String enodeName, String consumerGroup, String topic,
|
||||
int queueId) throws InterruptedException, RemotingTimeoutException,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.apache.rocketmq.snode.service;/*
|
||||
/*
|
||||
* 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.
|
||||
@@ -14,6 +14,7 @@ package org.apache.rocketmq.snode.service;/*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.rocketmq.snode.service;
|
||||
|
||||
public interface MetricsService {
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.rocketmq.snode.service;
|
||||
|
||||
import java.util.Set;
|
||||
import org.apache.rocketmq.client.exception.MQClientException;
|
||||
import org.apache.rocketmq.common.protocol.body.ClusterInfo;
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.rocketmq.snode.service;
|
||||
|
||||
public interface ScheduledService {
|
||||
void startScheduleTask();
|
||||
|
||||
void shutdown();
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ public class EnodeServiceImpl implements EnodeService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void persistOffsetToEnode(String enodeName, String groupName, String topic, int queueId, long offset) {
|
||||
public void persistOffset(String enodeName, String groupName, String topic, int queueId, long offset) {
|
||||
try {
|
||||
String address = this.snodeController.getNnodeService().getAddressByEnodeName(enodeName, false);
|
||||
UpdateConsumerOffsetRequestHeader requestHeader = new UpdateConsumerOffsetRequestHeader();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.rocketmq.snode.service.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
snode:
|
||||
countLimit: # flow control type, only requestCount & requestSize support
|
||||
- flowControlResourceName: 310
|
||||
flowControlGrade: directDeny
|
||||
flowControlBehavior: flowControlBehavior
|
||||
flowControlResourceCount: 100000.00 #QPS
|
||||
|
||||
- flowControlResourceName: overall
|
||||
flowControlGrade: directDeny
|
||||
flowControlBehavior: flowControlBehavior
|
||||
flowControlResourceCount: 100000.00 #QPS
|
||||
|
||||
sizeLimit:
|
||||
- flowControlResourceName: 310
|
||||
flowControlGrade: directDeny
|
||||
flowControlBehavior: flowControlBehavior
|
||||
flowControlResourceCount: 10.00 #MB/S
|
||||
|
||||
topicLimit:
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.apache.rocketmq.snode.flowcontrol.QPSFlowControlServiceImpl
|
||||
Reference in New Issue
Block a user