# Z21微服务学习 **Repository Path**: lkl321/z21-microservice-learning ## Basic Information - **Project Name**: Z21微服务学习 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2024-11-10 - **Last Updated**: 2024-12-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 微服务 ## 开发小技巧 ### Todo的使用 https://blog.csdn.net/qq_43102730/article/details/124936687 ### 元数据维护第三方 https://gitee.com/MARTIN-88/erd-online#https://gitee.com/MARTIN-88/erd-apis ## 什么是微服务 微服务并不是单一的技术或框架,而是一系列**微服务框架**和**解决方案**的有序集合。SpringCloud可以通俗的解释为微服务的一站式**解决方案**,利用SpringBoot的开发便利性,为开发人员提供了一套简单易懂,容易部署的系统开发工具包。 ## SpringCloud Alibaba SpringCloud Alibaba是阿里巴巴提供的一套微服务开发一站式**解决方案**,它集成了阿里巴巴中间件与SpringCloud深度融合。 SpringCloud Alibaba指在为中国市场及全球用户提供微服务开发与治理的能力,通过集成阿里巴巴开源的多个组件如: 1. Nacos(服务发现与配置管理) 提供服务发现和服务健康检查功能,允许服务实例在Nacos Server注册和注销,从而实现服务间自动发现与**负载均衡** 2. Sentinel(流量控制与熔断降级) 强大的流量控制组件,用于实现微服务的流量控制与防护,提供秒杀、大促等场景下的流量控制能力,避免服务因流量突增而崩溃。 支持熔断降级机制,当依赖的服务不可用或相应时间过长,能够快速失败并返回友好提示、保证整体服务的稳定和可用性。 3. Seata(分布式事务解决方案) 高性能、易于使用的分布式事务解决方案,支持XA、TCC、SAGA等事务模式,能够确保在分布式系统中数据一致性。 4. Dubbo(服务治理框架) 高性能、透明化的**RPC服务调用框架**,支持服务注册、**负载均衡**、服务监控等服务治理功能。 5. RocketMQ(消息队列) 5. higress(网关) 低延迟、高吞吐量的消息中间件,适用于大规模分布式系统中的消息传输。支持多种消息模式,点对点、发布/订阅,并且有高可用、可扩展的特性。 形成了一个功能全面的微服务生态体系,这些组件(框架)扮演了关键角色,涵盖了**服务发现**、**配置管理**、**流量控制**、**熔断降级**、**分布式事务处理**、**服务治理**及**消息队列**等多个方面。 ## 假定一个项目 需求:北京有个老板(陶建国)投资1亿,做短视频平台带一个直播带货的平台。 项目名:蕉点短视频 ### 需求调研阶段 #### 产品经理: 何苗(女,年龄31,1米6,云南人,能力中等) 与客户或甲方,通过聊天,问卷调查,观察等方式获取到的需求,如下: ![蕉点短视频](微服务.assets/蕉点短视频.jpg) 对功能优先级进行排序,哪些是必须实现的,哪些是可选的,对影响后续开发的功能需要优先开发。 ###### **文档一《需求调研报告》** ##### 需求分析 对收集的需求进行整理、分类、优先级排序 ![需求分析](../需求分析.jpg) ###### 文档二《需求规格说明书》(SRS) 描述项目的功能需求,和非功能需求(性能、安全、可用性和约束性政策) 此处省略...........两个月.... #### 项目经理: 齐帅(男,33岁,180,北京人) ### 系统设计阶段 ###### 文档三《概要设计说明书》 系统整体架构,技术选型(张工程师),模块划分,接口设计。 ###### 文档四《详细设计说明书》 数据结构,算法选择, 苏鑫(女、26、165、成都人) 用户界面设计(UI设计) #### DBA: 周瑞(男,30,170,成都人) ###### 文档五《数据库设计文档》 数据库结构》表结构》字段定义》关系模型 ---------------------此处省略1个月----------------------------- ### 开发准备阶段 #### 架构师: 张立东(男,35,180,台湾人) ![img](https://bkimg.cdn.bcebos.com/pic/d53f8794a4c27d1e78b2103711d5ad6edcc438a8?x-bce-process=image/format,f_auto/quality,Q_70/resize,m_lfit,limit_1,w_536) 环境搭建 开发环境,开发工具,服务器,数据库等。 代码规范制定:编码规范,版本控制规范,代码质量规范,团队协作等 齐帅(项目经理) 任务分配-长期工作 张工+齐工写以下文档: ##### 文档六《开发计划》 ##### 文档七《编码规范》 编码风格,命名规范,注释要求等 ### 测试阶段 1. 编码测试阶段(单元测试) 2. 集成测试(将各个模块,各个服务放在一起,检查接口是否正确,数据传递是否有误) 3. 系统测试(全面测试,包括功能测试,性能测试,安全测试) 4. 回归测试(对改了的bug进行二次测试) 5. 上线测试(用户验收测试,压力测试)在生产环境进行测试,邀请用户进行测试 #### 计划 ##### 文档八《测试计划》 测试的内容,进度,条件,人员等 测试用例 #### 报告 ##### 文档九《测试报告》 测试数据,测试过程,测试结果分析,测试结论意见。 ### 维护阶段 -------------------和开发一起-----------------5年后------------------------- ### 交付阶段 #### 文档十《用户操作手册》 软件描述,如何使用这个软件 #### 文档十一《帮助文档》 可能遇到的问题以及解决方案 #### 文档十二《验收报告》 收工 ----------------------------------------------------五年零六个月----------------------------------------------------------- ## 开发项目 **语言(后):** **Java** Python Go C++ C# **语言(前):** **Vue3** React Angular **框架:** **SpringBoot** SpringCloud(体系) **SpringCloud Alibaba(体系)** **SSM** SSH **数据库(关系型):** **Mysql** Sqlserver Oracle **数据库(非关系型):** **Redis** Mongodb Memcache ## Nacos(服务发现与配置管理) https://nacos.io/ ![image-20240912210933734](微服务.assets/image-20240912210933734.png) 默认是集群模式启动,需要单机启动 ``` startup.cmd -m standalone ``` ![image-20240914145841870](微服务.assets/image-20240914145841870.png) 需要配置JAVA_HOME环境变量 ![image-20240914150305835](微服务.assets/image-20240914150305835.png) ![image-20240914152046263](微服务.assets/image-20240914152046263.png) ### Nacos数据库配置 ![image-20241014151648694](README.assets/image-20241014151648694.png) 在nacos的conf中,有三个sql文件分别作用是 1、mysql-schema.sql 包含了创建Nacos所需的表结构,用数据库来管理nacos的配置信息。 2、1.4.0-ipv6_support-update 用于增强nacos支持ipv6 3、derby-schema.sql Java编写的嵌入式数据库管理系统 ### 使用教程 1、进入数据库 ``` mysql -u root -p ``` 2、创库和选择库的操作 ``` create database jiaodian_nacos; use jiaodian_nacos; ``` 3、导入mysql-schema.sql文件 执行这个sql语句 ``` source C:/Users/Administrator/Desktop/nacos/conf/mysql-schema.sql; ``` ![image-20241014152625166](README.assets/image-20241014152625166.png) 4、修改nacos的配置文件(配置数据库地址和数据库账号密码) ![image-20241014152924236](README.assets/image-20241014152924236.png) 创建配置文件 ![image-20241014153544627](README.assets/image-20241014153544627.png) 验证关联是否成功 ![image-20241014153709197](README.assets/image-20241014153709197.png) 如果有内容就证明同步成功 如何备份数据库? ``` mysqldump -u root -p123456 jiaodian_nacos > C:\jiaodian_nacos_1014.sql ``` ## 创建工程 1. 创建一个空白springboot工程 2. File Encodings换成Utf-8 3. 把平时不用的文件隐藏 ![image-20240914162557129](微服务.assets/image-20240914162557129.png) 4.安装插件方便转配置文件 ![image-20240914170716912](微服务.assets/image-20240914170716912.png) 5.开启nacos的鉴权 ``` nacos.core.auth.enabled=true ``` ## 消费者和服务提供者 在微服务中,服务提供者和消费者书两个**核心概念**,描述不同服务间的关系和角色 ### 服务提供者(Service Provider) 是指暴露功能或数据给其他服务调用的服务。 ### 服务消费者(Servicee Consumer) 是指需要调用其他服务完成自身业务逻辑的服务。 举例: 请问我有两个服务 **库存服务** 和 **订单服务** 谁是消费者谁是提供者? 库存服务(服务提供者):检查库存和更新库存的接口 订单服务(服务消费者):在创建订单之前需要验证是否有足够的库存 **先启动提供者才能启动消费者** ## 微服务框架学习 ### Feign框架 是一个声明式Web服务客户端,使得更容易编写HTTP请求,可以用作服务调用,简化HTTP客户端开发。 ### RPC是什么 RPC(Romote Procedure Call)是一种协议,远程过程调用。PRC的核心的**一个计算机程序**通过网络调用**另一个计算机的程序中的子程序**,并获取返回值,称为远程过程调用 ### Dubbo框架 Dubbo是一个阿里巴巴公司开源的高性能、轻量级的Java RPC框架,被广泛用于微服务框架中,为开发者提供了**面向接口**的远程**方法调用**、**智能容错**和**负载均衡**,能无缝集成Spring框架,简化开发步骤。 #### Feign和Dubbo的区别 | 区别 | Feign | Dubbo | | :----: | :----------------------: | :--------------------------: | | 协议 | HTTP协议 | Dubbo、RMI、HTTP、Redis等 | | 负载 | Ribbon作为负载均衡器 | 内置多种负载策略无需其他组件 | | 灵活性 | 适用于跨语言跨平台的场景 | Java、Go、Node、Web、Rust | | 依赖 | 是SpringCloud的一部分 | 独立的RPC框架 | ![image-20240923151412573](微服务.assets/image-20240923151412573.png) #### 修改服务的端口号 ![image-20240923161744161](微服务.assets/image-20240923161744161.png) ![image-20240923161832074](微服务.assets/image-20240923161832074.png) ``` -DServer.port=8003 ``` | 算法 | 特性 | 备注 | 配置值 | | :---------------------------- | :---------------------- | :--------------------------------------------------- | :--------------- | | Weighted Random LoadBalance | 加权随机 | 默认算法,默认权重相同 | random (默认) | | RoundRobin LoadBalance | 加权轮询 | 借鉴于 Nginx 的平滑加权轮询算法,默认权重相同 | roundrobin | | LeastActive LoadBalance | 最少活跃优先 + 加权随机 | 背后是能者多劳的思想 | leastactive | | Shortest-Response LoadBalance | 最短响应优先 + 加权随机 | 更加关注响应速度 | shortestresponse | | ConsistentHash LoadBalance | 一致性哈希 | 确定的入参,确定的提供者,适用于有状态请求 | consistenthash | | P2C LoadBalance | Power of Two Choice | 随机选择两个节点后,继续选择“连接数”较小的那个节点。 | p2c | | Adaptive LoadBalance | 自适应负载均衡 | 在 P2C 算法基础上,选择二者中 load 最小的那个节点 | adaptive | ### 网关 网关是一个很重要的模块,它充当了系统与外部世界的桥梁,在微服务中每个服务实现特定的业务,并独立部署。网关解决了 1. 统一入口 2. 路由转发 3. 负载均衡 4. 安全认证 5. 协议转换 6. 流量控制 7. 日志记录 8. API聚合 9. 灰度发布 等一系列解决方案 #### Higress网关 官网地址 https://higress.io/ #### 网关大致可以分为两种 1. 流量网关 Nginx 1. 服务网关 GateWay ![image-20240930151811649](README.assets/image-20240930151811649.png) 学习网关需要学习3个板块 ##### 路由(Route) 静态路由和动态路由,定义是收到http服务映射到后端的服务称为路由 ```yaml gateway: routes: - id: jiaodian-live #路由唯一标识符 # uri (统一资源标识符) 指定当请求匹配到该路由时,将请求转发到目标地址 # http 服务 http://地址 # 微服务 lb:从注册中心获取服务列表,进行负载均衡 uri: http://127.0.0.1:9001 ``` ##### 断言(Predicate) 断言是用来进行请求匹配的条件逻辑,基于Java 8的Predicate接口实现。允许开发者根据Http请求的各种属性(方法、路径、标头、参数)等来定义匹配规则 ##### 过滤器(Filter) 过滤器非常重要,用于请求在路由前后执行预处理或后处理的操作。 Gateway由多个组件构成,包括断言工厂、过滤器工厂、全局过滤器等。 ```yaml filters: - StripPrefix=1 # 局部过滤器 当请求匹配成功后移除第一个接口 如:/aaa/bbb/ccc 变成 /bbb/ccc再给下一个服务 ``` #### 全局过滤器 ````java package com.jiaodian.gateway.filters; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; /** * 删除swagger路径的全局过滤器 * GlobalFilter 全局过滤器 * Ordered 优先级 */ @Slf4j @Component public class RemoveSwaggerPathFilter implements GlobalFilter,Ordered { @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); String path = request.getURI().getRawPath(); // 判断路径里面是否包含 /v3/api-docs if (path != null && path.contains("/v3/api-docs")) { log.info("过滤掉路径:{}", path); // 过滤掉路径:/auth/v3/api-docs // 删除掉path第二个斜杠之前的内容 String newPath = path.substring(path.indexOf("/", 1)); log.info("过滤掉路径后:{}", newPath); /** * 重新设置请求路径 然后继续放行 */ return chain.filter(exchange.mutate().request(request.mutate().path(newPath).build()).build()); } // 放行 return chain.filter(exchange); } /** * 过滤的优先级 * -1 优先级最高 * @return */ @Override public int getOrder() { return -1; } } ```` ### 认证中心 ![image-20241029204158028](README.assets/image-20241029204158028.png) 会出现不同服务间无法共享登录状态的情况,需要用到Redis去同步。 ### 接口文档knife4j ![image-20241010193830224](README.assets/image-20241010193830224.png) ![image-20241010195648103](README.assets/image-20241010195648103.png) ### 配置中心 配置管理:集中管理应用的配置,提供动态配置更新于推送服务,避免应用重启降低运维成本。 ``` https://nacos.io/docs/v2/ecology/use-nacos-with-spring-cloud/ ``` 全局异常拦截 ![image-20241024214109321](assets/image-20241024214109321.png) # Minio MinIO 是一个高性能的分布式对象存储系统。 ![Erasure Coding](https://www.minio.org.cn/resources/img/products/erasure-code.svg) 1、对象存储没有C盘D盘等盘符概念 2、对象存储也没有文件夹的概念 3、靠的是对象的属性、属性下面也可以放对象 ### **下载流程** ``` 下载地址:https://www.minio.org.cn/download.shtml#/windows ``` ![image-20241104143523911](README.assets/image-20241104143523911.png) ### 安装 ``` Invoke-WebRequest -Uri "https://dl.min.io/enterprise/minio/release/windows-amd64/minio.exe" -OutFile "C:\minio.exe" ``` ### **启动教程** ``` setx MINIO_ROOT_USER minioadmin 成功: 指定的值已得到保存。 setx MINIO_ROOT_PASSWORD minioadmin 成功: 指定的值已得到保存。 C:\minio.exe server C:\Data --console-address ":9001" ``` 如果提示9001被占用就换一个端口 ### **登录** ``` http://localhost:9001/login 用户名 minioadmin 密码 minioadmin ``` ### 创建一个桶 ![image-20241104143914624](README.assets/image-20241104143914624.png) 创建用户 ![image-20241104144032928](README.assets/image-20241104144032928.png) ![image-20241104144128124](README.assets/image-20241104144128124.png) ![image-20241104144313113](README.assets/image-20241104144313113.png) ### 唯一键Key 对象存储中每个对象(文件)都有一个唯一的键(key),这个键允许包含分隔符 / 。 | key | value | | :----------------------------------------------: | :----------: | | name | 张三 | | vedio\happy\79f097a556d94b3784c7de4c2f20a498.jpg | 对象(文件) | | | | # 流媒体 ## RTMP协议 RTMP,即Real Time Messaging Protocol(实时消息传输协议),是Adobe公司开发的一种私有传输协议,基于TCP协议开发。RTMP协议的主要用途是音视频推流、实时交互语音和数据交互等功能。它是一个协议族,包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP协议的特点包括 直播、点播等使用场景。 ## RTSP协议 RTSP,即Real Time Streaming Protocol(实时流传输协议),是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学、网景和RealNetworks公司提交的IETF RFC标准。RTSP协议的主要目的是定义一对多应用程序如何有效地通过IP网络传送多媒体数据。 监控视频、摄像头画面等使用场景。 ## 流媒体服务器 或者叫流媒体服务 市面上常见的流媒体服务器 1、easydss ``` http://www.easydss.com/#1 ``` 2、zlm4j ``` https://gitee.com/aizuda/zlm4j ``` # 搜索(Elasticsearch) ## 镜像库 ES的 ``` https://mirrors.huaweicloud.com/elasticsearch/ ``` kibana的 ``` https://mirrors.huaweicloud.com/kibana/ ``` ## 原生搜素 ``` title like "%#{title}%" 139****5123 title like "139____5123" select * from news where title like "%#{title}%" or content like "%#{title}%"; ``` 原生SQL LIKE是用于匹配的操作符,用在关系型数据库中的简单模糊查询,只适用于简单查找,查询效率慢。 ## 搜索引擎 在Java中,搜索引擎通常使用ES(Elasticsearch),用于全文检索,**数据存储**和**分析**等场景。 ### 索引(Index) 类似于数据库的表,是ES存储数据的地方,用于对具有相识特征的文档进行分类管理。电商平台,可以给商品信息创建一个索引(表)。 ### 文档(Document) 是ES中的基本数据单元,以JSON格式存储,相当于数据库的一条记录。等与表里面的详细信息(名称,价格,描述等) ### 类型(Type) 在新版本中逐渐弱化,用来给索引里的文档进行逻辑分类用的。比如:食品类,家电类,药品类 ## 工作原理 ![image-20241111160259299](README.assets/image-20241111160259299.png) ### 查询执行 当发起一个查询请求,ES会根据索引找到匹配的文档。如:搜索商品时,通过商品名称描述等字段的索引,快速返回符合用户关键词的商品文档。 ## 安装ES搜索引擎 ### 找到官网 ``` https://www.elastic.co/cn/downloads/elasticsearch ``` ![image-20241111161659249](README.assets/image-20241111161659249.png) ![image-20241111162155976](README.assets/image-20241111162155976.png) ## 启动 ![image-20241111165317325](README.assets/image-20241111165317325.png) 找到账号密码 在浏览器输入 ``` https://localhost:9200 ``` ![image-20241111165539683](README.assets/image-20241111165539683.png) ![image-20241111165633250](README.assets/image-20241111165633250.png) 看到这个页面证明搜索引擎启动成功 ## Kibana获取Token ``` elasticsearch-create-enrollment-token -s kibana --url "https://localhost:9200" ``` ## Mysql和ES对比 SQL语句 select insert update delete DSL语句 ## 分词 IK分词器,是一个中文文本分析插件,提供了两种分词模式:ik_smart 和 ik_max_word ``` https://github.com/infinilabs/analysis-ik/releases ``` 下载IK分词器 ``` https://release.infinilabs.com/analysis-ik/stable/ ``` ``` # 原生分词 # 官方提供的,对中文支持不理想 POST /_analyze { "analyzer": "standard", "text": "你好世界" } # IK分词器 POST /_analyze { "analyzer": "ik_smart", "text": "你好世界" } ``` ### RestFul风格 RestFul风格语法使用**标准HTTP方法**和状态码进行通信,使得API设计更加简洁明了。客户端可以通过简单的HTTP请求(GET、POST、PUT、Delete)进行各种操作,无需复杂中间件。 ### ik_smart 粗细粒度算法,适用于将句子合理的切开,适合关键词搜索 ### ik_max_word 通常会分词语下面的词语,尽可能将词详细的切开,适合做索引分析 ### 为什么要分词 1.文本分割:就是讲一段文本进行拆分,方便后续对这些关键词进行搜索匹配,帮助搜索引擎对文本内容进行细致处理 2.索引构建:分词后的文本元素会被存储在ES的倒排索引中 ### 倒排索引 是一个加速文本搜索的数据结构,将每个单词映射到包含该单词的所有文档列表中,然后用列表替换单词,它是一种**全文搜索**数据结构 ### InooDB B+树索引,B树的变种,所有的值都出现在叶子节点,并且叶子节点和链表相连,便于范围查询。 ## 拓展词典 是在IK分词器config下面有一个IKAnalyzer.cfg.xml 可以在里面配置 ```xml IK Analyzer 扩展配置 online_dictionary.dic block_dictionary.dic ``` ## ES索引的概念 索引是一种数据结构,用于**存储**,**组织**和**管理**文档数据,是核心概念之一。 #### 添加索引 ```json PUT /boys { "settings": { "number_of_shards": 1, //设置主分片数量 "number_of_replicas": 1 //设置副本分片数量 }, "mappings": { // 字段映射, "properties": { "name":{ // 字段 "type": "text" }, "age":{ "type": "integer" }, "description":{ // 自我介绍,分词,倒排索引 "type": "text", "analyzer": "ik_smart" } } } } ``` #### 删除索引 ```json # 删除索引 DELETE /boys ``` ### 文档的概念 文档是索引的基本数据单位,相当于数据库表中的一行数据 ```json # 添加文档 = 添加数据 = insert POST /boys/_doc/1 { "name": "陶荣钊", "age": "21", "description": "身高185,帅气阳光八块腹肌,家住天鹅岭,某知名大厂主管,年薪百万,有期权股权,蕉点短视频科技有限公司创始人、董事长" } POST /boys/_doc/2 { "name": "张春", "age": "21", "description": "身高160,2块腹肌,家住五角大楼,焦点短视频在职员工,月薪7000+" } POST /boys/_doc/3 { "name": "肖付义", "age": "21", "description": "身高190,气质佳,正在腹肌,准备面试焦点短视,希望找一个成熟知性的另一半,上海、北京优先" } ``` ```json # 查询 GET /boys/_search { "size": 1, //查询条数 limit "min_score": 0.8, // 最低得分阈值 "query": { "match": { "description": "身高185的年薪百万董事长" } } } # 索引查询 GET /boys/_doc/2 # 修改索引 PUT /boys/_doc/2 { "name": "张春", "age": "21", "description": "身高170,2块腹肌,家住五角大楼,焦点短视频在职员工,月薪7000+" } # 删除索引 DELETE /boys/_doc/2 ``` ### 字段的概念 ### 分片的概念 number_of_shards 主分片数量,主分片提供负责存储和提供搜索,聚合等操作能力,创建后不可更改。 ### 副本的概念 number_of_replicas 提供冗余故障恢复能力 **以上4个共同组成了索引** 视频上传和ES整合的逻辑流程 ![未命名绘图](README.assets/未命名绘图.jpg) ## ES同步的概念 ### 全量同步 全量同步就是一次性同步所有的数据库到ES中,通常用于首次初始化操作 ### 增量同步 增量同步是指在全量同步完成之后讲数据库发生的变化(增、删、改)实时或异步的同步到ES中 ### 实现方式 1.基于消息队列(MQ)的同步:可以使用RocketMQ或kafka或RabbitMQ 2.基于Binlog的同步:Mysql中Binlog记录了数据库中的所有变更操作,可以利用Binlog来实现实时数据同步,如可以用阿里开源的Canal工具可以伪装成Mysql的从节点,订阅Binlog日志并将数据发送到ES中,这种方式没有代码侵入,实时性高 3.Easy-ES来实现,需要自己编码,能实现特殊需求,劣势在于非Java项目不适应 # 任务调度 (quartz) ## xxl-job ``` https://www.xuxueli.com/xxl-job/#%E3%80%8A%E5%88%86%E5%B8%83%E5%BC%8F%E4%BB%BB%E5%8A%A1%E8%B0%83%E5%BA%A6%E5%B9%B3%E5%8F%B0XXL-JOB%E3%80%8B ``` 开源工程 ``` https://gitee.com/xuxueli0323/xxl-job.git ``` ## disjob ``` https://gitee.com/dromara/disjob ``` ## CRON表达式 ``` 秒 分 时 日 月 星期 年 * * * * * [year] - - - - - - - | | | | | | | | | | | | | +--- 年(可选,1970-2099) | | | | | +----- 星期几(0-7,其中0和7都表示周日) | | | | +------- 月份(1-12) | | | +--------- 日期(1-31) | | +----------- 小时(0-23) | +------------- 分钟(0-59) +--------------- 秒 (0-59) ``` ### 字段说明 分钟 (0-59) 小时 (0-23) 日期 (1-31) 月份 (1-12) 星期几 (0-7,其中0和7都表示周日) 年(可选,1970-2099) ### 特殊字符 ``` *:表示所有可能的值。例如,*在分钟字段中表示每分钟。 ,:表示多个值。例如,1,15表示1号和15号。 -:表示一个范围。例如,1-5表示从1到5。 /:表示步长。例如,*/15表示每15分钟一次。 ?:表示不指定值。通常用于日期和星期几字段,表示“不关心”。 L:表示最后一天。例如,在日期字段中表示每月的最后一天。 W:表示最接近的平日(周一至周五)。例如,15W表示15号最近的一个工作日。 #:表示特定星期几的第几周。例如,6#3表示每月的第三个周五。 ``` ### 案例 ``` * 30 * * * * 每小时的第30分钟执行 * 0 1 * * * 每天的凌晨1点执行 * 0 1 * * 1 每周的周一凌晨1点执行 ``` ## 工程批量替换 ![image-20241119211008827](../../AppData/Roaming/Typora/typora-user-images/image-20241119211008827.png) ![image-20241119211103944](../../AppData/Roaming/Typora/typora-user-images/image-20241119211103944.png) ``` /* springboot2版本依赖 import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; springboot3版本需要替换的 import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; */ ``` 启动调度中心用ip地址访问 ``` http://192.168.1.16:8006/xxl-job-admin/jobgroup ``` ![image-20241120115848901](README.assets/image-20241120115848901.png) ![image-20241120115910759](README.assets/image-20241120115910759.png) # RocketMQ ### 为什么要用MQ? ``` 异步解耦 、 削峰填谷 ``` 异步解耦:可作为服务间调用的桥梁,实现服务间解耦,提高灵活性和扩展性。 削峰填谷: 在流量高峰期,RocketMQ可以存储大量的请求,然后按照一定的策略进行分发处理,避免系统过载。 ![image-20241125155725640](README.assets/image-20241125155725640.png) ```` start mqnamesrv.cmd start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true ```` 信息(Message) 主题(Topic) 生产者 (producer) 消费者(Consumer) 消息队列(Message Queue) # Seate 分布式事务 Apache Seata(incubating) 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务 ## 本地事务 ### ACID A原子性、C一致性、I隔离性、D持久性 多条Sql一起成功,一起失败 ### 数据库(Mysql) 在Mysql中可以通过Begin、Commit、Rollback等sql语句来显示管理事务,Mysql还提供了自动提交(Autocommit)机制,默认情况是开启的。 ### Mysql引擎 InnoDB:InnoDB是Mysql默认存储引擎,提供了一个叫**事务安全表**(事务日志),支持行锁定和外键,因此InnoDB完成支持本地事务。 MyISAM:事务有问题(因为只支持表级锁) MERGE:不支持事务 MYMORY:不支持事务 ..... ### InnoDB如何实现事务 事务日志(Redo Log) - 记录了所有对数据页的修改操作 - 用于在系统崩溃后恢复数据,确保持久性 - 在事务提交前,所有的更改都会先写入到日志中,如果系统系统崩溃用于重做事务操作,确保持久性 回滚日志(Undo Log) - 记录事务开始前的数据状态 - 用于回滚事务未提交或多版本并发控制(MVCC) - 如果事务需要回滚,InnoDB会使用回滚日志将数据回滚到事务开始前的状态 ### 本地事务如何实现 ## Mysql主从 Mysql主从提高了可用性,是一种常见的数据库高可用性和读写分离解决方案。 ### 提高可用性 主从复制允许在主服务故障时,从服务器接管其负载,确保持续可用性,降低了单点故障的风险,提高了系统稳定性和可靠性。 ### 读写分离 主从架构中通常将写指向主服务器,而将度定向到从服务器。这样可以有效的降低主服务器的压力,提高整体性能。 ### 数据冗余 通过主从复制,数据可以在多个服务器上冗余,提高数据库安全性和容错能力,某个服务器出现故障,数据也不会丢失。 ### 实现主从 **在实现整个操作之前被同步的数据库不能够存在** **在实现整个操作之前被同步的数据库不能够存在** **在实现整个操作之前被同步的数据库不能够存在** 主数据库(Master)、从数据库(Slave) 1、找到主数据库的my.cnf文件 ![image-20241128202531130](README.assets/image-20241128202531130.png) ![image-20241128202754107](README.assets/image-20241128202754107.png) 如果是在window是主从是**my.ini**如果是Linux则叫**my.cnf**,都是在安装路径下面 主库用,放在整个配置文件的最后 ``` #服务器 id,随意,但要唯一 server-id = 1 #二进制文件存放路径 log-bin = mysql-bin #参数用于排除自带的数据库。 binlog-ignore-db = mysql binlog-ignore-db = information_schema binlog-ignore-db = performance_schema #二进制日志格式,建议使用ROW格式以获得更好的兼容性和可靠性。 binlog-format = ROW ``` ``` 关闭服务(windows) ``` ``` net stop mysql80 ``` 开启服务 ``` net start mysql80 ``` 重启服务(Linux) ``` sudo systemctl restart mysql80 或 sudo service mysql80 restart ``` **添加一个用户用于主从复制(不允许使用root账号来做主从)** ```sql # 创建用于主从复制的数据库 CREATE USER 'replica_user_jiaodian'@'%' IDENTIFIED BY 'XyyMyyLyyFyy'; # 给予必要的权限 GRANT REPLICATION SLAVE ON *.* TO 'replica_user_jiaodian'@'%'; # 权限生效 FLUSH PRIVILEGES; # 如果用root 需要允许远程连接 USE mysql; UPDATE USER SET HOST='%' WHERE USER='root'; FLUSH PRIVILEGES; ``` ![image-20241202144459283](README.assets/image-20241202144459283.png) ![image-20241202145626165](README.assets/image-20241202145626165.png) ### 从数据库 创建一个和主库名字一样的数据库 ``` show master status; # 找到File 和 Position 的值记录下来 ``` ![image-20241202164918990](README.assets/image-20241202164918990.png) 从库也放在my.ini的最后然后重启服务 ``` server-id = 2 #中继日志文件的名称,用于从主服务器接收二进制日志事件。 relay-log = mysql-relay-bin #从服务器的二进制日志文件的名称。 log_bin = mysql-bin #不同步相关的库 replicate-ignore-db = mysql replicate-ignore-db = information_schema replicate-ignore-db = performance_schema ``` 修改从库的server-id=2 。如果第一个从就是2 第二从3 ```sql change master to master_host='主库ip地址',master_user='用户名',master_password='密码', master_log_file='mysql-bin.主库查看的值',master_log_pos=主库查询出来的值; ``` 启动复制进程 ```sql START SLAVE; ``` 检查复制状态 ```sql show slave status\G ``` ![image-20241128211905055](README.assets/image-20241128211905055.png) ![image-20241202165005643](README.assets/image-20241202165005643.png) ## AI搜索 向量库+LLM # 小猿 安装一个python pillow 图片处理 pytesseract 做OCR识别的 ``` pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pytesseract pillow ``` ```python from PIL import ImageGrab import pytesseract bbox = (0, 100, 300, 200) image = ImageGrab.grab(bbox=bbox) text = pytesseract.image_to_string(image,lang='chi_sim') print("文字是",text) ``` # 桌面程序 C/S架构 官方文档 ``` https://www.kaka996.com/ ``` 1、拉取工程 ``` # gitee git clone https://gitee.com/dromara/electron-egg.git ``` 2、项目根路径配置.npmrc ``` registry=https://registry.npmmirror.com/ disturl=https://registry.npmmirror.com/-/binary/node electron_mirror=https://npmmirror.com/mirrors/electron/ electron-builder-binaries_mirror=https://registry.npmmirror.com/-/binary/electron-builder-binaries/ ``` 内容 3、清理缓存 ``` npm cache clean --force ``` 4、下载依赖 ``` npm install ``` ## 好用的CSS工具网站 ``` 可以调颜色和阴影 https://neumorphism.io/#082400 这个可以选各种小组件 https://uiverse.io/elements 这个可以选按钮 https://cssbuttons.io/ ``` ![捕获](README.assets/捕获.PNG) Gateway网关 官网地址 https://spring.io/projects/spring-cloud-gateway ![image-20240926204302931](README.assets/image-20240926204302931.png) ![image-20240926205859756](README.assets/image-20240926205859756.png) ### 持续集成 #### 什么是持续集成? 是一种开发实践CI(Continuous Integration),持续集成包含 1. 代码仓库(Git) 2. 自动化构建工具(Maven、Gradle) 3. 持续集成服务器(Jenkins、GitLab CI、Travis CI、Circle CI等) 4. 自动化测试(确保代码质量、单元测试、集成测试) 5. 通知机制:当构建成功或失败时,及时通知团队成员 #### Jenkins Jenkins是一个非常流行的自动化服务器,主要用于持续集成。 官网:https://www.jenkins.io/zh/ ![image-20240925091152936](微服务.assets/image-20240925091152936.png) ##### Maven插件 ![image-20240925103204576](微服务.assets/image-20240925103204576.png) ![image-20240925102922887](微服务.assets/image-20240925102922887.png) ![image-20240925103022253](微服务.assets/image-20240925103022253.png) ![image-20240925103053243](微服务.assets/image-20240925103053243.png) ![image-20240925103109477](微服务.assets/image-20240925103109477.png) ##### Gitee插件 去配置Gitee的令牌 ![image-20240925103318827](微服务.assets/image-20240925103318827.png) ![image-20240925103348366](微服务.assets/image-20240925103348366.png) ![image-20240925103545737](微服务.assets/image-20240925103545737.png) ![image-20240925103640654](微服务.assets/image-20240925103640654.png) **会生成一串秘钥,请妥善保管** ![image-20240925104012191](微服务.assets/image-20240925104012191.png) ![image-20240925104052653](微服务.assets/image-20240925104052653.png) ![image-20240925104129374](微服务.assets/image-20240925104129374.png) ![image-20240925104316110](微服务.assets/image-20240925104316110.png) 令牌就是账号密码,用于在git上拉工程用的 ![image-20240925104913890](微服务.assets/image-20240925104913890.png) 创建Maven构建计划时可以选择Gitee链接名 ![image-20240925110230759](微服务.assets/image-20240925110230759.png) 打包之前要清理 #### Windows环境 **Pre Steps 预先脚本 ,在打包前使用的** ![image-20240925110409677](微服务.assets/image-20240925110409677.png) Execute Windows bath command 执行windows批处理命令 (Cmd命令) Execute shell 执行shell脚本 Post Steps 打包之后执行的脚本 ![image-20240925110739199](微服务.assets/image-20240925110739199.png) Run only if build Succeeds 仅仅在构建成功时启动脚本 Run only if build successds or is unstable 在成功或不稳定(未知)运行脚本 Run regardless of build result 不管结果如何都运行 ``` 后台启动jar包 start javaw -jar 包名.jar ``` ## 2024-12-17补: 配置文件数据库安全 https://baomidou.com/guides/security/ jar包安全 ``` jar tf xxx.jar 列出jar里所有的文件 jar xf xxx.jar conf/xxx.conf 解压出jar包指定文件 jar uf xxx.jar conf/xxx.conf 把改了的配置文件打回去 ``` ### Shell脚本 简单来说就是一系列命令组成的文件,这些命令就是平时在命令行手动输入的那些命令。 Shell脚本常见命令 ### 头部 ```shell #! /bin/bash ``` ### 注释 ```shell # 单行注释 :<<'EOF' 这是一个多行注释 多行 多行 EOF echo "这是一个输出" ``` ### 变量 ```shell # 定义变量 my_name="zhangsan" my_age=18 ``` 特殊变量 ```shell # 获取脚本名称 script_name=$0 # start stop restart state=$1 # 服务名 service_name=$2 # 获取参数个数 param_count=$# echo "当前状态是:$1" echo "对哪个服务操作:$2" ``` 环境变量 可以在任何脚本中被获取 临时会话,当前终端会话中有效 ```shell export MY_VALUE="hello" ``` 永久设置 ```shell vi /ect/profile #最后一行添加如 export MY_NAME="zhangsan" # 刷新配置 source /ect/profile # 或使用 . /ect/profile ``` 获取案例 ```shell var_in_script=$MY_VALUE echo "环境变量的值是$var_in_script" ``` ### 输出 ```shell echo "单行输出" echo -e "请输入你要启动的服务\n以服务id\n或服务名来启动" ``` ### 输入 ```shell read -p "your name:" user_name echo "hello,$user_name" ``` ### 控制语句 if判断 ```shell read -p "your score:" user_score if [ $user_score -lt 60 ]; then echo "$user_score不及格" else echo "及格" fi ``` | 运算符 | 描述 | 备注 | | ------ | -------- | ---- | | -gt | 大于 | | | -lt | 小于 | | | -eq | 等于 | | | -ne | 不等于 | | | -le | 小于等于 | | | -ge | 大于等于 | | | | | | ### 函数 ```shell getmsg() { echo "hello,$1,$2!" } getmsg "lishi" "zhangsan" ``` ### 循环 For 循环遍历范围 ```shell for((i=1; i<=5; i++));do echo "Number:$i" done ``` For 遍历列表 ```shell for item in apple banana pineapple;do echo "fruit:$item" done ``` ### 文件 ```shell # 创建文件 touch myfile.txt # 删除文件 rm myfile.txt # 复制文件 cp myfile.txt myfile_copy.txt # 移动文件 mv myfile.txt /aaa/myfile.txt cr ``` ### 多脚本互调 ```shell #! /bin/bash #这里是主脚本 # 相对路径调用另一个脚本 ./service_check.sh all # 绝对路径调用 /home/user/scripts/service_check.sh all # source 命令 source ./service_check.sh all # 如果想要获取子脚本的参数使用 ``` ### 定时任务 ```shell # 加上执行权限 chmod +x /root/shell/service_state.sh # 编辑当前用户的定时任务列表 crontab -e # 写上定时任务(最小单位是分钟) */2 * * * * /root/shell/service_state.sh # 查看当前用户所有的定时任务设置 crontab -l # 注意格式 # 分 时 日 月 周 # 分 0-59 # 时 0-23 # 日期 1-31 # 月 1-12 # 星期 0-6 # *是通配符 # 案例 每两个小时执行一次 0 */2 * * * ``` ### 标准输出重定向 覆盖输出(>) ```shell #! /bin/bash echo "testtest" > output.txt ``` 追加输出(>>) ```shell #! /bin/bash echo "date is $(date)" >> log.txt ``` 输出全部的写法 ```shell #! /bin/bash { echo "这是第一句" echo "这是一个时间 $(date)" .... } &>> all_outputs.log ``` ### 案例一 1、通过shell启动jar包停止jar包重启jar包 2、要求命令如 jar包名是 jiaodian.jar jar包和sh文件在同一目录下 ```shell sh system_jar.sh start #表示启动 sh system_jar.sh stop #表示停止 sh system_jar.sh restart #表示重启 ``` 写内容: ```shell #!/bin/bash # 定义变量名 JAR_NAME="jiaodian.jar" # PID文件名 # PID是进程ID的简称,进程ID是操作系统为每个进程分配的唯一标识符 PID_FILE="jiaodian.pid" # 函数定义 start() { # 判断PID文件是否存在 if [ -f $PID_FILE ]; then echo "应用已经在运行,PID: $(cat $PID_FILE)" else # 启动应用 nohup 后台运行 # 把命令的输出重定向到/dev/log # 2>&1 把错误输出重定向到输出 # & 表示后台运行 nohup java -jar $JAR_NAME > /dev/log 2>&1 & # $! 表示最后一个命令的进程ID # 保存PID echo $! > $PID_FILE echo "应用已启动,PID: $(cat $PID_FILE)" fi } stop() { if [ -f $PID_FILE ]; then PID=$(cat $PID_FILE) # kill -9 强制杀死进程 kill -9 $PID # 删除PID文件 rm -f $PID_FILE echo "应用已停止,PID: $PID" else echo "应用未在运行" fi } restart() { stop # 等待一段时间 2秒 sleep 2 start } # 根据参数执行对应操作$1第一个参数 if [ "$1" = "start" ]; then start elif [ "$1" = "stop" ]; then stop elif [ "$1" = "restart" ]; then restart else echo "$0脚本的参数必须是:{start|stop|restart}" exit 1 fi ``` 凌晨1点自动执行 V0.0.1 到 V0.0.2版本的升级 ```shell sh system_jar.sh update v0.0.1 v0.0.2 #从0.0.1版本升级到0.0.2版本 ``` ```shell #!/bin/bash # 定义变量名 JAR_NAME="jiaodian.jar" # PID文件名 # PID是进程ID的简称,进程ID是操作系统为每个进程分配的唯一标识符 PID_FILE="jiaodian.pid" # 函数定义 start() { # 判断PID文件是否存在 if [ -f $PID_FILE ]; then echo "应用已经在运行,PID: $(cat $PID_FILE)" else # 启动应用 nohup 后台运行 # 把命令的输出重定向到/dev/log # 2>&1 把错误输出重定向到输出 # & 表示后台运行 nohup java -jar $JAR_NAME > /dev/log 2>&1 & # $! 表示最后一个命令的进程ID # 保存PID echo $! > $PID_FILE echo "应用已启动,PID: $(cat $PID_FILE)" fi } stop() { if [ -f $PID_FILE ]; then PID=$(cat $PID_FILE) # kill -9 强制杀死进程 kill -9 $PID # 删除PID文件 rm -f $PID_FILE echo "应用已停止,PID: $PID" else echo "应用未在运行" fi } restart() { stop # 等待一段时间 2秒 sleep 2 start } update() { if [ "$#" -ne 2 ]; then echo "Usage: $0 update " exit 1 fi CURRENT_VERSION=$1 NEW_VERSION=$2 echo "开始从版本 $CURRENT_VERSION 升级到版本 $NEW_VERSION" # 停止当前应用 stop # 下载新版本的jar包 # 可以把下载路径放在OSS对象存储桶中,通过OSS的URL下载 wget -O $JAR_NAME "http://自己的OSS地址/jiaodian/jar/jiaodian-$NEW_VERSION.jar" # 重新启动应用 start echo "升级完成,当前版本为 $NEW_VERSION" } # 根据参数执行对应操作$1第一个参数 if [ "$1" = "start" ]; then start elif [ "$1" = "stop" ]; then stop elif [ "$1" = "restart" ]; then restart elif [ "$1" = "update" ]; then update $2 $3 else echo "$0脚本的参数必须是:{start|stop|restart|update}" exit 1 fi ``` ### 案例二 1、通过shell拉取焦点短视频的代码(提前安装好git) ```shell #备份系统自带的yum源配置文件: #替换为阿里云yum源 sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak sudo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo sudo yum clean all sudo yum makecache sudo yum -y update # 安装git sudo yum install -y git ``` 2、打包成jar包(提前安装好Maven) 3、执行docker-compose 打包成一镜像 4、把镜像文件提交到镜像仓库里去 5、执行k8s的脚本 # 流媒体搭建 https://gitee.com/aizuda/zlm4j # 大前端 ## TypeScript ts是在js语言的基础上进行的改进,支持:接口(Interfaces)、类(Classes)、模块化、编译成多种js版本。 1. 接口 用来确保对象具有特定的属性和方法。 2. 类 类包含封装、继承、多态等特性。 **//TODO 后期做微服务部署时用国产系统+国产数据库** 银河麒麟v10 瀚高 ``` https://www.highgo.com/ ```