SpringCloud>04 - 服务调用Ribbon、RestTemplate

扯淡:

前面已经将微服务注册到了 Eureka 中,此时,它们仅仅只是被 Eureka 管理监视的两个可独立运行的微服务。倘若服务之间有业务关联,那么就需要相互调用,SpringCloud中可以使用RestTemplate、Ribbon、Feign等完成此需求,本章将涉及RestTemplate、Ribbon的基本使用完成服务间的调用。

springboot、springcloud、docker学习目录:【传送门】    

需求:在用户微服务中调用文章微服务。

工程搭建:

1、方便测试,注释掉Eureka安全验证的相关代码,Eureka集群启动两个。

2、新建 springcloud_user_ribbon 模块。

此模块复制springcloud_user 模块,我习惯在windows文件目录下复制,然后修改父子两个工程pom,然后导入。

RestTemplate 使用:

RestTemplate 对 httpclient 做了封装,提供了更优雅的访问远程 rest 服务的方法。本章简单使用。

1、在启动类中配置RestTemplate

​// 基于spring-cloud-commons  可以采用其他作为注册中心
@EnableDiscoveryClient
// 基于spring-cloud-netflix  只能使用Eureka 作为注册中心
// @EnableEurekaClient
@MapperScan("com.coolron.user.dao")
@SpringBootApplication
public class RibbonUserApplication {
    public static void main(String[] args) {
        SpringApplication.run(RibbonUserApplication.class);
    }
    // 将RestTemplate注入到spring容器中,亦可在其他配置类中引入。
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

2、新建RestTemplateController

/**
 * @Auther: xf
 * @Date: 2018/12/22 9:30
 * @Description: 使用 RestTemplate 调用文章微服务 api
 * 
 * http://127.0.0.1:8082/article/ :文章微服务地址
 */
@RestController
@RequestMapping(value = "/restTemplate")
public class RestTemplateController {

    // 引入 RestTemplate
    @Autowired
    private RestTemplate restTemplate;

    // 根据文章 id 获取文章信息
    @GetMapping("article/{id}")
    public ApiResult getArticle(@PathVariable("id") String id){
        ApiResult apiResult = this.restTemplate.getForObject("http://127.0.0.1:8082/article/" + id, ApiResult.class);
        return apiResult;
    }

    // 文章列表
    @GetMapping("article/list")
    public ApiResult getArticleList(){
        ApiResult apiResult = this.restTemplate.getForObject("http://127.0.0.1:8082/article/list", ApiResult.class);
        return apiResult;
    }

    // 文章列表
    @GetMapping("article/entityList")
    public ApiResult getArticleEntityList(){
        List<Article> list = this.restTemplate.getForObject("http://127.0.0.1:8082/article/entityList", List.class);
        return ApiResult.ok(list);
    }
}

注意:根据id获取文章信息,文章微服务返回的是ApiResult,并不是Article实体,我在这最初使用的是Article 接收,这个错误找了半小时。

3、启动文章微服务、用户微服务。若有配置服务注册地址,需启动Eureka server。

4、测试:

4.1、http://127.0.0.1:8081/restTemplate/article/list

Ribbon 使用:


1、负载均衡。

线上环境中我们同一份服务往往会部署多份,那么服务调用者该如何选择哪一个服务提供者实现服务调用呢!那么就涉及到了负载均衡问题了。

1.1、服务端负载均衡:

最常见的就是使用nginx实现,请求到 nginx,由nginx 决定调用哪一个服务提供者。

1.2、客户端负载均衡:

Ribbon就是一个客户端负载均衡组件。

2、引入pom依赖

由于我们引入的eureka-client 依赖中包含了改依赖,所以不重复引入。

3、修改启动类,在RestTemplate 上加@LoadBalanced。

​    /**
     * @LoadBalanced 注解整合了 Ribbon
     * 使restTemplate 具备的Ribbon 客户端负载均衡的能力
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }​

4、新建RibbonController:

​/**
 * @Auther: xf
 * @Date: 2018/12/22 11:34
 * @Description:  Ribbon 请求文章微服务
 * 
 * http://springcloud-article/article/ : 文章微服务地址
 * springcloud-article : 文章微服务名称 即 spring.application.name
 */
@Slf4j
@RestController
@RequestMapping(value = "/ribbon")
public class RibbonController {

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

    @GetMapping("article/{id}")
    public ApiResult getArticle(@PathVariable("id") String id) {

        ServiceInstance serviceInstance = this.loadBalancerClient.choose("springcloud-article");
        log.info(">>>>>>>>>>>>>文章服务端口号:" + serviceInstance.getPort() + " >>>>>>>>>>");

        ApiResult apiResult = this.restTemplate.getForObject("http://springcloud-article/article/" + id, ApiResult.class);
        return apiResult;
    }

    @GetMapping("article/list")
    public ApiResult getArticleList() {
        ServiceInstance serviceInstance = this.loadBalancerClient.choose("springcloud-article");
        log.info(">>>>>>>>>>>>>文章服务端口号:" + serviceInstance.getPort() + " >>>>>>>>>>");

        ApiResult apiResult = this.restTemplate.getForObject("http://springcloud-article/article/list", ApiResult.class);
        return apiResult;
    }
}

5、启动Eureka(集群),文章微服务(可启两个,端口号不同)、用户微服务

5.1、修改如下配置,改变服务端口号可启动第二个文章微服务

5.2、查看注册中心:http://127.0.0.1:8761/

6、测试:

6.1、http://127.0.0.1:8081/ribbon/article/list

7、Ribbon的配置:

官方提供了 java配置类 和 配置文件 两种方式。

7.1、java配置类方式:

配置类需要在包扫描和springbootapplication注解之外,比较复杂,果断选择舍弃。

7.2、配置文件配置方式:

1、NFLoadBalancerRuleClassName:负载均衡规则,可以是ribbon提供的原生的几种规则,也可以是自己实现的规则,都实现了IRule接口。
2、NFLoadBalancerPingClassName:查看服务器是否存活。
3、NIWSServerListClassName:服务器列表处理类,用来维护服务器列表。
4、NIWSServerListFilterClassName:服务器的拦截类。
5、优先级:properties 配置 > java 配置 > SpringCloud Netiflix 默认

7.3、修改用户微服务:application.yml:

# 配置ribbon
springcloud-article:
  ribbon:
    # ribbon 负载均衡规则
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule  #  随机

7.4、测试:

多次请求 :http://127.0.0.1:8081/ribbon/article/5

随机请求文章微服务。

总结:

1、RestTemplate 方式请求服务。
2、负载均衡分客户端、服务端,Ribbon属于客户端负载均衡。常用的nginx属于服务端负载均衡。
3、Ribbon的使用,properties配置文件的方式配置请求规则。

代码地址:

https://gitee.com/cpla026/springcloud/tree/master/springcloud_parent/springcloud_user_ribbon

声明:

1、本节中 Ribbon 默认的轮询规则我并未实验出来,结果与预期不一致,若有大佬发现错误配置还请联系我指出。
2、本公众号主要以学习、分享为主,互联网相关资料很多,若有雷同还望包涵。


个人学习分享
更多 springboot、springcloud、docker 文章,关注公众号吧:

猜你喜欢

转载自blog.csdn.net/cp026la/article/details/86606313