SpringCloud之负载均衡

负载均衡(LB)的分类

  • 集中式LB(偏硬件):即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5,也可以是软件,如nginx),由该设施负责把访问请求通过某种策略转发至服务的提供方;

  • 进程式LB(偏软件):将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于进程内LB,它只是一个类库, 集成于消费方进程,消费方通过它来获取到服务提供方的地址。

Ribbon是什么?

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时, 重试等。简单的说,就是在配置文件中列出Load Balancer (简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。

搭建步骤

第一步,先在消费端的pom文件中加载相关依赖

<!-- Ribbon相关-->
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-eureka</artifactId>
		 <version>2.1.9.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.Cloud</groupId>
		<artifactId>spring-cloud-starter-ribbon</artifactId>
		 <version>2.1.9.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-config</artifactId>
		 <version>2.1.9.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
		 <version>2.1.9.RELEASE</version>
	</dependency>

第二步 修改消费端的application.yml追加eureka的服务注册地址

eureka: 
  client: 
    register-with-eureka: false     # false表示不向注册中心注册自己。
    service-url:  
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/  # 设置与Eureka Server交 互的地址查询服务和注册服务都需要依赖这个地址
  

第三步 对消费端的ConfigBean进行新注解@LoadBalanced获得Rest时加入Ribbon的配置

@Configuration
public class ConfigBean{
	
	@Bean
	@LoadBalanced //Spring Cloud Ribbon是基 于Netflix Ribbon实现的一套客户端负载均衡的工具。
	public RestTemplate getRestTemplate() {
		
	return new RestTemplate( );
	}
}

第四步 对消费端的主启动类DeptConsumer80_ App添加@EnableEurekaClient

@SpringBootApplication
@EnableEurekaClient
public class DeptConsumer80_APP {

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

第五步 修改DeptController_ Consumer客户端访问类

microservicecloud-dept是业务端在yml配置的在eureka中的注册名

//private static final String REST_URL__PREFIX = "http://localhost:8001" ;
	private static final String REST_URL__PREFIX = "http://microservicecloud-dept" ;

Ribbon和Eureka整合后Consumer可以直接调用服务而不用再关心地址和端口号

负载均衡之Ribbon

1架构图

Ribbon在工作时分成两步
第一步 先选择EurekaServer ,它优先选择在同一个区域内负载较少的server.
第二步 再根据用户指定的策略[,在从server取到的服务注册列表中选择一个地址。

在这里插入图片描述

2新建两个业务端的微服务,可拷贝第一个,yml中端口号和连接的数据库名字需要改,但是在eureka中注册的名字不能改,要统一

spring: 
  application: 
    name: microservicecloud-dept  

再用消费端去通过eureka调用业务端时,ribbin就会启动 默认的轮循算法,第一次访问是第一个业务端实例,第二次访问是第二个业务端实例,一次类推,不断循环,对于流量特别大的业务很合适一个微服务注册多个实例

ribbon的核心组件IRule

lRule:根据特定算法中从服务列表中选取一个要访问的服务

IRule的算法

  • RoundRobinRule 轮询算法(默认算法)
  • RandomRule 随机算法,
  • AvailabilityFilteringRule
    会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,还有并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问
  • WeightedResponseTimeRule
    根据平均响应时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越高。刚启动时如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够,会切换到WeightedResponseTimeRule
  • RetryRule
    先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务
  • BestAvailableRule
    会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
  • ZoneAvoidanceRule
    默认规则,复合判断server所在区域的性能和server的可用性选择服务器

自定义配置IRule自带的算法,在消费端的配置类中定义

@Configuration
public class ConfigBean{
	
	@Bean
	@LoadBalanced //Spring Cloud Ribbon是基 于Netflix Ribbon实现的一套客户端负载均衡的工具。
	public RestTemplate getRestTemplate() {
		
	return new RestTemplate( );
	}
	
	@Bean
	public IRule myRule() {
	//return new RoundRobinRule();
	return new RandomRule();//达到的目的,用我们重新选择的随机算法替代默认的轮询。
	}
}

自定义ribbon 的负载均衡策略

官方文档明确给出了警告: .
这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,
否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是说
我们达不到特殊化定制的目的了。

  • 第一步
    在消费端的主启动类中添加@RibbonClient( name=“MICROSERVICECLOUD-DEPT” , configuration=MySelfRule.class)
@SpringBootApplication
@EnableEurekaClient
@RibbonClient( name="MICROSERVICECLOUD-DEPT" , configuration=MySelfRule.class)
public class DeptConsumer80_APP {

	public static void main(String[] args) {
		SpringApplication.run(DeptConsumer80_APP.class, args);
	}
}
  • 第二步 创建自定义的ribbon配置类 注意这个配置类不能在@ComponentScan所扫描的当前包下以及子包下,@SpringBootApplication里包含了@ComponentScan,也就是说不能在主启动类的当前包下以及子包下.
    新建一个包,在包里 创建MySelfRule配置类
@Configuration
public class MySelfRule {
	@Bean
	public IRule myRule() {
	//return new RoundRobinRule();
	return new RandomRule();//达到的目的,用我们重新选择的随机算法替代默认的轮询。
	}
}

  • 第三步,修改源码
    在这里插入图片描述

负载均衡之Feign

Feign是一个声明式的Web服务客户端,使得编写Web服务客户端变得非常容易,
只需要创建一个接口, 然后在上面添加注解即可 。

Feign能干什么

Feign旨在使编写Java Http客户端变得更容易。
前面在使用Ribbon+ RestTemplate时,利用RestTemplate对http请求的封装处理,形成了’-套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用, 所以通常都会针对每个微服务自行封装-些客户端类来包装这些依赖服务的调用。所以, Feign在此基础上做了进一步封装, 由他来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口 上面标Mapper注解现在是一个微服务接口上面标注一个Feign注解即可),即呵完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon时,自动封装服务调用客户
端的开发量。

Feign集成了Ribbon利用Ribbon维护了MicroServiceCloud-Dept的服务列表信息,組通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用
Feign通过接口的方法调用Rest服务(之前是Ribbon+ RestTemplate) ,
该请求发送给Eureka服务器(http://MICROSERVICECLOUD-DEPT/dept/list),
通过Feign直接找到服务接口,由于在进行服务调用的时候融合了Ribbon技术,所以也支持负载均衡作用。

Fegin工程构建

  • 第一步 新建microservicecloud-consumer-dept-feign并修改主启动类名字
  • 第二步 添加依赖在Feign微服务的pom中和api公共微服务的pom中都要添加
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-feign</artifactId>
		<version>1.4.4.RELEASE</version>
	</dependency>

Ribbon+ RestTemplate是通过ConfigBean来创建一个RestTemplate模板,然后在controller中调用
在这里插入图片描述

@Configuration
public class ConfigBean{
	
	@Bean
	@LoadBalanced //Spring Cloud Ribbon是基 于Netflix Ribbon实现的一套客户端负载均衡的工具。
	public RestTemplate getRestTemplate() {
		
	return new RestTemplate( );
	}
@RestController
public class deptController_consumer {

	//private static final String REST_URL__PREFIX = "http://localhost:8001" ;
	private static final String REST_URL__PREFIX = "http://microservicecloud-dept" ;
	/**
	*使用
	使用restTemplate访问restful接口非常的简单粗暴无脑。
	(url, requestMap, ResponseBean.class)这三个参数分 别代表
	REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
	*
	**/
	
	@Autowired
	private RestTemplate restTemplate;
	
	@RequestMapping("/consumer/dept/add")
	public boolean add(Dept dept) {
		return restTemplate.postForObject(REST_URL__PREFIX+"/dept/add", dept,Boolean.class);
	}
	
	@RequestMapping("/consumer/dept/get/{id}")
	public Dept get(@PathVariable("id") Long id) {
		
		return restTemplate.getForObject(REST_URL__PREFIX+"/dept/get"+id,Dept.class);
	}
	
	@RequestMapping("/consumer/dept/list")
	public List<Dept> list() {
		
		return restTemplate.getForObject(REST_URL__PREFIX+"/dept/list",List.class);
	}

Feign则是面向接口编程,通过controller来调用service,在service添加注解@FeignClient(“microservicecloud-dept”)
在这里插入图片描述

@FeignClient("microservicecloud-dept")
public interface deptClientService {

	@PostMapping("/dapt/add")
	//@RequestMapping(value=" /dapt/add",method=RequestMethod . POST)
	public boolean add( Dept dept);
	
	
	@GetMapping("/dept/get/{id}")
	//@RequestMapping(value=" /dept/get/ {id}" ,method=RequestMethod . GET)
	public Dept get(@PathVariable("id") Long id);
	
	@GetMapping("/dept/list")
	//@RequestMapping(value=" /dept/list" ,method=RequestMethod . GET)
	public List<Dept> list();
	
	
}
public class deptController {
	@Autowired
	private deptClientService deptClientService;
	
	@RequestMapping("/consumer/dept/add")
	public boolean add(Dept dept) {
		return deptClientService.add(dept);
	}
	
	@RequestMapping("/consumer/dept/get/{id}")
	public Dept get(@PathVariable("id") Long id) {
		
		return deptClientService.get(id);
	}
	
	@RequestMapping("/consumer/dept/list")
	public List<Dept> list() {
		
		return deptClientService.list();
	}
	
}

在主启动类中需要添加@EnableFeignClients(basePackages= {“org.MXH”})
@ComponentScan(“org.MXH”),里面的地址是你的service包和controller包的父包地址

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages= {"org.MXH"})
@ComponentScan("org.MXH")

public class DeptConsumerFeign_APP {

	public static void main(String[] args) {
		SpringApplication.run(DeptConsumerFeign_APP.class, args);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值