1.服务治理-Ribbon-给消费者添加负载均衡功能

2020-05-02  本文已影响0人  溅十三
image.png
1.创建项目ribbon-consumer
2.添加pom依赖eureka、ribbon、boot
<?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">
    <parent>
        <artifactId>spring-cloud-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../../pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
    <name>ribbon-consumer</name>

    <artifactId>ribbon-consumer</artifactId>
    <dependencies>
        <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-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

</project>
4.创建启动类

ribbon的精华在哪里?

package com.imooc.springcloud;

import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class RibbonConsumerApplication {

//    精华所在
    @Bean
    @LoadBalanced
    public RestTemplate template() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder(RibbonConsumerApplication.class)
                .web(WebApplicationType.SERVLET)
                .run(args);
    }
}

5.创建Controller

没有引入Ribbon前如何使用RestTemplate来发送请求?
- RestTemplate
- LoadBalancerClient
- client.choose("eureka-client")

启动类:

package com.imooc.springcloud;

import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class EurekaConsumerApplication {
    /*
    * @Bean注解,spring会在初始化的时候会把这个方法加入到上下文,然后我们就可以在Controller里得到这个方法了
    * */
    @Bean
    public RestTemplate register(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder(EurekaConsumerApplication.class)
                .web(WebApplicationType.SERVLET)
                .run(args);
    }
}

controller:

package com.imooc.springcloud;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@Slf4j
@RestController
public class Controller {

    /*
    * 负载均衡器,帮我们从注册中心拉取的服务列表中挑选一个可用的serviceprovider
    * */
    @Autowired
    private LoadBalancerClient client;

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/hello")
    public String hello(){
        /*
        * 1.拿到服务提供者的实例
        * 2.借助RestTemplate发起真实的服务调用
        * 3.单独声明RestTemplate
        * */
        ServiceInstance instance = client.choose("eureka-client");

        /*
        * 防疫性编程:假定所有的输入都是不安全的,instance可能get到空
        * */
        if (instance == null) {
            return "No aviliable instance";
        }
        String target = String.format("http://%s:%s/sayHi",instance.getHost(),instance.getPort());
        log.info("url is {}",target);
        return restTemplate.getForObject(target, String.class);
    }

    @PostMapping("/hello")
    public Friend helloPost(){
        /*
         * 1.拿到服务提供者的实例
         * 2.借助RestTemplate发起真实的服务调用
         * 3.单独声明RestTemplate
         * 4.启动顺序:启动注册中心->服务提供者->服务消费者
         * */
        ServiceInstance instance = client.choose("eureka-client");

        /*
         * 防疫性编程:假定所有的输入都是不安全的,instance可能get到空
         * */
        if (instance == null) {
            return null;
        }
        String target = String.format("http://%s:%s/sayHi",instance.getHost(),instance.getPort());
        log.info("url is {}",target);
        Friend friend = new Friend();
        friend.setName("eureka-consumer");
        return restTemplate.postForObject(target, friend,Friend.class);

    }
}

引入Ribbon如何使用RestTemplate来发送请求?

启动类:

package com.imooc.springcloud;

import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class RibbonConsumerApplication {

//    精华所在
    @Bean
    @LoadBalanced
    public RestTemplate template() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder(RibbonConsumerApplication.class)
                .web(WebApplicationType.SERVLET)
                .run(args);
    }
}

controller:

package com.imooc.springcloud;

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

@RestController
public class Controller {

    @Autowired
    private RestTemplate restTemplate;

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

}
5.Ribbon application.properties的书写步骤?

1.name
2.port
3.serviceUrl

6.要做几件事情?

1.启动eureka-server
2.启动2个eureka-client
3.启动ribbon-consumer
4.看3个服务是否都在注册中心上
5.调用ribbon-consumer方法(或调用eureka-server的eureka-client方法?),看会不会轮训调用eureka-client,看ribbon服务负载均衡是否生效了

6.遇到哪些问题?

负载均衡没有起到作用
原因:2个eureka-client的name名称不一致导致的
eureka-server报连接超时错误:
解决:pom加eureka.client.serviceUrl.defaultZone=http://localhost:20000/eureka/

上一篇下一篇

猜你喜欢

热点阅读