step04day03微服务之负载均衡总结

1.nacos的四种负载均衡写法

1.1 基本知识点

1.1.1.@LoadBalanced注解

当使用RestTemplate进行远程服务调用时,假如需要负载均衡,可以在RestTemplate对象构建时,使用@LoadBalanced,对构建RestTemplate的方法进行修饰。修饰的同时也是对于负载均衡中的一些方法进行了封装;封装的代码大致如下:

     ServiceInstance choose =loadBalancerClient.choose(serverId);
            String ip=choose.getHost();
            int port =choose.getPort();
            //String url= "http://"+ip+":"+port+"/provider/echo/"+msg;
            String url =String.format("http://%s:%s/provider/echo/%s",ip,port,appName);

1.1.2.Ribbon负载均衡策略

基于Ribbon方式的负载均衡,Netflix默认提供了七种负载均衡策略,对于SpringCloud Alibaba解决方案中又提供了NacosRule策略,默认的负载均衡策略是轮训策略。

 一般常用轮训,当系统提供的负载均衡策略不能满足我们需求时,我们还可以基于IRule接口自己定义策略.可用ctrl+F6快速获取.

1.1.3.Feign

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

 Feign 最早是由 Netflix 公司进行维护的,后来 Netflix 不再对其进行维护,最终 Feign 由一些社区进行维护,更名为 OpenFeign。

1.2负载均衡四种写法间的关系

1.2.1.手写式和loadBalancerClient

 Resttemplate优势:单个较为方便,

 Resttemplate+loadBalancerClient优势:

1.2.2.注解@loadBalaced和loadBalancerClient

 区别:注解式将其中一部分封装给了拦截器,相对低效一些

1.2.3.注解@loadBalaced和loadBalancerClient

 区别:将网页服务进行封装,交给openFeign管理,可以远程调用

1.2.4 总结

 服务方在调用提供方时,有四种方式可供选择,而架构的任务在于根据不同的业务场景选择合适的方式,以实现功能调用.

1.2.5 fegin接口与注解配置

注解:

@EnableFeignClients
@SpringBootApplication
public class ConsumerApplication {…}

接口:

@FeignClient(name="sca-provider")//sca-provider为服务提供者名称
interface RemoteProviderService{
    @GetMapping("/provider/echo/{string}")//前提是远端需要有这个服务
    public String echoMessage(@PathVariable("string") String string);
}

配置优化:多接口时--引入contextId,作为远程调用服务的唯一标识

@FeignClient(name="sca-provider",contextId="remoteProviderService")//sca-provider为服务提供者名称
interface RemoteProviderService{
    @GetMapping("/provider/echo/{string}")//前提是远端需要有这个服务
    public String echoMessage(@PathVariable("string") String string);
}

调用超时的容错方案——优化用户体验

@Component
public class ProviderFallbackFactory
    implements FallbackFactory<RemoteProviderService> {
    //当正常远程调用的服务不可用时,系统可以调用此方法进行请求处理
    // @Override在jdk1.7之前的版本并不可用,在1.7接口重新定义后,才可以使用@Override
    @Override
    public RemoteProviderService create(Throwable throwable) {
        return new RemoteProviderService() {
            @Override
            public String echoMsg(String msg) {
                //...通知运维人员(发短信,发邮件,电话)...
                return "服务维护中,稍等片刻再访问";
            }

        };
    }

说明:写入工厂配置时,需要加入相应的配置机制

#接口中加入反射获取失败返回值
@FeignClient(name = "sca-provider", contextId = "remoteProviderService",
             fallbackFactory = ProviderFallbackFactory.class)//sca-provider为nacos中的服务名
public interface RemoteProviderService {
    @GetMapping("/provider/echo/{msg}")
    public String echoMsg(@PathVariable String msg);
}

注意在启动feign方式调用时增加服务中断处理机制.

feign:  
  hystrix:
    enabled: true #默认值为false

最后优化的效果如图:

 2.运行过程中常见错误分析

2.1 Application Failed to Start

界面如下:

 解决方案:找到类中中不能执行的原因,修改后重启启动类

2.2依赖注入失败(Bean Not Found)

界面如图:

 解决方案:检查依赖以及注解,使之在依赖接口与之匹配

2.3请求映射路径重复定义

 解决方案:检查@GetMapping请求的一些部分是否重复,重复则进行相应的修改

2.4Feign远程调用超时

 解决方案:确定程序运行时间,检查是否超时

3.相关知识点总结

3.1手写tomcat

public class Tomcat {
    public static void main(String[] args) throws IOException {
        //java服务的创建
        System.out.println("start server ...");
        //java中网络编程中的服务对象类型为serversocket
        //构建服务,并在9999端口访问
        ServerSocket server=new ServerSocket(9999);
        //监听端口,等待服务连接
        while(true){

            Socket socket=server.accept();//阻塞方法
            System.out.println("hello client"+socket);
            //获取向客户端输出数据的流对象
            OutputStream out=socket.getOutputStream();
            //向客户端写数据
            out.write("hello".getBytes());//这种方式浏览器不响应
            String content="HTTP/1.1 200\r\n"+//响应行
                    "Content-Type:text/html;char"//响应头
                    +"\r\n"+//空行
                    "<h1>client</h1>";//数据
            out.write(content.getBytes());
            socket.close();
        }
    }
}

3.2 延时任务的代码

public class TimerTests {
    public static void main(String[] args) {
        //通过timer对象可以启动一个定时任务
        Timer timer=new Timer();
        //基于timer对象启动并执行任务
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(System.currentTimeMillis());
            }
        },1000,1000);
    }
}

4.面试相关知识点

4.1 Feign 调用过程分析(了解)

Feign应用过程分析(底层逻辑先了解):
1)通过 @EnableFeignCleints 注解告诉springcloud,启动 Feign Starter 组件。
2) Feign Starter 在项目启动过程中注册全局配置,扫描包下所由@FeignClient注解描述的接口,然后由系统底层创建接口实现类(JDK代理类),并构建类的对象,然后交给spring管理(注册 IOC 容器)。


3) 接口被调用时被动态代理类逻辑拦截,将 @FeignClient 请求信息通过编码器生成 Request对象,基于此对象进行远程过程调用。
4) 请求对象经Ribbon进行负载均衡,挑选出一个健康的 Server 实例(instance)。
5) 通过 Client 携带 Request 调用远端服务返回请求响应。
6) 通过解码器生成 Response 返回客户端,将信息流解析成为接口返回数据。

4.2 服务调用实例

4.3 Bug分析

404错误

说明:404访问的资源不存在,检查输入网址是否匹配

405错误

500错误

在这里插入图片描述

 例如,打开后台,假如出现了如下问题,就是你远程调用的服务url应该是写错了

 例如:假如你的Consumer服务调用Provider服务,但是Provider服务没有启动就会出现如下问题:

 

 4.4 面试题总结

  • 为什么使用feign?(基于Feign可以更加友好的实现服务调用,简化服务消费方对服务提供方方法的调用)。
  • @FeignClient注解的作用是什么?(告诉Feign Starter,在项目启动时,为此注解描述的接口创建实现类-代理类)
  • Feign方式的调用,底层负载均衡是如何实现的?(Ribbon)
  • @EnableFeignCleints 注解的作用是什么?(描述配置类,例如启动类)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值