Skip to content

Commit

Permalink
Merge pull request apache#264 from 241600489/master
Browse files Browse the repository at this point in the history
hystrix 插件新增支持线程池模式
  • Loading branch information
yu199195 authored Jul 28, 2020
2 parents 964c244 + cd2a950 commit 28bc251
Show file tree
Hide file tree
Showing 16 changed files with 412 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.dromara.soul.admin.service.EnumService;
import org.dromara.soul.admin.vo.EnumVO;
import org.dromara.soul.common.enums.HttpMethodEnum;
import org.dromara.soul.common.enums.HystrixIsolationModeEnum;
import org.dromara.soul.common.enums.LoadBalanceEnum;
import org.dromara.soul.common.enums.MatchModeEnum;
import org.dromara.soul.common.enums.OperatorEnum;
Expand Down Expand Up @@ -53,6 +54,7 @@ public class EnumServiceImpl implements EnumService {
*
* @return {@linkplain Map}
*/
@SuppressWarnings({"checkstyle:WhitespaceAfter", "checkstyle:WhitespaceAround"})
@Override
public Map<String, List<EnumVO>> list() {
List<EnumVO> httpMethodEnums = Arrays.stream(HttpMethodEnum.values())
Expand Down Expand Up @@ -101,7 +103,9 @@ public Map<String, List<EnumVO>> list() {
List<EnumVO> redisModeEnums = Arrays.stream(RedisModeEnum.values())
.map(redisModeEnum -> new EnumVO(null, redisModeEnum.getName(), true))
.collect(Collectors.toList());

List<EnumVO> hystrixIsolationModeEnums = Arrays.stream(HystrixIsolationModeEnum.values())
.map(hystrixIsolationModeEnum -> new EnumVO(hystrixIsolationModeEnum.getCode(), hystrixIsolationModeEnum.getName(), true))
.collect(Collectors.toList());
Map<String, List<EnumVO>> enums = Maps.newHashMap();
enums.put("httpMethodEnums", httpMethodEnums);
enums.put("loadBalanceEnums", loadBalanceEnums);
Expand All @@ -115,6 +119,7 @@ public Map<String, List<EnumVO>> list() {
enums.put("serializeEnums", serializeEnums);
enums.put("wafEnums", wafEnums);
enums.put("redisModeEnums", redisModeEnums);
enums.put("hystrixIsolationModeEnums", hystrixIsolationModeEnums);
return enums;
}
}

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions soul-admin/src/main/resources/static/index.9c985f9d.js

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion soul-admin/src/main/resources/static/index.f5d0df1d.js

This file was deleted.

4 changes: 2 additions & 2 deletions soul-admin/src/main/resources/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>soul网关</title>
<link rel="icon" href="/favicon.png" type="image/x-icon">
<link href="/index.342da2e4.css" rel="stylesheet">
<link href="/index.65957209.css" rel="stylesheet">
</head>

<body>
<div id="httpPath" style="display: none" th:text="${domain}"></div>
<div id="root"></div>
<script type="text/javascript" src="/index.f5d0df1d.js"></script>
<script type="text/javascript" src="/index.9c985f9d.js"></script>
</body>

</html>
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,30 @@ public interface Constants {
String COLONS = ":";

String REQUEST_LATENCY = "REQUEST_LATENCY";


/**
* hystrix thead pool core size.
*/
int HYSTRIX_THREAD_POOL_CORE_SIZE = 10;

/**
* hystrix thread pool max size.
*/
int HYSTRIX_THREAD_POOL_MAX_SIZE = 10;

/**
* hystrix thread pool keep alive time minutes.
*/
int HYSTRIX_THREAD_KEEP_ALIVE_TIME_MINUTE = 1;

/**
* hystrix thread pool queue size.
*/
int HYSTRIX_THREAD_POOL_QUEUE_SIZE = 12;

/**
* String q.
*/
default void findConstants() {
}
default void findConstants() { }
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import lombok.Getter;
import lombok.Setter;
import org.dromara.soul.common.constant.Constants;
import org.dromara.soul.common.enums.HystrixIsolationModeEnum;

/**
* this is hystrix handle.
Expand Down Expand Up @@ -49,4 +50,22 @@ public class HystrixHandle {
* timeout is required.
*/
private long timeout = Constants.TIME_OUT;

/**
* call back uri.
* when some error occurs in hystrix invoke it will forward to this
*/
private String callBackUri;

/**
* Isolation strategy to use when executing a hystrix command.
*/
private int executionIsolationStrategy = HystrixIsolationModeEnum.SEMAPHORE.getCode();

/**
* hystrix thread pool config.
*/
private HystrixThreadPoolConfig hystrixThreadPoolConfig;


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.dromara.soul.common.dto.convert;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.dromara.soul.common.constant.Constants;

/**
* hystrix thread pool config.
* @author liangziqiang
*/
@Getter
@Setter
@EqualsAndHashCode
public class HystrixThreadPoolConfig {
private int coreSize = Constants.HYSTRIX_THREAD_POOL_CORE_SIZE;

private int maximumSize = Constants.HYSTRIX_THREAD_POOL_MAX_SIZE;

private int keepAliveTimeMinutes = Constants.HYSTRIX_THREAD_KEEP_ALIVE_TIME_MINUTE;

private int maxQueueSize = Constants.HYSTRIX_THREAD_POOL_QUEUE_SIZE;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.dromara.soul.common.enums;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

/**
* hystrix execution isolation strategy.
*
* @author liangziqiang
*/
@RequiredArgsConstructor
@Getter
public enum HystrixIsolationModeEnum {
/**
* thread pool mode.
*/
@SuppressWarnings("checkstyle:WhitespaceAfter") THREAD_POOL(0, "thread"),
/**
* semaphore mode.
*/
@SuppressWarnings("checkstyle:WhitespaceAfter") SEMAPHORE(1, "semaphore");

private final int code;

private final String name;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.dromara.soul.plugin.base.utils;

import java.net.URI;
import org.apache.commons.lang3.StringUtils;

/**
* uri util.
* @author liangziqiang
*/
public class UriUtils {


/**
* create URI {@link URI}.
* @param uri uri string eg:/fallback
* @return created {@link URI} from uri
*/
public static URI createUri(final String uri) {
if (StringUtils.isNotBlank(uri)) {
return URI.create(uri);
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@
import org.dromara.soul.common.dto.RuleData;
import org.dromara.soul.common.dto.SelectorData;
import org.dromara.soul.common.dto.convert.HystrixHandle;
import org.dromara.soul.common.enums.HystrixIsolationModeEnum;
import org.dromara.soul.common.enums.PluginEnum;
import org.dromara.soul.common.enums.ResultEnum;
import org.dromara.soul.common.utils.GsonUtils;
import org.dromara.soul.plugin.api.SoulPluginChain;
import org.dromara.soul.plugin.base.AbstractSoulPlugin;
import org.dromara.soul.plugin.api.context.SoulContext;
import org.dromara.soul.plugin.base.AbstractSoulPlugin;
import org.dromara.soul.plugin.hystrix.builder.HystrixBuilder;
import org.dromara.soul.plugin.hystrix.command.Command;
import org.dromara.soul.plugin.hystrix.command.HystrixCommand;
import org.dromara.soul.plugin.hystrix.command.HystrixCommandOnThread;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import rx.Subscription;
Expand All @@ -46,7 +49,7 @@
*/
@Slf4j
public class HystrixPlugin extends AbstractSoulPlugin {

@Override
protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
Expand All @@ -58,9 +61,9 @@ protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPlugi
if (StringUtils.isBlank(hystrixHandle.getCommandKey())) {
hystrixHandle.setCommandKey(Objects.requireNonNull(soulContext).getMethod());
}
HystrixCommand command = new HystrixCommand(HystrixBuilder.build(hystrixHandle), exchange, chain);
Command command = fetchCommand(hystrixHandle, exchange, chain);
return Mono.create(s -> {
Subscription sub = command.toObservable().subscribe(s::success,
Subscription sub = command.fetchObservable().subscribe(s::success,
s::error, s::success);
s.onCancel(sub::unsubscribe);
if (command.isCircuitBreakerOpen()) {
Expand All @@ -73,6 +76,15 @@ protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPlugi
}).then();
}

private Command fetchCommand(final HystrixHandle hystrixHandle, final ServerWebExchange exchange, final SoulPluginChain chain) {
if (hystrixHandle.getExecutionIsolationStrategy() == HystrixIsolationModeEnum.SEMAPHORE.getCode()) {
return new HystrixCommand(HystrixBuilder.build(hystrixHandle),
exchange, chain, hystrixHandle.getCallBackUri());
}
return new HystrixCommandOnThread(HystrixBuilder.buildForHystrixCommand(hystrixHandle),
exchange, chain, hystrixHandle.getCallBackUri());
}

@Override
public String named() {
return PluginEnum.HYSTRIX.getName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,25 @@

package org.dromara.soul.plugin.hystrix.builder;

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixObservableCommand;
import com.netflix.hystrix.HystrixThreadPoolProperties;
import lombok.extern.slf4j.Slf4j;
import org.dromara.soul.common.constant.Constants;
import org.dromara.soul.common.dto.convert.HystrixHandle;
import org.dromara.soul.common.dto.convert.HystrixThreadPoolConfig;

import java.util.Objects;

/**
* the hystrix builder.
*
* @author xiaoyu(Myth)
*/
@Slf4j
public class HystrixBuilder {

/**
Expand All @@ -38,18 +45,8 @@ public class HystrixBuilder {
* @return {@linkplain HystrixObservableCommand.Setter}
*/
public static HystrixObservableCommand.Setter build(final HystrixHandle hystrixHandle) {
if (hystrixHandle.getMaxConcurrentRequests() == 0) {
hystrixHandle.setMaxConcurrentRequests(Constants.MAX_CONCURRENT_REQUESTS);
}
if (hystrixHandle.getErrorThresholdPercentage() == 0) {
hystrixHandle.setErrorThresholdPercentage(Constants.ERROR_THRESHOLD_PERCENTAGE);
}
if (hystrixHandle.getRequestVolumeThreshold() == 0) {
hystrixHandle.setRequestVolumeThreshold(Constants.REQUEST_VOLUME_THRESHOLD);
}
if (hystrixHandle.getSleepWindowInMilliseconds() == 0) {
hystrixHandle.setSleepWindowInMilliseconds(Constants.SLEEP_WINDOW_INMILLISECONDS);
}
initHystrixHandleOnRequire(hystrixHandle);

HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey(hystrixHandle.getGroupKey());
HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey(hystrixHandle.getCommandKey());
final HystrixCommandProperties.Setter propertiesSetter =
Expand All @@ -66,4 +63,64 @@ public static HystrixObservableCommand.Setter build(final HystrixHandle hystrixH
.andCommandKey(commandKey)
.andCommandPropertiesDefaults(propertiesSetter);
}

/**
* this is build HystrixCommand.Setter.
* @param hystrixHandle {@linkplain HystrixHandle}
* @return {@linkplain HystrixCommand.Setter}
*/
public static HystrixCommand.Setter buildForHystrixCommand(final HystrixHandle hystrixHandle) {
initHystrixHandleOnRequire(hystrixHandle);
HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey(hystrixHandle.getGroupKey());
HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey(hystrixHandle.getCommandKey());

final HystrixCommandProperties.Setter propertiesSetter =
HystrixCommandProperties.Setter()
.withExecutionTimeoutInMilliseconds((int) hystrixHandle.getTimeout())
.withCircuitBreakerEnabled(true)
.withCircuitBreakerErrorThresholdPercentage(hystrixHandle.getErrorThresholdPercentage())
.withCircuitBreakerRequestVolumeThreshold(hystrixHandle.getRequestVolumeThreshold())
.withCircuitBreakerSleepWindowInMilliseconds(hystrixHandle.getSleepWindowInMilliseconds());
HystrixThreadPoolConfig hystrixThreadPoolConfig = hystrixHandle.getHystrixThreadPoolConfig();
final HystrixThreadPoolProperties.Setter threadPoolPropertiesSetter =
HystrixThreadPoolProperties.Setter()
.withCoreSize(hystrixThreadPoolConfig.getCoreSize())
.withMaximumSize(hystrixThreadPoolConfig.getMaximumSize())
.withMaxQueueSize(hystrixThreadPoolConfig.getMaxQueueSize())
.withKeepAliveTimeMinutes(hystrixThreadPoolConfig.getKeepAliveTimeMinutes())
.withAllowMaximumSizeToDivergeFromCoreSize(true);
return HystrixCommand.Setter
.withGroupKey(groupKey)
.andCommandKey(commandKey)
.andCommandPropertiesDefaults(propertiesSetter)
.andThreadPoolPropertiesDefaults(threadPoolPropertiesSetter);
}

private static void initHystrixHandleOnRequire(final HystrixHandle hystrixHandle) {
if (hystrixHandle.getMaxConcurrentRequests() == 0) {
hystrixHandle.setMaxConcurrentRequests(Constants.MAX_CONCURRENT_REQUESTS);
}
if (hystrixHandle.getErrorThresholdPercentage() == 0) {
hystrixHandle.setErrorThresholdPercentage(Constants.ERROR_THRESHOLD_PERCENTAGE);
}
if (hystrixHandle.getRequestVolumeThreshold() == 0) {
hystrixHandle.setRequestVolumeThreshold(Constants.REQUEST_VOLUME_THRESHOLD);
}
if (hystrixHandle.getSleepWindowInMilliseconds() == 0) {
hystrixHandle.setSleepWindowInMilliseconds(Constants.SLEEP_WINDOW_INMILLISECONDS);
}
if (Objects.isNull(hystrixHandle.getHystrixThreadPoolConfig())) {
hystrixHandle.setHystrixThreadPoolConfig(new HystrixThreadPoolConfig());
}
HystrixThreadPoolConfig hystrixThreadPoolConfig = hystrixHandle.getHystrixThreadPoolConfig();
if (hystrixThreadPoolConfig.getCoreSize() == 0) {
hystrixThreadPoolConfig.setCoreSize(Constants.HYSTRIX_THREAD_POOL_CORE_SIZE);
}
if (hystrixThreadPoolConfig.getMaximumSize() == 0) {
hystrixThreadPoolConfig.setMaximumSize(Constants.HYSTRIX_THREAD_POOL_MAX_SIZE);
}
if (hystrixThreadPoolConfig.getMaxQueueSize() == 0) {
hystrixThreadPoolConfig.setMaxQueueSize(Constants.HYSTRIX_THREAD_POOL_QUEUE_SIZE);
}
}
}
Loading

0 comments on commit 28bc251

Please sign in to comment.