微服务SpringCloud组件的断路器Hystrix的封装

在上一遍文章中(微服务SpringCloud组件的断路器Hystrix的介绍),我简单的介绍了断路器Hystrix的含义。

 然后,在开发中,怎么使用断路器Hystrix是一个问题。用原生的,写起来很繁琐。所以,我利用AOP的方法,将其进行了封装,让我们在开发中使用时非常简单。只需要一个注释就可以了。废话不多说,看代码。

 该工程源码在github上可下,github地址:断路器的封装

(一):定义注释 (MyHystrixCommand.java)

package com.eamon.myHystrix.hystrixTool;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @description 
 * @author EamonKang	
 * @Date 2018年1月24日
 */
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyHystrixCommand {
	
	/**
	 * Title: groupKey
	 */
	String groupKey() default "my_groupKey";

    /**
     * Title: commandKey
     */
    String commandKey() default "my_commandKey";

    /**
     * Title: threadPoolKey
     */
    String threadPoolKey() default "my_threadPoolKey";

    /**
     * Title: timeOutSecond 用来配置执行的超时时间
     */
    int timeOutSecond() default 30;
    
    /**
     * Title: timeOutEnabled 用来配置是否开启的超时功能
     */
    boolean timeOutEnabled() default true;

}
(二)、定义 通知器(MyHystrixCommandAdvice.java

package com.eamon.myHystrix.hystrixTool;

import org.aspectj.lang.ProceedingJoinPoint;

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixThreadPoolKey;

import lombok.Data;

/**
 * @description 
 * @author EamonKang	
 * @Date 2018年1月24日
 */
@Data
public class MyHystrixCommandAdvice {
	private String groupName;
	private String commandName;
	private String threadKey;
	private int timeOutSecond;
	private boolean timeOutEnable;

	public Object runCommand(final ProceedingJoinPoint pjp) {
		return wrapWithHystrixCommnad(pjp).execute();
	}

	private HystrixCommand<Object> wrapWithHystrixCommnad(final ProceedingJoinPoint pjp) {
		return new HystrixCommand<Object>(setter()) {
			@Override
			protected Object run() throws Exception {
				try {
					return pjp.proceed();
				} catch (Throwable throwable) {
					throw (Exception) throwable;
				}
			}

			@Override
			protected Object getFallback() {
				return "ERROR";
			}
		};
	}

	private HystrixCommand.Setter setter() {
		HystrixCommand.Setter setter = HystrixCommand.Setter
				.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupName))
				.andCommandKey(HystrixCommandKey.Factory.asKey(commandName))
				.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(threadKey));
		HystrixCommandProperties.Setter commandPropertiesDefaults = HystrixCommandProperties.Setter().withExecutionTimeoutEnabled(timeOutEnable)
				.withExecutionTimeoutInMilliseconds(timeOutSecond * 1000);
		setter.andCommandPropertiesDefaults(commandPropertiesDefaults);
		return setter;
	}

}

(三)、 定义切面(MyHystrixCommandAspect.java)

package com.eamon.myHystrix.hystrixTool;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.fastjson.JSONObject;
import com.eamon.myHystrix.common.BaseResponse;
import com.eamon.myHystrix.common.CommonResponseUtil;
import com.google.gson.Gson;

/**
 * @description 
 * @author EamonKang	
 * @Date 2018年1月24日
 */
@Aspect
@Component
public class MyHystrixCommandAspect {

	ThreadLocal<Long> startTime = new ThreadLocal<>();

	MyHystrixCommandAdvice hystrixCommandAdvice = new MyHystrixCommandAdvice();

	String methodName = "";

	Gson gson = new Gson();

	@Pointcut("@annotation(com.ec.common.hystrix.MyHystrixCommand)")
	public void requestMethod() {

	};

	@Around("requestMethod()")
	public void around(ProceedingJoinPoint joinPoint) {
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
		MyHystrixCommand action = method.getAnnotation(MyHystrixCommand.class);
		hystrixCommandAdvice.setCommandName(action.commandKey());
		hystrixCommandAdvice.setGroupName(action.groupKey());
		hystrixCommandAdvice.setThreadKey(action.threadPoolKey());
		hystrixCommandAdvice.setTimeOutSecond(action.timeOutSecond());
		hystrixCommandAdvice.setTimeOutEnable(action.timeOutEnabled());
		
		Object object = hystrixCommandAdvice.runCommand(joinPoint);
		
		if ("ERROR".equals((String)object)) {
			ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
			HttpServletRequest request = attributes.getRequest();
			HttpServletResponse response = attributes.getResponse();
			String requestJson = request.getParameter("data");
			JSONObject jsonObject = JSONObject.parseObject(requestJson);
			String lang = jsonObject.getString("lang");
			BaseResponse responseVO = new BaseResponse();
			String description = "请求超时,稍后重试";
			responseVO.outPutFailedResponse("errorCode1", description);
			responseVO.setExpendField("这是断路器返回的");
			String responseJson = gson.toJson(responseVO);
			try {
				CommonResponseUtil.writeResponse(request, response, responseJson);
			} catch (Exception e) {
			}
		}
	}
}
(四)、在对应的接口上,添加@MyHistrixCommand注释就可以了。

编写不易,转载请注明出处,谢谢!


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值