SpringCloud全家桶---客户端负载均衡Ribbon

1、SpringCloud全家桶—注册中心Eureka搭建
2、SpringCloud全家桶—注册中心Eureka高可用环境搭建
3、SpringCloud全家桶—客户端负载均衡Ribbon
4、SpringCloud全家桶—OpenFeign
5、SpringCloud全家桶—断路器Hystrix
6、SpringCloud全家桶—HystrixDashboard配置与基础功能演示
7、SpringCloud全家桶—Zuul网关

Ribbon的基本概念

Ribbon是Netflix体系中的基于客户端的负载均衡器,可以通过从eureka拉取服务提供方的地址列表中,按照某种负载均衡算法请求对应的服务方。

  • Ribbon可以单独使用,手动配置服务地址列表后就可以帮我们实现负载均衡。
  • Ribbon也可以配置Eureka使用,从Eureka服务端获取服务提供者的地址列表,然后基于负载均衡算法选择一个服务提供者进行调用。
  • Ribbon也可以和OpenFeign、RestTemplate无缝对接,让他们具有负载均衡的能力。

服务搭建

本文演示内容,部分基于前一篇 SpringCloud全家桶—注册中心Eureka搭建

1、新建一个membership服务。

现在要比之前多依赖一个jar包,spring-cloud-starter-netflix-ribbon,但是这个包默认在spring-cloud-starter-netflix-eureka-client中已经包含了,所以我们也不需要额外的引入。

在这里插入图片描述

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.5.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.wyl.springcloud</groupId>
	<artifactId>membership</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>membership</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>Hoxton.SR9</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.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</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>

2、注入RestTemplate

为了方便,我们会使用restTemplate方式来进行远程调用。

@EnableEurekaClient
@SpringBootApplication
public class MembershipApplication {

    public static void main(String[] args) {
        SpringApplication.run(MembershipApplication.class, args);
    }

    @Bean
    //@LoadBalanced,这个注解我们可以先不加,先使用编码的方式实现负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

这是第一种编码的方式实现负载均衡

LoadBalancerClient是一个接口,RibbonLoadBalancerClient实现了它。

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    LoadBalancerClient lb;

    @PostMapping("/queryOrder")
    public String queryOrder() {

        ServiceInstance choose = lb.choose("order");

        String str = restTemplate.getForObject("http://" + choose.getHost() + ":" + choose.getPort() + "/userOrder/queryOrderList", String.class);

        //String str = restTemplate.getForObject("http://order/userOrder/queryOrderList", String.class);

        System.out.println(str);

        return str;
    }
}

第二种通过@LoadBalanced注解实现

Ribbon和RestTemplate内部已经整合好了,加上注解就可以直接使用,这就使得调用时变得简单了,直接通过服务名调用即可。

@EnableEurekaClient
@SpringBootApplication
public class MembershipApplication {
    public static void main(String[] args) {
        SpringApplication.run(MembershipApplication.class, args);
    }
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
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.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private RestTemplate restTemplate;

    //@Autowired
    //LoadBalancerClient lb;

    @PostMapping("/queryOrder")
    public String queryOrder() {

        //ServiceInstance choose = lb.choose("order");

        //String str = restTemplate.getForObject("http://" + choose.getHost() + ":" + choose.getPort() + "/userOrder/queryOrderList", String.class);

        String str = restTemplate.getForObject("http://order/userOrder/queryOrderList", String.class);

        System.out.println(str);

        return str;
    }
}

原有的order服务,新增一个接口,供membership服务调用。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/userOrder")
public class UserOrderController {

    @GetMapping("/queryOrderList")
    public String queryOrderList(){
    	//我会启动两个order服务,一个服务端口号19200,再启另外一个服务时把端口号改成19201,这样可以在调用时看到负载均衡的效果。
        //return "queryOrderList,我的端口号:19201";
        return "queryOrderList,我的端口号:19200";
    }
}

可以看到,默认是以轮询的方式调用。

在这里插入图片描述

修改负载均衡策略

1、注解方式

@EnableEurekaClient
@SpringBootApplication
public class MembershipApplication {

    public static void main(String[] args) {
        SpringApplication.run(MembershipApplication.class, args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
	
	//
    @Bean
    public IRule myRule() {
        //return new RoundRobinRule();
        //return new RandomRule();
        return new RandomRule();
    }
}

随机调用。

在这里插入图片描述

IRule是ribbon-loadbalancer包下的一个接口

在这里插入图片描述

2、配置文件

可以更细粒度的针对具体的服务指定负载均衡策略。

order是服务提供方的服务名。

#配置ribbon负载均衡策略,优先级低于编码的方式
order.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

Ribbon提供的一些其他参数

这些参数都非常容易理解,本文也就不就演示了,建议大家自己的尝试一下,非常有意思。

#连接超时时间(单位秒)
ribbon.ConnectTimeout=1000
#连接后等待返回超时时间(单位秒)
ribbon.ReadTimeout=2000
#是否对所有操作都开启重试功能
ribbon.OkToRetryOnAllOperations=true
#切换实例重试次数
ribbon.MaxAutoRetriesNextServer=2
#当前实例重试次数
ribbon.MaxAutoRetries=1
#开启ribbon超时管理(注意如果不开启,以上配置将无效。)
ribbon.http.client.enabled=true

饥饿加载

默认是懒加载,在第一次请求时会加载服务列表,所以第一次访问会比较慢,开启饥饿加载后会改善第一次请求较慢的现象。

#开启饥饿加载
ribbon.eager-load.enabled=true
#指定加载的服务名
ribbon.eager-load.clients=order

未开启饥饿加载时,服务启动后控制台未输出相关内容,但是在第一次调用时会输出加载到的服务列表。

在这里插入图片描述

开启饥饿加载,服务启动后控制台输出了服务列表。

在这里插入图片描述

PS

如果你仔细观察,每次服务启动后都会看到如下告警项:

 WARN 8016 --- [           main] ockingLoadBalancerClientRibbonWarnLogger : You already have RibbonLoadBalancerClient on your classpath. It will be used by default. As Spring Cloud Ribbon is in maintenance mode. We recommend switching to BlockingLoadBalancerClient instead. In order to use it, set the value of `spring.cloud.loadbalancer.ribbon.enabled` to `false` or remove spring-cloud-starter-netflix-ribbon from your project.

表达的含义就是spring cloud ribbon现在已经是维护模式了,官方建议我们使用spring-cloud-loadbalancer中的BlockingLoadBalancerClient。

Spring官方是想用自家的spring-cloud-loadbalancer替代netflix的ribbon,所以提供了BlockingLoadBalancerClient,但是目前只有一种负载均衡策略:RoundRobinLoadBalancer,并且也没有相关的超时措施等,和ribbon比起来还是有一点差距,所以尽管告警吧,目前貌似没人搭理。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码拉松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值