《Spring Cloud 微服务实战》 学习笔记
客户端负载均衡
负载均衡在系统架构中是一个非常重要,并且不得不去实施的内容。
因为负载均衡是对系统的高可用、网络压力的环节和处理能力扩容的重要手段之一。
我们通常说的负载均衡指的是服务端负载均衡
.其中可以分为硬件负载均衡和软件负载均衡
硬件负载均衡
: 硬件负载均衡主要是通过在服务器节点间安装专门用于负载均衡的硬件设备,如:F5软件负载均衡
: 软件负载均衡则是通过在服务器上安装与一些具有负载均衡功能或模块的软件来完成请求分发的工作
。比如:Nginx
无论是硬件负载均衡还是软件负载均衡,都能用如下的架构图来构建起来:
硬件负载均衡的设备或者软件负载均衡的模块都会维护一个可用的服务端清单
,通过心跳监测来剔除故障的节点,以保证清单中都是可以正常访问的节点。
当客户端发送请求到负载均衡设备时,该设备通过某种算法(比如线性轮询,按权重负载,按流量负载等)从维护的可用服务清单中选择一个服务器,然后转发请求至该服务器。
客户端负载均衡与服务端负载均衡最大的不同是,上述提到的服务清单所存储的位置。
在客户端负载均衡中,所有的客户端节点都要维护一份自己要访问的服务端清单
,这些清单来自于服务注册中心。同服务端负载均衡类似,客户端负载均衡也需要心跳去维护服务清单的健康性,这个步骤需要与服务注册中心配合完成。
在Spring Cloud实现的服务治理框架中,默认会创建针对各个服务治理框架的Ribbon自动化整合配置。比如
- Eureka:
org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration
- Consul:
org.springframework.cloud.consul.discovery.RibbonConsulaAutoConfiguration
通过SpringCloud Ribbon的封装,在微服务启用客户端负载均衡只需要如下两步:
- 服务提供者启动多个实例到服务注册中心(or服务注册中心集群)
- 服务消费者通过带有
@LoadBalance
注解修饰过的RestTemplate
来实现对接口的调用.
demo搭建
注册中心
搭建高可用注册中心, s42,s43
注册中心1-s42
eureka:
instance:
hostname: s42
client:
#是否向注册中心注册自己
register-with-eureka: false
#是否从注册中心查询服务
fetch-registry: false
service-url:
defaultZone: http://s43:1111/eureka/
注册中心2-s43
eureka:
instance:
hostname: s43
client:
register-with-eureka: false
fetch-registry: false
service-url:
## 向s42注册
defaultZone: http://s42:1111/eureka/
服务提供者
部署eureka-echo-service
服务配置如下
配置
server:
port: 8888
servlet:
context-path: /echo
eureka:
client:
service-url:
defaultZone: http://s42:1111/eureka,http://s43:1111/eureka
instance:
prefer-ip-address: true
spring:
application:
#### name 不能带有 下划线
name: eureka-echo-service
EchoController
@RestController
public class EchoController {
@Value("${server.port}")
private int port;
@RequestMapping("/hi")
public String hi(String msg) {
return msg+",echo from 【"+ MacIpUtil.getIpv4()+":"+port+"】";
}
}
2个服务实例
部署两个实例:
- 实例1,至
s42:8888
- 实例2,至
s43:9999
服务消费者
配置
server:
port: 8080
servlet:
context-path: /test
eureka:
client:
service-url:
defaultZone: http://s42:1111/eureka,http://s43:1111/eureka
instance:
prefer-ip-address: true
spring:
application:
name: cloud-eureka-client
配置RestTemplate
@Bean
//加上 @LoadBalanced 注解
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder builder){
return builder.build();
}
新增CallRemoteController
@RestController
public class CallRemoteController {
@Autowired
private RestTemplate restTemplate;
// Ribbon使用 service-name 来替换host:port
private final String URL = "http://EUREKA-ECHO-SERVICE/echo/hi?msg={1}";
@RequestMapping("/call")
public String call(String msg) {
String result = restTemplate.getForObject(URL, String.class, msg);
System.out.println(result);
return result;
}
}
多次请求http://localhost:8080/test/call?msg=123
,后台打印日志:
客户端按照某种负载均衡策略
,交替的访问服务提供者的不同实例。
RestTemplate不是Spring自身提供的Http连接工具吗?跟Ribbon的客户端负载均衡有和关系呢?
Ribbon是如何把http://SERVICE-NAME/xxx
请求中的SERVICE-NAME
转化为具体的hostname:port
的?