微服务-2.负载均衡Ribbon

在上一个微服务模拟场景的基础上我们来搭建负载均衡
完整的初级微服务模拟场景点这里!!!

一.Ribbon是什么

1、Sping Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完整的配置项如连接超时,重试等。简单地说,就是在配置文件中列出Load Balancer(简称LB) 后面所有的机器, Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。
负载均衡
2、LB,
即负载均衡(Load Balancer),在微服务或分布式集群中经常用的一种应用。
负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用)。
常见的负载均衡软件有Nginx,LVS,硬件F5等。
相应的中间件,例如:dubbo和SpringCloud中均给我们提供了负载均衡,SpringCloud的负载均衡算法可以自定义。
3、集中式LB
即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件F5(好用但是贵),也可以说软件,如nginx),由该设施负责把访问请求通过某种策略转发至服务的提供方。
4、进程内LB
将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于进程内LB,它只是一个类库,集成消费方进程,消费方通过它来获取到服务提供方的地址。

二.使用负载均衡带来的好处很明显:

1、当集群里的1台或者多台服务器down的时候,剩余的没有down的服务器可以保证服务的继续使用
2、使用了更多的机器保证了机器的良性使用,不会由于某一高峰时刻导致系统cpu急剧上升

三.搭建微服务的负载均衡

1、修改ribbon初步设置
(1)配置pom文件

<!--        负载均衡-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.1.2.RELEASE</version><!--服务器有可不写-->
        </dependency>
    </dependencies>

(2)因为Eureka中已经集成了Ribbon,所以我们无需引入新的依赖。直接修改代码:
在RestTemplate的配置方法上添加 @LoadBalanced 注解:
#在主启动类的中找到RestTemplate加上@LoadBanced
我的主启动类是D:\idea2\cloud-project\user-consumer-project\src\main\java\livia\ConsumerApplication.java

package livia;



import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
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;


/**
 * @program: cloud-demo-project
 * @description
 * @author: livia
 * @create: 2019-12-26 14:38
 **/
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableDiscoveryClient
public class ConsumerApplication {
    public static void main(String[] args) {
       SpringApplication.run(ConsumerApplication.class,args);
    }
    @Bean
    @LoadBalanced//负载均衡需要注解
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

(3)注:新版本不用传入new RestTemplate(new OkHttp3ClientHttpRequestFactory())可不传
修改调用方式,不再手动获取ip和端口,而是直接通过服务名称调用:
原始的获取方式:

 @RequestMapping("findall2")
    public String findAll2(){
        ServiceInstance instans = loadBalancerClient.choose("user-service");
        String host = instans.getHost();
        int port = instans.getPort();
        String urlByEureka = "http://" + host + ":" + port + "/findall";
        return restTemplate.getForObject(urlByEureka,String.class);
    }

负载均衡后获取方式:

@GetMapping("findall3")
    //    user-service负载均衡加上之后才可以用
    public String findAll3(){
        return restTemplate.getForObject("http://user-service/findall",String.class);
    }

修改后的整体代码:

package livia.controller;

import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @program: cloud-project
 * @description
 * @author: livia
 * @create: 2019-12-26 15:47
 **/

@RestController
@RequestMapping("/")
public class ConsumerController {
    private String SERVICEURL = "http://localhost:1225/findall";
    @Autowired
    RestTemplate restTemplate;
    @Autowired
    DiscoveryClient discoveryClient;
    @Autowired
    LoadBalancerClient loadBalancerClient;
    @RequestMapping("findall")
    public String findAll(){
//        return restTemplate.getForObject(SERVICEURL,String.class);
        List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
        ServiceInstance instance = instances.get(0);
        String host = instance.getHost();
        int port = instance.getPort();
        String urlByEureka = "http://" + host + ":" + port +"/findall";
        return restTemplate.getForObject(urlByEureka,String.class);
    }
    @RequestMapping("findall2")
    public String findAll2(){
    //原始的获取方式:"http://" + host + ":" + port + "/findall"
        ServiceInstance instans = loadBalancerClient.choose("user-service");
        String host = instans.getHost();
        int port = instans.getPort();
        String urlByEureka = "http://" + host + ":" + port + "/findall";
        return restTemplate.getForObject(urlByEureka,String.class);
    }
     @GetMapping("findall3")
    //    user-service负载均衡加上之后才可以用
    public String findAll3(){
        return restTemplate.getForObject("http://user-service/findall",String.class);
    }

}


(4)application.yml中添加配置:(D:\idea2\cloud-project\user-consumer-project\src\main\resources\application.yml)

cloud:
    loadbalancer:
      retry:
        enabled: true # 开启Spring Cloud的重试功能
  user-service:
    ribbon:
      ConnectTimeout: 250 # Ribbon的连接超时时间
      ReadTimeout: 1000 # Ribbon的数据读取超时时间
      OkToRetryOnAllOperations: true # 是否对所有操作都进行重试
      MaxAutoRetriesNextServer: 1 # 切换实例的重试次数
      MaxAutoRetries: 1 # 对当前实例的重试次数

整体:


server:
  port: 1111

spring:
  application:
    name: user-consumer-project
  cloud:
    loadbalancer:
      retry:
        enabled: true # 开启Spring Cloud的重试功能
  user-service:
    ribbon:
      ConnectTimeout: 250 # Ribbon的连接超时时间
      ReadTimeout: 1000 # Ribbon的数据读取超时时间
      OkToRetryOnAllOperations: true # 是否对所有操作都进行重试
      MaxAutoRetriesNextServer: 1 # 切换实例的重试次数
      MaxAutoRetries: 1 # 对当前实例的重试次数

eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka,http://localhost:10087/eureka

相关配置完成后,我们来启动两个user-service服务实例(一个是原始的8082,在配置一个新的8083):
在这里插入图片描述
配置端口(这里我修改name为application2,端口号为8083)点击apply之前要选中name红的Allow parellel run
在这里插入图片描述
再点击运行就可以了!
查看服务是否真的启动了:
(1)http://localhost:8083/findall(使用新端口查看)
在这里插入图片描述
(2)http://localhost:10086/ 查看user-service进程有几个:
在这里插入图片描述
这样即使我们的8082服务器坏掉了,也会有8083服务器继续工作!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值