微服务调用的两种实现方式

方式一:RestTemplate

1.RestTemplate简述

RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版,例如 GET 请求、POST 请求、PUT 请求、DELETE 请求等。RestTemplate 继承自 InterceptingHttpAccessor 并且实现了 RestOperations 接口,其中 RestOperations 接口定义了基本的 Restful 操作,因此RestTemplate也支持restful风格请求

1.1 服务调用代码实现

背景: provider提供服务为服务端. consumer调用服务端为消费端

  • provider提供doSomething方法
        @GetMapping("/provider/{string}")
        public String doSomething(@PathVariable String string) {
            return "provider:Hello "+string;
        }
  • consumer调用provider的方法
 		@Autowired
 		private RestTemplate restTemplate;
		@GetMapping("/consumer")
        public String doSomething() {
        	String name="kris"
            //定义服务提供方的地址
            String url = "http://localhost:8081/provider/"+name; 
            //调用服务提供方(sca-provider)
            return restTemplate.getForObject(url, String.class);

打开provider和consumer的启动项后,访问http://localhost:8082/consumer ,调用成功则返回结果"provider:Hello kirs"
注:如果只关注服务返回的数据则使用getForObject若要定义响应头相关信息则推荐使用getForEntity

1.2 调用的负载均衡

当开发者想要实现服负载均衡时,则有如下两种实现方案

1.2.1 RestTempalte+ LoadBalanceClient

@Autowired
 		private RestTemplate restTemplate;
		@Autowired
		private LoadBalancerClient loadBalancerClient;

        @GetMapping("/consumer2")
        public String doSomething2() {
        	String name="kris"
            // 根据服务名serviceId,返回一个服务实例
            ServiceInstance serviceInstance = loadBalancerClient.choose("provider");
            //拼接url,
            String url = String.format("http://%s:%s/provider/%s",
                    serviceInstance.getHost(),
                    serviceInstance.getPort(),
                    Name);
             //显示每次访问,端口的变化
            System.out.println("request url:" + url);
            return restTemplate.getForObject(url, String.class);
        }

启动多台procvider时,loadBalancerClient可以动态的调用服务底层是基于Ribbon实现的,默认的规则为轮询机制

1.2.2 RestTempalte+@LoadBalanced

此外我们可以直接通过@LoadBalanced注解的方式来实现负载均衡

  1. 配置一个restTemplate交给spring容器
	@Bean
    @LoadBalanced
    public RestTemplate loadBalancedRestTemplate() {
        return new RestTemplate();
    }
  1. 在需要使用负载均衡的地方经行依赖注入
@Autowired
private RestTemplate loadBalancedRestTemplate;

  1. 业务的实现
@GetMapping("/consumer3")
public String doSomething3(){
	String name="kris"
    String url=String.format("http://%s/provider/%s",
"provider",Name);
    //向服务提供方发起http请求,获取响应数据
    return loadBalancedRestTemplate.getForObject(
            url,//要请求的服务的地址
            String.class);//String.class为请求服务的响应结果类型
}

方式二:Feign

1 简述Feign

Feign是一种声明式web服务客户端, 底层封装了rest技术, 通过feign可以简化消费方对远程服务的调用,
通过注解+接口,完成服务的简单调用.
那么我们如何再spring cloud项目中使用呢?

2.代码实现

  • 1.消费方添加项目依赖
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  • 2 启动类添加注解@EnableFeignClients
@EnableFeignClients
@SpringBootApplication
public class ConsumerApplication {}
  • 3 定义接口
@FeignClient(value="provider")// value映射服务提供名子
public interface RemoteProviderService {
    @GetMapping("/provider/{msg}")//与要调用的服务提供端名字一致
    String doSomething(@PathVariable("msg") String msg);//注解名要和路径定义名一致
}
//@FeignClient 描述的接口会被动态代理创建实现类

4.controller 中调用feign

@RestController
@RequestMapping("consumer")
public class FeignConsumerController {
    @Autowired
private RemoteProviderService remoteProviderService;
    @RequestMapping("{msg}")
    public String doSomething(@PathVariable String msg) {
        return remoteProviderService.doSomething(msg);
    }
}

3 Feign的远程调用原理

微服务调用的两种实现方式_第1张图片
小结 :

  • 项目启动后 @EnableFeignCleints 注解告诉springcloud,启动 Feign Starter 组件.
  • Feign Starter 在项目启动过程中注册全局配置,并扫描包下所由@FeignClient注解描述的接口,然后由系统底层创建接口实现类(JDK代理类),注册 IOC 容器。
  • 接口调用时被动态代理类逻辑拦截,将 @FeignClient 请求信息通过编码器生成 Request对象,基于此对象进行远程过程调用。
  • Request对象经Ribbon进行负载均衡,挑选出一个健康的 Server 实例
  • 通过Client 携带 Request 调用远端服务返回请求响应。
  • 通过解码器生成 Response 返回客户端,将信息流解析成为接口返回数据。

你可能感兴趣的:(spring,cloud,spring,java,spring,boot)