SpringCloudサービス間の2つの通信方式

8219 ワード

一、springCloudサービス間の通信方式は二つある

  • RestTemplate方式
  • Feignの方式
  • 二、RestTemplate方式


    RestTemplateでも3つに分けて簡単にデモンストレーションしてみましょう
  • 第1の方法はRestTemplateを直接使用し、urlはサービス側作成
  • を書く.
    /**
     *   order  
     * @author ccyang
     * @date 2018/7/1 16:06
     */
    @RestController
    public class serverController {
        @GetMapping("/getMsg")
        public String getMsg(){
            return "this is product' msg";
        }
    }

    クライアント作成
    /**
     * @author ccyang
     * @date 2018/7/1 16:13
     */
    @RestController
    @Slf4j
    public class clientController {
    
        @GetMapping("/getProductMsg")
        public String getProductMsg(){
    
            RestTemplate restTemplate = new RestTemplate();
            String response = restTemplate.getForObject("http://localhost:8080/getMsg",String.class);
            log.info("response = {}" , response);
            return response;
        }
    
    }
    

    そして訪問http://localhost:8080/getMsgできます.
    サービス側のapiはクライアントにハードコーディングされているため、登録センターに多くのサービスがある場合、必要なサービスが誰が提供するのか、apiがどれだけ提供されるのか分からないため、サービスを呼び出すことができない可能性があります.–apiが「localhost:9080/getMsg,localhost:9081/getMsg」のようなサービスが複数配備されている場合、このハードコーディングは明らかにシーンに合致しない負荷等化が必要になります.
  • 第2の方法:serviceエンドコードは依然として、クライアントはLoadBalancerClientを通じてアプリケーション名を取得し、さらにアドレスとポートを取得し、フォーマットパッチアドレスでproductサービスを呼び出す.
  • /**
     *   product msg
     * @author ccyang
     * @date 2018/7/1 16:13
     */
    @RestController
    @Slf4j
    public class clientController {
    
        @Autowired
        private LoadBalancerClient loadBalancerClient;
    
        @GetMapping("/getProductMsg")
        public String getProductMsg(){
    
            RestTemplate restTemplate = new RestTemplate();
            ServiceInstance serviceInstance = loadBalancerClient.choose("PRODUCT");  // serviceId  
            String url = String.format("http://%s:%s",serviceInstance.getHost(),serviceInstance.getPort() + "/getMsg");
            String response = restTemplate.getForObject( url, String.class);
            log.info("response = {}" , response);
            return response;
        }
    }

    欠点は、サービスを呼び出すたびにこのように書かれ、符号化が面倒であることです.
  • 第3の方法は@LoadBalancedを通じてrestTemplateで直接アプリケーション名を使用することができる.
  • @Component
    public class RestTemplateConfig {
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    @RestController
    @Slf4j
    public class clientController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @GetMapping("/getProductMsg")
        public String getProductMsg(){
    
            String response = restTemplate.getForObject( "http://PRODUCT/getMsg", String.class);  //  
            log.info("response = {}" , response);
            return response;
        }
    }

    三、Feign方式による通信

  • 宣言式RESTクライアント(擬似RPC)
  • はインタフェースベースの注釈
  • を採用する.
    まずFeignの使い方を見てみましょう:1.依存の追加
    
        <dependency>
            <groupId>org.springframework.cloudgroupId >
            <artifactId>spring-cloud-starter-feignartifactId>
            <version>1.4.4.RELEASEversion>
        dependency>
    2.  
    
    @EnableFeignClients
    3.  
    
    @FeignClient(name = "product")  //  
    public interface ProductClient {
    
        @GetMapping("/getMsg")  //   Product 
        String productMsg();
    
    }
    
    4.  
    
    @RestController
    @Slf4j
    public class clientController {
    
        @Autowired
        private ProductClient productClient;  //  , 
        @GetMapping("/getProductMsg")
        public String getProductMsg(){
    
            String response = productClient.productMsg();
            log.info("response = {}" , response);
            return response;
        }
    }
    

    Feignは擬似RPCと見なすことができ,HTTPリモートコールは開発者に完全に透明である.
    RestTemplate内部ではRibbonを負荷等化Feign内部でも使用するRibbonを負荷等化