SpringCloud之服务远程调用--ribbon的服务调用和负载均衡

(一)ribbon概述

Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。

ribbon的主要作用是服务调用负载均衡

(二)ribbon服务调用

服务调用:eureka内部继承了ribbon

1.在创建RestTemplate时,声明@LoadBalanced

2.使用restTemplate调用远程微服务,用服务的名称代替ip地址

还是回到之前的项目,这个项目可以看SpringCloud专题的前两篇博客,修改admin微服务中的启动类,在restTemplate中加上LoadBalanced注解:

@SpringBootApplication
@EntityScan("com.sdxb.admin.entity")
@EnableEurekaClient
public class AdminApplication {
    //增加ribbon注解
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

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

在adminController中使用服务名称代替ip地址

@RestController
@RequestMapping("/admin")
public class adminController {
    @Autowired
    private RestTemplate restTemplate;
    @RequestMapping(value = "/{id}",method = RequestMethod.GET)
    public User getuser(@PathVariable int id){
        //使用服务名称代替IP地址
        User user= restTemplate.getForObject("http://userservice/user/1",User.class);
        return user;
    }
}

注意一个可能发生的小错误,服务名称我们是在application.properties中定义的,服务名称不能出现下划线,否则会显示找不到该url

(三)ribbon负载均衡

ribbon最主要的功能不是远程调用,而是负载均衡,所谓负载均衡就是将请求分摊到各个微服务中,缓解服务器的压力。举个例子有相同的三个微服务ABC,都能实现同样的功能,此时一个请求发过来的时候,就需要客户端或服务器通过一定算法决定该给哪个微服务。

常见的服务器端负载均衡:nginx

常见的客户端负载均衡:ribbon

服务器端负载均衡是指服务器接收到请求后选择发给哪个服务,客户端负载均衡是指客户端决定了发给哪个服务从而实现负载均衡。

负载均衡实战:

首先对原来的userservice做个小小的修改,让它的数据中带有该微服务的ip地址和端口号:

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserMapper userMapper;
    @Value("${server.port}")
    private String port;//使用注解获取端口号
    @Value("${spring.cloud.client.ip-address}")
    private String ip;//使用注解获取ip地址

    @GetMapping("/{id}")
    public User user(@PathVariable("id") int id){
        User user = userMapper.selectbyid(id);
        user.setUsername(ip+":"+port);
        return user;
    }
}

通过@Value注解获取到端口号和ip地址,写到user的name中

启动eureka注册中心和UserApplication,将user微服务注册到eureka注册中心中,在Run DashBoard中copy一份UserApplication,命名为UserApplication2

 修改UserService的端口号为9010,启动UserApplication2

在浏览器中输入http://localhost:9000/,可以看到两个端口都注册到eureka注册中心了

 启动adminApplication,在浏览器中输入http://localhost:9002/admin/1

 

通过刷新浏览器可以看到负载均衡的效果。

负载均衡算法:

ribbon提供了许多负载均衡算法:

com.netflix.loadbalancer.RoundRobinRule    轮询的方式负载均衡(默认)

com.netflix.loadbalancer.RandomRule    随机

com.netflix.loadbalancer.RetryRule    重试

com.netflix.loadbalancer.WeightedResponseTimeRule   权重策略

com.netflix.loadbalancer.BestAvailableRule    最佳策略

com.netflix.loadbalancer.AvailabilityFilteringRule    过滤策略

用得比较多的轮询和权重策略,当所用的服务器配置有高有低时,推荐权重策略,它会计算每个服务器的权重。

修改负载均衡算法的方式也很简单,在你想修改负载均衡的客户端微服务的配置文件application.properties下,增加下面的语句:

微服务名称.ribbon.NFLoadBalancerRuleClassName=所采用的方式的全限定类名(上面红色字体),我将策略修改为随机,重启服务后刷新浏览器,发现所调用的服务不再是轮询了。

#修改ribbon负载均衡策略
userservice.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

(三)ribbon重试机制

ribbon属于客户端负载均衡,即客户端会选择要访问哪个微服务,如果这个时候微服务断掉了,就无法返回数据。因此需要引入重试机制。

重试机制的引入有两个步骤:

1.导入依赖:

在客户端的pom.xml导入依赖

<!--引入重试依赖-->
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>

 2.填写相关配置

配置的解释全部放在注解中了

#重试机制
#ribbon连接超时时间
userservice.ribbon.ConnectTimeout=250
#ribbon读取数据超时时间
userservice.ribbon.ReadTimeout=1000
#是否对所有操作都重试
userservice.ribbon.OkToRetryOnAllOperations=true
#切换实例的重试次数
userservice.ribbon.MaxAutoRetriesNextServer=1
#对当前实例的重拾次数
userservice.ribbon.MaxAutoRetries=1

此时如果出现一个端口断掉的情况依然可以保证服务不崩溃。

代码放在github中,与这篇博客对应的代码放在version3.0分支上:github

发布了54 篇原创文章 · 获赞 604 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_41973594/article/details/103481333