nacos注册中心+Ribbon负载均衡+完成openfeign的调用(超详细步骤)

目录

1.注册中心

1.1.nacos注册中心

1.2. 微服务注册和拉取注册中心的内容

2.3.修改订单微服务的代码

3.负载均衡组件

3.1.什么是负载均衡

3.2.什么是Ribbon

3.3.Ribbon 的主要作用

3.4.Ribbon提供的负载均衡策略

4.openfeign完成服务调用

4.1.什么是OpenFeign

4.2.完成openfeign的调用


 继  微服务工程  文章扩展的注册中心及负载均衡


1.注册中心

服务治理是微服务架构中最核心最基本的模块。用于实现各个微服务的自动化注册与发现

服务注册:在服务治理框架中,都会构建一个注册中心,每个服务单元向注册中心登记自己提供服务的详细信息。并在注册中心形成一张服务的清单,服务注册中心需要以心跳30s 90s的方式去监测清单中 的服务是否可用,如果不可用,需要在服务清单中剔除不可用的服务。

服务发现:服务调用方向服务注册中心咨询服务,并获取*所有服务*的实例清单,实现对具体服务实例的访问。

通过上面的调用图会发现,除了微服务,还有一个组件是服务注册中心,它是微服务架构非常重要的一个组件,在微服务架构里主要起到了协调者的一个作用。注册中心一般包含如下几个功能:

1. 服务发现:

服务注册:保存服务提供者和服务调用者的信息

服务订阅:服务调用者订阅服务提供者的信息,注册中心向订阅者推送提供者的信息

2. 服务配置:

配置订阅:服务提供者和服务调用者订阅微服务相关的配置

配置下发:主动将配置推送给服务提供者和服务调用者

3. 服务健康检测

检测服务提供者的健康情况,如果发现异常,执行服务剔除

1.1.nacos注册中心

官网nacos

nacos资源已上传

解压后打开

修改:

默认它启动模式为--集群模式---修改它为单机模式  

 修改后保存退出

访问:

http://localhost:8848/nacos

账号和密码: nacos

1.2. 微服务注册和拉取注册中心的内容

商品微服务:

引入依赖

 <!--引入nacos的依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

修改配置文件

#nacos注册中心的地址
spring.cloud.nacos.discovery.server-addr=localhost:8848
#为微服务定义名称
spring.application.name=qy165-product

发现:

2.3.修改订单微服务的代码

 引入依赖

 <!--引入nacos的依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

修改配置文件

#nacos注册中心的地址
spring.cloud.nacos.discovery.server-addr=localhost:8848
#为微服务定义名称
spring.application.name=qy165-order

解决硬编码问题

package com.wqg.order.controller;

import com.wqg.entity.Order;
import com.wqg.entity.Product;
import com.wqg.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
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
@RequestMapping("order")
public class OrderController01 {
    @Autowired
    private OrderService orderService;
    @Autowired
    private RestTemplate restTemplate;

    //在springcloud依赖中存在一个类DiscoveryClient 该类可以从注册中心拉取指定的服务列表清单
    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("insert")
    public String insert(Long pid, Integer num) {
        //创建订单--添加数据
        Order order = new Order();
        order.setUid(5L);
        order.setUsername("笔记本");
        order.setNumber(num);

        List<ServiceInstance> instances = discoveryClient.getInstances("qy165-product");
        ServiceInstance serviceInstance = instances.get(0);
        //根据服务实例对象获取相对应的ip和端口号
        String path = serviceInstance.getUri().toString();

        //商品信息
        Product product = restTemplate.getForObject(path+"/product/getById/"+pid, Product.class);
        order.setPid(product.getPid());
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());

        int i = orderService.saveOrder(order);

        return i > 0 ? "下单成功" : "下单失败";

    }
}

3.负载均衡组件

3.1.什么是负载均衡

通俗的讲, 负载均衡就是将负载(工作任务,访问请求)进行分摊到多个操作单元(服务器,组件)上进行执行。

根据负载均衡发生位置的不同,一般分为服务端负载均衡客户端负载均衡

服务端负载均衡指的是发生在服务提供者一方,比如常见的nginx负载均衡

而客户端负载均衡指的是发生在服务请求的一方,也就是在发送请求之前已经选好了由哪个实例处理请求

我们在微服务调用关系中一般会选择客户端负载均衡,也就是在服务调用的一方来决定服务由哪个提供者执行.

演示:---手动完成负载均衡

模拟搭建商品微服务n台

手动实现负载均衡----随机负载均衡

修改OrderController订单代码

@RestController
@RequestMapping("order")
public class OrderController02 {
    @Autowired
    private OrderService orderService;
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("insert")
    public String insert(Long pid, Integer num) {
        //创建订单--添加数据
        Order order = new Order();
        order.setUid(5L);
        order.setUsername("笔记本");
        order.setNumber(num);

        List<ServiceInstance> instances = discoveryClient.getInstances("qy165-product");
        int index = new Random().nextInt(instances.size());
        ServiceInstance serviceInstance = instances.get(index);
        String s = serviceInstance.getUri().toString();

        //商品信息
        Product product = restTemplate.getForObject(s+"/product/getById/"+pid, Product.class);
        order.setPid(product.getPid());
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());

        int i = orderService.saveOrder(order);

        return i > 0 ? "下单成功" : "下单失败";

    }
}

上面通过手动完成了负载均衡的调用,存在的问题: 它采用的随机负载均衡,如何我想使用轮询负载均衡策略。

只能修改源代码。耦合。---springcloud提供了一个组件--可以灵活的完成负载均衡。--ribbon

3.2.什么是Ribbon

是 Netflix 发布的一个负载均衡器,有助于控制 HTTP 和 TCP 客户端行为。在 Springcloud中, nacos 一般配合 Ribbon 进行使用,Ribbon 提供了客户端负载均衡的功能,Ribbon 利用从 nacos 中读 取到的服务信息,在调用服务节点提供的服务时,会合理(策略) 的进行负载。在Springcloud 中可以将注册中心和Ribbon 配合使用,Ribbon 自动的从注册中心中获取服务提供者的 列表信息,并基于内置的负载均衡算法,请求服务。

3.3.Ribbon 的主要作用

(1)服务调用

基于 Ribbon 实现服务调用,是通过拉取到的所有服务列表组成 ( 服务名-请求路径的 ) 映射关系。借助 RestTemplate最终进行调用.

(2)负载均衡

当有多个服冬提供者时,Ribbon 可以根据负载均衡的算法自动的选择需要调用的服务地址

如何使用Ribbon实现负载均衡

在RestTemplate生成类上加入@LoadBalanced

修改OrderController订单代码

@RestController
@RequestMapping("order")
public class OrderController03 {
    @Autowired
    private OrderService orderService;
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("insert")
    public String insert(Long pid, Integer num) {
        //创建订单--添加数据
        Order order = new Order();
        order.setUid(5L);
        order.setUsername("笔记本");
        order.setNumber(num);

        //商品信息
        Product product = restTemplate.getForObject("http://qy165-product/product/getById/"+pid, Product.class);
        order.setPid(product.getPid());
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());

        int i = orderService.saveOrder(order);

        return i > 0 ? "下单成功" : "下单失败";

    }
}

测试

3.4.Ribbon提供的负载均衡策略

Ribbon内置了多种负载均衡策略,内部负载均衡的顶级接口为:com.netflix.loadbalancer.IRule,具体的负载策略如下所示:

策略名策略描述实现说明
BestAvailableRule选中一个最小的并发请求的server逐个考察Server,如果Server被 tripped了,则忽略,在选择其中ActiveRequestsCount最小的server
RandomRule随机选择一个server在index上随机,选择index对应位置的server
RoundRobinRule轮询方式轮询选择轮询index,选择index对应位置的
AvailabilityFilteringRule过滤掉那些因为一直连接失败的被标记为circuittripped的后端server,并过滤掉 那些高并发的的后端server (activeconnections 超过配置的阈值)使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就是检查 status里记录的各个server的运行状态
WeightedResponseTimeRule根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低一个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成statas时,使用roubine策略选择server。
RetryRule对选定的负载均衡策略机上重试机制在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
ZoneAvoidanceRule复合判断server所在区域的性能和server的可用性选择server使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉

ribbon内置的负载均衡策略,默认轮询,也可以自定义负载均衡。

如何修改ribbon组件的负载均衡策略----修改配置文件

修改为随机:

#修改ribbon的负载均衡策略---随机
qy165-product.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

4.openfeign完成服务调用

4.1.什么是OpenFeign

OpenFeign是Spring Cloud提供的一个声明式的伪Http客户端, 它使得调用远程服务就像调用本地方法一样简单, 只需要创建一个接口并添加一个注解即可。

Nacos很好的兼容了OpenFeign, OpenFeign负载均衡默认集成了 Ribbon, 所以在Nacos下使用OpenFeign默认就实现了负载均衡的效果。

4.2.完成openfeign的调用

订单微服务

(1)依赖

<!--openfeign依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

(2)创建openfeign接口

@FeignClient(value = "qy165-product")
public interface ProductFeign {
    //接口的方法 必须 和被调用者的接口的参数一致
    @GetMapping("/product/getById/{id}")
    public Product getById(@PathVariable Long id); //springcloud 扫描到@FeignClient注解时--生产一个代理实现类.
}

(3)开启openfeign注解驱动

(4)修改OrderController

@RestController
@RequestMapping("order")
public class OrderController04 {
    @Autowired
    private OrderService orderService;
    @Autowired
    private ProductFeign productFeign;
    
    @GetMapping("insert")
    public String insert(Long pid, Integer num) {
        //创建订单--添加数据
        Order order = new Order();
        order.setUid(5L);
        order.setUsername("笔记本");
        order.setNumber(num);

        //商品信息
        Product product = productFeign.getById(pid);
        order.setPid(product.getPid());
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());

        int i = orderService.saveOrder(order);

        return i > 0 ? "下单成功" : "下单失败";

    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值