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

本文介绍了SpringCloud中服务间通过RestTemplate进行通信的实现过程,包括解决RestTemplate未在Spring容器中、如何使用服务别名以及启用@LoadBalanced实现负载均衡。通过设置,实现了通过服务别名进行集群效果的调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

专辑目录:SpringCloud学习日志

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

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

我们需要服务与服务之间进行通信,至少得有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的结果。

但是我们在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;
}

 

重启再访问是这个样子

 

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

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

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

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

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

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

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

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

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值