辛星Spring Cloud 教程第三篇:负载均衡

负载均衡

在现在的互联网应用中,一台机器通常并不能承担所有的流量,所以我们通常需要部署多台机器。对于某些访问量比较小的服务,即使一台机器可以承载所有的流量,为了避免单点故障,我们也通常至少部署两台。

而对于流量比较大的情况下,负载均衡则是一个必修课,是必须要过关的一个内容。它的重要性体现在很多方面:

(1).降低性能损失。在流量大的时候,根据不同的场景选择合适的地区、城市或机房来做流量的分发是很重要的,比如我们的机房可能分别部署在华南和华东,分别在青岛和深圳有机房,这个时候我们就需要同城优先来进行访问,要想合理的使用同城优先的策略,合理的负载均衡策略是必不可少的。

(2).机器保护。有时候我们的某台机器可能CPU飙升或者网络,这个时候可能是因为程序写的不好,有可能是某些请求太高,我们通常可以制定合理的负载均衡策略来降低这台机器的权重,来让更少的流量打到它上面。避免这台服务器被压垮或者太多请求超时,或者直接禁用它。

(3).负载均衡也和很多其他技术一起发挥作用,它也是很多技术的基础。比如动态的缩容和扩容,比如限流。

使用Ribbon做负载均衡

作为一个开源的通用组件,支持的策略还是蛮多的。Ribbon的负载均衡策略主要支持如下几种:
在这里插入图片描述
我们来分别介绍一下吧:
(1).RoundRobinRule即轮询策略,这也是默认的负载均衡策略。
(2).RadmonRule即随机策略,它会从服务器列表中选择一个进行访问。
(3).BestAvailableRule即最大可用策略,它会先过滤出故障服务器,然后选择一个当前请求数最小的。
(4).WeightedResponseTimeRule即带有加权的轮询策略,它会对各个服务器响应时间进行加权,然后在采用轮询的方式获取相应的服务器。
(5).AvailabilityFilteringRule即可用过滤策略,它先过滤出故障的或者并发请求大于某个阈值的一部分服务实例,然后再用轮询的方式从过滤后的实例中选择一个。
(6).ZoneAvoidanceRule即区域感知策略,它会先使用主过滤条件,比如区域负载器,选择最优的区域,然后对所有的实例进行过滤并且返回过滤后的实例列表,依次使用过滤列表条件中的过滤条件对主过滤条件的结果进行过滤,判断最小过滤数和最小过滤百分比,最后对所有满足条件的服务器使用RoundRobinRule选择一个服务器实例。

我们也可以选择直接使用注入LoadBalancerClient的方式来得到我们选择的对象列表。我们还是在我们的course-service这个微服务中进行编辑,我们新建一个bean子目录,我们写入如下代码:

package com.mengzhidu.java.demo.scdemo.course.service.bean;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.web.client.RestTemplate;

/**
 * Created by xinxing on 2019/1/23
 */
@Configuration
public class BeanConfig {

    @Primary
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

然后我们新建一个controller吧,我们编辑内容如下所示:

package com.mengzhidu.java.demo.scdemo.course.service.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.net.URI;

/**
 * Created by xinxing on 2019/1/23
 */
@RestController
@RequestMapping("/course/index/v2")
public class CourseIndexV2Controller {

    private static final Logger LOGGER = LoggerFactory.getLogger(CourseIndexV2Controller.class);

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private LoadBalancerClient loadBalancerClient;

    @RequestMapping("/my")
    public String my(Integer id) {
        if (id == null) {
            id = 0;
        }

        ServiceInstance instance = loadBalancerClient.choose("user-service");
        String addr = String.format("http://%s:%s/user/profile/name?id=%s", instance.getHost(), instance.getPort(), id);
        LOGGER.info("本次请求的地址:{}", addr);
        String userName = restTemplate.getForObject(URI.create(addr), String.class);
        return  "用户姓名: " + userName + "  教程名称: Course" + id;
    }
}

然后我们这里是调用的用户中心的服务,我们在9003和9004端口上分别启动user-service服务,然后我们请求 http://localhost:9002/course/index/v2/my?id=3 来看一下具体的日志信息吧,我们会看到如下的日志记录:
在这里插入图片描述
可以看到,这里分别访问9004端口和9003端口,实现了负载均衡。

小结

基本的使用Ribbon来进行负载均衡的例子就介绍到这里啦。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值