Java fresh business platform -SpringCloud micro-architecture network service request performance optimization and analytic source

Java fresh business platform -SpringCloud micro-architecture network service request performance optimization and analytic source

 

Description: Java fresh electronic business platform, because the service was split, leading to a lot of business service performance and network delay request consumption corresponding to these problems, we should deal with how to optimize the network requests it?

In the end there are some good suggestions and options?

 

The following article will reveal the above questions, let you SpringCloud micro network service request performance have a new understanding.

 

Table of Contents Introduction

  • 01. network requests malfunction classification
  • 02. development of attention problems
  • 03. The original approach
  • 04. How to reduce code coupling
  • 05. Abnormal unified processing steps
  • 06. complete version of the code shows

01. network requests malfunction classification

Network requests abnormal about what?

  • The first: access interface abnormalities, such as 404, 500 and other abnormalities, the emergence of such anomalies, Retrofit will automatically throw an exception.
  • The second: abnormal analytical data, data volume changes may cause this problem.
  • Third: Other types of abnormalities, such as a server response timeout exception, link failure abnormality, abnormality and so the network is not connected.
  • Fourth: The network request was successful, but the server is defined abnormal conditions, such as token failure, parameter passing errors, or unity to prompt (this place is a mouthful, such as shopping app, you n buy items request interface successfully, code 200, but the server is not found so much merchandise, this time it will give you a hint, then get this client were toast)

02. development of attention problems

In the process acquired data, when parsed data access interface and are likely to be wrong, we can intercept this error in two by the interceptor.

  • 1. When access interface, we do not set interceptor, because once an error occurs, Retrofit automatically throw an exception. For example, a common request an exception 404,500,503 and so on. In order to facilitate post troubleshoot the problem, this log can be printed in the debug environment can be.
  • 2. When parsing the data, we set up an interceptor, to determine whether the code inside the Result is successful, if unsuccessful, will have to throw an exception corresponding error code according to good agreement with the server. For example, token after the failure Jump login page, account login is disabled with multiple devices, the lack of parameters, parameter passing abnormalities and so on.
  • 3. In addition, we should try to avoid errors in judgment in the View layer, handling, we must also set an interceptor to intercept onError event and then use ExceptionUtils, let it be treated separately according to the type of error.

03. The original approach

  • The simplest approach, throwable directly returned by the type determining processing
//请求,对throwable进行判断
ServiceHelper.getInstance()
      .getModelResult(param1, param2)
      .subscribeOn(Schedulers.io())
      .observeOn(AndroidSchedulers.mainThread())
      .subscribe(new Subscriber<Model>() {
             @Override
              public void onCompleted() { } @Override public void onError(Throwable e) { if(e instanceof HttpException){ //获取对应statusCode和Message HttpException exception = (HttpException)e; String message = exception.response().message(); int code = exception.response().code(); }else if(e instanceof SSLHandshakeException){ //接下来就是各种异常类型判断... }else if(e instanceof ...){ }... } @Override public void onNext(Model model) { if(model.getCode != CODE_SUCCESS){ int code = model.getCode(); switch (code){ case CODE_TOKEN_INVALID: ex.setDisplayMessage("重新登陆"); break; case CODE_NO_OTHER: ex.setDisplayMessage("其他情况"); break; case CODE_SHOW_TOAST: ex.setDisplayMessage("吐司服务器返回的提示"); break; case CODE_NO_MISSING_PARAMETER: ex.setDisplayMessage("缺少参数,用log记录服务器提示"); break; default: ex.setDisplayMessage(message); break; } }else{ //正常处理逻辑 } } });

04. How to reduce code coupling

  • In order not to change the previous code structure, then how to do to be able to completely decouple it? Retrofit using general framework network requests, there is the callback method, as follows:
package retrofit2;

public interface Callback<T> { void onResponse(Call<T> var1, Response<T> var2); void onFailure(Call<T> var1, Throwable var2); } 
  • Whether or not the package before the code, a code that wants to intercept a request for network processing logic. Well, this time, is how I deal with it?
public class ResponseData<T> { private int code; private String message; private T t; public int getCode() { return code; } public String getMessage() { return message; } public T getT() { return t; } } new Callback<ResponseData<HomeBlogEntity>>(){ @Override public void onResponse(Call<ResponseData<HomeBlogEntity>> call, Response<ResponseData<HomeBlogEntity>> response) { int code = response.body().getCode(); String message = response.body().getMessage(); HomeBlogEntity t = response.body().getT(); if (code!= CODE_SUCCESS){ //网络请求成功200,不过业务层执行服务端制定的异常逻辑 ExceptionUtils.serviceException(code,message); } else { //网络请求成功,业务逻辑正常处理 } } @Override public void onFailure(Call call, Throwable throwable) { ExceptionUtils.handleException(throwable); } }; 

05. Abnormal unified processing steps

  • STEP 1: network layer failed request interface status code
/**
 * 对应HTTP的状态码
 */
private static final int BAD_REQUEST = 400; private static final int UNAUTHORIZED = 401; private static final int FORBIDDEN = 403; private static final int NOT_FOUND = 404; private static final int METHOD_NOT_ALLOWED = 405; private static final int REQUEST_TIMEOUT = 408; private static final int CONFLICT = 409; private static final int PRECONDITION_FAILED = 412; private static final int INTERNAL_SERVER_ERROR = 500; private static final int BAD_GATEWAY = 502; private static final int SERVICE_UNAVAILABLE = 503; private static final int GATEWAY_TIMEOUT = 504; 
  • The second step, the interface request is successful, the service layer is failed, the server status codes defined exception

For example, the login expires, to remind the user to log in again;
for example, add items, but found insufficient inventory server, this time the success of interface requests, the server fails to define the business layer, the server gives the prompt, the client toast
, for example, request Interface, parameter error or the wrong type, the request code 200 successful state, but given prompt, this time with a client log print server gives the prompt, convenient courier find the problem
, for example, the other case, the interface request is successful, but the service end defined business layer needs to toast the server returns the corresponding prompt

/**
 * 服务器定义的状态吗
 * 比如:登录过期,提醒用户重新登录;
 *      添加商品,但是服务端发现库存不足,这个时候接口请求成功,服务端定义业务层失败,服务端给出提示语,客户端进行吐司
 *      请求接口,参数异常或者类型错误,请求code为200成功状态,不过给出提示,这个时候客户端用log打印服务端给出的提示语,方便快递查找问题
 *      其他情况,接口请求成功,但是服务端定义业务层需要吐司服务端返回的对应提示语
 */
/**
 * 完全成功
 */
private static final int CODE_SUCCESS = 0; /** * Token 失效 */ public static final int CODE_TOKEN_INVALID = 401; /** * 缺少参数 */ public static final int CODE_NO_MISSING_PARAMETER = 400400; /** * 其他情况 */ public static final int CODE_NO_OTHER = 403; /** * 统一提示 */ public static final int CODE_SHOW_TOAST = 400000; 第三步,自定义Http层的异常和服务器定义的异常类 public class HttpException extends Exception { private int code; private String displayMessage; public HttpException(Throwable throwable, int code) { super(throwable); this.code = code; } public void setDisplayMessage(String displayMessage) { this.displayMessage = displayMessage; } public String getDisplayMessage() { return displayMessage; } public int getCode() { return code; } } public class ServerException extends RuntimeException { public int code; public String message; public int getCode() { return code; } public void setCode(int code) { this.code = code; } @Override public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } 
  • A fourth step, the unitary exception logic shown below
/**
 * 这个可以处理服务器请求成功,但是业务逻辑失败,比如token失效需要重新登陆
 * @param code                  自定义的code码
 */
public static void serviceException(int code , String content){ if (code != CODE_SUCCESS){ ServerException serverException = new ServerException(); serverException.setCode(code); serverException.setMessage(content); handleException(serverException); } } /** * 这个是处理网络异常,也可以处理业务中的异常 * @param e e异常 */ public static void handleException(Throwable e){ HttpException ex; //HTTP错误 网络请求异常 比如常见404 500之类的等 if (e instanceof retrofit2.HttpException){ retrofit2.HttpException httpException = (retrofit2.HttpException) e; ex = new HttpException(e, ErrorCode.HTTP_ERROR); switch(httpException.code()){ case BAD_REQUEST: case UNAUTHORIZED: case FORBIDDEN: case NOT_FOUND: case METHOD_NOT_ALLOWED: case REQUEST_TIMEOUT: case CONFLICT: case PRECONDITION_FAILED: case GATEWAY_TIMEOUT: case INTERNAL_SERVER_ERROR: case BAD_GATEWAY: case SERVICE_UNAVAILABLE: //均视为网络错误 default: ex.setDisplayMessage("网络错误"+httpException.code()); break; } } else if (e instanceof ServerException){ //服务器返回的错误 ServerException resultException = (ServerException) e; int code = resultException.getCode(); String message = resultException.getMessage(); ex = new HttpException(resultException, ErrorCode.SERVER_ERROR); switch (code){ case CODE_TOKEN_INVALID: ex.setDisplayMessage("token失效"); //下面这里可以统一处理跳转登录页面的操作逻辑 break; case CODE_NO_OTHER: ex.setDisplayMessage("其他情况"); break; case CODE_SHOW_TOAST: ex.setDisplayMessage("吐司"); break; case CODE_NO_MISSING_PARAMETER: ex.setDisplayMessage("缺少参数"); break; default: ex.setDisplayMessage(message); break; } } else if (e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException){ ex = new HttpException(e, ErrorCode.PARSE_ERROR); //均视为解析错误 ex.setDisplayMessage("解析错误"); }else if(e instanceof ConnectException){ ex = new HttpException(e, ErrorCode.NETWORK_ERROR); //均视为网络错误 ex.setDisplayMessage("连接失败"); } else if(e instanceof java.net.UnknownHostException){ ex = new HttpException(e, ErrorCode.NETWORK_ERROR); //网络未连接 ex.setDisplayMessage("网络未连接"); } else if (e instanceof SocketTimeoutException) { ex = new HttpException(e, ErrorCode.NETWORK_ERROR); //网络未连接 ex.setDisplayMessage("服务器响应超时"); } else { ex = new HttpException(e, ErrorCode.UNKNOWN); //未知错误 ex.setDisplayMessage("未知错误"); } String displayMessage = ex.getDisplayMessage(); //这里直接吐司日志异常内容,注意正式项目中一定要注意吐司合适的内容 ToastUtils.showRoundRectToast(displayMessage); } 
  • The fifth step, how to call
@Override
public void onError(Throwable e) { //直接调用即可 ExceptionUtils.handleException(e); } 

06. complete version of the code shows

  • As follows
public class ExceptionUtils {

    /* * 在使用Retrofit+RxJava时,我们访问接口,获取数据的流程一般是这样的:订阅->访问接口->解析数据->展示。 * 如上所说,异常和错误本质是一样的,因此我们要尽量避免在View层对错误进行判断,处理。 * * 在获取数据的流程中,访问接口和解析数据时都有可能会出错,我们可以通过拦截器在这两层拦截错误。 * 1.在访问接口时,我们不用设置拦截器,因为一旦出现错误,Retrofit会自动抛出异常。 * 2.在解析数据时,我们设置一个拦截器,判断Result里面的code是否为成功,如果不成功,则要根据与服务器约定好的错误码来抛出对应的异常。 * 3.除此以外,为了我们要尽量避免在View层对错误进行判断,处理,我们必须还要设置一个拦截器,拦截onError事件,然后使用ExceptionHandler,让其根据错误类型来分别处理。 */ /** * 对应HTTP的状态码 */ private static final int BAD_REQUEST = 400; private static final int UNAUTHORIZED = 401; private static final int FORBIDDEN = 403; private static final int NOT_FOUND = 404; private static final int METHOD_NOT_ALLOWED = 405; private static final int REQUEST_TIMEOUT = 408; private static final int CONFLICT = 409; private static final int PRECONDITION_FAILED = 412; private static final int INTERNAL_SERVER_ERROR = 500; private static final int BAD_GATEWAY = 502; private static final int SERVICE_UNAVAILABLE = 503; private static final int GATEWAY_TIMEOUT = 504; /** * 服务器定义的状态吗 * 比如:登录过期,提醒用户重新登录; * 添加商品,但是服务端发现库存不足,这个时候接口请求成功,服务端定义业务层失败,服务端给出提示语,客户端进行吐司 * 请求接口,参数异常或者类型错误,请求code为200成功状态,不过给出提示,这个时候客户端用log打印服务端给出的提示语,方便快递查找问题 * 其他情况,接口请求成功,但是服务端定义业务层需要吐司服务端返回的对应提示语 */ /** * 完全成功 */ private static final int CODE_SUCCESS = 0; /** * Token 失效 */ public static final int CODE_TOKEN_INVALID = 401; /** * 缺少参数 */ public static final int CODE_NO_MISSING_PARAMETER = 400400; /** * 其他情况 */ public static final int CODE_NO_OTHER = 403; /** * 统一提示 */ public static final int CODE_SHOW_TOAST = 400000; /** * 这个可以处理服务器请求成功,但是业务逻辑失败,比如token失效需要重新登陆 * @param code 自定义的code码 */ public static void serviceException(int code , String content){ if (code != CODE_SUCCESS){ ServerException serverException = new ServerException(); serverException.setCode(code); serverException.setMessage(content); handleException(serverException); } } /** * 这个是处理网络异常,也可以处理业务中的异常 * @param e e异常 */ public static void handleException(Throwable e){ HttpException ex; //HTTP错误 网络请求异常 比如常见404 500之类的等 if (e instanceof retrofit2.HttpException){ retrofit2.HttpException httpException = (retrofit2.HttpException) e; ex = new HttpException(e, ErrorCode.HTTP_ERROR); switch(httpException.code()){ case BAD_REQUEST: case UNAUTHORIZED: case FORBIDDEN: case NOT_FOUND: case METHOD_NOT_ALLOWED: case REQUEST_TIMEOUT: case CONFLICT: case PRECONDITION_FAILED: case GATEWAY_TIMEOUT: case INTERNAL_SERVER_ERROR: case BAD_GATEWAY: case SERVICE_UNAVAILABLE: //均视为网络错误 default: ex.setDisplayMessage("网络错误"+httpException.code()); break; } } else if (e instanceof ServerException){ //服务器返回的错误 ServerException resultException = (ServerException) e; int code = resultException.getCode(); String message = resultException.getMessage(); ex = new HttpException(resultException, ErrorCode.SERVER_ERROR); switch (code){ case CODE_TOKEN_INVALID: ex.setDisplayMessage("重新登陆"); break; case CODE_NO_OTHER: ex.setDisplayMessage("其他情况"); break; case CODE_SHOW_TOAST: ex.setDisplayMessage("吐司"); break; case CODE_NO_MISSING_PARAMETER: ex.setDisplayMessage("缺少参数"); break; default: ex.setDisplayMessage(message); break; } } else if (e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException){ ex = new HttpException(e, ErrorCode.PARSE_ERROR); //均视为解析错误 ex.setDisplayMessage("解析错误"); }else if(e instanceof ConnectException){ ex = new HttpException(e, ErrorCode.NETWORK_ERROR); //均视为网络错误 ex.setDisplayMessage("连接失败"); } else if(e instanceof java.net.UnknownHostException){ ex = new HttpException(e, ErrorCode.NETWORK_ERROR); //网络未连接 ex.setDisplayMessage("网络未连接"); } else if (e instanceof SocketTimeoutException) { ex = new HttpException(e, ErrorCode.NETWORK_ERROR); //网络未连接 ex.setDisplayMessage("服务器响应超时"); } else { ex = new HttpException(e, ErrorCode.UNKNOWN); //未知错误 ex.setDisplayMessage("未知错误"); } String displayMessage = ex.getDisplayMessage(); //这里直接吐司日志异常内容,注意正式项目中一定要注意吐司合适的内容 ToastUtils.showRoundRectToast(displayMessage); } } 

Thank you can read the last, I hope you can help.

 If you need to source code or schema document, please add QQ group: 793 305 035

Guess you like

Origin www.cnblogs.com/jurendage/p/11357234.html