SpringCloud服务之间远程调用

2,713 阅读2分钟

上一篇:SpringCloud注册中心Eureka主要是做微服务的注册与发现,这一篇主要是讲解Eureka中微服务之间的相互调用。

微服务之间的远程调用主要有两种:RestTemplate方式和Feign方式

一、RestTemplate调用方式
RestTemplate调用是两个服务之间的调用,所以天然的存在server和client,但server和client不是固定不变的。调用者是client,被调用者就是server。server端不需要进行处理配置,client端要进行实例化配置。
1、简单的RestTemplate方式

  • 启动类代码
@SpringBootApplication
@EnableDiscoveryClient
public class MasterServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(MasterServiceApplication.class, args);
    }

    @Bean
    public RestTemplate initRestTemplate(){
        return new RestTemplate();
    }
}
  • Controller类
@Autowired
private RestTemplate template;

@GetMapping("/master")
private String master(){
    return template.getForObject("http://127.0.0.1:8082/server/master", String.class);
}

RestTemplate除了getForObject方法外,还提供了多种调用方法,如get/post等;
2、升级版RestTemplate方式
简单的RestTemplate方式直接调用的是服务的地址,服务地址可能发生变化,为了方便微服务调用,官方提供了LoadBalancerClient接口来实现调用,但前提是你的服务注册进了eureka的注册中心。
启动类代码没有变化,主要是Controller层加入了LoadBalancerClient。

  • Controller类
@Autowired
private RestTemplate template;

@Autowired
private LoadBalancerClient loadBalancerClient;

@GetMapping("/master")
private String master(){
    ServiceInstance serviceInstance = loadBalancerClient.choose("master-template-server");
    String url = String.format("http://%s:%s/server/master", serviceInstance.getHost(), serviceInstance.getPort());
    String result = template.getForObject(url, String.class);
    return template.getForObject(url, String.class);
}

3、终极版RestTemplate方式
升级版后的RestTemplate还是需要每次通过ServiceInstance去获取对象,然后再进行接口调用。官方还提供了更简便的方式,直接使用注解。

  • 启动类代码
public static void main(String[] args) {
    SpringApplication.run(MasterServiceApplication.class, args);
}

@Bean
@LoadBalanced
public RestTemplate initRestTemplate(){
    return new RestTemplate();
}
  • Controller类
@Autowired
private RestTemplate template;

@GetMapping("/master")
private String master(){
    String url = String.format("http://%s/server/master","master-template-server");
    String result = template.getForObject(url, String.class);
    return template.getForObject(url, String.class);
}

4、负载均衡策略
RestTemplate方式的远程调用,很方便的实现了负载均衡策略,因为@LoadBalanced自带默认负载策略,为轮询方式(负载包含:随机、轮询、哈希、权重)。SpringCloud的底层是通过Ribbn的核心组件IRule来实现,分别包含了RandomRule(随机)、RoundRobinRule(轮询)、WeightedResponseTimeRule(权重)。
修改默认负载均衡策略(启动类或者yml配置文件)

  • 启动类
public static void main(String[] args) {
    SpringApplication.run(MasterServiceApplication.class, args);
}

@Bean
public IRule initIRule() {
    return new RandomRule();
}

@Bean
@LoadBalanced
public RestTemplate initRestTemplate(){
    return new RestTemplate();
}
  • yml配置
master-template-server:
  ribbin:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

二、Fegin调用方式
Fegin的调用方式需要在client端添加Fegin依赖,pom文件如下:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  • 启动类(添加@EnableFeignClients注解)
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class MasterServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(MasterServiceApplication.class, args);
    }

    @Bean
    public IRule initIRule() {
        return new RandomRule();
    }

    @Bean
    @LoadBalanced
    public RestTemplate initRestTemplate(){
        return new RestTemplate();
    }
}
  • 接口调用层
@FeignClient("master-template-server")
public interface FeginServer {

    @GetMapping("/server/master")
    String master();
}

接口调用层的指定的@FeignClient(name)中的name是server应用在注册中心的名称,即服务名称,client端配置的远程调用的接口和server端被调用的接口一样。