SpringCloud学习笔记(五)服务之间的调用,RestTemplate

微服务之间是通过RPC来交互的。

Eureka server和client 的jar包 都会引用一个 ribbon 包和httpclient包,显然Eureka是通过httpclient来进行通信的。

SpringCloud学习笔记(五)服务之间的调用,RestTemplate_第1张图片

我们需要服务与服务之间进行通信,至少得有2个服务才能看出效果(自己和自己通信的别闹)。

所以我们从会员服务copy出一个订单服务。

pom.xml 是一样的(除了项目名artifactId、name),

application.yml 里面我将端口号改成了8121(每个服务隔个10),服务别名改成:app-order

启动类还是一样(就改了类名),但是controller我贴一下

package com.study.api.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class OrderController{

    /**
     *  RestTemplate 是由SpringBoot Web 提供的 ,默认整合ribbon负载均衡器
     *  rest 方式底层是采用httpclient 技术
     */
    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/getOrder")
    public String getOrder(){
        String url = "http://localhost:8110/getMember";
        String result = restTemplate.getForObject(url,String.class);
        System.out.println("订单服务调用会员服务:"+result);
        return result;
    }
}

我们在getOrder中尝试使用RestTemplate来调用会员服务。

然后启动就会报错


***************************
APPLICATION FAILED TO START
***************************

Description:

Field restTemplate in com.study.api.controller.OrderController required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found.


Action:

Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.

  

这其实是因为RestTemplate 默认是没有在spring 容器中的,所以无法通过Autowired来获取实例,

我们需要在启动类中将它加到spring容器中,在启动类加上

package com.study.api.controller;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
public class AppOrder {

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

    @Bean // 解决RestTemplate 找不到,将其添加到spring容器
    RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

再启动的时候就可以用之前那个方式去访问getOrder了,当然,它调用了getMember,所以我们看到的是getMember的结果。

SpringCloud学习笔记(五)服务之间的调用,RestTemplate_第2张图片

但是我们在getOrder() 方法中直接写会员服务的地址了,这样还要eureka有个屁用。

所以我们要改成通过服务别名来进行服务间的通信。getOrder方法改成如下

@RequestMapping("/getOrder")
public String getOrder(){
    String url = "http://app-member/getMember";
    String result = restTemplate.getForObject(url,String.class);
    System.out.println("订单服务调用会员服务:"+result);
    return result;
}

 

重启再访问是这个样子

SpringCloud学习笔记(五)服务之间的调用,RestTemplate_第3张图片

服务器500,报的是java.net.UnknownHostException: app-member

其实是因为我们没有开启 rest 别名访问 的支持,我们在注册RestTemplate的时候加上@LoadBalanced 来开启对 rest 别名访问的支持

@Bean // 解决RestTemplate 找不到,将其添加到spring容器
@LoadBalanced // 如果需要使用rest方式以别名方式进行调用ribbon负载均衡器,默认为轮询方式
RestTemplate restTemplate(){
    return new RestTemplate();
}

加了这个注解之后会调用ribbon负载均衡器,重启后就可以通过别名来访问了

SpringCloud学习笔记(五)服务之间的调用,RestTemplate_第4张图片 

因为开启了负载均衡,所以我们可以通过使用相同项目别名的方式来达到集群的效果。

假如我有一台服务器用别名app-member注册到eureka,然后另一台服务器也以别名注册到eureka,

当我们通过别名进行服务间调用时,eureka就会根据负载均衡的策略(默认是轮训)来分配最终调用的服务器。

集群的时候可以在eureka里看到有几个叶子节点。

 

你可能感兴趣的:(SpringCloud学习日志)