SpringCloud应用间通信-RestTemplate与Feign

SpringCloud 应用间通信基于HTTP的Restful调用方式有两种,RestTemplate与Feign

1.RestTemplate是远程调用Http的工具,支持本地负载均衡,是对Ribbon的封装。

  pom文件加入spring-boot-starter-web依赖

  调用的url是服务名,在eureka注册中心注册的服务名。使用服务名可以支持本地的负载均衡,如果使用ip地址,则不支持负载均衡。

  一般使用@Bean将RestTemplate 注册到spring 容器中 @LoadBalanced 开启负载均衡

@Configuration
public class RestTemplateConfig { 
    
    @Value("${remote.maxTotalConnect}")
    private int maxTotalConnect; //连接池的最大连接数默认为0
    @Value("${remote.maxConnectPerRoute}")
    private int maxConnectPerRoute; //单个主机的最大连接数默认200
    @Value("${remote.connectTimeout}")
    private int connectTimeout; //连接超时默认2s
    @Value("${remote.readTimeout}")
    private int readTimeout; //读取超时默认30s
    @Bean// 将RestTemplate  注册到spring 容器中
    @LoadBalanced// 开启负载均衡
    RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate(createFactory());
         List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
         //重新设置StringHttpMessageConverter字符集为UTF-8,解决中文乱码问题
         HttpMessageConverter<?> converterTarget = null;
         for (HttpMessageConverter<?> item : converterList) {
             if (StringHttpMessageConverter.class == item.getClass()) {
                 converterTarget = item;
                 break;
             }
         }
         if (null != converterTarget) {
             converterList.remove(converterTarget);
         }
         converterList.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }
        
    //创建HTTP客户端工厂
    private ClientHttpRequestFactory createFactory() {
        if(this.maxTotalConnect <= 0){
            SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
            factory.setConnectTimeout(this.connectTimeout);
            factory.setReadTimeout(this.readTimeout);
            return factory;
        }
        HttpClient httpClient = HttpClientBuilder.create().setMaxConnTotal(this.maxTotalConnect).setMaxConnPerRoute(this.maxConnectPerRoute).build();
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
        factory.setConnectTimeout(this.connectTimeout);
        factory.setReadTimeout(this.readTimeout);
        return factory;
    }
}
View Code

  service中直接引用restTemplate调用接口

@Service
public class RemoteServiceImpl  implements IRemoteService{
    
    @Autowired
    private  RestTemplate restTemplate;
    
    /**
     * @description:远程请求方法(同步)
     * @author @author skj  
     * @date 2019年10月29日
     */
    @Override
    public JSONObject excute(MultiValueMap<String, Object> map,String url) throws Exception{
        ResponseEntity<JSONObject> responseEntity = null;
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String,Object>>(map, headers);
        responseEntity = restTemplate.postForEntity(url, requestEntity,JSONObject.class);
        JSONObject result = responseEntity.getBody();
        return result;
    }
    
    /**
     * @description:远程请求方法(异步)
     * @author @author skj  
     * @date 2019年10月29日
     */
    @Override
    @Async
    public void asyncExcute(MultiValueMap<String, Object> map,String url) throws Exception{
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String,Object>>(map, headers);
        restTemplate.postForEntity(url, requestEntity,JSONObject.class);
    }
}
View Code

2.Feign客户端是一个web声明式http远程调用工具,提供了接口和注解方式进行调用,是对Ribbon的封装。

  pom文件加入spring-cloud-starter-openfeign依赖

  接口指定服务器名称及方法:

@FeignClient(value = "erecord-search-service")// 指定服务名称
public interface ERecordFeignClient {

    @RequestMapping(value = "/vendorInfo/vendor-by-unitid-deviceid",method = RequestMethod.POST)
    JSONObject findByunitIdAndDeviceId(
            @RequestParam("unitId") String unitId,
            @RequestParam("deviceId") String deviceId
    );
}
View Code

  service中直接调用该接口:。

@Autowired
private ERecordFeignClient eRecordFeignClient;; //引入接口

@RequestMapping("/devicetypes")
public String devicetypes() {
    return eRecordFeignClient.devicetypes(accidentInfo.getDeviceTypeId(), null, null); // 调用服务
}
View Code

  开启配置:

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients  // 启用feign 客户端
public class AppOrder {
    public static void main(String[] args) {
        SpringApplication.run(AppOrder.class, args);
    }

    // 如果使用rest方式以别名方式进行调用依赖ribbon负载均衡器         
        @LoadBalanced
    // @LoadBalanced就能让这个RestTemplate在请求时拥有客户端负载均衡的能力
        // 这个就是前面介绍到的RestTemplate的配置方式
    @Bean 
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

}
View Code

 

 

参考博客:https://blog.csdn.net/u010548207/article/details/100073964

posted @ 2019-12-23 22:44  苏大大的园子  阅读(1880)  评论(0编辑  收藏  举报