无参数:注解RequestMapping中的属性用method = RequestMethod.POST/GET 区分即可

单参数:注解RequestMapping,不指明method ,默认就是post请求。如果想用get请求,参数上注解@RequestParam

多参数:为了方便最好都转换成单参数的请求,用对象封装,默认会是POST请求。如果想用GET请求,封装的对象换成map,和单参数一样注解@RequestParam

有个问题要注意:在重试机制中,LoadBalancerFeignClient.execute--->(没有引入spring.retry包的情况下)FeignLoadBalancer.executeWithLoadBalancer方法中,buildLoadBalancerCommand的时候,要通过getRequestSpecificRetryHandler方法生成一个retryHandler,放入RXJava的onNext、onError这些的责任链中,以决定当ribbon的请求发生失败之后,要不要重试。在上面的主要的单参数的配置中,不指明method且不注解@RequestParam,起初feign会认为是GET请求,但是实际上最后发出的时候是POST请求*,那么在getRequestSpecificRetryHandler方法中,生成的retryHandler是允许重试的**,那么如果被调用的服务实际上收到了这个post请求,只不过返回的时候超时了,那么ribbon会等不及进行重试,就会发生插入两条的情况。如果一开始就指明了method为POST,那么生成的retryHandler就是不允许重试的,可以避免重复插入。但是我个人倾向于不注明POST,允许重试,自己做好幂等。这样的话如果一个服务偶然掉线了,不至于产生当前POST请求不成功的情况。

也可以在yml文件中配置OkToRetryOnAllOperations为true,允许所有请求都重试,就不会区分Get和Post了。

*开始是GET请求,后来变成POST请求的逻辑是在LoadBalancerFeignClient的execute中,会new 一个ribbonRequest,它的client属性传入的是LoadBalancerFeignClient的delegate,在LoadBalancerFeignClient实例化的时候,FeignRibbonClientAutoConfiguration的@import注解导入了三个Configuration,前两个不满足,实际用的是FeignRibbonClientAutoConfiguration,那么这个delegate就是new Client.Default。而实际发出请求的是FeignLoadBalancer的execute方法,里面把ribbonRequest的client,也就是这个new Client.Default取出,执行convertAndSend方法,发出请求的是httpconnection.getOutputStream(),点进去看,如果body请求体是有内容的,doOutput为true,即使是GET请求,也是用POST请求发出。

**重试次数:由ribbon的初始化的时候NamedContextFactory传入的RibbonClientSpecification中实例化的DefaultClientConfigImpl中的DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER---向下重试其他server的次数默认1