72-第1章 SpringCloud

发布时间:2022-06-20 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了72-第1章 SpringCloud脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

第1章 SPRingCloud

今日内容介绍

72-第1章 SpringCloud

学习目标:

  • 掌握架构演进过程
  • 理解微服务拆分流程及远程调用过程
  • 掌握注册中心Eureka的使用
  • 掌握负载均衡Ribbon的使用
  • 能够基于Feign实现服务远程调用
  • @H_406_22@

    1 服务架构演进[了解]

    章节知识点

    • 单体架构
    • 分布式架构
    • 微服务架构
    • SpringCloud

    过去的互联网

    1:用户量不多
    2:并发低
    3:数据少
    

    现在的互联网:

    1:用户多
    2:并发高
    3:数据庞大
    

    互联网架构从简到繁的演进经历了单体架构、分布式架构、SOA架构、微服务架构以及最新的service mesh的演进过程。

    1.1 单体架构

    1)概念

    早期互联网产品用户量少,并发量低,数据量小,单个应用服务器可以满足需要,这就是最早互联网架构。我们用一句话总结什么是单体架构:将业务的所有功能集中在一个项目中开发,部署为一个节点。
    

    2)架构图

    72-第1章 SpringCloud

    3)优缺点

    #优点:
    	1)架构简单
    	2)部署成本低
    	
    #缺点:
    	1)耦合度高
    

    1.2 分布式架构

    1)概念

    根据业务功能对系统进行拆分,每个业务模块称为一个服务。
    

    2)架构图

    72-第1章 SpringCloud

    3)优缺点

    #优点
    	1)降低服务耦合度
    	2)有利于服务升级拓展
    	
    #缺点
    	1)维护成本增加
    	2)服务间调用复杂度增加
    

    4)需要解决的问题

    1)服务拆分粒度如何?
    2)服务之间如何实现调用?
    3)服务关系如何管理?
    

    1.3 微服务

    1)概念

    微服务是系统架构的一种设计风格,将一个原本独立的服务拆分成多个小型服务,每个服务独立运行在在各自的进程中,服务之间通过 HTTP RESTful API 进行通信.每个小型的服务都围绕着系统中的某个耦合度较高的业务进行构建。
    
    #微服务是一种经过良好设计的分布式架构方案,而全球的互联网公司都在积极尝试自己的微服务落地方案。其中在java领域最引人注目的是SpringCloud提供的方案。
    

    2)架构图

    72-第1章 SpringCloud

    3)微服务架构特征

    单一职责:微服务拆分粒度更小,每个服务都应对唯一的业务能力,做到单一职责
    自治:团队独立、技独立、数据独立,独立部署和交付
    面向服务:服务提供统一标准的接口,与语言无关、与技术无关
    隔离性强:服务调用做好隔离、容错、降级,避免出现级联问题
    

    1.4 SpringCloud

    • SpringCloud是目前国内使用最广泛的微服务技术栈。官网地址:https://spring.io/projects/spring-cloud。

    • SpringCloud集成了各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配,从而提供了良好的开箱即用体验:

    72-第1章 SpringCloud

    • SpringCloud与SpringBoot的版本兼容关系如下:

    72-第1章 SpringCloud

    • 我们课堂学习的版本是 Hoxton.SR10,因此对应的SpringBoot版本是2.3.x(2.3.8)版本。

    1.5 总结

    • 单体架构:简单方便,高度耦合,扩展性差,适合小型项目。例如:学生管理系统,后台管理系统,ERP,OA 中小级企业级应用

    • 分布式架构:松耦合,扩展性好,但架构复杂,难度大。适合大型互联网项目,例如:京东淘宝

    • 微服务:一种良好的分布式架构方案

    • 优点:拆分粒度更小、服务更独立、耦合度更低

    • 缺点:架构非常复杂,运维、监控、部署难度提高

    • SpringCloud:SpringCloud是微服务架构的一站式解决方案,集成了各种优秀微服务功能组件

    2 服务拆分及远程调用[掌握]

    章节知识点

    • 远程调用案例业务介绍
    • 工程导入
    • 使用RestTemplate实现远程调用
    • 服务提供者、服务消费者概念
    • RestTemplate码剖析
    • 服务调用出现的问题

    案例说明:管理员查询订单详情->根据订单id查询订单的同时,把订单所属的用户信息一起返回,如下图:

    72-第1章 SpringCloud

    2.1 工程导入

    1. SQL导入

    资料工程代码springcloud-parentsql脚本中的cloud-order.sqlcloud-user.sql分别导入到两个数据库中。

    1. 工程导入

    资料工程springcloud-parent导入到IDEA中

    72-第1章 SpringCloud

    1. 修改数据库配置,并测试

    查询某用户详情信息:http://localhost:18081/user/1

    查询某订单详情信息:http://localhost:18082/order/101

    2.2 远程调用

    1)RestTemplate介绍

    RestTemplate 是spring家族中一款基于http协议的组件(HttpURLConnection),他的作用就是:用来实现基于http的协议方式的服务之间的通信(也就是远程服务调用)。
    
    RestTemplate 采用同步方式执行 HTTP 请求,底层使用 JDK 原生 HttpURLConnection API 。
    
    #概念总结:RestTemplate是spring提供的一个用来模拟浏览器发送请求和接收响应的一个类,它能基于Http协议实现远程调用。
    

    2)注册RestTemplate

    ITheima-orderOrderApp中注册RestTemplate`:

    72-第1章 SpringCloud

    3)远程调用

    修改itheima-order中的OrderServiceImplfindById方法

    72-第1章 SpringCloud

    4)测试

    72-第1章 SpringCloud

    2.3 服务提供者、服务消费者

    服务提供者:一次业务中,被其它微服务调用的服务。(提供接口给其它微服务)

    服务消费者:一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)

    72-第1章 SpringCloud

    在上面案例中itheima-order调用了itheima-user提供的接口,所以itheima-order是服务消费者,itheima-user是服务提供者。

    2.4 RestTemplate源码剖析

    下面是RestTemplate部分源码,我们可以看到执行过程中采用了Http请求。

    沿着RestTemplate.doExecute()往下看相关源码:

    72-第1章 SpringCloud

    一直往后跟踪,在SimpleBufferingClientHttpRequest类中的executeInternal方法中,可以发现会调用sun.net.www.protocol.http.HttpURLConnection.connect()实现远程调用:

    72-第1章 SpringCloud

    2.5 服务调用出现的问题

    72-第1章 SpringCloud

    按照上面调用流程,消费者调用服务者存在很多问题:

    1:服务消费者该如何获取服务提供者的地址信息?
    2:如果有多个服务提供者,消费者该如何选择?
    3:消费者如何得知服务提供者的健康状态?
    

    2.6 总结

    • RestTemplate使用有2个步骤:
      • 1)注册RestTemplate
      • 2)使用restTemplate.getForObject(url,T.class)远程调用
    • RestTemplate底层是封装了Http请求
    • 服务提供者、服务消费者
      • 服务提供者:一次业务中,被其它微服务调用的服务。(提供接口给其它微服务)
      • 服务消费者:一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)

    3 注册中心-Eureka[会搭建]

    章节知识点

    • 注册中心的作用讲解
    • EurekaServer搭建
    • 服务提供者注册
    • 服务消费者注册

    3.1 Eureka的作用

    Eureka注册中心如何解决上面的问题?

    72-第1章 SpringCloud

    Eureka工作原理

    #1:消费者该如何获取服务提供者具体信息?
    	服务提供者启动时向eureka注册自己的信息
    	eureka保存这些信息
    	消费者根据服务名称向eureka拉取提供者信息
    	
    #2:如果有多个服务提供者,消费者该如何选择?
    	服务消费者利用负载均衡算法,从服务列表中挑选一个
    	
    #3:消费者如何感知服务提供者健康状态?
    	服务提供者会每隔30秒向EurekaServer发送心跳请求,报告健康状态
    	EurekaServer在90秒内没有接收到某个微服务节点的心跳,EurekaServer将会注销该微服务的节点
    	消费者就可以拉取到最新的信息
    

    3.2 Eureka注册中心实战

    72-第1章 SpringCloud

    3.2.1 搭建EurekaServer

    搭建EurekaServer服务步骤如下:

    1)pom.XMl

    创建项目itheima-eurekaserver,引入spring-cloud-starter-netflix-eureka-server的依赖:

    <dePEndencies>
        <!--EurekaServer包-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
    

    2)启动类

    创建启动类com.itheima.EurekaServerApp,代码如下:

    package com.itheima;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaServerApp {
        public static void main(String[] args) {
            SpringApplication.run(EurekaServerApp.class,args);
        }
    }
    

    3)核心配置文件application.yML

    server:
      port: 8001    #端口号
    spring:
      application:
        name: eureka-server # 应用名称,会在Eureka中作为服务的id标识(serviceId)
    eureka:
      client:
        register-with-eureka: false   #是否将自己注册到Eureka中
        fetch-registry: false   #是否从eureka中获取服务信息
        service-url:
          defaultZone: http://localhost:8001/eureka
    

    此时我们访问EurekaServer地址http://localhost:8001/,效果如下:

    72-第1章 SpringCloud

    3.2.2 服务提供者注册

    将itheima-user服务注册到EurekaServer步骤如下:

    1)pom.xml

    itheima-user添加如下依赖:

    <!--EurekaClient包-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    

    2)修改application.yml

    修改itheima-userapplication.yml,添加如下配置:

    ...
    eureka:
      client:
        service-url:
          # EurekaServer的地址
          defaultZone: http://localhost:8001/eureka
      instance:
      	#以IP地址注册到服务中心
        prefer-ip-address: true
        #服务向eureka注册时,注册名默认:“IP名:应用名:应用端口名”
        #现在配置:注册名:应用名:端口:项目版本号
        instance-id: ${spring.application.name}:${server.port}:@project.version@
    

    prefer-ip-address:true 效果图

    72-第1章 SpringCloud

    prefer-ip-address:flase 效果图

    72-第1章 SpringCloud

    3)多实例启动

    72-第1章 SpringCloud

    72-第1章 SpringCloud

    分别启动3个服务配置,Eureka(http://localhost:8001/)信息如下:

    72-第1章 SpringCloud

    3.3.3 服务消费者注册

    itheima-order虽然是消费者,但与itheima-user一样都是eurekaclient端,同样可以实现服务注册: 在itheima-order项目引入spring-cloud-starter-netflix-eureka-client的依赖

    1)pom.xml

    itheima-orderpom.xml中引入如下依赖

    <!--EurekaClient包-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    

    2)修改application.yml

    修改itheima-orderapplication.yml,添加如下配置:

    server:
      port: 18082
    spring:
      application:
        name: itheima-order
      datasource:
        driverclassname: com.MySQL.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/springcloud-order?characterEncoding=UTF-8&&serverTimezone=GMT
        username: root
        password: 123456
    eureka:
      client:
        service-url:
          # EurekaServer的地址
          defaultZone: http://localhost:8001/eureka
      instance:
        prefer-ip-address: true
        instance-id: ${spring.application.name}:${server.port}:@project.version@
    

    3.3.4 远程调用

    itheima-order完成服务拉取实现远程调用,服务拉取是基于服务名称获取服务列表,然后在对服务列表做负载均衡。

    修改itheima-order的OrderServiceImpl的代码,修改访问的url路径,用服务名代替ip、端口,代码如下:

    在itheima-order项目的启动类OrderApplication中的RestTemplate添加负载均衡注解:

    @H_126_524@

    在itheima-order工程启动类OrderApp中,开启负载均衡

    /***
     * 注册RestTemplate
     */
    @Bean
    @LoadBalanced//开启负载均衡
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
    

    我们访问http://localhost:18082/order/101测试效果如下:

    72-第1章 SpringCloud

    3.3.5 Eureka配置说明

    服务注册时默认使用的是主机名,如果我们想用ip进行注册,可以在客户端(提供者与消费者)中的application.yml添加配置:

    eureka:
      client:
        service-url:
          # EurekaServer的地址
          defaultZone: http://localhost:8001/eureka
      instance:
        prefer-ip-address: true
        instance-id: ${spring.application.name}:${server.port}:@project.version@
        lease-renewal-interval-in-seconds: 30 #心跳周期,默认是30秒
        lease-expiration-duration-in-seconds: 90 #心跳失败最长超时间,默认90秒
    

    itheima-eurekaserver 服务端,可以关闭保护机制

    eureka:
      ...
      server:
        enable-self-preservation: false # false关闭保护机制。 15分钟内,如果心跳成功率<85%,则启动保护(服务提供者列表不再变化)
    

    3.3.6 总结

    • 搭建EurekaServer

      • 引入eureka-server依赖
      • 启动类上添加@EnableEurekaServer注解
      • 在application.yml中配置eureka地址
    • 服务注册

      • 引入eureka-client依赖
      • 在application.yml中配置eureka地址
    • 服务发现

      • 引入eureka-client依赖
      • 在application.yml中配置eureka地址
      • 给RestTemplate添加@LoadBalanced注解
      • 用服务提供者的服务名称远程调用(由原来的ip:port改服务名(spring.application.name))

    4 负载均衡Ribbon

    章节知识点

    • Ribbon是什么
    • 负载均衡流程讲解
    • 负载均衡算法学习
    • Ribbon负载均衡使用

    Ribbon是什么?

    Ribbon是Netflix发布的负载均衡器,有助于控制HTTP客户端行为。为Ribbon配置服务提供者地址列表后,Ribbon就可基于负载均衡算法,自动帮助服务消费者请求。

    概念:Ribbon是基于Http协议请求的客户端负载均衡器,能实现很丰富的负载均衡算法。

    4.1 负载均衡流程

    72-第1章 SpringCloud

    负载均衡流程如上图所示:

    1:用户发起请求,会先到达itheima-order服务
    2:itheima-order服务通过Ribbon负载均衡器从eurekaserver中获取服务列表
    3:获取了服务列表后,轮询(负载均衡算法)调用
    

    4.2 负载均衡算法【面试】

    72-第1章 SpringCloud

    轮询调用会涉及到很多负载均衡算法,负载均衡算法比较多,关系图如下:

    72-第1章 SpringCloud

    Ribbon的负载均衡算法策略如下表:

    内置负载均衡规则类 规则描述
    RoundRobinRule 简单轮询服务列表来选择服务器。
    AvailabilityFilteringRule 对以下两种服务器进行忽略: (1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。(2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的<clientName>.<clientConfignamespace>.ActiveConnectionsLimit属性进行配置。
    WeightedResponseTimeRule 为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。
    ZoneAvoidanceRule【默认】 以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询。它是Ribbon默认的负载均衡规则。
    BestAvailableRule 忽略哪些短路的服务器,并选择并发数较低的服务器。
    RandomRule 随机选择一个可用的服务器。
    RetryRule 重试机制的选择逻辑

    4.3 Ribbon负载均衡算法使用

    Ribbon负载均衡算法的使用有2种方式

    • 代码方式

      • 注册IRule接口的实现类(负载均衡算法):在itheima-order的启动类中添加如下负载均衡注册代码:

        /**
         * 随机负载均衡算法
         * @return
         */
        @Bean
        public IRule randomRule() {
            return new RandomRule();
        }
        
    • 配置方式

      • 为指定服务配置负载均衡算法:在itheima-order的核心配置文件中添加如下配置:

        #注意配置到跟节点
        
        #指定服务使用指定负载均衡算法
        itheima-user:
          ribbon:
            NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #负载均衡规则
        

    从懒加载 变为 饥饿加载

    Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。 而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,在itheima-order的核心配置文件中,添加如下配置开启饥饿加载:

    #注意配置到跟节点
    
    #饥饿加载
    ribbon:
      eager-load:
        clients: itheima-user #指定对user这个服务饥饿加载
        enabled: true #开启饥饿加载 
    

    4.4. 总结

    • Ribbon负载均衡规则

      • 规则接口是IRule
      • 默认实现是ZoneAvoidanceRule,根据zone选择服务列表,然后轮询
    • 负载均衡自定义方式

      • 代码方式:配置灵活,但修改时需要重新打包发布
      • 配置方式:直观,方便,无需重新打包发布,但是无法做全局配置
    • 饥饿加载

      • 开启饥饿加载
      • 指定饥饿加载的微服务名称

    5 http客户端Feign[掌握]

    章节知识点

    • Feign介绍
    • Feign入门案例学习
    • Feign日志功能、性能优化、最佳实践讲解

    5.1 Feign介绍

    先来看我们以前利用RestTemplate发起远程调用的代码:

    User user = restTemplate.getForObject("http://itheima-user/user/"+orderInfo.getUserId(), User.class);
    

    存在下面的问题:

    • 代码可读性差,编程体验不统一
    • 参数复杂URL难以维护

    上面RestTemplate存在的问题可以使用Feign解决,那么什么是Feign?

    Feign是一个声明式的http客户端,官方地址:https://github.COM/OpenFeign/feign 其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。

    72-第1章 SpringCloud

    5.2 Feign入门案例

    定义和使用Feign客户端的步骤如下:

    1:引入依赖包 spring-cloud-starter-openfeign
    2:添加注解@EnableFeignClients开启Feign功能
    3:定义远程调用接口,在接口中知名远程调用的【服务名字】、【方法签名】
    4:注入接口,执行远程调用(接口)
    

    1)引入依赖

    itheima-order中引入如下依赖:

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

    2)开启Feign功能

    itheima-order的启动类OrderApplication添加@EnableFeignClients注解开启Feign功能,代码如下:

    @SpringBootApplication
    @EnableFeignClients
    public class OrderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(OrderApplication.class, args);
        }
        //...其他略
    }
    

    3)定义远程调用接口

    itheima-order中创建接口UserClient,代码如下:

    72-第1章 SpringCloud

    上图代码如下:在itheima-order工程中添加

    package com.itheima.client;
    import com.itheima.user.pojo.User;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVARiable;
    
    /**
     * order调用user服务(代替了 String url = "http://itheima-user/user/" + orderInfo.getUserId();)
     * 1.接口上使用@FeignClient(value="被调用服务名")
     * 2.定义被调用接口中的方法(基于被调用的controller编写)
     *  2.1 requestMapping中的路径必须是全路径(controller类上的+方法上的)
     *  2.2 使用PathVariable注解,必须取别名
     */
    @FeignClient(value = "itheima-user")
    public interface UserClient {
    
        /**
         * 调用用户微服中controller的方法
         */
        @GetMapping(value = "/user/{id}")
        public User one(@PathVariable(value = "id") Long id);
    }
    

    主要是基于SpringMVC的注解来声明远程调用的信息,比如:

    • 服务名称:user
    • 请求方式:GET
    • 请求路径:/user/{username}
    • 请求参数:String username
    • 返回值类型:User

    4)远程调用

    修改itheima-orderOrderServiceImpl.one()方法,执行远程调用,代码如下:

    @Autowired
    private UserClient userClient;
    
    /**
     * 根据ID查询订单信息
     */
    @override
    public OrderInfo findById(Long id) {
        //1.查询订单
        OrderInfo orderInfo = orderDAO.selectById(id);
        //2.根据订单查询用户信息->需要调用  【item-user】  服务
        User user = userClient.one(orderInfo.getUserId());
        //3.封装user
        orderInfo.setUser(user);
        //4.返回订单信息
        return orderInfo;
    }
    

    5.3 Feign其他功能

    Feign运行自定义配置来覆盖默认配置,可以修改的配置如下:

    类型 作用 说明
    feign.LOGger.Level 修改日志级别 包含四种不同的级别:NONE、BASIC、HEADERS、FULL
    feign.codec.Decoder 响应结果的解析器 http远程调用的结果做解析,例如解析json字符串为java对象
    feign.codec.Encoder 请求参数编码 将请求参数编码,便于通过http请求发送
    feign. Contract 支持的注解格式 默认是SpringMVC的注解
    feign. Retryer 失败重试机制 请求失败的重试机制,默认是没有,不过会使用Ribbon的重试
    NONE:默认的,不显示任何日志
    BASIC:仅记录请求方法、URL、响应状态码以及执行时间
    HEADERS:除了BASIC中定义的信息以外,还有请求和响应的头信息
    FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据
    

    SpringBoot日志配置;

    5.3.1 Feign日志配置

    要想让Feign日志生效,得结合着SpringBoot的日志配置一起使用

    SpringBoot日志配置

    logging:
      level:
        # feign 日志以什么级别监控哪个接口
        com.itheima: debug
    

    配置Feign日志有两种方式:

    • 配置文件方式

      • 全局生效

        feign:
          client:
            config:
              default: #这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
                loggerLevel: FULL #日志级别
        
      • 局部生效

        feign:
          client:
            config:
              itheima-user: #指定服务
                loggerLevel: FULL #日志级别
        
    • 代码方式

      • 注册日志级别

        /**
         * 注册日志级别
         * @return
         */
        @Bean
        public Logger.Level feignLogLevel() {
            return Logger.Level.FULL;
        }
        
      • 全局生效

        #如果是全局配置,则把它放到@EnableFeignClients这个注解中
        @EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)
        
      • 局部生效

        #如果是局部配置,则把它放到@FeignClient这个注解中
        @FeignClient(value = "itheima-user",configuration = FeignClientConfiguration.class)
        

    5.3.2 Feign性能优化

    Feign底层的客户端实现:

    • URLConnection:默认实现,不支持连接池
    • apache HttpClient :支持连接池
    • OKHttp:支持连接池

    因此优化Feign的性能主要包括:

    • 使用连接池代替默认的URLConnection
    • 日志级别,最好用basic或none

    Feign切换Apache HttpClient步骤如下:

    1:引入依赖
    2:配置连接池
    

    1)引入依赖

    itheima-order中引入如下依赖:

    <!--httpClient依赖-->
    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-httpclient</artifactId>
    </dependency>
    

    2)配置连接池

    itheima-order的核心配置文件application.yml中添加如下配置:

    feign:
      client:
        config:
          default: #这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
            loggerLevel: BASIC #日志级别
          itheima-user: #指定服务
            loggerLevel: BASIC #日志级别
      httpclient:
        enabled: true #开启feign对HttpClient的支持
        max-connections: 200 #最大的连接数
        max-connections-per-route: 50 #每个路径的最大连接数
    

    5.3.3 Feign最佳实现

    方式一(继承):给消费者的FeignClient和提供者的controller定义统一的父接口作为标准。

    • 服务紧耦合
    • 父接口参数列表中的映射不会被继承

    72-第1章 SpringCloud

    方式二(抽取):将FeignClient抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用

    @H_777_1099@

    Feign最佳实现流程如上图所示:

    实现最佳实践方式二的步骤如下:
    1:创建itheima-api,然后引入feign的starter依赖 itheima-user依赖
    2:将itheima-order中编写的UserClient复制到itheima-api项目中
    3:在itheima-order中引入itheima-api的依赖
    4:重启测试
    

    1)引入依赖

    创建itheima-api,然后引入feign的starter依赖 itheima-user依赖

    <dependencies>
         <!--openfeign-->
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-openfeign</artifactId>
         </dependency>
    
         <!--httpClient依赖-->
         <dependency>
             <groupId>io.github.openfeign</groupId>
             <artifactId>feign-httpclient</artifactId>
         </dependency>
    
         <dependency>
             <groupId>com.itheima</groupId>
             <artifactId>itheima-pojo</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
    </dependencies>
    

    2)编写的UserClient

    将itheima-order中编写的UserClient复制到itheima-api项目中

    package com.itheima.client;
    
    import com.itheima.user.pojo.User;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    /**
     * order调用user服务(代替了 String url = "http://itheima-user/user/" + orderInfo.getUserId();)
     * 1.接口上使用@FeignClient(value="被调用服务名")
     * 2.定义被调用接口中的方法(基于被调用的controller编写)
     *  2.1 requestMapping中的路径必须是全路径(controller类上的+方法上的)
     *  2.2 使用PathVariable注解,必须取别名
     */
    @FeignClient(value = "itheima-user")
    public interface UserClient {
    
        /**
         * 调用用户微服中controller的方法
         */
        @GetMapping(value = "/user/{id}")
        public User one(@PathVariable(value = "id") Long id);
    }
    

    3)在itheima-order中引入itheima-api的依赖

    <!--引入feign-api-->
    <dependency>
        <groupId>com.itheima</groupId>
        <artifactId>itheima-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    

    4)当定义的FeignClient不在SpringBootApplication的扫描包范围时,这些FeignClient无法使用。

    有两种方式解决: 方式一:指定FeignClient所在包

    @EnableFeignClients(basePackages = "com.itheima.user.feign")

    方式二:指定FeignClient字节码

    @EnableFeignClients(clients = {UserClient.class})

    5.3.4. 总结

    • Feign的使用步骤

      • 引入依赖
      • 添加@EnableFeignClients注解
      • 编写FeignClient接口
      • 使用FeignClient中定义的方法代替RestTemplate
    • Feign的日志配置:

      • 方式一是配置文件,feign.client.config.xxx.loggerLevel
      • 如果xxx是default则代表全局
      • 如果xxx是服务名称,例如userservice则代表某服务
    • 方式二是java代码配置Logger.Level这个Bean

      • 如果在@EnableFeignClients注解声明则代表全局
      • 如果在@FeignClient注解中声明则代表某服务
    • Feign的优化

      • 日志级别尽量用basic
      • 使用HttpClient或OKHttp代替URLConnection
        • 引入feign-httpClient依赖
        • 配置文件开启httpClient功能,设置连接池参数
    • Feign的最佳实践:

      • 让controller和FeignClient继承同一接口
      • 将FeignClient、POJO、Feign的默认配置都定义到一个项目中,供所有消费者使用

    脚本宝典总结

    以上是脚本宝典为你收集整理的72-第1章 SpringCloud全部内容,希望文章能够帮你解决72-第1章 SpringCloud所遇到的问题。

    如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

    本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
    如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。