Spring Coud zulカスタム統一異常処理の実現方法


Zuulは、springcloudマイクロサービスシステムにおいてfilerとrouter機能を提供するために、マイクロサービスに不可欠な部分である。filer処理は、デフォルトで実装されたもの以外にも、独自に承認、制限ストリーム、セキュリティチェックなどを行うことができ、routerは、NFIx逆エージェントに代わることができます。Zuul異常処理はSendError Filterによって行われます。
私たちが応用する過程で、デフォルトの異常filterを使うと、二つの問題が友好的ではないことが分かりました。
1.ルーティングを要求するサービスのタイムアウトか、それとも利用可能なノードがないかを素早く識別できません。エラーが発生したらログを確認してスタックを通して位置を特定するしかありません。
2.カスタムの例えば{code:500,msg:”xx error”}フォーマットのレスポンスパケットフォーマットを互換できません。
次に、異常処理、カスタム異常提示情報などのカスタマイズについて検討します。
まず、私たちはデフォルトのSendError Filterを無効にしなければなりません。公式はすでにスイッチの配置を提供しています。直接配置すればいいです。

zuul.SendErrorFilter.post.disable=true
Errer Filterをカスタマイズします。ここでは多く言わないで、直接コードを貼ります。

public class ErrorFilter extends ZuulFilter {
  private static final String ERROR_STATUS_CODE_KEY = "error.status_code";
  private Logger log = LoggerFactory.getLogger(ErrorFilter.class);
  public static final String DEFAULT_ERR_MSG = "    ,     ";
  @Override
  public String filterType() {
    return "post";
  }
  @Override
  public int filterOrder() {
    return 0;
  }
  @Override
  public boolean shouldFilter() {
    RequestContext ctx = RequestContext.getCurrentContext();
    return ctx.containsKey(ERROR_STATUS_CODE_KEY);
  }
  @Override
  public Object run() {    
    RequestContext ctx = RequestContext.getCurrentContext();
    try {
      HttpServletRequest request = ctx.getRequest();
      int statusCode = (Integer) ctx.get(ERROR_STATUS_CODE_KEY);
      String message = (String) ctx.get("error.message");
      if (ctx.containsKey("error.exception")) {
        Throwable e = (Exception) ctx.get("error.exception");
        Throwable re = getOriginException(e);
        if(re instanceof java.net.ConnectException){
          message = "Real Service Connection refused";
          log.warn("uri:{},error:{}" ,request.getRequestURI(),re.getMessage());
        }else if(re instanceof java.net.SocketTimeoutException){
          message = "Real Service Timeout";
          log.warn("uri:{},error:{}" ,request.getRequestURI(),re.getMessage());
        }else if(re instanceof com.netflix.client.ClientException){
          message = re.getMessage();
          log.warn("uri:{},error:{}" ,request.getRequestURI(),re.getMessage());
        }else{
          log.warn("Error during filtering",e);
        }
      }
      if(StringUtils.isBlank(message))message = DEFAULT_ERR_MSG;
      request.setAttribute("javax.servlet.error.status_code", statusCode);
      request.setAttribute("javax.servlet.error.message", message);
      WebUtils.responseOutJson(ctx.getResponse(), JsonUtils.toJson(new WrapperResponse<>(statusCode, message)));
    } catch (Exception e) {
      String error = "Error during filtering[ErrorFilter]";
      log.error(error,e);
      WebUtils.responseOutJson(ctx.getResponse(), JsonUtils.toJson(new WrapperResponse<>(500, error)));
    }
    return null;
  }
  private Throwable getOriginException(Throwable e){
    e = e.getCause();
    while(e.getCause() != null){
      e = e.getCause();
    }
    return e;
  }
}
最後に私達がカスタマイズしたErr Filterを登録します。

@Bean 
public ErrorFilter errorFilter(){
  return new ErrorFilter();
}
締め括りをつける
以上は小编がご绍介したSpring Cloud zulカスタム统一异常処理の実现方法です。皆様に何かご迷惑があったらメッセージをください。小编はすぐにご返事します。ここでも私たちのサイトを応援してくれてありがとうございます。