provider集群和负载均衡 ribbon

provider 集群和负载均衡 ribbon

上一篇:Feign 的日志
下一篇:使用zuul 构建微服务网关

provider集群。

我用的是第二种启动方式 。修改application.yml配置文件,还是用—隔开把文件中不同的隔开如下所示:

#当前项目启动端口
#server:
#  port: 8000
#连接数据库的信息
# generate-ddl: false 取消让它自动见数据库
# show-sql: true展示sql
spring:
  jpa:
    generate-ddl: false
    show-sql: true
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/cloud?useUnicode=true&characterEncoding=UTF-8&useSSL=true
    driver-class-name: com.mysql.jdbc.Driver
  #当前启动的名字
  profiles:
    active: provider2
#  application:
#    name: springcloud-provider
info:
  head: head
  body: body
  app:
    name: @project.artifactId@
    encoding: @project.build.sourceEncoding@
    java:
      source:  @java.version@
      target:  @java.version@
management:
  endpoints:
    web:
      exposure:
        #加载所有的端点,默认只加载了info、health
        include: '*'
  endpoint:
    health:
      show-details: always
      #可以关闭指定的端点
    shutdown:
      enabled: false
eureka:
  client:
    service-url:
      defaultZone: http://root:root@peer1:8761/eureka/,http://root:root@peer2:8762/eureka/
  instance:
    prefer-ip-address: true
#    virtual-host-name: provider
---
spring:
  profiles: provider1
  application:
    name: provider
server:
  port: 8000
---
spring:
  profiles: provider2
  application:
    name: provider
server:
  port: 8001

启动好之后
测试提供者是否正常提供服务

http://localhost:8000/user/2
在这里插入图片描述
http://localhost:8001/user/2
在这里插入图片描述
是不是注册到服务发现组件上面去了,如图所示
在这里插入图片描述

负载均衡 ribbon

来一个请求,将请求分配到对应的服务消费者来一个请求,判断一下,交给哪一个提供者获取数据,返回数据?
1 jar包,已经在eureka-client中引入。
在这里插入图片描述
2 在启动主类上的restTemplate添加 @LoadBalanced注解

@SpringBootApplication
@EnableEurekaClient
public class SpringcloudConsumerApplication {
    
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
    
    
        return new RestTemplate();
    }
    public static void main(String[] args) {
    
    
        SpringApplication.run(SpringcloudConsumerApplication.class, args);
    }

}

修改消费者的访问路径,provider做好集群后配置文件变了,只能通过提供者的应用名字(也叫serviceId)来访问了也就是提供者的如图所示:
在这里插入图片描述
修改消费者UserController的中的路径如下所示:

 @RequestMapping("/user/{id}")
    public User findUserById(@PathVariable("id") Integer id){
    
    
        //消费者,调用生产者
//        User user = restTemplate.getForObject(userServiceUrl+id,User.class);
        User user = restTemplate.getForObject("http://provider/"+id,User.class);
        return user;
    }

测试消费者访问提供者
在这里插入图片描述
如下访问了四次:两个提供者各调用两次
在这里插入图片描述
在这里插入图片描述
默认的负载均衡是轮询(为了更直观一点我把控制台清空了)。跟dubbo的默认的随机不一样。

负载均衡算法种类

Ribbon的核心组件是IRule,是所有负载均衡算法的父接口,其子类有:

RoundRobinRule 轮询

RandomRule 随机

AvailabilityFilteringRule 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,还有并发的连接数超过阈值的服务,然后对剩余的服务列表进行轮询

WeightedResponseTimeRule 权重 根据平均响应时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越高。刚启动时,如果统计信息不足,则使用轮询策略,等信息足够,切换到WeightedResponseTimeRule

RetryRule 重试 先按照轮询策略获取服务,如果获取失败则在指定时间内重试,获取可用服务

BestAvailableRule 选过滤掉多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务

ZoneAvoidanceRule 符合判断server所在区域的性能和server的可用性选择服务

自定义配置负载均衡算法

有两种方式

一、 JAVA配置

配置很简单

public class SpringcloudConsumerApplication {
    
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
    
    
        return new RestTemplate();
    }

    /**自定义配置ribbon负载均衡算法
     * @return
     */
    @Bean
    public IRule myRule(){
    
    
//        return new RoundRobinRule();//轮询
        return new RandomRule();
//        return new RetryRule();//重试

//        return new BestAvailableRule();
    }

    public static void main(String[] args) {
    
    
        SpringApplication.run(SpringcloudConsumerApplication.class, args);
    }

}

(随机)提供者的控制台输入的结果如下:
访问了八次
在这里插入图片描述
在这里插入图片描述
其他的就一一列举了。
具体业务需求选择合适的算法即可,当然可以根据具体业务需求自己写一个算法类。
使用配置文件实现负载均衡策略

二、属性配置

在消费者项目中的配置文件中添加

#指定负载均衡策略
springcloud-consumer:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

ribbon配置优先级:Ribbon配置的优先级:属性配置 > JAVA配置
java配置
在这里插入图片描述
属性配置
在这里插入图片描述

如下所示遵循轮询:
在这里插入图片描述
在这里插入图片描述

Ribbon配置大致完成了。

日志输出

在消费者项目的controller层使用日志。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RestController
public class UserController {
    
    
    private static final Logger logger = LoggerFactory.getLogger(User.class);
    @Autowired
    private LoadBalancerClient loadBalancerClient;
    @Autowired
    private UserFeignClient userFeignClient;
    @Autowired
    private RestTemplate restTemplate;
    @Value("${user.userServiceUrl}")
    private String userServiceUrl;
    @RequestMapping("user/{id}")
    public User findById(@PathVariable("id") Integer id){
    
    
        return restTemplate.getForObject("http://provider/user/"+id, User.class);
//        return restTemplate.getForObject(userServiceUrl+id,User.class);
    }
    @GetMapping("/log")
    public void logUserInstance(){
    
    
        //虚拟主机名
        ServiceInstance serviceInstance = this.loadBalancerClient.choose("provider");
        this.logger.info("{}:{}:{}", serviceInstance.getInstanceId(),serviceInstance.getHost(),serviceInstance.getPort(),serviceInstance.getInstanceId());
    }
}

测试:
在这里插入图片描述
看访问的时候访问那个提供者那个提供者就会打印访问了那个端口主机地址之类的。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_39095899/article/details/107460121