远程服务调用失败重试之简单实现

一、前言

在业务多、并发高的情况下,我们的系统,一般都会拆分为多个子系统,子系统之前通过 RPC 联系。

RPC 调用偶尔会出现失败的问题,而有些问题实际上不是问题,例如只是网络延迟,方法调用超时,再试一遍就完事了。

这时候,重试的引入即势在必行了。

二、正文

下面写一个简单的 demo,模拟远程服务重试的最简单实现方式——循环实现

1.模拟调用远程服务

重点在于引入 try catch 处理逻辑

package com.cun.retry.client;

import com.cun.retry.service.RemoteService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class Test {

    private static final int RETRY_TIMES = 3;

    private static final Logger logger = LoggerFactory.getLogger(Test.class);

    public static void main(String[] args) {

        int retryCount = 0;
        while (retryCount < RETRY_TIMES) {
            try {
                RemoteService.execute();
                break; // 能执行到这行,说明执行没有异常
            } catch (Exception e) {
                retryCount++;
                logger.info("【远程服务调用失败,重试中】");
            }
        }
        if (retryCount >= RETRY_TIMES){
            logger.info("【无法调用远程服务】");
        }
        logger.info(String.format("【重试次数:%s >>> 最终执行是否成功:%s】", retryCount, retryCount < RETRY_TIMES));
    }

}

2.模拟远程的服务方法

有几率 ÷0 引发失败

package com.cun.retry.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Random;

public class RemoteService {

    private static final Logger logger = LoggerFactory.getLogger(RemoteService.class);

    public static int execute() {
        logger.info("【远程服务执行中】");
        int num = new Random().nextInt(3);
        return 10 / num;
    }

}

可能结果
在这里插入图片描述

在这里插入图片描述
完整代码放在 GitHub 上了:https://github.com/larger5/retry

三、结尾

实际业务中,我们会把调用失败的操作暂存起来,等其他业务过一遍后。再重复执行,以确保大量的其他业务完成,而不至于卡在一个点上。

已标记关键词 清除标记
下面这段代码,在别的电脑就能运行,在我自己的电脑上就不行,不知道是什么原因,找了好久也没找到原因,请各位大佬帮帮忙,不行只能做系统了. ``` string postDataStr = "发送报文"; string Url = "地址"; Encoding encoding = Encoding.UTF8; byte[] postData = encoding.GetBytes(postDataStr); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); request.Method = "POST"; //request.ContentType = "application/x-www-form-urlencoded"; request.ContentType = "text/xml"; request.ContentLength = postData.Length; Stream myRequestStream = request.GetRequestStream(); myRequestStream.Write(postData, 0, postData.Length); myRequestStream.Close(); //报错行 HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, encoding); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); return retString; ``` 直接错误原因:System.Net.WebException:“远程服务器返回错误: (500) 内部服务器错误。” 这是提取的错误: ``` <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Header> <soap12:Upgrade xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> <soap12:SupportedEnvelope qname="soap:Envelope"></soap12:SupportedEnvelope> <soap12:SupportedEnvelope qname="soap12:Envelope"></soap12:SupportedEnvelope> </soap12:Upgrade> </soap:Header> <soap:Body> <soap:Fault> <faultcode>soap:VersionMismatch</faultcode> <faultstring>System.Web.Services.Protocols.SoapException: SOAP 版本可能不匹配: 出现意外的 Envelope 命名空间 。应为 http://schemas.xmlsoap.org/soap/envelope/。 在 System.Web.Services.Protocols.SoapServerProtocol.CheckHelperVersion() 在 System.Web.Services.Protocols.SoapServerProtocol.Initialize() 在 System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)</faultstring> <detail/> </soap:Fault> </soap:Body> </soap:Envelope> ``` 用SoapUI 调用自己的webService 就没事. 当我固定在地址固定某个接口的时候就会报这个错,但是我的格式就是 request.ContentType = "text/xml"; ``` System.InvalidOperationException: 请求格式无效: text/xml。 在 System.Web.Services.Protocols.HttpServerProtocol.ReadParameters() 在 System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest() ```
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页