接口超时,接口参数的特殊符号,接口的有序性,重试机制的结果一致性

发布时间 2023-12-20 23:03:43作者: oktokeep

接口超时,接口参数的特殊符号,接口的有序性,重试机制的结果一致性

1.http超时时间,将restTemplate的连接,超时时间设置更加长的时间。
2.http mvc GET请求,?a=1&b=2&c=#3,测试发现含#符号会在服务接口接收参数异常。需要将#特殊符合过滤,比如:可以替换为中文”井“
3.请求的有序性保持
3.1服务端方法:比如接收到无序的MQ消息或者binlog,比如对库存的控制,删除之前先验证订单状态。只有取消订单状态才会删除库存。
删除库存记录之前,先验证一下订单状态(非取消的情况下)库存是需要占据的,不应删除。
正常的顺序是:先删后增。如果反过来:先增后删,就会出现增加的时候无法新增,因为已经存在了。而最终的结果是删除了。
1. A >> B
2. 删除,没有记录了,导致库存没有记录,引起超卖。


3.2客户端方法:客户端请求失败 + 重试机制,如何保障2次请求的结果正确,而不被覆盖。
从大的方面来看:其实是涉及到两个系统的事务一致性问题,A系统的结果 = B系统的结果。
比如:请求a 参数100 失败
请求b 参数200 成功 >> B系统结果200
重试请求a 参数100 成功 >> B系统结果100

以上操作就会出现最终的结果不一致:期望是A系统结果200,B系统的结果是100

解决方法:在重试请求的操作中,需要获取最新的参数值来发起请求,而不是基于上一次请求失败的参数来发起。关键


3.3 客户端方法2: 异步方法@Async + 延时重试 + while循环(在一段时间内的循环,确保接口的顺序执行,比如:先取消后新增,没有取消成功之后,不能新增操作)

@Transactional事务注解及请求接口的定义先后执行顺序设计

//超时时间设置代码
    @Autowired
    RestTemplateConfig restTemplateConfig;

HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.set("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE);   //application/x-www-form-urlencoded
            httpHeaders.set("user-agent", "自定义");
            HttpEntity httpEntity = new HttpEntity(httpHeaders);
String responseStr = restTemplateConfig.restTemplate().postForObject(url+"?"+object, httpEntity, String.class);



import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

/***
 * 内部服务调用者
 */
@Configuration
public class RestTemplateConfig {

    /**
     * 适用于服务使用RestTemplate调用外部地址请求
     * @return
     */
    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());
        return restTemplate ;
    }

    /***
     * 适用于服务内部之间使用RestTemplate相互调用增加Rinbbo机制
     * 通过服务名方式
     * @return
     */
    @Bean(name="loadBalancedRestTemplate")
    @LoadBalanced
    public RestTemplate loadBalancedRestTemplate() {
        RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());
        return restTemplate ;
    }

    private ClientHttpRequestFactory clientHttpRequestFactory() {
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setReadTimeout(30000);
        factory.setConnectTimeout(30000);
        factory.setConnectionRequestTimeout(30000);
        return factory;
    }

}