锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

SpringCould微服务

时间:2023-04-24 13:07:01 cp114差压变送器

SpringCould--微服务

互联网服务架构的演变 : 由简到繁
单体架构 -- 分布式架构 -- SOA架构 --微服务架构 -- service mesh
单体架构 : 在早期的互联网产品中,用户数量少,并发量小,单个应用程序可以满足需求. 总结 : 将所有功能集中在一个项目中,并将其部署为节点
优点 : 结构简单,成本低
缺点 : 耦合度高
分布式架构 : 根据业务需要拆分系统功能,每个业务模块称为服务
优点 : 降低服务之间的耦合度,有利于服务的升级和扩展
缺点 : 维护成本高,服务之间调用的复杂度增加

微服务架构 : 微服务是系统架构的设计风格,将原有的独立服务分为多个小服务,每个服务在自己的过程中独立运行,服务之间通过HTTP RESTFul API通信;每一个小服务都围绕着系统这个高耦合度的业务构建
优点 : 拆分粒度小,服务更独立,耦合度低
缺点 : 架构非常复杂,运维、监控和部署难度相对增加
微服务架构的特点 : 官网地址:https://spring.io/projects/spring-cloud
1.单一职责 : 微服务拆分粒度小,每个服务对应唯一的业务能力
2.自治 : 团队独立,技术独立,数据独立,独立部署和交付
3.面向服务 : 服务提供与语言和技术无关的统一标准接口
4.隔离性 : 隔离、容错、降级服务之间的调用,避免等级问题

SpringCould基于各种微服务功能组件的集成SpringBoot实现这些组件的自动组装

服务提供者 : 其他微服务在业务中调用的服务.(为其他微服务提供接口)
服务消费者 : 一次业务中调用其他微服务的服务.(调用其他微服务提供的接口)

远程调用微服务的方式Fegin :
1.RestTemplate是spring基于HTTP实现远程调用.(他同步执行HTTP请求,底层使用JDK原生的HttpURLConnection API
使用方式 : 1.注册RestTemplate 2.使用RestTemplate.getForObject(url,T.class)远程调用
缺点 : 代码可读性差,编程体验不统一,参数复杂URL难以维护
2.Feign :
1. 使用方式 :
1.引入依赖
2.在启动类上添加注释@EnableFeignClients开启Feign功能
3.定义远程调用接口,在接口中指定远程调用的【服务名字】、【方法签名】.注解 : @FeignClient(value = "被调用的服务名称")
4.注入接口,远程调用(接口)
2. 主要是基于SpringMVC注释声明远程调用的信息
1.服务名称 2.请求方式 3.请求路径 4.请求参数
3. Fegin自定义配置可以覆盖默认配置
类型 作用 说明
| ---------------------- | ----------------| ---------------------------------------------------
| **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除了定义的信息,还有文本和元数据的请求和响应
3.Fegin日志配置 -- 必须结合SpringBoot日志使用才能生效
feign:
client:
config:
default: #这里用default如果是全局配置default换成服务名称,配置微服务
loggerLevel: FULL #日级别
    4.Fegin性能优化
        它的底层客户端实现是 : 
            1.URLConnection : 默认的,不支持连接池
            2.Apache HttpClient : 支持连接池 (需要引入依赖)
                配置文件配置: httpclient:
                                enabled: true #开启feign对HttpClient的支持
                                max-connections: 200 #最大的连接数
                                max-connections-per-route: 50 #每个路径的最大连接数
            3.OKHttp : 支持连接池 (需要引入依赖)
        性能优化主要包括 :
            1.使用连接池代替默认的URLConnection
            2.日志级别,最好用basic或none
        实现方式 : 
            1.(继承)给消费者的FeignClient和提供者的controller定义统一的父接口作为标准。(注:父接口的参数列表中的映射不会被继承)
            2.(抽取-最佳实现方式 : 可以很好的管理远程调用的接口)将FeignClient抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用
                注: 当定义的FeignClient不在SpringBootApplication的扫描包范围时,这些FeignClient无法使用。
                     1.指定FeignClient所在包 (@EnableFeignClients(basePackages = "com.itheima.user.feign"))
                     2.指定FeignClient字节码 (@EnableFeignClients(clients = {UserClient.class}))

Eureka微服务自带的注册中心 :
    1.服务启动后,服务提供者向注册中心注册服务信息 : 服务名称以及IP端口
        1.1.服务提供者每个30秒向注册中心发送一次心跳
        1.2.注册中心在90秒内没有收到某个服务提供者节点的心跳,注册中心将会注销这个服务节点
    2.服务消费者根据服务名称向注册中心拉取服务信息
    3.如果有多个服务提供者,那么服务消费者是根据负载均衡算法从服务列表中获取一个服务
    Eureka搭建 : 
        服务注册
            1.引入Eureka依赖
            2.创建Eureka启动类,添加@EnableEurekaServer注解
        服务发现 :
            3.配置文件中配置Eureka信息
            4.微服务中引入EurekaClient依赖
            5.远程调用中开启负载均衡     注解 : @LoadBalanced//开启负载均衡
            6.用服务提供者的服务名称远程调用(由原来的ip:port改服务名(spring.application.name))

Nacos注册中心 : SpringCloudAlibaba推出的注册中心。 访问地址 : http://localhost:8848/nacos 控制台账号:nacos  密码:nacos
    实现方式 :
        1.引入依赖
        2.配置nacos
            spring:
                  cloud:
                    nacos:
                      server-addr: localhost:8848
      服务分级存储 :
          一个服务可以有多个实例 例 : 相同IP不同的端口
          我们可以将nacos看做一个机房,机房里有多个服务看做是一个集群,集群下有多个实例,微服务之间相互访问是尽可能的访问本地的,本地的速度比较快,当本地集群不可用时采访问其他集群
          配置文件 : 
              spring:
                  cloud:
                    nacos:
                      server-addr: localhost:8848
                      discovery:
                        cluster-name: SZ # 集群名称
      同集群优先负载均衡 :
          nacos提供了NacosRule实现优先从同集群中调用
          ribbon:
            NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
    权重配置 : 
           场景 :
               1.服务器设备性能差,部分实例所在的服务器性能好
               2.默认情况下NacosRule是同集群内随机挑选,不会考虑机器的性能问题
           因此Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高。
           操作 : 在nacos的控制台配置权重,权重为0,该实例永远不会被访问
       隔离环境 :
           Nacos提供了namespace来实现环境隔离功能。
           1.nacos中可以有多个namespace(环境隔离:test dev pro)
           2.namespace下有group(项目隔离 探花项目 头条项目)、service(实例隔离tanhua-server tanhua-service)等
           3.不同namespace之间相互隔离,例如不同namespace的服务互相不可见
           创建 :
               默认情况下,所有service、data、group都在同一个namespace,名为public(空间名称)
           配置文件 : 在上面 集群名称同级下加
               namespace: devnamespace # 命名空间,填空间ID
       Nacos与Eureka的区别 :
           Nacos的服务实例分为两种l类型:
             临时实例:如果实例宕机超过一定时间,会从服务列表剔除,默认的类型。
             非临时实例:如果实例宕机,不会从服务列表剔除,也可以叫永久实例。
         配置 :
             discovery:
                ephemeral: false # 设置为非临时实例
        Nacos与eureka的共同点 :
              都支持服务注册和服务拉取
              都支持服务提供者心跳方式做健康检测
        Nacos与Eureka的区别 :
              Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
              临时实例心跳不正常会被剔除,非临时实例则不会被剔除
              Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
              Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式(CAP理论:C一致性,A高可用,P分区容错性)
              Nacos使用的netty和服务进行连接,属于长连接。eureka使用定时发送和服务进行连接,属于短连接

nacos配置中心 :
    Nacos一方面可以将配置集中管理,另一方可以在配置变更时,及时通知微服务,实现配置的热更新。
    在nacos中添加配置文件 :
        配置管理--配置列表
        ID : 微服务名称-环境.配置文件后缀
        group : 分组
        配置格式 : 配置文件的类型
    注意:项目的核心配置,需要热更新的配置才有放到nacos管理的必要。基本不会变更的一些配置还是保存在微服务本地比较好

    微服务要拉取nacos中管理的配置,并且与本地的application.yml配置合并,才能完成项目启动。
    spring引入了一种新的配置文件:bootstrap.yaml文件,会在application.yml之前被读取
    流程 : 项目启动--加载bootstrap.yaml文件,获取nacos地址,配置文件的id--读取nacos配置--读取application.yml,加载本地配置,与nacos的配置进行合并--创建spring容器--加载bean
    需要引入nacos-config依赖
    配置 : 根据spring.cloud.nacos.server-addr获取nacos地址
        config:
            file-extension: yaml # 文件后缀名
                server-addr: localhost:8848 #nacos配置中心地址
            namespace: devnamespace #空间id
    修改nacos中的配置后,微服务中无需重启即可让配置生效,也就是配置热更新
    读取配置的方式 :
        1.控制层添加注解 @RefreshScope //刷新配置
        2.@ConfigurationProperties(prefix = "user") //配置读取注解

    配置共享 :
        微服务启动时,会去nacos读取多个配置文件
        [spring.application.name].yaml不包含环境,因此可以被多个环境共享。
    配置共享的优先级 :
        例 : itheima-user-dev.yaml(当前环境配置) > itheima-user.yaml(共享配置) > application.yml(本地配置)>bootstrap.yml(本地配置)

nacos集群搭建 : Nacos生产环境下一定要部署为集群状态
    Nacos默认数据存储在内嵌数据库Derby中,不属于生产可用的数据库。
    官方推荐的最佳实践是使用带有主从的高可用数据库集群,主从模式的高可用数据库可以参考**传智教育**的后续高手课程。

Ribbon : 负载均衡
    作用 : 有助于HTTP客户端行为,    基于负载均衡算法,自动帮助服务消费者请求
    负载均衡流程 : 服务消费者发送请求 -- 进入ribbon负载均衡(负载均衡拦截器拦截获取请求路径中的服务id) -- 去注册中心拉取服务 -- 返回服务列表 
    -- 算法 : 默认轮询的方式(选择某个服务) -- 根据服务的ip端口修改请求URL,调用微服务
    负载均衡算法策略 :
        RoundRobinRule : 简单轮询服务列表选择服务器
        AvailabilityFilteringRule : 对以下两种服务器进行忽略: 
            1.在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。
            2.并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,
            可以由客户端的..ActiveConnectionsLimit属性进行配置。
        WeightedResponseTimeRule : 为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。
        ZoneAvoidanceRule : 以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询。它是Ribbon默认的负载均衡规则。
        BestAvailableRule : 忽略哪些短路的服务器,并选择并发数较低的服务器。
        RandomRule : 随机选择一个可用的服务器
        RetryRule : 重试机制的选择逻辑
    负载均衡使用方式 :
        1.启动类中添加负载均衡算法(注入Bean方式) -- 可以做到全局配置,如需修改需要项目重新打包
        2.配置文件中指定某个服务只有指定的负载均衡算法 -- 无法做到全局配置,但修改方便,无需重新打包
    Ribbon默认采用的是懒加载方式,也就是第一次访问的时候才会去创建LoadBalanceClient,请求的时间很长;饥饿加载会在项目启动时就会创建,降低了第一次请求时间,所以我们需要在配置文件中开启ribbon的饥饿加载

微服务网关gateway : 为微服务提供简单有效且统一的API路由管理方式(掌握 : 路由过滤器,全局过滤器,跨域问题)
    gateway是基于Spring5.0,SpringBoot2.0实现的属于响应式编程事件流技术开发的网关,具有很好的性能
    核心功能 :
        1.权限控制 : 网关是作为微服务的入口,所以我们需要校验用户是否有请求资格,如果没有则进行拦截
        2.请求路由 : 网关不出来任何业务,但一切的请求都必须经过网关.他会根据负载均衡的策略将请求路由到微服务
        3.限流 : 当请求流量过高时,在网关中按照下流的微服务所能够承受的速度放行请求,避免服务的压力过大
        4.还能解决跨域问题
        5.所有请求的统一入口
        6.请求和响应处理
    配置文件相关配置 :
    spring:
        cloud:
            gateway:
                  routes: # 网关路由配置
                    - id: user-service # 路由id,自定义,只要唯一即可
                      # uri: http://127.0.0.1:18081 # 路由的目标地址 http就是固定地址
                          uri: lb://itheima-user # 路由的目标地址 lb就是负载均衡,后面跟服务名称
                          filters: # 过滤器
                            - AddRequestHeader=Heima,szheima119 nb! # 添加请求头
                              predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
                                - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
    断言工厂 : 配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件
        |      名称     |           说明            |                             示例                           |
        | ---------- |------------------------------|------------------------------------------------------------|
        | After      | 是某个时间点后的请求           | -  After=2037-01-20T17:42:47.789-07:00[America/Denver]       |
        | Before     | 是某个时间点之前的请求         | -  Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]       |
        | Between    | 是某两个时间点之前的请求       | -  Between=2037-01-20T17:42:47.789-07:00[America/Denver],  2037-01-21T17:42:47.789-07:00[America/Denver] |
        | Cookie     | 请求必须包含某些cookie        | - Cookie=chocolate, ch.p                                     |
        | Header     | 请求必须包含某些header        | - Header=X-Request-Id, \d+                                   |
        | Host       | 请求必须是访问某个host(域名) | -  Host=**.somehost.org,**.anotherhost.org                   |
        | Method     | 请求方式必须是指定方式        | - Method=GET,POST                                            |
        | Path       | 请求路径必须符合指定规则      | - Path=/red/{segment},/blue/**                               |
        | Query      | 请求参数必须包含指定参数      | - Query=name, Jack或者-  Query=name                          |
        | RemoteAddr | 请求者的ip必须是指定范围      | - RemoteAddr=192.168.1.1/24                                  |
        | Weight     | 权重处理                     |                                                              |
    过滤器工厂 :
        GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理
        spring提供了31种不同的过滤器工厂,主要常用的有 :
        |        名称          |            说明            |
        | -------------------- | ---------------------------|
        | AddRequestHeader     | 给当前请求添加一个请求头     |
        | RemoveRequestHeader  | 移除请求中的一个请求头       |
        | AddResponseHeader    | 给响应结果中添加一个响应头   |
        | RemoveResponseHeader | 从响应结果中移除有一个响应头 |
        | RequestRateLimiter   | 限制请求的流量              |
    网关过滤器的作用 :
        1.对路由请求或响应做加工处理
        2.配置在路由下的过滤器只对当前路由的请求生效
        3.default-filters 对所有路由的请求都生效
    全局过滤器的作用 :
        也是处理一切进入网关的请求和微服务的响应
        实现方式 : 实现GlobalFilter接口即可
        在filter中编写自定义逻辑,可以实现下列功能:
            1.登录状态判断
            2.权限校验
            3.请求限流等
    过滤器的执行顺序 :
        请求进入网关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter
        请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器
        排序的规则是什么呢?
            1.每一个过滤器都必须指定一个int类型的值,值越小,优先级越高,执行顺序越靠前。
            2.GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定
            2.路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增。
            2.当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行。
        源码 : 
            org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters()方法是先加载defaultFilters,然后再加载某个route的filters,然后合并。
            org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()方法会加载全局过滤器,与前面的过滤器合并后根据order排序,组织过滤器链

跨域问题 :
    域名不一致就是跨域
    例 : 
        域名不同 : www.taobao.com 和 www.taobao.org
        域名相同,端口不同 : localhost:8080和localhost8081
    跨域问题指 : 浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题
    解决方式 : 配置文件配置
        spring:
              cloud:
                gateway:
                  # 。。。
                  globalcors: # 全局的跨域处理
                    add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
                    corsConfigurations:
                      '[/**]':
                        allowedOrigins: # 允许所有跨域请求 
                          - "*"
                        allowedMethods: # 允许的跨域ajax的请求方式
                          - "GET"
                          - "POST"
                          - "DELETE"
                          - "PUT"
                          - "OPTIONS"
                        allowedHeaders: "*" # 允许在请求中携带的头信息
                        allowCredentials: true # 是否允许携带cookie
                      maxAge: 360000 # 这次跨域检测的有效期

微服务雪崩问题及解决方案 : 微服务之间相互调用,因为调用链中的一个服务故障,引起整个链路都无法访问的情况。
    微服务中,服务之间调用是错终复杂的,一个微服务往往依赖多个其他微服务,如果有一个服务发生了故障那么就会导致整个微服务发生瘫痪
    详解 : 
        1.如果服务提供者I发生了故障,当前的应用的部分业务因为依赖于服务I,因此也会被阻塞。此时,其它不依赖于服务I的业务似乎不受影响。
        2.但是,依赖服务I的业务请求被阻塞,用户不会得到响应,则tomcat的这个线程不会释放,于是越来越多的用户请求到来,越来越多的线程会阻塞
        3.服务器支持的线程和并发数有限,请求一直阻塞,会导致服务器资源耗尽,从而导致所有其它服务都不可用,那么当前服务也就不可用了。
        4.那么,依赖于当前服务的其它服务随着时间的推移,最终也都会变的不可用,形成级联失败,雪崩就发生了
    雪崩处理方式 :
        1.超时处理 : 设定超时时间,请求超过一定的时间没有响应就会返回错误信息,不会进入无休止的等待
        2.仓壁模式(线程池隔离) : 这个方式来源于船舱设计,限定每个业务使用的线程数避免耗尽整个tomcat资源,因此叫线程池隔离
        3.断路器 : 由断路器去统计业务执行发生的异常比例,如果超出了阈值就会熔断该业务,拦截访问该业务的一切请求
            达到阈值后默认进入熔断,五秒内拦截一切请求,五秒后试着放行一个请求,如果成功访问了,则断路器进入关闭状态,整个过程是循环的
        4.限流(流量控制) : 限制业务访问的QPS阈值(每秒处理请求的数量),避免服务因流量突增而发送故障
        超时处理、线程隔离、降级熔断是在部分服务故障时,将故障控制在一定范围,避免雪崩。是一种补救措施。

服务保护技术对比 (Sentinel : 访问http://localhost:8090页面 账号和密码,默认都是:sentinel):
    Netfix Hystrix 断路器 : 
    Resilience4J :
    Sentinel 哨兵机制(常用) : Sentinel是阿里巴巴开源的一款微服务流量控制组件。官网地址:https://sentinelguard.io/zh-cn/index.html
        丰富的应用场景 : (可以承受阿里巴巴10年来双十一大促流量的核心场景),消息削峰填谷,集群流量控制,实时熔断下游不可用的应用等
        完备的实时监控 : Sentinel可以提供实时的监控功能,可以在控制台中看到接入应用的单台机器秒级数据,甚至500台以下规模集群的汇总运行情况
        广泛的开源生态 : Sentinel 提供开箱即用的与其它开源框架/库的整合模块,只需要引入相应的依赖并进行简单的配置即可快速地接入Sentinel。
        完善的SPI扩展点 : Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel控制台 : 相关配置可查询SpringCould第三天资料
    流控、熔断等都是针对簇点链路中的资源来设置的
    流控 : 流量控制        降级 : 熔断降级        热点 : 热点参数限流,属于限流的一种            授权 : 请求的权限控制
    配置后可以利用jmeter测试
    流控模式 : 
        在添加限流规则时,点击高级选项,可以选择三种流控模式 :
            直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式
            关联:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流
                语法说明:当/write资源访问量触发阈值时,就会对/read资源限流,避免影响/write资源。
                使用场景:比如用户支付时需要修改订单状态,同时用户要查询订单。查询和修改操作会争抢数据库,产生竞争。业务需求是优先支付和更新订单的业务,因此当修改订单业务触发阈值时,需要对查询订单业务限流。
                满足该条件可以使用关联 :
                    1.两个有竞争关系的资源
                    2.一个优先级高,一个优先级低
            链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流
    流控规则 :
        对那个接口限流,就在后面点击流控进行配置

    链路模式 : 
        只针对指定链路访问到本资源的请求做统计,判断是否超过阈值

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章