目录
一、服务提供者与服务消费者
二、远程调用存在的问题
三、Eureka原理
四、Eureka架构
五、搭建Eureka服务
六、Eureka服务注册
七、Eureka服务发现
八、Ribbon负载均衡流程
九、Ribbon负载均衡源码
十、Ribbon负载均衡策略
十一、Ribbon饥饿加载
一、服务提供者与服务消费者
在分布式系统一次业务中提供服务的叫做提供者,它提供接口给其他微服务,而调用提供者接口i的叫做服务消费者。但是提供者与消费者并不是一成不变的,他们是相对而言的
二、远程调用存在的问题
传统的远程调用,采用的是通过RestTemplate向其他微服务接口发起HTTP请求去获取数据,而发起HTTP请求时的url采用硬编码的方式即指定了IP与端口(http://IP:port/),如果提供者的服务在多台服务器部署,那么硬编码的方式就存在弊端。此时注册中心的出现解决了这一问题,所有的服务先去注册中心注册,调用时再从注册中心拉去调用信息
三、Eureka原理
服务提供者在启动时向eureka注册中心注册自己的信息,eureka保存这些注册的信息,消费者根据服务的名称向eureka拉去提供者信息,如果存在多个提供者,服务消费者在调用时会利用负载均衡算法,从服务器列表中进行挑选。消费者如何感知提供者的健康状态呢?服务提供者每隔30秒向eurekaServer发送心跳包,报告健康状态,eureka会更新记录服务列表信息,心跳不正常会被剔除,消费者就可以拉取到最新的信息
四、Eureka架构
在Eureka中,微服务角色有两类
EurekaServer服务端,注册中心:它记录服务信息以及进行心跳监控
EurekaClient客户端,服务提供者会将自己的信息注册到EurekaServer,每隔30s向EurekaServer发送心跳包。服务消费者会根据服务名从EurekaServer拉去服务列表,基于服务列表做负载均衡,选择其中一个发起远程调用
五、搭建Eureka服务
首先我们需要创建一个注册中心的SpringBoot项目,在pom.xml中引入以下依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
然后在启动类上加注解
@EnableEurekaServer
最后在配置文件填写注册中心信息
server:
port: 10086
spring:
application:
name: eurekaserver
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka/
六、Eureka服务注册
在服务的项目里引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
然后在配置文件里添加配信息进行注册
spring:
application:
name: userservice # 服务名后续获取服务时需要用
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka/
七、Eureka服务发现
服务消费者进行调用时,首先需要创建配置类将RestTemplate注入到Spring容器里,注入时添加负载均衡的注解
@Bean
@LoadBalanced
public RestTemplate rest(){
return new RestTemplate();
}
其次在需要调用处装配该对象进行调用
String url="http://userservice/user?id=1"; // 此处IP与端口填写服务注册时的name即可
User user = restTemplate.getForObject(url,User.class);
八、Ribbon负载均衡流程
消费者发起请求请求提供者的服务,Ribbon拦截请求,此时取EurekaServer拉取提供者信息列表,拉取到之后Ribbon采用负载均衡策略进行选择后发起请求
九、Ribbon负载均衡源码
之前注入RestTemplate时加了注解LoadBalanced,加该注解后由RestTemplate发起的请求都会被Ribbon拦截,LoadBalancedInterceptor负载均衡拦截器将请求拦截后RibbonLoadBalancerCliennt获取请求url中的访问ID也就是访问注册时的name,此时DynamicServerListLoadBalancer就会取服务器拉取相关服务列表,之后服务负载均衡后选择某一个之后将原来url中的服务ID与负载均衡后选择的服务地址信息进行替换后访问
十、Ribbon负载均衡策略
内置负载均衡规则类 | 描述 |
RoundRobinRule | 简单的轮询服务列表,他是Ribbon默认的负载均衡规则 |
WeightedResponseTimeRule | 为每一个服务器赋予一个权重值,服务器响应时间越长,权重越小。这个规则会随机选择服务器,这个权重会影响服务器的选择 |
ZoneAvoidanceRule | 以区域可以的服务器为基础进行服务器选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房,一个机架等,然后再对Zone中的服务轮询,可以理解为先选择机房,再从机房中轮询选择服务器 |
BestAvailableRule | 忽略短路的服务器,选择并发低的服务器 |
RandomRule | 随机选择一个可用的服务器 |
RetryRule | 重试机制的选择逻辑 |
我们可以通过两种方式修改负载均衡策略
1.创建配置类注入对应的负载均衡类
@Bean
public IRule randomRule(){
return new randomRule();
}
2.在配置文件中声明
userserver: #服务名
ribbon:
NFLoadBalancerRuleClassName:com.netflix.loadbalancer.RandomRule # 负载均衡规则类
十一、Ribbon饥饿加载
Ribbon模式是采用懒加载,这就使得第一次访问服务会变的慢,他需要先去创建LoadBalaceClient,请求时间会很长。我们可以通过让它变为饥饿加载来减少第一次访问的时间,
饥饿加载是在项目启动时就创建,我们需要在配置中添加以下信息
ribbon:
eager-load:
enable: true # 开启饥饿加载
clients:
- userservice
- orderservice # 针对哪些服务进行饥饿加载