微服务下全局异常处理方案

Roselani ·
更新时间:2024-09-20
· 917 次阅读

1、新建jhjcn-common-base基础工程

2、自定义全局异常类BaseException

package com.jhjcn.common.base.exception; /** * @Deacription TODO * @Author jianhua.hong * @Date 2020/2/25 9:56 **/ public class BaseException extends RuntimeException { private String code; private String message; public BaseException(String message) { this.message = message; } public BaseException(String code, String message) { this.code = code; this.message = message; } public BaseException(Throwable cause) { super(cause); } public String getCode() { return code; } @Override public String getMessage() { return message; } }

3、异常工具类

package com.jhjcn.common.base.exception; /** * @Deacription TODO * @Author jianhua.hong * @Date 2019/11/19 19:41 **/ public class ExceptionUtils { public static String getStackTraceString(Throwable ex) { StackTraceElement[] traceElements = ex.getStackTrace(); StringBuilder traceBuilder = new StringBuilder(); if (traceElements != null && traceElements.length > 0) { for (StackTraceElement traceElement : traceElements) { traceBuilder.append(traceElement.toString()); traceBuilder.append("\n"); } } return traceBuilder.toString(); } }

4、自定义异常处理抽象类BaseExceptionHandler

package com.jhjcn.common.base.exception; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import java.util.HashMap; import java.util.Map; /** * @Deacription TODO * @Author jianhua.hong * @Date 2020/3/26 16:46 **/ @Slf4j public abstract class BaseExceptionHandler { @ResponseBody @ExceptionHandler(value = BaseException.class) public Map handlerCommonException(BaseException exception) { String code = exception.getCode(); String message = exception.getMessage(); Map map = this.buildRespMap(code, message, false, null); log.info("BaseException message is:{},exception info is:{}" + " {} ", exception.getMessage(), ExceptionUtils.getStackTraceString(exception)); return map; } protected Map buildRespMap(String code, String message, boolean isSuccess, Object data) { Map respMap = new HashMap(); respMap.put("code", code); respMap.put("message", message); respMap.put("isSuccess", false); respMap.put("data", null); return respMap; } }

5、微服务信息类FeignServiceInfo

package com.jhjcn.common.base.exception; import org.apache.commons.lang3.StringUtils; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @Deacription TODO * @Author jianhua.hong * @Date 2020/3/26 15:07 **/ public final class FeignServiceInfo { private final static Map Service_Map = new ConcurrentHashMap(); public static void addService(final String name, String descr) { if (StringUtils.isBlank(name)) { return; } if (StringUtils.isBlank(descr)) { descr = name; } Service_Map.put(name, descr); } protected static Map getServiceMap() { return Service_Map; } }

6、异常处理类

package com.jhjcn.common.base.exception; import feign.FeignException; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import java.util.Map; /** * @Deacription TODO * @Author jianhua.hong * @Date 2020/2/25 11:24 **/ @Slf4j @ControllerAdvice public class ServiceExceptionHandler extends BaseExceptionHandler { private final static String NO_AVAILABLE_SERVER_MESSAGE = "Load balancer does not have available server for client"; private final static String DEFAULT_ERROR_CODE = "999999"; @ResponseBody @ExceptionHandler(value = {com.netflix.client.ClientException.class}) public Map handlerCommonException(com.netflix.client.ClientException exception) { String message = exception.getErrorMessage(); String clientMessage = this.getServiceDescr(message); if (!StringUtils.isBlank(message) && message.startsWith(NO_AVAILABLE_SERVER_MESSAGE)) { clientMessage = "未找到可用的" + clientMessage; } else { clientMessage = clientMessage + "异常"; } Map map = this.buildRespMap(DEFAULT_ERROR_CODE, clientMessage, false, null); log.info("微服务客户端异常:{}", message); return map; } @ResponseBody @ExceptionHandler(value = {FeignException.class}) public Map handlerCommonException(FeignException exception) { String message = exception.getMessage(); String feignMessage = this.getServiceDescr(message) + "出现异常"; Map map = this.buildRespMap(DEFAULT_ERROR_CODE, feignMessage, false, null); log.info("调用微服务异常:{}", message); return map; } private String getServiceDescr(String message) { if (StringUtils.isBlank(message)) { return null; } Map map = FeignServiceInfo.getServiceMap(); if (!map.isEmpty()) { String descr = null; for (Map.Entry entry : map.entrySet()) { String key = entry.getKey(); if (message.contains(key)) { descr = entry.getValue(); break; } } if (StringUtils.isBlank(descr)) { descr = message; } return descr; } else { return message; } } }

7、微服务信息配置组件

package com.jhjcn.business.config; import com.jhjcn.common.base.exception.FeignServiceInfo; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Configuration; import org.springframework.util.ObjectUtils; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.Map; /** * @Deacription TODO * @Author jianhua.hong * @Date 2020/3/26 15:24 **/ @Configuration @ConditionalOnClass(ServiceInfo.class) public class ServiceInfoConfig { @Resource private ServiceInfo serviceInfo; @PostConstruct public void init() { Map serviceMap = serviceInfo.getMaps(); if (!ObjectUtils.isEmpty(serviceMap)) { for (Map.Entry entry : serviceMap.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); FeignServiceInfo.addService(key, value); } } } }

8、微服信息配置信息类
配置文件

services: info: maps: jhjcn-service-pay: 聚行家支付微服务 jhjcn-service-user: 聚行家用户微服务 jhjcn-service-behavior: 聚行家行为日志微服务 jhjcn-service-base: 聚行家基础微服务 jhjcn-service-diagnose: 聚行家企业诊断微服务 jhjcn-service-bigsearch: 聚行家搜索微服务 jhjcn-service-live: 聚行家直播微服务 jhjcn-service-circle: 聚行家圈子微服务 package com.jhjcn.business.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.Map; /** * @Deacription TODO * @Author jianhua.hong * @Date 2020/3/31 9:39 **/ @Component @ConfigurationProperties(prefix = "services.info") public class ServiceInfo { private Map maps; public Map getMaps() { return maps; } public void setMaps(Map maps) { this.maps = maps; } }
作者:hong_myth



微服务 异常 异常处理

需要 登录 后方可回复, 如果你还没有账号请 注册新账号