springcloud系列教程(三) 用restTemplate + ribbon 实现服务消费

前言

上一篇文章介绍了服务注册发现组件Eureka,并搭建了三个工程演示了服务的注册发现,以及消费调用的过程,本章将对服务的消费功能介绍做进一步的延伸,讲解如何用负载均衡组件Ribbon来做服务的消费调用。

Ribbon是一个客户端负载均衡器,它可以很好地控制HTTP和TCP客户端的行为,根据特定的策略来控制请求负载分摊到多个执行单位上,是属于软负载的方式之一,ribbon结合eureka可以在注册中心注册,如果要消费的服务做了集群,那么ribbon就能在调用过程做负载均衡处理。笔者准备了4个工程来展现这个调用过程。

准备好注册的服务工程

上篇文章中我们创建了eureka-server、eureka-client这两个工程作为服务的注册中心客户端,为了实现负载的效果,我们至少需要注册两个服务。

沿用这两个工程,启动server工程,端口为1111;对于同一个工程来说,换一个端口启动,就相当于创建了新的服务实例,将eureka-client的端口改为1113并启动后,这时你会发现:eureka-client在注册中心注册了两个实例,这就相当于一个最简单的集群了。
这里写图片描述

为了能方便看到负载均衡的效果,我们在eureka-client的应用主类中注入一个变量来获取实例的端口,这样一来,哪个服务被调用就能看到效果了。
值得说明的是,正常情况下,启动两个服务名称相同的springboot工程会报冲突,在idea中,可以这样解决,点开右上角Application右边的下三角 ,弹出选项后,点击Edit Configuration ,在配置页面将默认的Single instance only的钩去掉,这样修改端口之后,启动多个实例就没有问题了。
这里写图片描述

创建引入ribbon依赖的服务消费者

在主工程中右键新建一个module,工程名称为eureka-ribbon,引入eureka-client和ribbon的依赖,成功后pom文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.yeya</groupId>
    <artifactId>eureka</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>eureka</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

在配置文件application.yml做如下的配置:

spring:
  application:
    #工程名称
    name: eureka-ribbon
eureka:
  client:
    service-url:
      #注册中心的url
      defaultZone: http://localhost:1111/eureka
server:
  #端口
  port: 1114

在启动类上加入@EnableDiscoveryClient 注解,并初始化restTemplate,在restTemplate加上@LoadBalanced注解表明这个restRemplate开启负载均衡的功能。

@EnableDiscoveryClient
@SpringBootApplication
public class EurekaApplication {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}

新建一个controller类来访问eureka-client中的 “/hello” 接口,通过restTemplate对传入的服务地址做负载均衡并返回访问地址,代码如下:

@RestController
public class ConsumeController {

    @Autowired
    private LoadBalancerClient client;

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/consumer")
    public String consumer() {
        String dc = restTemplate.getForObject("http://eureka-client/hello",String.class);
        return dc;
    }
}

在main主类中启动eureka-ribbon工程,打开浏览器,访问http://localhost:1111/,可以看到有三个工程已经注册成功,分别是client的两个工程和eureka-ribbon工程,
这里写图片描述

开启新网页标签,访问http://localhost:1114/consumer,多次刷新后,浏览器会交替显示:

hi forezp,i am from port:8762

hi forezp,i am from port:8763

这表明,ribbon在调用同一个服务实例时做了负载均衡,也实现了我们预想中的效果。

总结

到这里,ribbon结合restTemplate的实现负载均衡的效果已经给大家展示完毕了,本文一共用到了四个工程,这是项目的架构图:
这里写图片描述
从架构图上看,工程之间的调用并不复杂,建议读者们自己尝试写个实例验证一下。

本文源码地址:https://github.com/Taoxj/SpringCloudDemo/tree/master/ribbon

猜你喜欢

转载自blog.csdn.net/yeyazhishang/article/details/81392085