1. 负载均衡LB:
load balance是微服务中经常使用的一种技术,处理高并发,缓解网络压力和进行服务网端扩容手段之一,将用户平均分配到多个服务上,从而实现系统的高可用的集群。可以通过硬件设备来实现(硬件F5)、软件来实现(Nginx)。常说的负载均衡是服务器端负载均衡
2. 服务器端负载均衡分为硬件和软件:
硬件负载均衡设备或软件负载均衡设备都会维护一个下挂可用的服务端清单,通过心跳检测来剔除故障的服务端节点以保证清单中都是可正常访问的服务端节点
3. 客户端的负载均衡Ribbon
Ribbon是Netflix公司开源的一个负载均衡的项目(https://github.com/Netflix/ribbon),它是一个基于HTTP、TCP的客户端负载均衡器。
4. 客户端的负载均衡Ribbon和服务端的负载均衡的区别 :
客户端负载均衡,例如spring cloud中的ribbon,客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这是客户端负载均衡,即在客户端就进行负载均衡算法分配;而服务器端负载均衡,例如Nginx,通过Nginx进行负载均衡, 先发送请求,然后通过负载均衡算法,在多个服务器之间选择一个进行访问,即在服务器端再进行负载均衡算法分配。
将Ribbon和Eureka一起使用时:
- 在消费者微服务中使用Ribbon实现负载均衡,Ribbon先从Eureka中获取服务列表
- Ribbon根据负载均衡的算法(默认就是轮询算法)去调用微服务
5. 通过Spring Cloud Ribbon的封装,微服务架构中使用客户端负载均衡调用只需如下两步:
- 服务提供者只需启动多个服务实例并注册到一个注册中心或是多个相关联的服务注册中心
- 服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用
@LoadBalanced注解用于给RestTemplate做标记,以使用负载均衡的客户端(LoadBalancerClient)来配置它
Ribbon服务实现负载均衡的调用实例(注:代码接 Rest构建分布式微服务 一期的博客
不增加新的服务,在消费者端通过Ribbon进行负载均衡。客户端的负载均衡的实现前提:必须有两个或两个以上的服务提供者
0. 增加一个数据库和一个服务提供者,将这个新的服务提供者连接到这个新增的数据库,测试时方便区分(实际开发中访问的是同一个数据库。
1. 修改pom.xml文件(添加负载均衡的依赖
<!--负载均衡依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2. 修改application .yml
server:
port: 80
eureka:
client:
register-with-eureka: false #禁止自己注册自己
fetch-registry: true #发现服务中 获得注册信息
serviceUrl:
defaultZone: http://eureka6001.com:6001/eureka,http://eureka6002.com:6002/eureka
3. 修改了自定义的配置类(给RestTemplate加@LoadBalanced注解
package cn.zf.springcloud.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* 自定义Rest相关配置类
*
* Rest相关配置类访问RestFull的方法(url,requestMap,ResponseBean.class)
* url 访问路径
* requestMap 返回值类型
* ResponseBean.class http响应格式
*/
@Configuration
public class ConfigBean {
@LoadBalanced
// 向容器中添加RestTemplate组件 直接通过该组件可以调用REST接口
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
4. 修改消费者的控制层
package cn.zf.springcloud.controller;
import cn.zf.springcloud.entities.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
public class ProductController_Consumer {
//将REST_URL_PREFIX的值从服务提供者本地IP+端口号改为微服务整合的命名,大写
//MICROSERVICE-PRODUCT 微服务整合的命名,对外暴露的名字
private static final String REST_URL_PREFIX="http://MICROSERVICE-PRODUCT";
//通过RestTemplate发现服务提供者
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/consumer/product/add")
public boolean add(Product product){
return restTemplate.postForObject(REST_URL_PREFIX+"/product/add",product,Boolean.class);
}
@RequestMapping(value = "/consumer/product/get/{id}")
public Product get(@PathVariable("id") Long id){
return restTemplate.getForObject(REST_URL_PREFIX+"/product/get/"+id,Product.class);
}
@RequestMapping(value = "/consumer/product/list")
public List<Product> list(){
return restTemplate.getForObject(REST_URL_PREFIX+"/product/list",List.class);
}
}
5. 修改主启动类(给主启动类加@EnableEurekaClient注解
package cn.zf.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableEurekaClient // 向注册中心进行注册
@SpringBootApplication
public class ProductConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(ProductConsumer_80.class,args);
}
}
Ribbon和Eureka整合后,消费者可以直接调用服务者,不用关心端口号和地址
6. 测试,先启动两个eureka注册中心的主启动类(两个注册中心顺序无所谓),再启动两个服务提供者的主启动类(两个服务提供者顺序无所谓),最后启动ProductConsumer_80服务消费者的主启动类
over~