微服务的负载均衡
什么是负载均衡
通俗的讲, 负载均衡就是将负载(工作任务,访问请求)进行分摊到多个操作单元(服务器,组件)上
进行执行。
根据负载均衡发生位置的不同,一般分为服务端负载均衡和客户端负载均衡。
服务端负载均衡指的是发生在服务提供者一方,比如常见的nginx负载均衡
而客户端负载均衡指的是发生在服务请求的一方,也就是在发送请求之前已经选好了由哪个实例处理请
求
我们在微服务调用关系中一般会选择客户端负载均衡,也就是在服务调用的一方来决定服务由哪个提供
者执行
自定义实现负载均衡
在idea中开启一个项目的多个端口,新建服务填写服务名称,选择服务的启动类,填写启动服务的端口号。
启动完成
在nacos的服务列表里可以到实例数已经改变并且可以看到实例的端口号
调用结果
可以清晰的看到两个服务调用的日期时间差。
8082服务
8081服务
基于Ribbon实现负载均衡
启动类中添加
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
@LoadBalanced
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
//服务调用后面要更换成Feign
@Autowired
private RestTemplate restTemplate;
//下单- Ribbon支持的负载均衡策略
// RestTemplate 增加 @LoadBalanced 注解的方式
@GetMapping("/order/prod/{pid}")
public Order order(@PathVariable("pid") Integer pid) {
log.info("接收到{}号商品的下单请求,接下来调用商品微服务查询此商品信息", pid);
//直接写入要调用的服务名称 和接口信息
Product product =
restTemplate.getForObject("http://service-product/product/" + pid, Product.class);
log.info("查询到{}号商品的信息,内容是:{}", pid, JSON.toJSONString(product));
//下单(创建订单)
Order order = new Order();
order.setUid(1);
order.setUsername("测试用户");
order.setPid(pid);
order.setPname(product.getPname());
order.setPprice(product.getPprice());
order.setNumber(1);
orderService.save(order);
log.info("创建订单成功,订单信息为{}", JSON.toJSONString(order));
return order;
}
application.yml
server:
port: 8091
tomcat:
max-threads: 10 #tomcat的最大并发值修改为10,默认是200
spring:
cloud:
sentinel:
transport:
port: 9999 #跟控制台交流的端口,随意指定一个未使用的端口即可
dashboard: localhost:8080 # 指定控制台服务的地址
nacos:
discovery:
server-addr: 127.0.0.1:8848
application:
name: service-order
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://114.55.93.211/shop?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
username: root
password: yuanchengszw123
jpa:
properties:
hibernate:
hbm2ddl:
aito: update
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
service-product: # 调用的提供者的名称
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
Ribbon支持的负载均衡策略
Ribbon内置了多种负载均衡策略,内部负载均衡的顶级接口为
com.netflix.loadbalancer.IRule , 具体的负载策略如下图所示: