1. 概念

    1.1 了解什么是微服务
    微服务概念
    微服务(Microservices)是一种架构风格,一个大型复杂的项目,可以由多个微服务组成。项目中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注完成自己的业务。

    架构特点
    每个服务都有单一的业务职责
    每个服务都要相对”独立”
    每个服务都要对外暴露Rest风格服务接口API
    每个服务都可以是一个独立的开发团队
    每个服务都可以是不同的技术栈
    每个服务都访问各自的数据库
    每个服务都可以单独部署
    服务间调用方式
    RPC
    并发能力强
    代表框架: dubbo
    HTTP
    更轻量,更灵活
    代表框架: HttpClient、UrlConnection、OkClient
    Spring提供了整合: RestTemplate

    1.2 SpringCloud的概念和基础架构
    Spring Cloud概述 微服务架构一站式解决方案
    版本,以伦敦地铁站命名规则,springboot 2.3.x,Hoxton
    核心架构
    服务注册中心,eureka、nacos
    负载均衡,ribbon
    熔断器,hystrix、sentinel
    服务调用,feign
    API网关,gateway
    配置中心,nacos

    1. 核心组件

    2.1 eureka注册中心
    基础架构,eureka-server,eureka-client(提供者,消费者)

    微服务如何得知提供者地址?
    提供者启动,必须立即注册自己的信息到eureka
    eureka会保存服务名称及实例ip和端口的映射关系
    消费者去eureka根据服务名称拉取服务实例列表

    消费者如何在多个服务中选择一个?
    利用组件做负载均衡,挑选一个,Ribbon组件

    如何感知服务故障?
    提供者会与eureka维持一个心跳,默认30秒一次
    超时未心跳,就认为服务宕机,就会被剔除

    搭建Eurekaserver
    1)引入eureka-server依赖
    2)加注解,@EnableEurekaServer
    3)编写配置,eureka地址、服务名称

    服务注册
    1)引入eureka-client依赖
    2)编写配置,eureka地址、服务名称

    服务发现
    1)引入eureka-client依赖
    2)编写配置,eureka地址、服务名称作为Key
    3)给RestTemplate加@LoadBalanced注解
    4)http请求时,用服务名称代替ip和端口

    2.2 ribbon
    负载均衡的原理
    1)请求被LoadBalancerInterceptor拦截
    2)获取uri中的host,也就是服务名称
    3)交给RibbonLoadBalanceClient的对象,根据服务名称获取服务列表,保存到 DynamicServerListLoadBalancer
    4)交给IRule,利用负载均衡规则选择一各实例
    5)利用真实实例的ip和端口替换url的服务名称,发起请求。

    IRule,默认的实现是ZoneAvoidanceRule,是轮询机制。

    负载均衡策略
    ZoneAvoidanceRule(默认)。
    轮询,RoundRobinRule。
    随机,RandomRule。
    重试机制,RetryRule。
    AvailabilityFilteringRule。
    WeightedResponseTimeRule。
    BestAvailableRule。

    饥饿加载
    默认是懒加载,第一次请求时才去拉取服务列表
    配置ribbon.egar-load.enable=true开启饥饿加载
    ribbon.egar-load.clients=userservice,指定服务名称
    2.3 nacos注册中心
    使用:搭建nacos
    下载
    解压
    运行,startup.cmd -m standalone

    服务注册
    1)引入nacos-discovery依赖
    2)编写配置,nacos地址、服务名称

    服务发现
    1)引入nacos-discovery依赖
    2)编写配置,nacos地址、服务名称
    3)给RestTemplate加@LoadBalanced注解
    4)http请求时,用服务名称代替ip和端口

    服务分级管理模型
    服务service,例如userservice
    集群cluster,这个服务部署在不同的机房,每个机房是一个cluster
    实例,一个服务启动多个
    NacosRule,路由时就近原则(优先从本集群负载均衡本集群没有,再去访问其它集群本集群内部采用随机负载均衡)

    权重
    值的范围是0~1,权重越大,被访问的频率越高
    作用:
    针对不同性能的服务器,分配不同的权重
    把权重置为0,服务就不会被访问,无缝升级切换

    namespace
    作用:环境隔离,不同开发环境或者多租户隔离

    nacos和eureka的区别和联系
    联系
    注册发现的整体流程一样,都实现SpringCloudCommon的接口
    都基于心跳机制监测提供者的整体
    都可以采用服务拉取来获取实例列表

    区别
    nacos针对永久实例是采用主动访问机制,临时实例才是心跳机制
    nacos消费者可以定时拉取服务;nacos还会在服务变更时主动推送服务列表
    nacos可以是CP,也可以是AP,默认是AP
    eureka是AP模式,可用性优先
    2.4 nacos配置管理
    统一配置管理
    在nacos添加配置
    dataID,配置文件名称:服务名-环境.后缀名
    group,分组,默认
    类型,yaml,properties
    内容,不是服务的所有配置,而是自定义的,经常变动的配置

    配置热更新
    微服务整合nacos配置
    1)引入nacos-config依赖
    2)配置bootstrap.yaml,nacos地址,dataID(spring.application.namespring.profiles.activefile.extenssion)
    基于@Value
    利用@Value注入属性
    在@Value注解所在类添加@RefreshScope注解
    基于@ConfigurationProperties
    默认就是热更新

    配置共享
    nacos默认读取两个文件
    服务名-环境.后缀名
    服务名.后缀名,多环境共享的
    优先级
    环境独享的配置 > 多环境共享的 > 服务本地的

    nacos集群
    准备mysql,准备数据库表
    部署多台nacos实例,配置访问mysql
    nginx反向代理
    2.5 Feign远程调用
    Feign基本用法
    1)引入openFeign依赖
    2)在启动类加@EnableFeignClients注解
    3)编写客户端接口(@FeignClient(“uservice”)
    public interface UserClient{
    @GetMapping(“/user/{id}”)
    User findById(@PathVariable(“id”) Long id)
    })

    自定义配置
    自定义日志配置
    Logger.Level的四种级别
    NONE
    BASIC
    HEADERS
    FULL
    yaml
    全局( feign:
    client:
    config:
    default: # 针对某个微服务的配置
    loggerLevel: FULL # 日志级别
    局部( feign:
    client:
    config:
    userservice: # 针对某个微服务的配置
    loggerLevel: FULL # 日志级别 )
    基于bean
    定义bean(public class DefaultFeignConfiguration {
    @Bean
    public Logger.Level feignLogLevel(){
    return Logger.Level.BASIC; // 日志级别为BASIC
    }})
    全局
    把配置声明到@EnableFeignClients上
    局部
    把配置声明到@FeignClient上

    性能优化
    日志,最好basic、none
    使用ApacheHttpClient代替默认的URLConnection
    1)引依赖
    2)加配置

    最佳实践
    继承
    让提供者的Controller和Feign的客户端都继承统一接口,统一API规范
    缺点:
    紧耦合
    SpringMVC的注解无法继承,定义Controller时还要定义
    抽取
    将Feign客户端、实体类、默认配置都抽取到一个项目模块中
    其它服务依赖该模块即可
    2.6 Gateway网关
    网关的作用
    请求路由、负载均衡
    身份认证、权限校验
    请求限流

    快速入门,基本用法
    1)创建项目,引入依赖
    gateway依赖
    nacos-discovery依赖
    2)配置
    基本配置,nacos地址、服务名
    路由规则
    id,路由的唯一标示
    uri,路由的目的地:lb://userserivce
    predicates,断言,路由的匹配条件,符合了才做路由
    filters,可选的
    路由过滤器 GatewayFilterFactory
    局部路由生效的
    在某个路由下配置,filters
    所有路由生效的
    default-filters

    全局过滤器 GlobalFilter
    作用于GatewayFilter一样
    GlobalFilter可以自定义业务逻辑
    如何自定义GlobalFilter
    1)实现GlobalFilter接口
    2)实现Ordered接口或者加@Order注解
    3)编写过滤逻辑
    WebHandlerExchange
    封装了Request、Response
    GatewayFilterChain
    过滤器链,放行并委托给下一个过滤器
    如何拦截
    response.setStatsuCode()
    response.setComplete()

    过滤器执行顺序
    order值越小,执行优先级越高
    order值一样,default-filters > 路由filters > GlobalFilter

    网关限流
    限流作用
    在高并发时,网关可以限制请求流量来保证微服务安全
    限流实现
    基于算法:令牌桶算法
    具体实现: Redis + Gateway限流过滤器