spring could微服务三大核心技术:Ribbon负载均衡&Nacos&网关Gateway

Ribbon负载均衡

①:负载均衡流程
②:负载均衡策略(了解即可)

Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个子接口都是一种规则

③: 饥饿加载

Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。 而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:

1.Ribbon负载均衡规则

规则接口是IRule

默认实现是ZoneAvoidanceRule,根据zone选择服务列表,然后轮询

2.负载均衡自定义方式

代码方式:配置灵活,但修改时需要重新打包

配置方式:直观,方便,无需重新打包发布但是无法做全局配置

3.饥饿加载

开启饥饿加载

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

Nacos注册中心

Nacos安装

在Nacos的GitHub页面,提供有下载链接,可以下载编译好的Nacos服务端或者源代码:

GitHub主页: github.com/alibaba/nac...

下载页: github.com/alibaba/nac...

windows版本使用 nacos-server-1.4.1.zip 包即可

解压

将这个包解压到任意非中文目录下

bin:启动脚本 conf:配置文件

端口配置

Nacos的默认端口是8848,如果你电脑上的其它进程占用了8848端口,请先尝试关闭该进程

如果无法关闭占用8848端口的进程,也可以进入nacos的conf目录,修改配置文件中的端口:

修改内容

进入bin目录 启动

windows命令

复制代码
startup.cmd -m standalone

在浏览器输入地址:http://127.0.0.1:8848/nacos即可

默认的账号和密码都是nacos,进入后:

服务注册到Nacos

  1. 在cloud-demo父工程中添加spring-cloud-alilbaba的管理依赖:
xml 复制代码
<dependency>
 <groupId>com.alibaba.cloud</groupId>
 <artifactId>spring-cloud-alibaba-dependencies</artifactId>
 <version>2.2.6.RELEASE</version>
 <type>pom</type>
 <scope>import</scope>
 </dependency>
  1. 注释掉order-service和user-service中原有的eureka依赖。

  2. 添加nacos的客户端依赖:

xml 复制代码
<!-- nacos客户端依赖 -->
 <dependency>
 <groupId>com.alibaba.cloud</groupId>
 <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
 </dependency>
  1. 修改user-service&order-service中的application.yml文件,注释eureka地址,添加nacos地址:
yaml 复制代码
spring:
 cloud:
  nacos:
   server-addr: localhost:8848 # nacos 服务端地址
Nacos服务分级存储模型
服务跨集群调用问题

服务调用尽可能选择本地集群的服务,跨集群调用延迟较高

本地集群不可访问时,再去访问其它集群

⑥:服务集群属性
yaml 复制代码
spring:
 cloud:
  nacos:
   server-addr: localhost:8848 # nacos 服务端地址
   discovery:
     cluster-name: HZ # 配置集群名称,也就是机房位置
根据集群负载均衡

修改user-service集群属性配置

ini 复制代码
-Dserver.port=端口号
ini 复制代码
 -Dspring.cloud.nacos.discovery.cluster-name=BJ 添加集群
根据集群负载均衡
  1. 修改order-service中的application.yml,设置集群为HZ:
yaml 复制代码
spring:
 cloud:  	
  nacos:
   server-addr: localhost:8848 # nacos 服务端地址
   discovery:
    cluster-name: HZ # 配置集群名称,也就是机房位置
  1. 然后在order-service中设置负载均衡的IRule为NacosRule,这个规则优先会寻找与自己同集群的服务:
yaml 复制代码
userservice:
 ribbon:
 NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则

NacosRule负载均衡策略

① 优先选择同集群服务实例列表

② 本地集群找不到提供者,才去其它集群寻找,并且 会报警告

③ 确定了可用实例列表后,再采用随机负载均衡挑选 实例

根据权重负载均衡

实例的权重控制

Nacos控制台可以设置实例的权重值,0~1之间

同集群内的多个实例,权重越高被访问的频率越高

权重设置为0则完全不会被访问

环境隔离 - namespace
  1. 在Nacos控制台可以创建namespace,用来隔离不同环境

  2. 然后填写一个新的命名空间信息:

  1. 保存后会在控制台看到这个命名空间的id:

4.修改order-service的application.yml,添加namespace:

yaml 复制代码
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/heima?useSSL=false
    username: root
    password: 123
    driver-class-name: com.mysql.jdbc.Driver
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: SH # 上海
        namespace: 492a7d5d-237b-46a1-a99a-fa8e98e4b0f9 # 命名空间,填ID  ##
  1. 重启order-service后,再来查看控制台:

Nacos环境隔离

namespace用来做环境隔离

每个namespace都有唯一id

不同namespace下的服务不可见

nacos注册中心细节分析
临时实例和非临时实例

服务注册到Nacos时,可以选择注册为临时或非临时实例,通过下面的配置来设置:

yaml 复制代码
spring:
 cloud:
  nacos:
   discovery:
    ephemeral: false # 设置为非临时实例
nacos与eureka的区别'

1.Nacos与eureka的共同点

都支持服务注册和服务拉取

都支持服务提供者心跳方式做健康检测

2.Nacos与Eureka的区别

Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式

临时实例心跳不正常会被剔除,非临时实例则不会被剔除

Nacos支持服务列表变更的消息推送模式,服务列表更新更及时

Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式 ; Eureka采用AP方式

Nacos配置管理

配置更改热更新

在Nacos中添加配置信息:

配置内容

ruby 复制代码
pattern:
    dateformat:yyyy年MM月dd日 HH:mm:ss

配置获取

1.引入Nacos的配置管理客户端依赖:

xml 复制代码
<!--nacos配置管理依赖-->
 <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
 </dependency>

2.在userservice中的resource目录添加一个bootstrap.yml文件,这个文件是引导文件,优先级高于 application.yml:

yaml 复制代码
spring:
  application:
    name: userservice # 服务名称
  profiles:
    active: dev #开发环境,这里是dev 
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
      config:
        file-extension: yaml # 文件后缀名

日志

yaml 复制代码
mybatis:
  type-aliases-package: cn.jinzhu.user.pojo
  configuration: 
    map-underscore-to-camel-case: true
logging:
  level:
    cn.jinzhu: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS

在user-service中将pattern.dateformat这个属性结合@Value注解注入到UserController中做测试:

less 复制代码
@RestController
 @RequestMapping("/user")
 public class UserController {
 // 注入nacos中的配置属性
    @Value("${pattern.dateformat}")
    private String dateformat;
 // 编写controller,通过日期格式化器来格式化现在时间并返回
    @GetMapping("now")
    public String now(){
        return LocalDate.now().format(
                DateTimeFormatter.ofPattern(dateformat, Locale.CHINA)
        );
    }
 // ... 略
}
配置自动刷新

方式一: 在@Value注入的变量所在类上添加注解@RefreshScope 在UserController层

方式二: 通过@ConfigurationProperties注入,自动刷新

Nacos中的配置文件变更后,微服务无需重启就可以感知。

要在UserController服务层注入写好的配置类

多环境配置共享

1.在Nacos中添加配置信息

2.在comfig层PatternProperties类里面添加成员变量

3.返回UserController服务层添加并注入返回对象

多种配置的优先级:

可读性差、参数复杂URL难以维护

网关Gateway

在SpringCloud中网关的实现包括两种:

gateway

zuul

Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响 应式编程的实现,具备更好的性能。

搭建网关服务

搭建网关服务的步骤:

  1. 创建新的module,引入SpringCloudGateway的依赖和nacos的服务发现依赖:
xml 复制代码
<!--网关依赖-->
 <dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-gateway</artifactId>
 </dependency>
 <!--nacos服务发现依赖-->
 <dependency>
 <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
 </dependency>

2.编写路由配置及nacos地址

yaml 复制代码
server:
 port: 10010 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求

网关作用流程

路由断言工厂Route Predicate Factory

关于断言工厂为什么不是过滤器

断言工厂是用来匹配请求的,比方说有很多微服务交由网关管理。

每个微服务都有不同的断言 工厂配置,有的微服务必须几点之前、有的微服务必须什么IP

当前端发来URL,请求的时候,URL会跟配置中比较

满足断言工厂配置条件的才能找到对应的服务并响应

路由过滤器 GatewayFilter

( 了解即可)

默认过滤器

例: 给所有进入userservice的请求添加一个请求头

yaml 复制代码
server:
  port: 10010 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          uri: lb://userservice
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
            - Before=2028-01-20T17:42:47.789-07:00[America/Denver]

        - id: order-service # 路由id,自定义,只要唯一即可
          uri: lb://orderservice
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/order/** # 这个是按照路径匹配,只要以/user/开头就符合要求
          filters: # 过滤器
          - AddRequestHeader=Truth, Good! # 添加请求头
全局过滤器GlobalFilter

全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。

过滤器执行顺序

1、 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前

2、 GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定

3、 路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增

4、 当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器>GlobalFilter的顺序执行

跨域问题处理

跨域:域名不一致就是跨域,主要包括:

域名不同:www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.co

域名相同,端口不同:localhost:8080和localhost8081

跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题

解决方案:CORS

csharp 复制代码
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些网站的跨域请求
              - "http://127.0.0.1:5500"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期
相关推荐
Rain的Java大神之路5 天前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
需要8265 天前
MySQL 索引 B+ 树与“查询为什么变慢了
java·spring boot·spring·spring cloud·tomcat
需要8265 天前
Arthas 一个命令排查线上问题
java·jvm·spring·spring cloud
苏渡苇6 天前
Spring Insight 里如何把 Span 画成瀑布时间线
后端·spring·spring cloud·springboot·监控·apm
叶总没有会6 天前
Nacos—注册中心
spring cloud·微服务
苏渡苇7 天前
Spring Insight 里如何把 Span 收成一条链路
spring boot·spring·spring cloud·系统监控·apm
叶总没有会7 天前
微服务--分布式基础
java·spring·spring cloud·微服务
孙启超8 天前
【AI开发之Rust】第 7 课:错误处理 —— panic、Result 与 `?`
人工智能·分布式·后端·爬虫·spring cloud·架构·rust
行百里er9 天前
Spring Insight 里如何把 Span 收成一条链路
spring boot·spring cloud·监控
砍材农夫9 天前
spring|spring web|拦截器、过滤器、aop
java·spring boot·spring·spring cloud