SpringCloud学习笔记(截图来自黑马程序员B站教学视频,不是打广告)

1. 远程调用

微服务就是拆分, 当拆分后某些数据在不同的服务里,此时用RestTemplate发送Http请求,实现远程调用。

  • tips:

2.服务治理,当我想开启多个服务去处理请求时,会遇到一些问题,比如说:a、b、c三个请求,端口号不一样,那我怎么去选择请求地址?类似的问题,此时就需要服务治理。

2.1 注册中心原理

2.2Nacos注册中心

调用服务的人需要做以下的事情,服务注册只需要做前两步,心跳等功能都包含在依赖里,直接就封装注册好了。

配合远程调用使用,解决远程调用时把服务地址写死的问题。

以下是加上服务发现改造的代码。

2.3OpenFeign

2.3.1 是什么?

2.3.2使用

这里是创建了一个接口类,给类上加了@FeignClient注解, value名称就是要调用的服务名称,接口类的方法编写如图所示, 类似Controller。 且在调用的时候类似Mapper,不需要写实现的方法,直接注入后调用方法就可以了。 里面封装了获取服务地址、参数、负载均衡等功能,所以之前调用服务的方法里RestTemplate和DiscoveryClient的代码都用不到了。 直接一行代码调用方法,搞定。

上面在使用时,底层是反射代理,每次都要去连接,这里再次优化。(这我没太听懂说实话,像是线程 jdbc吗?)

这时候又出现了别的问题, 难道每一个需要调用商品的服务都要去写对应的DTO和ItemClient接口吗?给出解决方案:

2.3.3 配置OpenFeign的日志级别, 建议平常不要开启(因为会输出很多信息,降低性能), 需要调试的时候再开启。

上面四个功能总结

3.网关

3.1什么是网关

网关就是网络的关口,负责请求的路由、转发、身份校验。 

有了网关以后,微服务的地址也不需要再暴露给前端,前端只需要知道网关的地址就可以了。

3.2 快速入门

步骤: 1. 创建新模块(网关模块gateway)2.引入网关依赖 3.编写启动类 4.配置路由规则

在 网关gateway微服务里 的 .yaml文件中配置路由

spring:
  cloud:
    gateway:
      routes:
        - id: item-service;
#          路由目标 lb的意思的是 负载均衡
          uri: lb://item-service
#          路径 只要符合这个路径就会路由到 item-service这个微服务里
          predicates:
#            当有很多的controller时,用,分隔配置多个
            - Path=/item/**, /search/**

3.3 路由属性

常见的路由过滤器,拿StripPrefix举例,在前端有时候发请求会以/api/items/list这种,那么就会去除/api这段前缀

举例

spring:
  cloud:
    gateway:
      routes:
        - id: item-service;
#          路由目标 lb的意思的是 负载均衡
          uri: lb://item-service
#          路径 只要符合这个路径就会路由到 item-service这个微服务里
          predicates:
#            当有很多的controller时,用,分隔配置多个
            - Path=/item/**, /search/**

          filters:
            # 添加了一段请求头 truth = Nothing is impossible
            - AddRequestHeader=truth, Nothing is impossible

如果不是只想在某一个微服务里配置过滤器, 可以这样写

spring:
  cloud:
    gateway:
      routes:
             xxxx
      
      default-filters:
             - AddRequestHeader=truth, xxxx

3.4 网关登录校验

三个问题:1. 如何实现登录校验? 2. 如何通过网关传递用户信息 3.微服务间的调用如何传递用户信息?

3.4.1  自定义过滤器

实现登录校验 的过滤器

@Component
@RequiredArgsConstructor //构造注入bean
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    //引入配置信息bean
    private final AuthProperties authProperties;
    //jwt工具
    private final JwtTool jwtTool;
    //路径匹配器
    private final AntPathMatcher antPathMathcer = new AntPathMatcher()

    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){
    //获取Servlet
    ServerHttpRequest request = exchange.getRequest();
    //判断是否需要做登录拦截
    if(isExclude(request.getPath().toString())){
        //放行
        return chain.filter(exchange)
        }
    //获取token
    String token = null;
    List<String> headers = request.getHeaders().get("authorization");
    //判断
    if(headers != null && !headers.isEmpty()){
        token = headers.get(0);
        }
    //解析token
    Long userId = null;
    try{
        userId = jwtTool.parseToken(token);
        }catch(UnauthorizedException e){
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return  response.setComplete();
         }

    //TODO 传递登录信息 
    System.out.println("userId:" + userId)
    //放行
    return chain.filter(exchange)
    }

    //判断路径是否为 不需要登陆权限的方法
    private boolean isExclude(String path){
    for (String pathPattern : authProperties.getExcludePaths()){
        if(antPathMathcer.match(pathPatter, path)){
            return true;
            }
        }
         retrun false;
    }




}

实现网关传递信息给微服务

完成第一件事:保存用户信息到请求头

完善上面最后两段代码


@Component
@RequiredArgsConstructor //构造注入bean
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    //引入配置信息bean
    private final AuthProperties authProperties;
    //jwt工具
    private final JwtTool jwtTool;
    //路径匹配器
    private final AntPathMatcher antPathMathcer = new AntPathMatcher()

    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){
    //获取Servlet
    ServerHttpRequest request = exchange.getRequest();
    //判断是否需要做登录拦截
    if(isExclude(request.getPath().toString())){
        //放行
        return chain.filter(exchange)
        }
    //获取token
    String token = null;
    List<String> headers = request.getHeaders().get("authorization");
    //判断
    if(headers != null && !headers.isEmpty()){
        token = headers.get(0);
        }
    //解析token
    Long userId = null;
    try{
        userId = jwtTool.parseToken(token);
        }catch(UnauthorizedException e){
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return  response.setComplete();
         }

   //传递用户信息
    String userInfo = userId.toString();
    //通过封装好的方法,把userInfo写入请求头,注意这里要和接受方统一请求头名称
    ServerWebExchange swe = exchange.mutate()
                .request(builder -> builder.header("user-info", userInfo))
                .build();

    //放行
    return chain.filter(swe)
    }

    //判断路径是否为 不需要登陆权限的方法
    private boolean isExclude(String path){
    for (String pathPattern : authProperties.getExcludePaths()){
        if(antPathMathcer.match(pathPatter, path)){
            return true;
            }
        }
         retrun false;
    }




}

完成第二件事:在微服务里添加拦截器, 获取用户信息保存到ThreadLocal中。

思考:要在每一个微服务中都添加拦截器,那么代码重复性过高。 所以把拦截器写在common模块中,微服务直接调用。

实现 : 1. 写完拦截器代码后,注册拦截器信息。但是包不同,如何让这个配置类生效? 

答: 利用自动装配的原理, 写入 spring.factories中。

2. 一开始所有微服务都生效,但是报错。 因为网关里是无法扫描SpringMVC的包的。

解决:

第三件事: 微服务之间互相调用,如何传递用户信息?

总结:登录功能解决

3.5配置管理

问题: 不同微服务的配置文件重复配置过多,维护成本高

解决: 配置管理服务, 让微服务去读取配置。

实现:

在Nacos中配置列表新建配置文件,不同的模块创建不同的配置文件。

注意:

步骤:

这样的话微服务里的 .yaml文件只需要去定义端口号、变量等很少的配置信息就可以了。

比如

3.5.1配置热更新

即修改文件中的配置信息时,微服务无需重启就可以生效。

4. 雪崩问题

4.1.服务保护方案 : 请求限流、线程隔离、服务熔断,统称服务降级。

请求限流:限制流量在服务可以处理的范围内

线程隔离: 控制业务可用的线程数量,将故障隔离到一定范围(类似船的各个船舱,A进水了,就隔离在A。)

4.2服务保护技术

Hystrix只支持2020之前版本的SpringCloud,Sentinel支持新版本的

4.2.1认识 Sentinel

(1)参考文档搭建图形化控制台

(2)系统整合 引入依赖

调用请求,查看控制台

最后一行:

请求限流设置

线程隔离 

Fallback

作用:出现异常时走Fallback的逻辑,不要去抛异常,这样对客户端的用户提示更加友好

设置熔断规则

扩展: 熔断规则的持久化,通过Nacos拉取配置文件完成。(了解一下)

5.分布式事务

5.1 概念

5.2 认识 Seata事务管理

5.3 部署TC服务

5.4XA模式        强一致性,因为都会锁住

5.5AT模式   最终一致 如果微服务1、2没问题都提交了,就可以进行别的操作了。但是如果3出问题了,那么会出现数据短暂不一致的情况。

1.需要在每一个微服务的数据库生成自己的快照表。

2.修改配置文件

  • 45
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值