commit
8509040d81
@ -0,0 +1,15 @@ |
||||
package com.gitee.sop.gatewaycommon.manager; |
||||
|
||||
import com.gitee.sop.gatewaycommon.bean.InstanceDefinition; |
||||
import com.gitee.sop.gatewaycommon.route.RegistryEvent; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
public interface InstanceManager extends RegistryEvent { |
||||
|
||||
List<InstanceDefinition> listInstance(String serviceId); |
||||
|
||||
} |
@ -0,0 +1,86 @@ |
||||
package com.gitee.sop.servercommon.exception; |
||||
|
||||
import com.alibaba.fastjson.JSON; |
||||
import com.gitee.sop.servercommon.bean.ServiceConfig; |
||||
import com.gitee.sop.servercommon.result.ServiceResultBuilder; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.web.util.UriUtils; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.nio.charset.StandardCharsets; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
@Slf4j |
||||
public class ExceptionHolder { |
||||
/** |
||||
* 与网关约定好的状态码,表示业务出错 |
||||
*/ |
||||
private static final int BIZ_ERROR_CODE = 4000; |
||||
|
||||
/** |
||||
* 与网关约定好的系统错误状态码 |
||||
*/ |
||||
private static final int SYSTEM_ERROR_CODE = 5050; |
||||
|
||||
/** |
||||
* header中的错误code |
||||
*/ |
||||
private static final String X_SERVICE_ERROR_HEADER_NAME = "x-service-error-code"; |
||||
|
||||
/** |
||||
* header中的错误信息 |
||||
*/ |
||||
private static final String X_SERVICE_ERROR_MESSAGE = "x-service-error-message"; |
||||
|
||||
/** |
||||
* header中的返回信息 |
||||
*/ |
||||
private static final String X_SERVICE_ERROR_RESPONSE = "x-service-error-response"; |
||||
|
||||
/** |
||||
* 处理微服务异常信息,做到不与原系统的错误处理相冲突 |
||||
* @param request request |
||||
* @param response response |
||||
* @param exception exception |
||||
*/ |
||||
public static void hold(HttpServletRequest request, HttpServletResponse response, Exception exception) { |
||||
log.error("系统错误", exception); |
||||
int code = exception instanceof ServiceException ? BIZ_ERROR_CODE : SYSTEM_ERROR_CODE; |
||||
// 需要设置两个值,这样网关会收到错误信息
|
||||
// 并且会统计到监控当中
|
||||
response.setHeader(X_SERVICE_ERROR_HEADER_NAME, String.valueOf(code)); |
||||
String responseBody = buildResponse(request, response, exception); |
||||
response.setHeader(X_SERVICE_ERROR_RESPONSE, UriUtils.encode(responseBody, StandardCharsets.UTF_8)); |
||||
|
||||
// 如果是未知错误,还需要收集异常信息
|
||||
if (code == SYSTEM_ERROR_CODE) { |
||||
StringBuilder msg = new StringBuilder(); |
||||
msg.append(exception.getMessage()); |
||||
StackTraceElement[] stackTrace = exception.getStackTrace(); |
||||
// 取5行错误内容
|
||||
int lineCount = 5; |
||||
for (int i = 0; i < stackTrace.length && i < lineCount; i++) { |
||||
StackTraceElement stackTraceElement = stackTrace[i]; |
||||
msg.append("\n at ").append(stackTraceElement.toString()); |
||||
} |
||||
response.setHeader(X_SERVICE_ERROR_MESSAGE, UriUtils.encode(msg.toString(), StandardCharsets.UTF_8)); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 处理异常 |
||||
* |
||||
* @param request request |
||||
* @param response response |
||||
* @param exception 异常信息 |
||||
* @return 返回最终结果 |
||||
*/ |
||||
private static String buildResponse(HttpServletRequest request, HttpServletResponse response, Exception exception) { |
||||
ServiceResultBuilder serviceResultBuilder = ServiceConfig.getInstance().getServiceResultBuilder(); |
||||
Object result = serviceResultBuilder.buildError(request, response, exception); |
||||
return JSON.toJSONString(result); |
||||
} |
||||
} |
@ -1,4 +1,5 @@ |
||||
# 错误配置 |
||||
# \u9519\u8BEF\u914D\u7F6E |
||||
|
||||
isp.error_isp.unknown-error=Service is temporarily unavailable |
||||
isp.error_isp.service-unknown-error=Service not unavailable |
||||
isp.error_isv.invalid-parameter=Invalid parameter |
||||
isp.error_isv.common-error=Service error |
@ -1,5 +1,6 @@ |
||||
# 错误配置 |
||||
# \u9519\u8BEF\u914D\u7F6E |
||||
|
||||
isp.error_isp.unknown-error=\u670d\u52a1\u6682\u4e0d\u53ef\u7528 |
||||
# 参数无效 |
||||
isp.error_isv.invalid-parameter=\u53c2\u6570\u65e0\u6548 |
||||
isp.error_isp.service-unknown-error=\u672A\u77E5\u9519\u8BEF |
||||
# \u53C2\u6570\u65E0\u6548 |
||||
isp.error_isv.invalid-parameter=\u53C2\u6570\u65E0\u6548 |
||||
isp.error_isv.common-error=\u7CFB\u7EDF\u9519\u8BEF |
@ -0,0 +1,48 @@ |
||||
package com.gitee.sop.storyweb; |
||||
|
||||
import com.gitee.sop.servercommon.exception.ExceptionHolder; |
||||
import com.gitee.sop.servercommon.exception.ServiceException; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.web.bind.annotation.ControllerAdvice; |
||||
import org.springframework.web.bind.annotation.ExceptionHandler; |
||||
import org.springframework.web.bind.annotation.ResponseBody; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
/** |
||||
* 全局异常处理 |
||||
* |
||||
* @author tanghc |
||||
*/ |
||||
@ControllerAdvice |
||||
@Slf4j |
||||
public class StoryGlobalExceptionHandler { |
||||
|
||||
|
||||
/** |
||||
* 捕获手动抛出的异常 |
||||
* |
||||
* @param request request |
||||
* @param response response |
||||
* @param exception 异常信息 |
||||
* @return 返回提示信息 |
||||
*/ |
||||
@ExceptionHandler(Exception.class) |
||||
@ResponseBody |
||||
public Object exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception exception) { |
||||
// 在返回前加这一句
|
||||
ExceptionHolder.hold(request, response, exception); |
||||
// 下面可以实现自己的全局异常处理
|
||||
return new ErrorResult(500, exception.getMessage()); |
||||
} |
||||
|
||||
@Data |
||||
@AllArgsConstructor |
||||
public static class ErrorResult { |
||||
private int code; |
||||
private String msg; |
||||
} |
||||
} |
@ -0,0 +1,27 @@ |
||||
package com.gitee.sop.gateway.mapper; |
||||
|
||||
import org.apache.ibatis.annotations.Insert; |
||||
import org.apache.ibatis.annotations.Mapper; |
||||
import org.apache.ibatis.annotations.Param; |
||||
import org.apache.ibatis.annotations.ResultType; |
||||
import org.apache.ibatis.annotations.Select; |
||||
|
||||
/** |
||||
* @author tanghc |
||||
*/ |
||||
@Mapper |
||||
public interface SystemLockMapper { |
||||
|
||||
/** |
||||
* 插入唯一值 |
||||
* @param content 唯一值 |
||||
* @return 1:返回成功,0:插入失败 |
||||
*/ |
||||
@Insert("INSERT IGNORE INTO system_lock(content) VALUES (#{content})") |
||||
@ResultType(int.class) |
||||
int insert(@Param("content") String content); |
||||
|
||||
@Select("SELECT id FROM system_lock WHERE id=1 FOR UPDATE") |
||||
@ResultType(long.class) |
||||
long lock(); |
||||
} |
@ -0,0 +1,19 @@ |
||||
从之前版本升级到4.4.0必须看,如果直接从4.4.0开始使用,不用看。 |
||||
|
||||
- 首先执行升级脚本 |
||||
|
||||
```sql |
||||
use sop; |
||||
|
||||
CREATE TABLE `system_lock` ( |
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, |
||||
`content` varchar(64) NOT NULL DEFAULT '', |
||||
PRIMARY KEY (`id`), |
||||
UNIQUE KEY `uk_content` (`content`) USING BTREE |
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
||||
|
||||
INSERT INTO `system_lock` (`id`, `content`) VALUES (1,'lock'); |
||||
``` |
||||
|
||||
类`com.gitee.sop.servercommon.configuration.GlobalExceptionHandler`已被废弃,替代方案改用自己的全局异常处理 |
||||
参考:`com.gitee.sop.storyweb.StoryGlobalExceptionHandler`。这样改的目的是对于老项目的全局异常无入侵。 |
Loading…
Reference in new issue