Search in sources :

Example 1 with RestyCommand

use of com.github.df.restypass.command.RestyCommand in project RestyPass by darren-fu.

the class RestyProxyInvokeHandler method invoke.

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (isSpecialMethod(method)) {
        return handleSpecialMethod(proxy, method, args);
    }
    Object result;
    // 创建请求载体,RestyCommand
    RestyCommand restyCommand = new DefaultRestyCommand(method.getDeclaringClass(), method, method.getGenericReturnType(), args, restyCommandContext);
    // 获取过滤器
    List<CommandFilter> filterList = commandFilterContext.getFilterList();
    // 执行过滤器
    for (CommandFilter commandFilter : filterList) {
        if (CommandFilterType.BEFOR_EXECUTE.equals(commandFilter.getFilterType()) && commandFilter.shouldFilter(restyCommand)) {
            commandFilter.before(restyCommand);
        }
    }
    // 创建负载均衡器
    LoadBalancer loadBalancer = LoadBalanceFactory.createLoadBalancerForService(restyCommand.getServiceName(), restyCommand.getRestyCommandConfig().getLoadBalancer());
    // 为executor设置服务容器
    commandExecutor.setServerContext(serverContext);
    try {
        if (commandExecutor.executable(restyCommand)) {
            result = commandExecutor.execute(loadBalancer, restyCommand);
        } else {
            throw new IllegalStateException("Resty command is not executable:" + restyCommand);
        }
    } catch (RestyException ex) {
        if (fallbackExecutor.executable(restyCommand)) {
            if (log.isDebugEnabled()) {
                log.debug("{}使用降级服务", restyCommand.getPath());
            }
            try {
                result = fallbackExecutor.execute(restyCommand);
            } catch (FallbackException fe) {
                log.warn("服务{}降级发生异常:{}", restyCommand.getPath(), fe.getMessage());
                // 抛出原始Resty异常
                throw ex;
            }
        } else {
            log.warn("请求{}发生异常:{}", restyCommand.getPath(), ex.getMessage());
            throw ex;
        }
    }
    return result;
}
Also used : CommandFilter(com.github.df.restypass.filter.CommandFilter) RestyCommand(com.github.df.restypass.command.RestyCommand) DefaultRestyCommand(com.github.df.restypass.command.DefaultRestyCommand) RestyException(com.github.df.restypass.exception.execute.RestyException) LoadBalancer(com.github.df.restypass.lb.LoadBalancer) FallbackException(com.github.df.restypass.exception.execute.FallbackException) DefaultRestyCommand(com.github.df.restypass.command.DefaultRestyCommand)

Example 2 with RestyCommand

use of com.github.df.restypass.command.RestyCommand in project RestyPass by darren-fu.

the class DefaultCircuitBreaker method startTask.

/**
 * 消费队列 统计已完成的command信息,更新 segment
 */
private void startTask() {
    Executors.newSingleThreadExecutor().submit(() -> {
        log.info("启动RestyCommand统计线程:" + this.eventKey);
        while (true) {
            try {
                // 阻塞
                RestyCommand firstCommand = commandQueue.take();
                // 取出queue中所有的数据
                List<RestyCommand> commandList = new LinkedList<>();
                commandList.add(firstCommand);
                commandQueue.drainTo(commandList);
                for (RestyCommand restyCommand : commandList) {
                    String key = getMetricsKey(restyCommand.getPath(), restyCommand.getInstanceId());
                    // 获取 计数器
                    Metrics metrics = getCommandMetrics(key);
                    if (metrics == null) {
                        log.warn("获取计数器失败:{}", key);
                        continue;
                    }
                    boolean isSuccess = isCommandSuccessExecuted(restyCommand);
                    boolean forceUseNewMetrics = false;
                    // 如果当前处在短路或半短路状态
                    CircuitBreakerStatus breakerStatus = statusMap.get(key);
                    if ((breakerStatus == CircuitBreakerStatus.BREAK || breakerStatus == CircuitBreakerStatus.HALF_OPEN)) {
                        // 结果成功 则不再短路,打开断路器
                        if (isSuccess) {
                            // 并使用一个新的计数器
                            forceUseNewMetrics = true;
                            statusMap.put(key, CircuitBreakerStatus.OPEN);
                        } else {
                            // 否则恢复到短路状态
                            statusMap.put(key, CircuitBreakerStatus.BREAK);
                        }
                    }
                    metrics.store(isSuccess, forceUseNewMetrics);
                }
                if (log.isTraceEnabled()) {
                    log.trace("处理完成, 处理个数:{},剩余:{}个", commandList.size(), commandQueue.size());
                }
            } catch (Exception ex) {
                log.error("断路器RestyCommand处理失败:{}", ex);
            }
        }
    });
}
Also used : RestyCommand(com.github.df.restypass.command.RestyCommand) ToString(lombok.ToString) CircuitBreakerStatus(com.github.df.restypass.enums.CircuitBreakerStatus) RequestException(com.github.df.restypass.exception.execute.RequestException)

Aggregations

RestyCommand (com.github.df.restypass.command.RestyCommand)2 DefaultRestyCommand (com.github.df.restypass.command.DefaultRestyCommand)1 CircuitBreakerStatus (com.github.df.restypass.enums.CircuitBreakerStatus)1 FallbackException (com.github.df.restypass.exception.execute.FallbackException)1 RequestException (com.github.df.restypass.exception.execute.RequestException)1 RestyException (com.github.df.restypass.exception.execute.RestyException)1 CommandFilter (com.github.df.restypass.filter.CommandFilter)1 LoadBalancer (com.github.df.restypass.lb.LoadBalancer)1 ToString (lombok.ToString)1