《Ribbon负载均衡策略+Feign+GZIP压缩》

2020-05-25 00:00:00 多个 调用 服务 注解 负载均衡

  1. 什么是Ribbon及作用
    1. 什么是Ribbon?


Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随即连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。

    1. Ribbon解决了什么问题?


    解决并提供了微服务的 负载均衡的问题。

    1. 集中式负载均衡与进程式的负载均衡区别
      1. 负载均衡方案有哪些分类?


    目前业界主流的负载均衡方案可分成两类:

    类:集中式负载均衡

    第二类:进程内负载均衡

      1. 什么是集中式负载均衡?


      在 consumer 和 provider 之间使用独立的负载均衡设施(可以是硬件,如 F5, 也可以是软件,如 nginx), 由该设施负责把 访问请求 通过某种策略转发至 provider;


        1. 什么是进程内负载均衡?


        将负载均衡逻辑集成到 consumer,consumer 从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的 provider。

        Ribbon 就属于进程内负载均衡,它只是一个类库,集成于 consumer 进程,consumer 通过它来获取到 provider 的地址。


          1. 二者之间有什么区别?




          1. Ribbon的入门案例
            1. Ribbon中默认的负载均衡策略是什么策略?


          默认为:轮询策略

            1. LoadBalancerClient对象得作用是什么?


            ribbon 负载均衡器

            1. Ribbon常见负载均衡策略

            Ribbon的负载均衡策略有哪些?每一种负载均衡的特点是什么?











            1. 如何更换其他负载均衡策略
              1. 阐述更换其他负载均衡策略的步骤。


            方式一:在启动器内使用@Bean注解进行配置:



            方式二:在application.properties配置文件中配置:




            1. Ribbon的点对点直连
              1. 什么情况下需要配置Ribbon的点对点直连?


            一般在项目的开发过程中,会有多个开发人员同时启动项目,比如有张三,李四,王五,同时提供了这个服务,那么根据ribbon的负载均衡算法,比如轮询,本来消费方是要和张三联调,结果请求第二次发给了李四,第三次发给了王五,这样就会影响李四王五的工作,而且也不利于消费方和张三的联调。所以这时就需要点对点直连,让消费方只和张三联调,不影响其他人


              1. 配置Ribbon点对点直连的步骤是什么?


              1.去掉 Eureka 的坐标添加 Ribbon 坐标

              <dependency>

              <groupId>org.springframework.cloud</groupId>

              <artifactId>spring-cloud-starter-ribbon</artifactId>

              </dependency>

              2. 修改配置文件去掉与 Eureka 配置,添加新配置项

              #禁用 eureka

              ribbon.eureka.enabled=false

              #指定具体的服务实例清单

              eureka-provider.ribbon.listOfServers=192.168.70.137:9090

              3.启动类中删除@EnableEurrkaClient注解

              1. 什么是Feign及作用
                1. 什么是Feign?


              Feign 是一种声明式、模板化的 HTTP 客户端(仅在 consumer 中使用)。

                1. 什么是声明式服务调用?


                声明式调用就像调用本地方法一样调用远程方法;无感知远程 http 请求。

                  1. 声明式服务调用有什么作用?


                  1,Spring Cloud 的声明式调用, 可以做到使用 HTTP 请求远程服务时能就像调用本地方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这是个 HTTP 请求。

                  2,它像 Dubbo 一样,consumer 直接调用接口方法调用 provider,而不需要通过常规的Http Client 构造请求再解析返回数据。

                  3,它解决了让开发者调用远程接口就跟调用本地方法一样,无需关注与远程的交互细节,更无需关注分布式环境开发


                    1. 声明式服务调用解决了什么?


                    它解决了让开发者调用远程接口就跟调用本地方法一样,无需关注与远程的交互细节,更无需关注分布式环境开发。

                    1. Feign入门案例-创建product-service
                      1. 创建服务的API项目。




                      1. 修改POM文件添加相关依赖坐标。


                      <project xmlns="maven.apache.org/POM/4."

                      xmlns:xsi="w3.org/2001/XMLSchema-i"

                      xsi:schemaLocation="maven.apache.org/POM/4.

                      maven.apache.org/xsd/ma">

                      <modelVersion>4.0.0</modelVersion>

                      <groupId>com.bjsxt</groupId>

                      <artifactId>springcloud-ego-product-service</artifactId>

                      <version>0.0.1-SNAPSHOT</version>

                      <parent>

                      <groupId>org.springframework.boot</groupId>

                      <artifactId>spring-boot-starter-parent</artifactId>

                      <version>1.5.13.RELEASE</version>

                      <relativePath /> <!-- lookup parent from repository -->

                      </parent>

                      <properties>

                      <project.build.sourceEncoding>UTF-8</project.build.sourceEn

                      coding>

                      <project.reporting.outputEncoding>UTF-8</project.reporting.

                      outputEncoding>

                      <java.version>1.8</java.version>

                      </properties>

                      <dependencyManagement>

                      <dependencies>

                      <dependency>

                      <groupId>org.springframework.cloud</groupId>

                      <artifactId>spring-cloud-dependencies</artifactId>

                      <version>Dalston.SR5</version>

                      <type>pom</type>

                      <scope>import</scope>

                      </dependency>

                      </dependencies>

                      </dependencyManagement>

                      <dependencies>

                      <dependency>

                      <groupId>org.springframework.boot</groupId>

                      <artifactId>spring-boot-starter-web</artifactId>

                      </dependency>

                      <dependency>

                      <groupId>org.springframework.boot</groupId>

                      <artifactId>spring-boot-starter-test</artifactId>

                      <scope>test</scope>

                      </dependency>

                      <dependency>

                      <groupId>org.springframework.cloud</groupId>

                      <artifactId>spring-cloud-starter-config</artifactId>

                      </dependency>

                      <dependency>

                      <groupId>org.springframework.cloud</groupId>

                      <artifactId>spring-cloud-starter-eureka</artifactId>

                      </dependency>

                      </dependencies>

                      </project>


                        1. 编写查询所有商品的接口。


                        /**

                        * Product 服务接口

                        * @author Administrator

                        *

                        */

                        @RequestMapping("/product")

                        public interface ProductService {

                        //查询所有商品

                        @RequestMapping(value="/findAll",method=RequestMethod.GE

                        T)

                        public List<Product> findAll();

                        }


                        1. Feign入门案例-创建product-provider
                          1. 创建实现服务API的Provider。




                          1. 修改POM文件添加相关依赖坐标。


                          <project xmlns="maven.apache.org/POM/4."

                          xmlns:xsi="w3.org/2001/XMLSchema-i"

                          xsi:schemaLocation="maven.apache.org/POM/4.

                          maven.apache.org/xsd/ma">

                          <modelVersion>4.0.0</modelVersion>

                          <groupId>com.bjsxt</groupId>

                          <artifactId>springcloud-ego-product-provider</artifactId

                          >

                          <version>0.0.1-SNAPSHOT</version>

                          <parent>

                          <groupId>org.springframework.boot</groupId>

                          <artifactId>spring-boot-starter-parent</artifactId>

                          <version>1.5.13.RELEASE</version>

                          <relativePath /> <!-- lookup parent from repository -->

                          </parent>

                          <properties>

                          <project.build.sourceEncoding>UTF-8</project.build.sourceEn

                          coding>

                          <project.reporting.outputEncoding>UTF-8</project.reporting.

                          outputEncoding>

                          <java.version>1.8</java.version>

                          </properties>

                          <dependencyManagement>

                          <dependencies>

                          <dependency>

                          <groupId>org.springframework.cloud</groupId>

                          <artifactId>spring-cloud-dependencies</artifactId>

                          <version>Dalston.SR5</version>

                          <type>pom</type>

                          <scope>import</scope>

                          </dependency>

                          </dependencies>

                          </dependencyManagement>

                          <dependencies>

                          <dependency>

                          <groupId>org.springframework.boot</groupId>

                          <artifactId>spring-boot-starter-web</artifactId>

                          </dependency>

                          <dependency>

                          <groupId>org.springframework.boot</groupId>

                          <artifactId>spring-boot-starter-test</artifactId>

                          <scope>test</scope>

                          </dependency>

                          <dependency>

                          <groupId>org.springframework.cloud</groupId>

                          <artifactId>spring-cloud-starter-config</artifactId>

                          </dependency>

                          <dependency>

                          <groupId>org.springframework.cloud</groupId>

                          <artifactId>spring-cloud-starter-eureka</artifactId>

                          </dependency>

                          <!-- 添加 product-service 坐标 -->

                          <dependency>

                          <groupId>com.bjsxt</groupId>

                          <artifactId>springcloud-ego-product-service</artifactId>

                          <version>0.0.1-SNAPSHOT</version>

                          </dependency>

                          </dependencies>

                          <build>

                          <plugins>

                          <plugin>

                          <groupId>org.springframework.boot</groupId>

                          <artifactId>spring-boot-maven-plugin</artifactId>

                          </plugin>

                          </plugins>

                          </build>

                          </project>


                            1. 配置文件:


                            spring.application.name=ego-product-provider

                            server.port=9001

                            #设置服务注册中心地址,指向另一个注册中心

                            eureka.client.serviceUrl.defaultZone=user:123456@eur

                            eka1:8761/eureka/,user:123456@eureka2:8761/eureka/


                              1. 创建Controller实现服务API的接口,并实现接口中的抽象方法。


                              /**

                              * Product-Provider 服务

                              * @author Administrator

                              *

                              */

                              @RestController

                              public class ProductController implements ProductService {

                              @Override

                              public List<Product> findAll() {

                              List<Product> list = new ArrayList<>();

                              list.add(new Product(1, "电视"));

                              list.add(new Product(2, "电脑"));

                              list.add(new Product(3, "冰箱"));

                              list.add(new Product(4, "手电筒"));

                              return list;

                              }

                              }


                              1. Feign入门案例-创建product-consumer
                                1. @RestController注解的作用是什么?


                              @RestController是@ResponseBody和@Controller的组合注解

                                1. @FeignClient注解的作用是什么?


                                FeignClient注解被@Target(ElementType.TYPE)修饰,表示FeignClient注解的作用目标在接口上

                                  1. @EnableFeignClients注解的作用是什么?


                                  注解@EnableFeignClients告诉框架扫描所有使用注解@FeignClient定义的feign客户端。它又通过注解@Import导入了类FeignClientsRegistrar( feign客户端注册器),

                                    1. @EnableDiscoveryClient注解的作用是什么?


                                    @EnableEurekaClient上有@EnableDiscoveryClient注解,可以说基本就是EnableEurekaClient有@EnableDiscoveryClient的功能,另外上面的注释中提到,其实@EnableEurekaClient注解就是一种方便使用eureka的注解而已,可以说使用其他的注册中心后,都可以使用@EnableDiscoveryClient注解,但是使用@EnableEurekaClient的情景,就是在服务采用eureka作为注册中心的时候,使用场景较为单一。

                                    1. Feign传递单个参数
                                      1. 阐述Feign传递单个参数的原理。


                                    /**

                                    * Product 服务接口

                                    * @author Administrator

                                    *

                                    */

                                    @RequestMapping("/product")

                                    public interface ProductService {

                                    //查询所有商品

                                    @RequestMapping(value="/findAll",method=RequestMethod.GE

                                    T)

                                    public List<Product> findAll();

                                    //根据商品 ID 查询商品

                                    @RequestMapping(value="/getProductById",method=RequestMe

                                    thod.GET)

                                    public Product getProductById(@RequestParam("id") Integer

                                    id);

                                    }


                                    1. Feign传递多个参数-方式一使用GET
                                      1. 使用Feign基于GET请求传递多个参数的原理是什么?


                                    /**

                                    * Product 服务接口

                                    * @author Administrator

                                    *

                                    */

                                    @RequestMapping("/product")

                                    public interface ProductService {

                                    //查询所有商品

                                    @RequestMapping(value="/findAll",method=RequestMethod.GE

                                    T)

                                    public List<Product> findAll();

                                    //根据商品 ID 查询商品

                                    @RequestMapping(value="/getProductById",method=RequestMe

                                    thod.GET)

                                    public Product getProductById(@RequestParam("id") Integer

                                    id);

                                    //添加商品传递多个参数 方式一 :GET 方式

                                    @RequestMapping(value="/add",method=RequestMethod.GET)

                                    public Product addProduct(@RequestParam("id") Integer

                                    id,@RequestParam("name") String name);

                                    }


                                    1. Feign传递多个参数-方式二使用POST
                                    2. 使用Feign基于POST请求传递多个参数的原理是什么?

                                    /**

                                    * Product 服务接口

                                    * @author Administrator

                                    *

                                    */

                                    @RequestMapping("/product")

                                    public interface ProductService {

                                    //查询所有商品

                                    @RequestMapping(value="/findAll",method=RequestMethod.GE

                                    T)

                                    public List<Product> findAll();

                                    //根据商品 ID 查询商品

                                    @RequestMapping(value="/getProductById",method=RequestMe

                                    thod.GET)

                                    public Product getProductById(@RequestParam("id") Integer

                                    id);

                                    //添加商品传递多个参数 方式一 :GET 方式

                                    @RequestMapping(value="/add",method=RequestMethod.GET)

                                    public Product addProduct(@RequestParam("id") Integer

                                    id,@RequestParam("name") String name);

                                    //添加商品传递多个参数 方式二 :POST 方式

                                    @RequestMapping(value="/add",method=RequestMethod.POST)

                                    public Product addProduct2(@RequestBody Product product);

                                    }


                                    1. Gzip介绍及Http协议中的传输规则
                                      1. 什么是Gzip?


                                    gzip 介绍:gzip 是一种数据格式,采用用 deflate 算法压缩 data;gzip 是一种流行的文件压缩算法,应用十分广泛,尤其是在 Linux 平台。

                                    gzip 能力:当 Gzip 压缩到一个纯文本文件时,效果是非常明显的,大约可以减少 70%以上的文件大小。

                                    gzip 作用:网络数据经过压缩后实际上降低了网络传输的字节数,明显的好处就是可以加快网页加载的速度。网页加载速度加快的好处不言而喻,除了节省流量,改善用户的浏览体验外,另一个潜在的好处是 Gzip 与搜索引擎的抓取工具有着更好的关系。例如 Google就可以通过直接读取 gzip 文件来比普通手工抓取 更快地检索网页。

                                      1. HTTP协议中关于压缩传输的规定是什么?


                                      :客户端向服务器请求中带有:Accept-Encoding:gzip, deflate 字段,向服务器表示,客户端支持的压缩格式(gzip 或者 deflate),如果不发送该消息头,服务器是不会压缩的。

                                      第二:服务端在收到请求之后,如果发现请求头中含有 Accept-Encoding 字段,并且支持该类型的压缩,就对响应报文压缩之后返回给客户端,并且携带 Content-Encoding:gzip 消

                                      息头,表示响应报文是根据该格式压缩过的。

                                      第三:客户端接收到请求之后,先判断是否有 Content-Encoding 消息头,如果有,按该格式解压报文。否则按正常报文处理。

                                      相关文章