序言
之前我们介绍了分布式系统就是分成多个微服务,那么微服务怎么相互调用接口呢?通过注册中心Eureka统一管理全部微服务的注册服务域名、IP和端口,谁要调用哪个服务就找注册中心返回给你就完事了。
为了提高微服务的性能,减轻微服务的压力,有时候微服务也会采用集群方式通过部署多台服务器执行相同的微服务来提高对该服务请求的处理效率,那么该如何将这些调用分配给这些服务器呢?所以我们这里引入了负载均衡工具Ribbon(负载均衡的大概解决思路参考nginx)
什么是客户端负载均衡?(相对的就是服务端负载均衡)
详情可看此链接:https://blog.csdn.net/qq_42039738/article/details/105515996
从图示我们可以清楚看到客户端负载均衡Ribbon就是部署在 消费者(发起调用的微服务)的
图示流程:
1、消费者发起远程调用,内含被调用微服务在注册中心Eureka注册的域名,触发Ribbon
//被调用微服务在注册中心Eureka注册的域名
String serviceId = "XC-SERVICE-MANAGE-CMS";
ResponseEntity<Map> map = restTemplate.getForEntity("http://" + serviceId + "/cms/page/get/5a754adf6abb500ad05688d9", Map.class);
如图红色框住区域就是被调用微服务在注册中心Eureka注册的域名
2、Ribbon根据注册中心Eureka中的注册域名寻找与发起远程调用请求相同的域名,若相同则根据负载均衡算法分发给该微服务下的服务器
负载均衡算法:
1、随机,通过随机选择服务进行执行,一般这种方式使用较少;
2、轮训,负载均衡默认实现方式,请求来之后排队处理;
3、加权轮训,通过对服务器性能的分型,给高配置,低负载的服务器分配更高的权重,均衡各个服务器的压力;
4、地址Hash,通过客户端请求的地址的HASH值取模映射进行服务器调度。
5、最小链接数;即使请求均衡了,压力不一定会均衡,最小连接数法就是根据服务器的情况,比如请求积压数等参数,将请求分配到当前压力最小的服务器上。
6、其他若干方式。
3、具体服务器接收到请求处理请求
代码实现
1、引入依赖
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-ribbon -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.2.7.RELEASE</version>
</dependency>
<!-- 第三方远程调用工具-->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
<!-- 导入Eureka客户端的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、启动类添加 @EnableDiscoveryClient 表示它是一个Eureka的客户端(微服务)
(Eureka的服务端就是注册中心)
3、restTemplate远程服务调用配置(加上 @LoadBalanced开启Ribbon客户端负载均衡 )
package com.xuecheng.manage_course.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
/**
* @author Huang
* @version 1.0
* @date 2020/4/14 20:32
*/
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced //开启客户端负载均衡
public RestTemplate getRestTemplate(){
//RestTemplate是实现SpringMVC提供的http调用接口,OkHttp是第三方的http调用接口,从RestTemplate设置OkHttp意思是使用第三方的http调用接口
System.out.println("远程调用接口配置成功");
return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}
}
4、测试(通过for循环模拟多请求实现负载均衡场景(轮询))
@Autowired
RestTemplate restTemplate;
/**
* 测试客户端负载均衡ribbon
*/
@Test
public void test05() {
//服务ID
String serviceId = "XC-SERVICE-MANAGE-CMS";
//ribbon从eureka获取服务列表
for(int i=0; i<10; i++){
ResponseEntity<Map> map = restTemplate.getForEntity("http://" + serviceId + "/cms/page/get/5a754adf6abb500ad05688d9", Map.class);
Map body = map.getBody();
System.out.println(body);
}
}