【学习笔记】springcloud

教学视频地址:
B站图灵springcloud教学视频(主要的)
b站山硅谷springcloud教学视频

学习代码:
springcloud学习代码资源
其他框架资源
脚手架项目git地址

一、为服务架构理论知识

二、springcloud简介


三、springcloud技术栈

1、项目搭建

  • 创建springboot工程
    pom文件加上
<packaging>pom</packaging>
  • 根据版本对应关系加入springcloud-alibaba、springcloud等依赖
    版本对应
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.2.7.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
  • 子工程项目搭建
    创建maven工程(会自动继承父项目)

2、注册中心:Nacos

1、项目部署
  • 下载项目(github中)
    在这里插入图片描述
    根据版本对应关系下载对应的版本即可(文件保存位置不可有中文符号)
    在这里插入图片描述
  • 启动项目
    因为默认是集群模式,所以需要先修改为单机模式
    在这里插入图片描述
    对启动文件右键编辑,更改模式即可
    在这里插入图片描述
    也可以进行一些其他配置
    在这里插入图片描述
    用户名密码默认都是nacos
    在这里插入图片描述
2、nacosClient搭建
  • 在需要用到nacos的子项目中加入依赖
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
  • 配置
    在这里插入图片描述
  • 使用resttemplet调用即可
    在这里插入图片描述
    在这里插入图片描述
3、nacos基本概念
  • 保护阈值:健康实例占比小于保护阈值的时候将会调用非健康实例,以免雪崩
4、集群
  • 环境搭建(推荐使用nginx进行负载均衡)
    修改properties,配置mysql,运行官方给的sql文件
    在这里插入图片描述
    修改(新建)cluster.config,加入集群的ip和端口
    在这里插入图片描述
  • 理论知识
    两种集群方式
    在这里插入图片描述
    在这里插入图片描述
    负载均衡策略(loadblance实现负载均衡的方式略过)
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 使用
    消费方的resttemplet加上注解
    在这里插入图片描述
    修改负载均衡策略
    1、方法一:使用配置类
    在这里插入图片描述
    在这里插入图片描述
    2、使用配置文件
    在这里插入图片描述

3、服务调用:openfeign

用于代替之前resttemplet的调用方式

1、添加依赖
	<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
2、声明接口

在这里插入图片描述

3、启用注解

在这里插入图片描述

4、使用

在这里插入图片描述

配置项
  • 日志配置-配置类
    springboot默认的日志级别是info,feign的debug级别的日志就不会输出,所以将feign接口的日志级别改为debug带能看得到feign的日志输出
logging:
  level:
    com.example.demo.feign: debug

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 日志配置-配置文件
    在这里插入图片描述
  • 契约配置
    将feign的原生注解和mvc的注解对应,通常用于版本升级而而做出的代码规范
    在这里插入图片描述
  • 超时时间
    在这里插入图片描述
  • feign自定义拦截器
    配置方法一:
    在这里插入图片描述
    方法二:
    在这里插入图片描述
    实现类:
    在这里插入图片描述

4、配置中心:nacos

  • 新建配置文件
    在这里插入图片描述
    在这里插入图片描述
    DataId公式= ${spring.cloud.config.prefix}-${spring.profiles.active}.${spring.cloud.config.file-extension}
    spring.cloud.config.prefix:配置文件前缀
    spring.profiles.active:服务环境标识,dev、test、prod
    spring.cloud.config.file-extension:配置文件后缀,如yaml、properties等格式
    在这里插入图片描述
    *只有配置的与dataid对应的上才能获取得到nacos上的配置文件

  • 导入依赖,写配置文件

<dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

推荐使用bootstrap.yml全局配置文件
在这里插入图片描述

  • 在controller上添加,动态刷新注解:@RefreshScope

  • 其他配置
    通过dataid指定特定的配置文件(一般用于共享配置文件,shared-configs是自己取的名字可以有多个)
    在这里插入图片描述

  • 权限管理
    可新建角色,设置权限(会影响配置中心,待解决)

需要修改nacos中conf/application.properties配置文件:
改为true,默认false
在这里插入图片描述

5、流控:sentinel

流控是部署在服务提供者上面的
sentinel github官网
有两种使用方式:使用API,使用控制台
略过p43,p44,p45

1、整合springcloudalibaba的控制台

1、从sentinel github官网下载jar包
2、通过java -Dserver.port=8891 -Dsentinel.dashboard.auth.username=admin -Dsentinel.dashboard.auth.password=123 -jar sentinel-dashboard-1.8.1.jar命令运行jar包,账号密码默认都是sentinel,也可以指定端口账户密码
3、添加依赖、配置sentinel控制台地址

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>

在这里插入图片描述
访问接口之后就可以在sentinel上面显示出来了

2、流控规则
  • 流控处理:
    使用@SentinelResource(需要依赖,整合在cloud中了,对普通方法也可以流控,不单单是controller):
    1、注入bean:
    在这里插入图片描述
    2、在需要流控的接口加上注释(不成功可以尝试重启sentinel或项目本体)
    在这里插入图片描述
  • 流控方式:QPS,线程数
  • 全局流控处理
    想要让全局异常处理就不能加上这个SentinelResource注解
@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {

    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {

        //判断错误类型
        if (e instanceof FlowException) {

        } else if (e instanceof DegradeException) {

        } else if (e instanceof ParamFlowException) {

        } else if (e instanceof SystemBlockException) {

        } else if (e instanceof AuthorityException) {

        }

        //返回数据
        httpServletResponse.setStatus(500);
        httpServletResponse.setCharacterEncoding("utf-8");
        httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
        new ObjectMapper().writeValue(httpServletResponse.getWriter(),"全局处理---出现错误");
    }
}
  • 流控模式

1、直接模式:访问自己限流自己
2、关联模式:访问关联资源限流自己
3、链路模式:和直接模式一样,但是根据不同的入口资源进行流控(链路的入口资源好像只能限制在同一个项目内,并不可以跨项目)
在这里插入图片描述

  • 流控效果
    1、快速失败:直接丢弃多余请求,直接报错
    2、warm up:针对激增流量,会慢慢将求请求放进来,让系统的缓冲层进行预热,直至达到流控阈值,通过预热时长设置请求放进来的速度
    3、排队等待:针对脉冲流量,通过设置等待时间让超过阈值的的请求在空闲时间执行,充分利用空闲时间
3、熔断降级
  • 慢调用比例:
    在这里插入图片描述
  • 异常比例
    在这里插入图片描述
  • 异常数量
    在这里插入图片描述
  • 整合opoenfeign的熔断(错误处理,提供者出错)
    以下配置都是在消费端的
    1、添加配置
    在这里插入图片描述
    2、实现服务端接口,加上@Component
    在这里插入图片描述
    3、在服务接口注解中添加fallback类,即实现类
    在这里插入图片描述
    服务端出错后调用的就是消费端实现的方法了
4、热点流控

在这里插入图片描述

5、系统规则

针对当前系统的指标进行处理,用于造成压力的原因来自哪里的时候,可以作为一个兜底的方案
在这里插入图片描述

6、持久化

1、原始模式:啥也没有
2、拉模式:结合远吗进行扩展
3、推模式:将配置推送到远程配置中心

  • 导入依赖
    在这里插入图片描述
  • 在nacos中编写对应配置文件(默认是json格式,各个不同属性可以在文档找到,流控,熔断,热点)
    在这里插入图片描述
    官网配置属性参考
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 编写配置文件
    在这里插入图片描述
    更多属性可以参考(还有他的父类中的属性):
    在这里插入图片描述
7、sentinel的集群

待定
整合gateway,学完gateway再回来看p60

6、分布式事务组件:seata

seata官网
根据版本对照下载github的zip包:下载地址

1、服务端搭建
  • 搭建数据库(新版已经改为yml来配置,参照着文件里的模板来就可以)
    1、修改conf中的file.conf
    坑:mysql8.0以上还要修改
    1、驱动名:com.mysql.cj.jdbc.Driver
    2、在数据库连接后面加上:?characterEncoding=utf-8&serverTimezone=UTC
    在这里插入图片描述
    2、创建数据库,运行sql语句(新版在下载的文件中的script-server-db中有)
  • 整合nacos
    1、修改conf中的registry.conf:对应注册中心和配置中心
    在这里插入图片描述
    在这里插入图片描述

2、去gihub官网下载项目,在script中找到script\config-center\config.txt
修改(新版的在script中就有config-center)
坑:mysql8.0以上还要修改
1、驱动名:com.mysql.cj.jdbc.Driver
2、在数据库连接后面加上:?characterEncoding=utf-8&serverTimezone=UTC
项目地址
在这里插入图片描述
默认分组名也可以
在这里插入图片描述
3、运行script\config-center\nacos\nacos-config.sh(将config.txt同步到nacos)

也可以指定参数:
在这里插入图片描述
在这里插入图片描述

2、客户端搭建
  • 1、在有关事务的项目中添加依赖
    在这里插入图片描述
  • 2、在有关事务的项目数据库中新建undolog表
CREATE TABLE undo_log(
	id bigint(20) NOT NULL AUTO_INCREMENT,
	branch_id bigint(20) NOT NULL,
	xid varchar(100) NOT NULL,
	context varchar(128) NOT NULL,
	rollback_info longblob NOT NULL,
	log_status int(11) NOT NULL,
	log_created datetime NOT NULL,
	log_modified datetime NOT NULL,
	PRIMARY KEY (id),
	UNIQUE KEY ux_undo_log (xid,branch_id)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
  • 3、配置事务分组、注册中心和配置中心
    在这里插入图片描述
    在这里插入图片描述
  • 4、在需要分布式事务的方法上面加上@GlobalTransactional就可以了
3、各个模式的原理

不同的模式使用:seata不同模式的原理及实现
saga模式的使用(大概是实现StateMachineEngine状态机中的方法来使用的吧)

  • XA
    1、过程:两阶段提交(各个服务提交,全局提交)
    2、使用前提:需要数据库支持XA协议,即数据库自己就要拥有事务的开始、执行、提交或回滚的能力
    3、大致原理:一阶段时调用各个服务自己的事务,全部成功时再全局提交
    4、优缺点:一阶段时各个服务全程开启事务,性能低下,但拥有XA协议的强一致性
  • AT
    1、过程:两阶段提交
    2、使用前提:需要支持ACID的关系型数据库,不需要支持XA协议
    3、大致原理:需要在各个需要用到全局事务的表中增加一个undoLog表(AT模式下自己定义的回滚表,不是mysql的undoLog)
    4、优缺点:由于有了自己的undoLog,各个服务在执行完自己一阶段的任务后可以立马提交,利用全局锁读写分离,一致性相比XA较差,不需要等待其他服务,并发性能较高
  • TCC
    1、大致原理:完全不依赖数据库的事务实现,全部使用业务代码来处理事务的回滚,即实现执行、回滚、提交三个接口方法即可,可使用额外字段来判断事务隔离性(一般难以实现,几乎没有事务隔离)
    2、优缺点:实现繁琐,对业务代码入侵较大,无锁无事务隔离,但性能最好,适合业务简单,性能要求高的场景
  • SAGA
    1、大致原理:根据调用链路逐级补偿,需要使用状态机?和编写补偿方法
    2、优缺点:需要手动实现代码,无锁无隔离,适用于在一致性性要求不高、调用多方业务的分布式场景

7、网关:gateway

1、快速开始

作为网关,一般是放在一个单独的项目当中

  • 添加依赖
    在这里插入图片描述
  • 配置
    在这里插入图片描述
2、整合nacos
  • 添加依赖
    在这里插入图片描述
  • 配置
    在这里插入图片描述
    也可以让gateway根据nacos上的服务名自动匹配
    在这里插入图片描述
3、断言详解
  • 内置的断言工厂
    直接看文档就可以:gateway文档

  • 自定义断言工厂
    可以根据AbstractRoutePredicateFactory的实现类来写,内部断言工厂都实现了这个类
    在这里插入图片描述

@Component
public class MyRoutePredicateFactory
        extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {


    public MyRoutePredicateFactory() {
        super(MyRoutePredicateFactory.Config.class);
    }

    //从配置文件接受参数
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("myParam");
    }

    //将需要接收的参数声明在Config类中
    @Validated
    @Data
    @ToString
    public static class Config {
        private String myParam;
    }

    @Override
    public Predicate<ServerWebExchange> apply(MyRoutePredicateFactory.Config config) {
        return new GatewayPredicate() {
            //实现具体逻辑
            @Override
            public boolean test(ServerWebExchange exchange) {
                //这个参数只有等于520时才通过
                if (config.getMyParam().equals("520") ) {
                    return true;
                } else {
                    return false;
                }
            }

        };
    }


}

在这里插入图片描述

4、过滤器详解
  • 内置过滤器:gateway过滤器官方文档

  • 自定义过滤器
    与断言工厂类似,可以从AbstractGatewayFilterFactory进行模仿

@Component
public class MyFilterGatewayFilterFactory
        extends AbstractGatewayFilterFactory<MyFilterGatewayFilterFactory.Config> {

    public MyFilterGatewayFilterFactory() {
        super(MyFilterGatewayFilterFactory.Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("myPath");
    }


    @Override
    public GatewayFilter apply(MyFilterGatewayFilterFactory.Config config) {

        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                //具体实现逻辑
                //修改路径
                ServerHttpRequest req = exchange.getRequest();
                String newPath = req.getURI().getRawPath()+config.myPath;
                ServerHttpRequest request = req.mutate().path(newPath).build();
                //执行
                return chain.filter(exchange.mutate().request(request).build());
            }

        };
    }


    @Data
    @ToString
    public static class Config {
        //添加一层路径
        private String myPath;
    }
}

  • 全局过滤器
    不用配置,对所有路由生效
    1、内置全局过滤器
    在这里插入图片描述
    2、自定义全局过滤器
@Component
public class LogFlobalFilter implements GlobalFilter {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //具体逻辑:日志记录请求路径
        logger.info(exchange.getRequest().getURI().toString());

        //执行
        return chain.filter(exchange);
    }
}
5、请求日志、跨域处理

开启请求日志(要作为jvm参数):
在这里插入图片描述
跨域配置:
在这里插入图片描述

6、整合sentinel

可以根据网关、网关中的具体属性进行限流

  • 添加依赖
    在这里插入图片描述
  • 配置
    在这里插入图片描述
  • 使用
    根据路由id
    在这里插入图片描述
    根据路径分组
    在这里插入图片描述
    在这里插入图片描述
  • 流控处理
    在这里插入图片描述
7、集群

利用nginx对多个网关进行分发即可

8、链路追踪:skyWalking

1、服务端搭建
  • 修改UI前端端口号
    在这里插入图片描述
    在这里插入图片描述
  • 持久化
    1、修改配置文件(这里使用mysql的方式,但官方建议用elasticsearch)
    (这里的数据库连接错了,我的情况应该是远程数据库:jdbc:mysql://139.224.46.237:3307/seata?characterEncoding=utf-8&serverTimezone=UTC),然后在mysql中创建swtest就好,表会自动创建
    在这里插入图片描述
    2、加入jar包
    找到本地项目中的mysql jar包,放入aop-libs中
    在这里插入图片描述

在这里插入图片描述

2、使用

在每个服务的jvm参数中加上如下配置:
在这里插入图片描述
gateway网关默认不会加入链路追踪,需要将agent中的optional-plugins中gatwayjar包复制到plugins中(版本随便选一个,不行就换,本次选的是apm-spring-cloud-gateway-2.1.x-plugin-8.7.0)
在这里插入图片描述

以下是skyWalking的参数含义:
在这里插入图片描述

3、自定义链路追踪

1、添加依赖
在这里插入图片描述
2、使用
在这里插入图片描述

4、性能剖析

方法加上@trace点击分析之后就可以查看路径上是哪个部分占用的时间较多了
在这里插入图片描述

5、集成日志

暂时略过,等学了日志框架之后再回来看p92

6、告警
  • 默认告警规则
    在这里插入图片描述
  • 自定义钩子告警方法(也有一些内置的钩子方法)
    1、修改配置文件:
    在这里插入图片描述

2、在github的skyWalking项目中搜索alarmMessage这个类,查看对应版本中这个类的属性
在这里插入图片描述
在这里插入图片描述

@ToString
@Data
public class AlarmMessage {
    private int scopeId;
    private String scope;
    private String name;
    private String id0;
    private String id1;
    private String ruleName;
    private String alarmMessage;
//    private List<Tag> tags;
    private long startTime;
    private transient int period;
    private transient boolean onlyAsCondition;
}

3、实现具体接收告警的方法

@PostMapping("/receive")
    public void receive(@RequestBody List<AlarmMessage> alarmMessageList) {
        //接收到消息之后就可以实现具体逻辑了,如将消息通过微信通知开发人员等
        HashMap<String, String> map = new HashMap<>();

        for (AlarmMessage alarmMessage : alarmMessageList) {
            map.put("Name",alarmMessage.getName());
            map.put("AlarmMessage",alarmMessage.getAlarmMessage());
        }
        System.out.println(map.toString());
    }
7、集群
  • 修改aop配置文件
    将standalone改为下面对应的注册中心如nacos,然后把nacos的地址用户名密码填好就可以
    在这里插入图片描述
  • 修改UI配置文件
    在这里插入图片描述
    在这里插入图片描述

四、总结

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值