【第四阶段 day22 day23】服务负载均衡设计及特点

1.服务负载均衡设计及特点

一个服务实例可以处理的请求是有限的,假如服务实例的并发访问比较大,我们会启动多个服务实例,让这些服务实例采用一定策略均衡(轮询,权重,随机,hash等)的处理并发请求,在nacos中服务的负载均衡(nacos客户端负载均衡)是如何应用的?

1.1 LoadBalanceClient应用

LoadBalanceClient对象可以从nacos中基于服务名获取服务实例,然后在工程中基于特点算法实现负载均衡的调用

1.1.1 启动服务消费方,启动服务提供方,两个端口:8081,8082

对于服务提供方,打开idea服务启动配置,修改并发运行选项,再修改sca-provider的配置文件端口,分别以8081,8082端口的方式启动
在这里插入图片描述

1.1.2 修改ConsumerController类,注入LoadBalanceClient对象,并添加doRestEcho2方法,然后进行服务访问

在这里插入图片描述

/**
     * 负载均衡客户端对象
     * 注入LoadBalancerClient对象
     * 此对象可以从nacos中基于服务名获取服务实例
     * 然后再工程中基于特点算法实现负载均衡方式的调用
     * 采用一定的负载均衡算法
     */
    @Autowired
    private LoadBalancerClient loadBalancerClient;
     
    @Value("${spring.application.name:8090}")
    private String appName;
	
	//http://localhost:8090/consumer/doRestEcho2
    @GetMapping("/consumer/doRestEcho2")
    public String doRestEcho2(){
        //基于服务名获取服务实例
        ServiceInstance serviceInstance =
                loadBalancerClient.choose("sca-provider");//serviceId中的服务名
        //构建远端服务的url
        //基于服务实例中的ip,port构建服务的url
        String url = String.format("http://%s:%s/provider/echo/%s",serviceInstance.getHost(),serviceInstance.getPort(),appName);
        System.out.println("request url:"+url);
        return restTemplate.getForObject(url, String.class);
    }
1.1.3 重新启动sca-consumer项目模块,打开浏览器,输入网址进行重复访问

会发现sca-provider的两个服务都可以处理sca-consumer的请求
在这里插入图片描述
在这里插入图片描述
这里多个实例并发提供服务的方式为负载均衡,这里的负载均衡实现默认是nacos集成了Ribbon来实现的,Ribbon配合ResrTemplate,可以非常容易的实现服务之间的访问.Ribbon是spring cloud 的核心组件之一,它提供的最重要的功能就是客户端的负载均衡(客户端可以在用一定的算法:比如轮询访问,访问服务端的实例信息),这个功能可以让我们轻松地将面向服务的REST模板请求自动转换为客户端负载均衡的服务调用

1.2 @LoadBalanced 应用

1.2.1 在RestTemplate对象构件时,加@LoadBalanced实现负载均衡

当使用RestTemplate进行远程服务调用时,假如需要负载均衡,可以在RestTemplate对象构建时,使用@LoadBalanced对构建RestTemplate的方法进行修饰,例如在ConsumerApplication中构建名字为loadBalancedRestTemplate的RestTemplate对象

/**
     * 当我们使用@LoadBalanced注解描述RestTemplate对象时
     * 假如此时再基于RestTemplate对象对远程服务进行访问
     * 此请求就会被一个拦截器拦截下来
     * 请求被拦截到以后,就会现基于服务名找到服务实例
     */
    @Bean
    @LoadBalanced
    public RestTemplate loadBalancedRestTemplate(){//基于此对象实现远端服务调用
        return new RestTemplate();
    }
1.2.2 在需要RestTemplate实现负载均衡调用的地方进行依赖注入

在ConsumerController类中添加loadBalancedRestTemplate

 @Autowired
//@Qualifier("loadBalancedRestTemplate")
  private RestTemplate loadBalancedRestTemplate;
1.2.3 在对应的服务端调用方的方法内,基于RestTemplate借助服务名进行服务调用
    @GetMapping("/consumer/doRestEcho3")
    public String doRestEcho3(){
        String url=String.format("http://%s/provider/echo/%s","sca-provider",appName);
        return loadBalancedRestTemplate.getForObject(
                url,//要请求的服务的地址
                String.class);//String.class为请求服务的响应结果类型
    }

RestTemplate在发送请求的时候会被LoadBalancerInterceptor拦截,它的作用就是用于RestTemplate的负载均衡,LoadBalancerInterceptor将负载均衡的核心逻辑交给了loadBalanced

@LoadBalanced注解属于Spring,而不是Ribbon的,Spring在初始化容器的时候,如果检测到Bean被@LoadBalanced注解,Spring会为其设置LoadBalancerInterceptor拦截器

*2.面试题

  • @Bean注解的作用?(一般用于配置类的内部,用于告诉Spring此方法的返回值要交给spring管理,bean的名字默认为方法名,假如需要指定名字可以@Bean(“bean的名字”),最多的应用场景是为了整合第三方的资源-对象)
  • @Autowired注解的作用?(此注解用于描述属性,构造方法,set方法等等,用于告诉spring框架,按照一定的规则为属性进行DI操作,默认按照属性方法参数类型查找对应的对象,假如只找到一个,则直接注入,类型多个时还会按照属性名或方法参数名进行值的注入,假如名字也不同,直接报错)
  • nacos中的负责均衡的底层是如何实现的?(通过Ribbon中定义了一些负载均衡的算法,然后基于这些算法从服务实例中获取一个实例为消费方法提供服务)
  • ribbon是什么(netfix公司提供的负载均衡客户端,一般应用于服务的消费方法)
  • ribbon可以解决什么问题?(基于负载均衡策略进行服务的调用,所有的策略都会实现rule端口)
  • ribbon内置的负载策略有哪些(8种)
  • @LoadBalanced的作用是什么?(描述RestTemplate对象,用于告诉Spring框架,在使用RestTemplate进行服务调用时,这个调用过程会被一个拦截器拦截,然后再拦截器的内部,启动负载均衡策略)
  • 我们可以自己定义负载均衡策略码?(可以,基于IRule接口进行策略定义,也可以参考NacosRule进行实现)

3.基于Feign的远程服务调用

feign是一种声明式web服务客户端,底层封装了Rest技术的应用,通过feign可以简化服务消费方对远程服务提供方法的调用实现

3.1 在服务的消费方,添加项目依赖
<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-openfeign</artifactId>
 </dependency>
3.2 在启动类上添加@EnableFeignClient注解,代码:
@EnableFeignClients
@SpringBootApplication
public class ConsumerApplication{...}
3.3 定义http请求API,基于此API借助OpenFeign访问远端服务
package com.jt.consumer.service;

import com.jt.service.factory.ProviderFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
 * 这里的@FeignClient注解用于描述Feign远程服务调用接口
 * 假如在项目配置类或启动类上添加了@EnableFeignClients注解
 * 系统会在启动时,扫描@FeignClient
 * 注解描述的接口
 * 并为接口创建实现类对象(代理对象)
 * 此对象内部会封装对远程服务调用的过程
 * @FeignClient注解中name属性的值有两个层面的含义:
 * 1>远程调用服务名
 * 2>RemoteProviderService接口类型对象交给spring管理时,这个对象(bean)的名字*/
/*描述的接口底层会为其创建实现类*/
@FeignClient(name = "sca-provider",contextId="remoteProviderService",
            fallbackFactory = ProviderFallbackFactory.class)
public interface RemoteProviderService {
    @GetMapping("/provider/echo/{string}")//前提是远端需要有这个服务
    public String echoMessage(@PathVariable("string") String string);
}

其中,@FeignClient描述的接口底层会为其创建实现类

3.4 添加feign访问
    @Autowired
    private RemoteProviderService remoteProviderService;
    @GetMapping("/echo/{msg}")
    public String doRestEcho4(@PathVariable String msg){
        return  remoteProviderService.echoMessage(msg);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值