1.背景引入
1.1问题描述
java
List<ServiceInstance> instances = discoveryClient.getInstances("product-service");
//服务可能有多个, 获取第⼀个
EurekaServiceInstance instance = (EurekaServiceInstance) instances.get(0);
针对某个服务,我们启动多个实例进行观察



访问eureka后,可以看到注册的实例

但是发现一个问题,每次进行数据访问时,都是同一台机器
我们启动多个实例, 是希望可以分担其他机器的负荷
1.2负载均衡
负载均衡(Load Balance) , 是⾼并发, ⾼可⽤系统必不可少的关键组件.当服务流量增⼤时, 通常会采⽤增加机器的⽅式进⾏扩容, 负载均衡就是⽤来在多个机器或者其他资源中, 按照⼀定的规则合理分配负载
1.3服务端负载均衡
在服务端进⾏负载均衡的算法分配.
⽐较有名的服务端负载均衡器是Nginx. 请求先到达Nginx负载均衡器, 然后通过负载均衡算法, 在多个服务器之间选择⼀个进⾏访问.

1.4客户端负载均衡
在客⼾端进⾏负载均衡的算法分配.
把负载均衡的功能以库的⽅式集成到客⼾端, ⽽不再是由⼀台指定的负载均衡设备集中提供.
⽐如Spring Cloud的Ribbon, 请求发送到客⼾端, 客⼾端从注册中⼼(⽐如Eureka)获取服务列表, 在发
送请求前通过负载均衡算法选择⼀个服务器,然后进⾏访问.

2.Spring Cloud LoadBalancer
2.1使⽤Spring Cloud LoadBalancer实现负载均衡
(1)给 RestTemplate 这个Bean添加 @LoadBalanced 注解
java
@Configuration
public class BeanConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
(2)修改IP端⼝号为服务名称
java
public OrderInfo selectOrderById(Integer orderId){
OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
String url="http://product-service/product/"+orderInfo.getProductId();
log.info("远程调用url{}",url);
ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
orderInfo.setProductInfo(productInfo);
return orderInfo;
}
2.2负载均衡策略
负载均衡策略是⼀种思想, ⽆论是哪种负载均衡器, 它们的负载均衡策略都是相似的. Spring Cloud LoadBalancer 仅⽀持两种负载均衡策略: 轮询策略 和 随机策略
- 轮询: 轮询策略是指服务器轮流处理⽤⼾的请求. 这是⼀种实现最简单, 也最常⽤的策略. ⽣活中也有类似的场景, ⽐如学校轮流值⽇, 或者轮流打扫卫⽣.
- 随机选择: 随机选择策略是指随机选择⼀个后端服务器来处理新的请求.
Spring Cloud LoadBalancer 默认负载均衡策略是轮询策略,如果服务的消费者如果想采⽤随机的负载均衡策略, 也⾮常简单
(1)定义随机算法对象, 通过 @Bean 将其加载到 Spring 容器中
java
public class CustomLoadBalancerConfiguration {
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory
.getLazyProvider(name, ServiceInstanceListSupplier.class),
name);
}
}
(2)使⽤ @LoadBalancerClient 或者 @LoadBalancerClients 注解
在 RestTemplate 配置类上⽅, 使⽤ @LoadBalancerClient 或 @LoadBalancerClients 注解, 可以对不同的服务提供⽅配置不同的客⼾端负载均衡算法策略
java
//name指定这个配置针对的服务名称是"product-service",configuration指定自定义的负载均衡配置类
@LoadBalancerClient(name = "product-service",configuration = CustomLoadBalancerConfiguration.class)
@Configuration
public class BeanConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
2.3LoadBalancer原理
LoadBalancer 的实现, 主要是 LoadBalancerInterceptor , 这个类会对 RestTemplate 的请求进⾏拦截, 然后从Eureka根据服务id获取服务列表,随后利⽤负载均衡算法得到真实的服务地址信息,替换服务id
3.服务部署(Linux)
3.1准备数据
- 安装mysql
- 数据初始化
- 修改配置文件,主要包括用户名和密码
3.2服务构建打包
采用Maven打包,对所以服务进行打包

3.3启动服务
java
#后台启动eureka-server, 并设置输出⽇志到logs/eureka.log
nohup java -jar eureka-server.jar >logs/eureka.log &
#其他服务同理
#再多启动两台实例
#启动实例, 指定端⼝号为9091
nohup java -jar product-service.jar --server.port=9091 >logs/product-9091.log &
#启动实例, 指定端⼝号为9092
nohup java -jar product-service.jar --server.port=9092 >logs/product-9092.log &
3.4开放端口号
对于不同的服务厂商,开放端口号的方法不同,这里以阿里云为例
