微服务
开发小技巧
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指在为中国市场及全球用户提供微服务开发与治理的能力,通过集成阿里巴巴开源的多个组件如:
- Nacos(服务发现与配置管理)
提供服务发现和服务健康检查功能,允许服务实例在Nacos Server注册和注销,从而实现服务间自动发现与负载均衡
- Sentinel(流量控制与熔断降级)
强大的流量控制组件,用于实现微服务的流量控制与防护,提供秒杀、大促等场景下的流量控制能力,避免服务因流量突增而崩溃。
支持熔断降级机制,当依赖的服务不可用或相应时间过长,能够快速失败并返回友好提示、保证整体服务的稳定和可用性。
- Seata(分布式事务解决方案)
高性能、易于使用的分布式事务解决方案,支持XA、TCC、SAGA等事务模式,能够确保在分布式系统中数据一致性。
- Dubbo(服务治理框架)
高性能、透明化的RPC服务调用框架,支持服务注册、负载均衡、服务监控等服务治理功能。
- RocketMQ(消息队列)
- higress(网关)
低延迟、高吞吐量的消息中间件,适用于大规模分布式系统中的消息传输。支持多种消息模式,点对点、发布/订阅,并且有高可用、可扩展的特性。
形成了一个功能全面的微服务生态体系,这些组件(框架)扮演了关键角色,涵盖了服务发现、配置管理、流量控制、熔断降级、分布式事务处理、服务治理及消息队列等多个方面。
假定一个项目
需求:北京有个老板(陶建国)投资1亿,做短视频平台带一个直播带货的平台。
项目名:蕉点短视频
需求调研阶段
产品经理:
何苗(女,年龄31,1米6,云南人,能力中等)
与客户或甲方,通过聊天,问卷调查,观察等方式获取到的需求,如下:
对功能优先级进行排序,哪些是必须实现的,哪些是可选的,对影响后续开发的功能需要优先开发。
文档一《需求调研报告》
需求分析
对收集的需求进行整理、分类、优先级排序
文档二《需求规格说明书》(SRS)
描述项目的功能需求,和非功能需求(性能、安全、可用性和约束性政策)
此处省略...........两个月....
项目经理:
齐帅(男,33岁,180,北京人)
系统设计阶段
文档三《概要设计说明书》
系统整体架构,技术选型(张工程师),模块划分,接口设计。
文档四《详细设计说明书》
数据结构,算法选择,
苏鑫(女、26、165、成都人)
用户界面设计(UI设计)
DBA:
周瑞(男,30,170,成都人)
文档五《数据库设计文档》
数据库结构》表结构》字段定义》关系模型
---------------------此处省略1个月-----------------------------
开发准备阶段
架构师:
张立东(男,35,180,台湾人)
环境搭建
开发环境,开发工具,服务器,数据库等。
代码规范制定:编码规范,版本控制规范,代码质量规范,团队协作等
齐帅(项目经理)
任务分配-长期工作
张工+齐工写以下文档:
文档六《开发计划》
文档七《编码规范》
编码风格,命名规范,注释要求等
测试阶段
- 编码测试阶段(单元测试)
- 集成测试(将各个模块,各个服务放在一起,检查接口是否正确,数据传递是否有误)
- 系统测试(全面测试,包括功能测试,性能测试,安全测试)
- 回归测试(对改了的bug进行二次测试)
- 上线测试(用户验收测试,压力测试)在生产环境进行测试,邀请用户进行测试
计划
文档八《测试计划》
测试的内容,进度,条件,人员等
测试用例
报告
文档九《测试报告》
测试数据,测试过程,测试结果分析,测试结论意见。
维护阶段
-------------------和开发一起-----------------5年后-------------------------
交付阶段
文档十《用户操作手册》
软件描述,如何使用这个软件
文档十一《帮助文档》
可能遇到的问题以及解决方案
文档十二《验收报告》
收工
----------------------------------------------------五年零六个月-----------------------------------------------------------
开发项目
语言(后): Java Python Go C++ C#
语言(前): Vue3 React Angular
框架: SpringBoot SpringCloud(体系) SpringCloud Alibaba(体系) SSM SSH
数据库(关系型): Mysql Sqlserver Oracle
数据库(非关系型): Redis Mongodb Memcache
Nacos(服务发现与配置管理)
默认是集群模式启动,需要单机启动
startup.cmd -m standalone
需要配置JAVA_HOME环境变量
Nacos数据库配置
在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;
4、修改nacos的配置文件(配置数据库地址和数据库账号密码)
创建配置文件
验证关联是否成功
如果有内容就证明同步成功
如何备份数据库?
mysqldump -u root -p123456 jiaodian_nacos > C:\jiaodian_nacos_1014.sql
创建工程
- 创建一个空白springboot工程
- File Encodings换成Utf-8
- 把平时不用的文件隐藏
4.安装插件方便转配置文件
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框架 |
修改服务的端口号
-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 |
网关
网关是一个很重要的模块,它充当了系统与外部世界的桥梁,在微服务中每个服务实现特定的业务,并独立部署。网关解决了
- 统一入口
- 路由转发
- 负载均衡
- 安全认证
- 协议转换
- 流量控制
- 日志记录
- API聚合
- 灰度发布
等一系列解决方案
Higress网关
官网地址
https://higress.io/
网关大致可以分为两种
- 流量网关
Nginx
- 服务网关
GateWay
学习网关需要学习3个板块
路由(Route)
静态路由和动态路由,定义是收到http服务映射到后端的服务称为路由
gateway:
routes:
- id: jiaodian-live #路由唯一标识符
# uri (统一资源标识符) 指定当请求匹配到该路由时,将请求转发到目标地址
# http 服务 http://地址
# 微服务 lb:从注册中心获取服务列表,进行负载均衡
uri: http://127.0.0.1:9001
断言(Predicate)
断言是用来进行请求匹配的条件逻辑,基于Java 8的Predicate接口实现。允许开发者根据Http请求的各种属性(方法、路径、标头、参数)等来定义匹配规则
过滤器(Filter)
过滤器非常重要,用于请求在路由前后执行预处理或后处理的操作。
Gateway由多个组件构成,包括断言工厂、过滤器工厂、全局过滤器等。
filters:
- StripPrefix=1 # 局部过滤器 当请求匹配成功后移除第一个接口 如:/aaa/bbb/ccc 变成 /bbb/ccc再给下一个服务
全局过滤器
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<Void> 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;
}
}
认证中心
会出现不同服务间无法共享登录状态的情况,需要用到Redis去同步。
接口文档knife4j
配置中心
配置管理:集中管理应用的配置,提供动态配置更新于推送服务,避免应用重启降低运维成本。
https://nacos.io/docs/v2/ecology/use-nacos-with-spring-cloud/
全局异常拦截
Minio
MinIO 是一个高性能的分布式对象存储系统。
1、对象存储没有C盘D盘等盘符概念
2、对象存储也没有文件夹的概念
3、靠的是对象的属性、属性下面也可以放对象
下载流程
下载地址:https://www.minio.org.cn/download.shtml#/windows
安装
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
创建一个桶
创建用户
唯一键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)
在新版本中逐渐弱化,用来给索引里的文档进行逻辑分类用的。比如:食品类,家电类,药品类
工作原理
查询执行
当发起一个查询请求,ES会根据索引找到匹配的文档。如:搜索商品时,通过商品名称描述等字段的索引,快速返回符合用户关键词的商品文档。
安装ES搜索引擎
找到官网
https://www.elastic.co/cn/downloads/elasticsearch
启动
找到账号密码
在浏览器输入
https://localhost:9200
看到这个页面证明搜索引擎启动成功
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 version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict">online_dictionary.dic</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords">block_dictionary.dic</entry>
<!--用户可以在这里配置远程扩展字典 -->
<!-- <entry key="remote_ext_dict">words_location</entry> -->
<!--用户可以在这里配置远程扩展停止词字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
ES索引的概念
索引是一种数据结构,用于存储,组织和管理文档数据,是核心概念之一。
添加索引
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"
}
}
}
}
删除索引
# 删除索引
DELETE /boys
文档的概念
文档是索引的基本数据单位,相当于数据库表中的一行数据
# 添加文档 = 添加数据 = 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,气质佳,正在腹肌,准备面试焦点短视,希望找一个成熟知性的另一半,上海、北京优先"
}
# 查询
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整合的逻辑流程
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点执行
工程批量替换
/*
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
RocketMQ
为什么要用MQ?
异步解耦 、 削峰填谷
异步解耦:可作为服务间调用的桥梁,实现服务间解耦,提高灵活性和扩展性。
削峰填谷: 在流量高峰期,RocketMQ可以存储大量的请求,然后按照一定的策略进行分发处理,避免系统过载。
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文件
如果是在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账号来做主从)
# 创建用于主从复制的数据库
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;
从数据库
创建一个和主库名字一样的数据库
show master status; # 找到File 和 Position 的值记录下来
从库也放在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
change master to master_host='主库ip地址',master_user='用户名',master_password='密码', master_log_file='mysql-bin.主库查看的值',master_log_pos=主库查询出来的值;
启动复制进程
START SLAVE;
检查复制状态
show slave status\G
AI搜索
向量库+LLM
小猿
安装一个python
pillow 图片处理
pytesseract 做OCR识别的
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pytesseract pillow
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/
Gateway网关
官网地址
https://spring.io/projects/spring-cloud-gateway
持续集成
什么是持续集成?
是一种开发实践CI(Continuous Integration),持续集成包含
- 代码仓库(Git)
- 自动化构建工具(Maven、Gradle)
- 持续集成服务器(Jenkins、GitLab CI、Travis CI、Circle CI等)
- 自动化测试(确保代码质量、单元测试、集成测试)
- 通知机制:当构建成功或失败时,及时通知团队成员
Jenkins
Jenkins是一个非常流行的自动化服务器,主要用于持续集成。
Maven插件
Gitee插件
去配置Gitee的令牌
会生成一串秘钥,请妥善保管
令牌就是账号密码,用于在git上拉工程用的
创建Maven构建计划时可以选择Gitee链接名
打包之前要清理
Windows环境
Pre Steps 预先脚本 ,在打包前使用的
Execute Windows bath command 执行windows批处理命令 (Cmd命令)
Execute shell 执行shell脚本
Post Steps 打包之后执行的脚本
Run only if build Succeeds 仅仅在构建成功时启动脚本
Run only if build successds or is unstable 在成功或不稳定(未知)运行脚本
Run regardless of build result 不管结果如何都运行
后台启动jar包
start javaw -jar 包名.jar
流媒体搭建
https://gitee.com/aizuda/zlm4j
大前端
TypeScript
ts是在js语言的基础上进行的改进,支持:接口(Interfaces)、类(Classes)、模块化、编译成多种js版本。
- 接口 用来确保对象具有特定的属性和方法。
- 类 类包含封装、继承、多态等特性。
//TODO 后期做微服务部署时用国产系统+国产数据库
银河麒麟v10
瀚高
https://www.highgo.com/
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脚本常见命令
头部
#! /bin/bash
注释
# 单行注释
:<<'EOF'
这是一个多行注释
多行
多行
EOF
echo "这是一个输出"
变量
# 定义变量
my_name="zhangsan"
my_age=18
特殊变量
# 获取脚本名称
script_name=$0
# start stop restart
state=$1
# 服务名
service_name=$2
# 获取参数个数
param_count=$#
echo "当前状态是:$1"
echo "对哪个服务操作:$2"
环境变量
可以在任何脚本中被获取
临时会话,当前终端会话中有效
export MY_VALUE="hello"
永久设置
vi /ect/profile
#最后一行添加如
export MY_NAME="zhangsan"
# 刷新配置
source /ect/profile
# 或使用
. /ect/profile
获取案例
var_in_script=$MY_VALUE
echo "环境变量的值是$var_in_script"
输出
echo "单行输出"
echo -e "请输入你要启动的服务\n以服务id\n或服务名来启动"
输入
read -p "your name:" user_name
echo "hello,$user_name"
控制语句
if判断
read -p "your score:" user_score
if [ $user_score -lt 60 ]; then
echo "$user_score不及格"
else
echo "及格"
fi
运算符 | 描述 | 备注 |
---|---|---|
-gt | 大于 | |
-lt | 小于 | |
-eq | 等于 | |
-ne | 不等于 | |
-le | 小于等于 | |
-ge | 大于等于 | |
函数
getmsg() {
echo "hello,$1,$2!"
}
getmsg "lishi" "zhangsan"
循环
For 循环遍历范围
for((i=1; i<=5; i++));do
echo "Number:$i"
done
For 遍历列表
for item in apple banana pineapple;do
echo "fruit:$item"
done
文件
# 创建文件
touch myfile.txt
# 删除文件
rm myfile.txt
# 复制文件
cp myfile.txt myfile_copy.txt
# 移动文件
mv myfile.txt /aaa/myfile.txt cr
多脚本互调
#! /bin/bash
#这里是主脚本
# 相对路径调用另一个脚本
./service_check.sh all
# 绝对路径调用
/home/user/scripts/service_check.sh all
# source 命令
source ./service_check.sh all
# 如果想要获取子脚本的参数使用
定时任务
# 加上执行权限
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 * * *
标准输出重定向
覆盖输出(>)
#! /bin/bash
echo "testtest" > output.txt
追加输出(>>)
#! /bin/bash
echo "date is $(date)" >> log.txt
输出全部的写法
#! /bin/bash
{
echo "这是第一句"
echo "这是一个时间 $(date)"
....
} &>> all_outputs.log
案例一
1、通过shell启动jar包停止jar包重启jar包
2、要求命令如
jar包名是 jiaodian.jar
jar包和sh文件在同一目录下
sh system_jar.sh start #表示启动
sh system_jar.sh stop #表示停止
sh system_jar.sh restart #表示重启
写内容:
#!/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版本的升级
sh system_jar.sh update v0.0.1 v0.0.2 #从0.0.1版本升级到0.0.2版本
#!/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 <current_version> <new_version>"
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)
#备份系统自带的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的脚本