SpringBoot、SpringCloud框架
2022-10-17 11:30:34 47 举报
AI智能生成
coco博
作者其他创作
大纲/内容
Liunx
Docker
Nginx
Redis
概念:<font color="#ff0000">非</font>关系型数据库(缓存数据)
解决mysql数据库数据达到<font color="#ff0000">3000万,速度慢</font>,最大<font color="#ff0000">连接数只有500</font>
解决<font color="#ff0000">并发集群数据库性能低</font>,<font color="#ff0000">锁失效(</font><font color="#0d47a1">类似negix并发多台tomcat服务区session失效</font><font color="#ff0000">)</font>
redis<font color="#ff0000"><b><i>缓存</i></b></font>数据存储在<font color="#ff0000">内存</font>中,MySQL存储在硬盘中
访问redis还是发生<font color="#ff0000">service层</font>
类型:
关系型数据库:mysql、oracle、DB2
非关系型数据库库:<font color="#ff0000">Redis</font>、mongoDb、<font color="#ff0000">ES</font>
安装
<font color="#ff0000">5中基本类型</font>
String类型-----值类型
Hash类型-----散列类型----存储对象
LIst类型----列表类型----<font color="#ff0000">应用场景排队、秒杀</font>
Set类型----集合类型(无序)----<font color="#ff0000">shiro权限</font>
ZSet类型-----有序集合类型(<font color="#ff0000">序:分数</font>)---积分,排行榜
<font color="#d32f2f">补充3种</font>
HyperLogLog计算近似值
GEO 地理位置
BIT 数组类型byte[]
常用基础命令
数据库操作
只有<font color="#ff0000">0~15</font> 16个数据库 ---<font color="#0d47a1"> select 0~15</font>
移动key到另一个数据库
清空当前数据库
清空所有数据库
查看当前数据库有多少key
String常用操作
添加值 <font color="#ff0000">set</font> key value
setnx key value--(<font color="#ff0000">key存在什么都不做</font>不存在添加,<font color="#ff0000">分布式锁应用</font>)
取值 <font color="#ff0000">get</font> key
批量存取值 <font color="#ff0000">mset</font> key value 。。。
自增长----incr key(将<font color="#ff0000">value++</font>)
设置存活时间--<font color="#ff0000"> expire key 毫秒值 </font><font color="#0000ff"> key值存在情况下</font><font color="#ff0000"><br>setex key 秒值 value---</font><font color="#0000ff">-key值不存在情况下</font>
追加----append key value 再已存在的key后追加值
Hash常用命令(存储对象)
添加 <font color="#ff0000">hset key field value</font> ---key反复使用添加
查看 hget key field
自增--只有value为数字
获取全部fieldd value
获取全部 value
获取field的数量
list管道常用命令
左侧插入,右侧插入
lpush key 【value】
lpushx key 【value】---key不存在操作无效
rpush key 【value】
rpushx key 【value】---key不存在操作无效<br>
<font color="#ff0000">应用于商品秒杀</font>
修改数据
<font color="#ff0000">lset key index角标 value</font>
弹出数据
lpop 左边弹出一个value
rpop 右边弹出一个数据
<ul><li>删除列表中的数据 <font color="#ff0000"> lrem key </font><font color="#0000ff">count</font><font color="#ff0000"> value ---<br>count>0,从左往右删除count个<br>count<0,从右往左删除count个<br></font></li></ul>
<font color="#ff0000">将一个列表中最后的一个数据,插入到另外一个列表的头部位置</font><br>rpoplpush list1 list2
Set常用命令
添加值----sadd key member [member ...]
取值---smembers key
子主题
ZSet常用命令
添加数据(<font color="#0000ff">score必须是数值。member不允许重复的</font>。)<br><font color="#ff0000">zadd key score member [score member ...]</font>
修改member的分数----<font color="#ff0000">zincrby key increment member</font>
根据分数从小到大排序
zrange key start stop [withscores]
start stop <font color="#0000ff">为角标</font> <font color="#ff0000">0 -1 所有范围</font>
zrevrange key start stop [withscores]---大到小
<font color="#ff0000">Java连接Redis</font>
存储对象,以字节数组方式存储到Redis
以json串的方式
<font color="#ff0000">连接池</font>
管道的使用,<font color="#ff0000">批量操作</font>
Redis持久化机制
弱事务----没有4大特性
<font color="#ff0000">RDB</font>默认的持久化机制 dump.rdb(二进制文件)
无法保证数据绝对安全
在设置的时间范围内如果key发生的了改变,将会持久化
<font color="#ff0000">临时持久化</font>
<font color="#ff0000">AOF</font>
<font color="#ff0000">实时持久化</font>
每当有写操作就持久化
Redis的key的删除机制
定期删除
每隔一段时间去查看,过期了的key,
惰性删除
当去查询时才会删除
<font color="#ff0000">淘汰机制</font>
子主题
<font color="#0000ff">缓存问题</font>
<font color="#ff0000">缓存击穿</font>
Redis<font color="#ff0000">访问的数据刚好过期</font>导致,50000访问量直接访问数据库
解决方式:在访问数据库时加锁,一个一个访问
<font color="#ff0000">缓存穿透</font>
访问的数据在Redis中没有,在数据库中也没有用
解决方式:查询DB时发现没有,将NULL值存储到Redis中 2.布隆过滤器
<font color="#ff0000">缓存雪崩</font>
Redis中的缓存中的<font color="#ff0000">过期时间设置相同</font>,导致同时<font color="#0000ff">集体过期失效</font>
解决方式:数据库设置锁,将每个<font color="#ff0000">key过期时间随即设置</font>
缓存倾斜
Redis承受不住大量的访问
解决方式:集群搭建Redis
ElasticSerach
概念:全文检索nosql
关系型数据库的索引类型
普通索引
<font color="#0d47a1">主键索引 次之</font>
唯一索引
<font color="#ff0000">组合索引(复合索引)最多</font>
全文索引---必须是MyISAM引擎
mysql数据库查询海量数据时效率低
<font color="#ff0000">全文索引专用引擎</font>
为什么学习ES
支持海量数据查询
支持IK分词器,对<font color="#ff0000">中文智能分词</font>
支持查询高亮显示
ES和solr的区别
ES非常稳定,不管所应是否发生变化
Solr依赖第三方产品<font color="#ff0000">Zookeeper搭建集群</font>
搜索方式
顺序扫描法:性能差,速度慢,先找文件后找内容
<font color="#ff0000">倒排索引法:先找内容,再找内容对应的文件</font>
ES构成
分词库
子主题
数据存储库-----<font color="#ff0000">数据进行分片存储,指定信息分词放入分词库</font>
kibana (ES管理工具,基于ES)
<font color="#3e9a3e">DSL语句</font>
POST <font color="#ff0000">_analyze</font><br>{<br> "analyzer": "ik_max_word",<br> "text": "中华人民共和国"<br>}
<font color="#ff0000">IK分词器</font>
扩充词
停用词
索引库
分片(就是集群,每一个分片就是一个服务器)
<font color="#ff0000">文档(一条数据就是一个文档)</font>
id域
name域
副本(备份,不应该与主分片放到同一个服务器)
创建索引库<font color="#ff0000">DSL</font>
指定分片
<font color="#3e9a3e">PUT /person<br>{<br> "settings": {<br> "number_of_shards": 5,<br> "number_of_replicas": 1<br> }<br>} </font><font color="#ff0000">//分成5个分片,每个分片一个备份</font>
指定文档(Document)的域(<font color="#ff0000">每个域</font><font color="#3e9a3e"><span class="equation-text" contenteditable="false" data-index="0" data-equation="是否分词"><span></span><span></span></span></font><font color="#ff0000">等属性</font>)(不参与分词的数据会整体放如分词库)
<font color="#ff0000">域(field)</font>类型
字符串类型
<font color="#ff0000">text分词</font>
<font color="#ff0000">keyword不分词</font>
数值
<font color="#ff0000">时间</font>
布尔类型
二进制类型
范围类型
<font color="#ff0000">经纬度类型</font>
<font color="#ff0000">ip类型</font>
添加文档
<font color="#ff0000">/索引库/</font><font color="#3e9a3e">_doc</font>
默认随机生成一个id
指定id
搜索
<font color="#ff0000">/索引库/</font><font color="#3e9a3e">_search</font>
<font color="#ff0000">指定域名和域值</font>
match--模糊搜索(检测分析库的词,和数据本身)
term--精准搜索(只检测分词库中的词,<font color="#ff0000">不参与分词的属性会将内容全部存到分词库作为一个词</font>)
<font color="#ff0000">修改</font>
<font color="#ff0000">/索引库/</font><font color="#3e9a3e">_doc</font><font color="#ff0000">/id</font>-----添加一个新的,id设置为与之前相同(<font color="#ff0000">覆盖式修改</font>)
<font color="#ff0000">/索引库/</font><font color="#3e9a3e">_update</font><font color="#ff0000">/id</font>-----更新式修改<br>
删除 <font color="#ff0000">delete /索引库/</font><font color="#3e9a3e">_doc</font><font color="#ff0000">/id</font>
JAVA代码的方式操作
导入依赖包
ES包
高级别客户端包
编写连接ES工具类
public static RestHighLevelClient getClient() {<br> <font color="#ff0000">//1. 创建和服务器的连接</font><br> HttpHost httpHost = new HttpHost("192.168.200.129", 9200);<br> <font color="#ff0000"> //2. 创建RestClient对象</font><br> RestClientBuilder builder = RestClient.builder(httpHost);<br> //3. 创建返回可以使用的连接对象<br> RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);<br> return <font color="#ff0000">restHighLevelClient;</font><br> }
操作索引库
创建索引库,创建域,指定域的类型
创建索引
.<font color="#ff0000">indices().create</font>
删除索引
操作文档
<font color="#ff0000">查询</font>
创建接收<font color="#ff0000">文档的对象</font>
<font color="#ff0000">//5:执行搜索 结果有13条 查询所有之后结果</font><br> SearchResponse <font color="#ff0000">searchResponse</font> = restHighLevelClient<font color="#ff0000">.search(searchRequest,</font> RequestOptions.DEFAULT);<br><br> SearchHits hits = searchResponse.getHits();
SearchRequest searchRequest = new <font color="#ff0000">SearchRequest(index);</font><br> //搜索条件<br> //searchRequest.indices("book","person");//二个索引库的名称<br> //1:设置索引库的名称<br> //searchRequest.indices("book");//索引库的名称<br> <font color="#ff0000">//2:最外层大括号 { }<br> SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();</font><br> <font color="#3e9a3e">//2.1查询所有</font><br> searchSourceBuilder.query(QueryBuilders.matchAllQuery());<br> <font color="#3e9a3e">//2.1精准查询</font><br> //searchSourceBuilder.query(QueryBuilders.<font color="#ff0000">termQuery</font>("name","java"));<br> searchSourceBuilder.query(QueryBuilders<br> .term<font color="#ff0000">s</font>Query("name","java","鬼吹灯"));<br> <font color="#3e9a3e"> //2.1匹配查询<br></font> <font color="#3e9a3e"> * match == 先分词 + 再精准查询 desc:分词后的对应</font><br> searchSourceBuilder.query(QueryBuilders.<font color="#ff0000">matchQuery</font>("desc","盗古墓"));<br> <font color="#ff0000">//3:设置分页 不设置默认是每页显示10条</font><br> searchSourceBuilder.from(0); //开始行=(当前页-1)*每页数<br> searchSourceBuilder.size(20);//默认是10<br><br> <font color="#ff0000"> //4:将最外层大括号 { } 设置给上面的SearchRequest</font><br> searchRequest.source(searchSourceBuilder);
搜索所有数据
分页查询
深分页:因为form,size的和不能超过1w
<font color="#ff0000">scroll</font>+size在ES查询数据的方式
精髓;将在分词库中查询到的<font color="#ff0000">文档id,存到服务器上下文中</font>,而不是直接前去文档库中查找文档
<font color="#ff0000">各种查询</font>
term(完全匹配,不会出对你<font color="#ff0000">搜索的内容进行分词处理</font>)
match:将搜索内容<font color="#ff0000">先进行分词</font>,再去分词库匹配
match_all查询
match指定一个Field作为筛选的条件
布尔match查询 :<font color="#ff0000">基于一个Field匹配的内容,采用and或者or的方式连接</font>
multi_match查询:multi_match针对<font color="#ff0000">多个field进行检索</font>,多个field对应一个text。
id查询
//2. 执行查询<br> GetResponse resp = client.get(request, RequestOptions.DEFAULT);
ids查询
prefix查询<font color="#ff0000">(前缀)</font>
fuzzy查询(模糊)
wildcard查询(通配)
盘*:多个字
盘?:一个字
range查询(范围)
数量,日期
复合查询
bool查询
相关度查询(匹配精准度)
tf/idf相关度算法计算评分
filter查询
<font color="#ff0000">高亮查询</font>
<font color="#ff0000">聚合查询</font>
添加
单文档添加<font color="#ff0000">.index()</font>
(批量添加)<font color="#ff0000">.bulk(</font>bulkRequest, RequestOptions.DEFAULT<font color="#ff0000">)</font>
bulkRequest.add(添加,修改,删除,“”)
修改
覆盖式修改(弃用)
真正修改
删除
批量删除
SpringBoot
简介
不是一门新的技术,只是将spring+springmvc框架进行了简单的封装(<font color="#ff0000">简化配置,敏捷式开发</font>)
不需要引入<font color="#ff0000">坐标依赖包</font>,需要引入<font color="#ff0000">starter的依赖包(启动器=依赖包+配置文件)</font>
有且仅有一个application.yml配置文件
没有war包只有jar包,自带<font color="#ff0000">tomcat服务器</font>
父jar叫做fat jar
黑窗口启动 fat jar---(打包成为jar包,<font color="#ff0000">java -jar</font>)
idea通过<font color="#ff0000">启动类</font>启动
idea创建一个springboot项目
创建一个maven项目
pom
配置jdk 1.8
中导入panter工程标签-----(<font color="#ff0000">声明了这是一个spring boot项目,以及stater依赖的版本</font>)
导入启动项依赖包
导入spring-maven插件(<font color="#ff0000">打包成为jar包时,不会出现依赖丢失</font>)
创建controller
创建<font color="#ff0000">启动类</font>(与所有包同级目录)
启动方式
启动类启动
黑窗口 mvn spring-boot:run
黑窗口 Java -jar
注意:<font color="#ff0000">所有类必须有包</font>
springboot的常用注解
@Configuration
当前类是一个<font color="#ff0000">配置类</font>
@Bean
实例对象注解
@SpringBootApplication(<font color="#ff0000">组合注解</font>)
@SpringBootConfiguration(就是一个<font color="#ff0000">配置类注解</font>)
@EnableAutoConfiguration(<font color="#ff0000">自动装配注解</font>)--只要导入了start依赖就必须写对应的配置文件
@ComponentScan
扫描注解---相当于<font color="#ff0000">context包扫描标签</font>的
@MapperScan注解
配置
配置文件
properties
yml(推荐)
轻量级
<font color="#ff0000">缩进管理</font>
<font color="#ff0000">value后面跟一个空格</font>
json
多环境配置
第一步:application.yml,只用来指定使用哪一个配置文件<br><font color="#3e9a3e">spring:<br> profiles:<br> active: @profileActive@(</font><font color="#ff0000">dev</font><font color="#3e9a3e">)</font><br>
第二步:application-dev(环境名).yml写具体的配置
子主题
引入外部配置文件信息
如一个照片存储路径等
@Value(”${key值}“)
方式2(推荐)<font color="#ff0000">创建一个外部配置类,将所有key赋值给该类<br>@ConfigurationProperties(prefix=”外部配置名“)</font>
热加载:不用重新发布项目,重新加载配置文件中的配置信息
SpringBoot 整合Mybatis
第一步:导入statrt依赖包
第二步:编写配置文件
第三步:在启动类上打<font color="#ff0000">@MapperScan</font>注解,扫描mapper接口
分页助手使用:导入依赖---直接使用
SpringBoot结合ES联系案例
问题1:批量导入索引数据时对象转换json注意<font color="#b71c1c">时间类型的转换以及某些属性的忽略转换</font>
问题2:springboot<font color="#b71c1c">不支持JSP页面</font>,以及普通的<font color="#b71c1c">视图解析器</font>。将html页面创建在<font color="#d32f2f">resouce里的templates</font>里
页面的跳转需要,pro中引入<font color="#b71c1c">Thymelea</font>f启动依赖
${hello}使用<font color="#b71c1c">[[${hello}]]</font>代替
RabbitMQ
简介
spring公司的产品,解决秒杀,高并发,解耦
消息队列:消息先进先出
常用的MQ
RabbitMQ spring官方
ActivMQ apache
<font color="#ff0000">kafak</font> 速度最快,高并发,容易丢失数据
<font color="#ff0000">RocketMQ</font>:阿里的(springcloudalibaba)
底层
JSM:Java messaage system---<font color="#ff0000">activeMQ,ROcketMQ</font>
AMQP:高级MQ协议(<font color="#ff0000">底层都是tcp</font>)--伊朗语言开发(<font color="#ff0000">一次链接,多个channal信道(会话),多路复用</font>)
<font color="#3e9a3e">不同于sql的连接池,一个链接,一次会话,一条sql</font>
四大功能
异步
用户体验好,用户支付,风控归档
解耦
大量模块处理一个事务,一旦一个模块出现问题,所有模块回滚
削峰
高并发,大量请求访问网站,造成瘫痪
可恢复性
出现问题的模块,重新执行
入门应用程序
创建Springboot项目
创建生产者模块
导入mq启动器依赖
yml文件中配置连接的MQ
<font color="#3e9a3e">spring:<br> rabbitmq:<br> host: 192.168.200.129<br> port: 5672<br> virtual-host: /qf<br> username: test<br> password: test</font>
注入RabbitTemplate 对象
<font color="#ff0000">rabbitTemplate.convertAndSend(</font><font color="#3e9a3e">"队列名"</font><font color="#ff0000">,</font><font color="#3e9a3e">"消息内容</font><font color="#ff0000">" );----发送消息</font>
<font color="#ff0000">rabbitTemplate.receive(</font><font color="#3e9a3e">"队列名"</font><font color="#ff0000"> );----</font>接收消息(<font color="#ff0000">手动接受</font>)
创建消费者
创建监听器,监听消息队列
<font color="#ff0000">@Component<br>@RabbitListener(queues = "work_queue")</font>
<div><font color="#ff0000">@RabbitHandler</font></div><div> public void testListener(String <font color="#ff0000">message</font>)--自动监听</div>
rabbit架构模式
虚拟主机V-host
交换机exchage
路由rouetes---交换机与队列之间的传送策略
消息队列queue
生产者
消费者
链接
信息通道channal
RabbitMQ的7种工作模式
简单模式
入门程序,一个生产者一个消费者(<font color="#ff0000">默认交换机</font>)
工作模式
<font color="#ff0000">一个生产者</font>,发给一个消息队列,<font color="#ff0000">多个消费者</font>监听该消息队列(<font color="#ff0000">默认交换机</font>)
多个消费者之间是<font color="#ff0000">竞争关系</font>,消息只能被<font color="#ff0000">一个消费者消费</font>
<font color="#3e9a3e">发布与订阅模式</font>
交换机类型:广播类型**Fanout
<font color="#3e9a3e">无RoutingKey</font>
将消息转发给所有的<font color="#ff0000">绑定的消息队列</font>(所有消费者都能收到消息)
创建广播类型的交换机,bing队列,发送消息<font color="#ff0000">(交换机名,“无rountingkey”,消息内容)</font>
将<font color="#ff0000">监听队列注解放到监听方法上</font>
<font color="#3e9a3e">路由模式</font>
交换机类型:定向类型**Direct
<font color="#3e9a3e">Rounting是一个字符串</font>
创建定向类型交换机,bing队列,<font color="#ff0000">设置rountingkey ,发送消息(</font>交换机名,“<font color="#ff0000">rountingkey</font>”,消息内容<font color="#ff0000">)</font>
<font color="#3e9a3e">主题模式</font>
交换机类型:主题类型**Topic
<font color="#ff0000">Rountingkey带有*#。</font>
*:代表一个单词
#:代表多个单词
例<font color="#ff0000">*.aopple.*</font>
创建主题类型交换机,bing队列,<font color="#ff0000">设置rountingkey (</font>*.aopple.*<font color="#ff0000">) ,发送消息(</font>交换机名,“<font color="#ff0000">aaa.aopple.bbb</font>”,消息内容<font color="#ff0000">)</font>
远程RPC模式(属于远程调用不算MQ)--被apache的<font color="#ff0000">DubboRPC远程调用</font>
<font color="#ff0000">发布确认模式(高级模式)</font>
子主题
使用java代码创建交换机,队列
RabbirMQ配置类(放到消费者模块中)
RabbitMQconfig类
@Bean----队列<br>public Queue getqueue(){<br>return <font color="#ff0000">new queue("队列名")<br></font>return QueueBuilder.----默认持久化,不自动删除<br>}
@Bean---交换机<br>public Exchange getExchange(){<br>return <font color="#ff0000"> ExchangeBuilder.交换机类型("交换机名").build</font><br>}
@Bean---绑定<br>public Binding getbinding(<font color="#3e9a3e">@Autowired @Qualifier("方法名") Queue queue<br>@Autowired(可以省略) @Qualifier("方法名") Exchange exchange</font>){<br>return <font color="#ff0000">BindingBuilder.bind(</font>queue<font color="#ff0000">).to(</font>exchange<font color="#ff0000">).with(“rountingkey”).noargs();</font>
RabbitMQ保证消息不丢失
丢弃的方式:通过开启MQ的事务(<font color="#ff0000">会使得效率变得很低</font>)
confirm机制
return机制
消息丢失的位置
将消息发送到交换机(高)
交换机传到队列(可能性低)
队列到消费者(高)
SpringCloud
简介:
微服务架构的落地的一套技术栈,将一个<font color="#ff0000">完整的项目拆分成多个模块</font>独立开发
每个模块部署到各自的Tomcat服务器上,每一个服务器属于一个微服务
<font color="#ff0000">第一步</font>:用户发送请求,通过nginx负载均衡
<font color="#ff0000">第二步</font>:通过网关指定到对应的模块
6大技术
Eureka(注册中心)---Nacos(阿里巴巴产品)
作用:<font color="#ff0000">注册与发现 ,</font><font color="#000000"></font><font color="#000000"></font><br>
<font color="#000000"></font><font color="#000000">注册:所有模块的</font><font color="#ff0000">ip和端口号</font><font color="#000000">都存储到</font><font color="#ff0000">Eureka</font><font color="#000000">中</font>
<font color="#000000">发现:在Eureka中寻找到</font><font color="#ff0000">其他微服务的IP和端口号</font>
仅仅是发现,模块之间的<font color="#ff0000">通讯还时依靠Feign</font>
Eureka服务端(<font color="#ff0000">单独创建</font>)
创建一个javamaven项目
pom中导入springboot和springcloud的父工程配置
创建Eureka服务端项目
创建配置yml,服务器<font color="#ff0000">端口号</font>,<font color="#ff0000">微服务的名字</font>,eureka配置
实例化,默认localhost
是否将自己本身注册到eureka
是否同步其他eureka的集群
指定eureka的<font color="#ff0000" style="">url地址 </font>http://<font color="#3e9a3e">${eureka.instance.hostname}</font>:<font color="#3e9a3e">${server.port}/</font>eureka/
<ul><li>创建启动类,需要打上<font color="#ff0000">@EnableEurekaServer</font></li></ul>
Eureka客户端(在每一个<font color="#ff0000">微服务内</font>)
添加依赖包
eureka:<br> client:<br> <font color="#ff0000"> # 指定Eureka服务地址</font><br> service-url:<br> defaultZone: <font color="#ff0000">http://localhost:8761/eureka</font>
在启动类上打<font color="#ff0000">@EnableEurekaClient-----注册</font>
Eureka安全
给Eureka<font color="#ff0000">服务端</font>添加<font color="#ff0000">用户和密码</font>,自己的微服务才能注册和发现
在服务端添加<font color="#ff0000">安全启动器依赖</font>
Eureka高可用
集群搭建微服务
Eureka服务端之间关系平等,不存在<font color="#ff0000">主从关系</font>
eureka服务端的<font color="#ff0000">uri除了要有自己的地址还要有另外几台eurka的地址</font>
<font color="#ff0000">微服务需要同时注册到多个eureka服务端中,</font><font color="#3e9a3e">只会注册到其中一台</font>
<font color="#ff0000">30秒进行一次心跳检查,宕机后90秒进行将微服务注册到另一台eureka服务器</font>
注:<font color="#ff0000">发现一次后会存到本地缓存</font>,即使服务端宕机没有微服务,也不会找不到
CAP定律
C - 一致性,A-可用性,P-<font color="#ff0000">分区容错性</font>,这三个特性在分布式环境下,只能满足2个<br>
<font color="#ff0000">分区容错性</font>:集群微服务,一台微服务器宕机,并不影响使用
一致性:两台服务器数据同步(<font color="#ff0000">强一致</font>)
<font color="#ff0000">可用性</font>:
Ribbon(负载均衡)
作用:在<font color="#ff0000">每个微服务内</font>,都有负载均衡
实现负载均衡的策略
轮询--使用不多
随机--使用不多
权重(<font color="#ff0000">通过轮询赋予权重</font>)
<font color="#ff0000">被调用方</font>并发性数最小
使用
导入启动器(Eureka会顺便导入)
在客户端配置
<font color="#ff0000"># 指定具体服务的负载均衡策略</font><br><font color="#3e9a3e">QF-SEARCH:<br> ribbon:</font><br> <font color="#ff0000"> # 具体负载均衡使用的类--随机测试</font><br> <font color="#3e9a3e">NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule</font>
Feign(远程调用---服务之间的通讯)
模块之间的调用方式
http
RPC
MQ
<font color="#ff0000">LoadBalancerClient</font>(负载均衡)---使用<font color="#ff0000">Ribbon实现负载均衡策略算法</font>
底层方式
创建config配置类
<font color="#ff0000">RestTemplate</font>(ClientHttpRequestFactory factory)
<font color="#f44336">补充</font>:RedisTemplate--连接redis
RabbitTemplate----连接MQ
<font color="#ff0000">ClientHttpRequestFactory</font>
第一步:<font color="#ff0000">@LoadBalancerClient :</font>去Eureka中根据<font color="#ff0000">微服务的名字</font><font color="#3e9a3e">发现其中一个</font><font color="#ff0000">微服务的地址<br></font> :<font color="#ff0000">@RestTemplate:</font>去Eureka中根据<font color="#ff0000">微服务的url</font>发现<font color="#ff0000">远程调用</font><font color="#ff0000"><br></font>
第二步:从一个微服务中获取<font color="#ff0000">uri</font><br> 远程调用resttemplate.<font color="#3e9a3e">getForObject</font>(<font color="#ff0000">url+请求地址,返回值类型,是否有参数</font>)
<font color="#ff0000">远程调用手动代码</font>
feign封装
在调用服务放导入启动器
创建被调用的Feign接口
<font color="#ff0000">@FeignClient("QF-SEARCH")</font><br>@RestController<br>public interface SearchFeign {<br><br> /**<br> * 搜索feign接口方法, 建议复制被调用服务方法, 不要手写, 容易写错<br> * @return<br> */<br> <font color="#ff0000"> @RequestMapping(value = "/search")</font><br> public <font color="#ff0000">String</font> list();<br>}
在<font color="#ff0000">启动类</font>上打扫描接口注解<font color="#ff0000">@EnableFeignClients(basePackages = {"com.qf.feign"})</font>
Feign传递参数
传递单个参数--基本类型
@GetMapping("/parm/<font color="#3e9a3e">{id}/{name}</font>")
@<font color="#ff0000">PathVariable</font>(value=“id”)--单个参数
@<font color="#ff0000">RequestParam</font>(value=“id”)---多个参数
<font color="#ff0000">value 必须加上</font>
传递对象
使用POST请求
通过json传请求体
postman发送一个对象json串
json类型
Feign的Fallback(远程调用失效问题)
因为<font color="#ff0000">本地缓存更新不及时</font>导致不知道微服务已经宕机--解决方案:<font color="#ff0000">降级处理(兜底处理)---底层走的熔断器</font>
在自己本身中配置处理配置(<font color="#ff0000">实现远程调用接口中的全部方法</font>,当远程调用失败后,走自身的实现类)
方式一(实现类)
@Component<br>@RequestMapping(<font color="#ff0000">"/fallback"</font>)<br>public class SearchFeignFallBack implements SearchFeign {
远程调用接口@FeignClient(value = "QF-SEARCH", <font color="#ff0000">fallback = SearchFeignFallBack.class)</font>
<font color="#3e9a3e">配置文件中开启降级处理<br>feign:<br> hystrix: -----</font><font color="#ff0000">-熔断</font><br><font color="#3e9a3e"> enabled: true</font>
方式二(<font color="#ff0000">远程调用降级工厂</font>)
Hystrix(熔断器)
作用:在远程调用中A调用B调用C调用D----<font color="#ff0000">形成一条调用链,当中间一个微服务出现问题引发雪崩问题</font>
<font color="#ff0000">先熔断在走降级处理</font>
解决雪崩问题
熔断,<font color="#ff0000">阈值</font>---连续远程调用<font color="#ff0000">3次</font>仍然不成功就会熔断
缓存:熔断后先请求缓存功能
降级处理,降级方法使用<font color="#ff0000">熔断器线程池</font>还是<font color="#ff0000">信号量</font>(<font color="#ff0000">tomcat线程池)</font>---产生<font color="#ff0000">隔离问题</font>
隔离:降级方法由谁执行---默认走熔断器的线程池
熔断器操作
<font color="#ff0000">给被调用方添加--搜索微服务</font>
导入熔断器启动器
在Conctroller的方法上<font color="#ff0000">@HystrixCommand(fallbackMethod = "listBack",</font>commandProperties = {<br> <font color="#3e9a3e"> @HystrixProperty(name = "execution.isolation.strategy",value = "</font>SEMAPHORE<font color="#3e9a3e">")---(信号量)熔断隔离级别</font>}<font color="#ff0000">)</font>
下面写<font color="#ff0000">自身降级</font>方法----自身降级处理不了,在调用<font color="#ff0000">兜底处理</font>
启动类上添加熔断器注解//开启Hystrix<br><font color="#ff0000">@EnableCircuitBreaker</font><br>
断路器
异常,<font color="#ff0000">大量的线程中只有一小部分有异常</font>
1导入断路器监控包
2在启动类上添加开启监控注解<font color="#ff0000">@EnableHystrixDashboard</font><br> 扫描注解//扫描Hystrix的servlet所在包<br><font color="#ff0000">@ServletComponentScan("com.qf.servlet")</font>
3编写servlet
断路器的属性
缓存
<font color="#ff0000">成功一次远程调用后,将请求的数据存到本地缓存</font>
<font color="#ff0000">FIlter过滤器</font>将查询的结果拦截在<font color="#ff0000">缓存</font>中
流程
在请求微服务添加缓存依赖
启动类上添加//扫描过滤器所在包<br><font color="#ff0000">@ServletComponentScan("com.qf.filter")</font>
编写过滤器
<font color="#ff0000">service层,写缓存业务逻辑</font>
GateWay(网关)
概念:
帮助微服务架构提供一种简单有效**统一的REST 请求路由管理方式**。
<font color="#ff0000">请求通过nginx负载均衡后再由网关转发对应的微服务(</font><font color="#3e9a3e">网关也是一个微服务,需要注册到注册中心</font><font color="#ff0000">)</font>
一切请求都要先通过网关
<font color="#ff0000">两者冲突,只能引用其一</font>
核心功能
路由
断言函数
过滤器
局部过滤器
手动为某一位服务添加前缀
# 路由表<br> routes:<br> # id: 唯一标识<br> - id: qf-search<br> # 路由服务地址: 也就是业务服务的访问地址<br> # uri: http://localhost:9003<br> # 采用lb协议,会从Eureka注册中心获取服务请求地址<br> # 路由地址如果通过lb协议加服务名称时,会自动使用负载均衡访问对应服务<br> # 规则:lb协议+服务名称<br> uri: lb://QF-SEARCH<br> # 断言: 用于拦截匹配用户在浏览器中输入的访问路径<br> predicates:<br> - Path=/search/**<br> filters:<br> # 去除路径前缀过滤器<br> - StripPrefix=1<br> # id: 唯一标识
在通过过滤器去掉前缀
全局过滤器
9大默认全局过滤器(默认开启)
自定义全局过滤器class MyGlobalFilter implements <font color="#ff0000">GlobalFilter, Ordered</font>
Config(配置中心)重要
简介
将所有微服务的配置文件,<font color="#ff0000">统一放到配置中心管理</font>
在配置中心修改配置文件,立马生效
<font color="#ff0000">运行项目会自动发现配置中心的配置文件发生变化</font>
更加安全
配置中心服务端(连接码云)
生成公钥与私钥(<font color="#ff0000">RSA算法生成</font>)
子主题
bootstrap.yml
系统级别的配置文件(Tomcat启动时加载)
子主题
不停机维护
原理:config模块连接<font color="#ff0000"><span class="equation-text" data-index="0" data-equation="消息队列" contenteditable="false"><span></span><span></span></span></font>,其他模块<font color="#ff0000">监听消息队列</font>
实现
导入<font color="#ff0000">BUS组件的rabbirmq</font>包
导入Autuator<font color="#ff0000">监控启动器(监控GIt)</font>包
management:<br> endpoints:<br> web:<br> exposure:<br> include: "*"<br>
<font color="#ff0000">controller</font>://动态刷新<br><font color="#3e9a3e">@RefreshScope</font><br>public class TestController {<br><br> @Value("${version}")<br> private String version;<br><br> @RequestMapping("/version")<br> public String testVersion() {<br> return version;<br> }
变更后,<font color="#ff0000">手动发送一个post的git变更请求</font>
使用Gitee实现自动配置
Gitee中的<font color="#ff0000">WebHooks</font>
<font color="#ff0000">内网穿透(没有域名时)</font>
全链路监控
Sleuth
<font color="#ff0000">监控各个微服务之间混乱的远程调用</font>
所有微服务中加入<font color="#ff0000">全链路监控启动器</font>
配置文件中开启前端<font color="#ff0000">监控日志<br></font><font color="#3e9a3e">logging:<br> level:<br> org.springframework.web.servlet.DispatcherServlet: DEBUG</font><font color="#ff0000"><br></font>
Zipkin
<font color="#ff0000">图像化界面显示(收集日志,监控日志)</font>
收集的日志放到<font color="#ff0000">rabbitMQ</font>中,zipkin从MQ中取
mq和zipkin的连接需要在<font color="#ff0000">创建zipkin容器时指定</font>
zipkin的持久化需要在<font color="#ff0000">创建zipkin容器时指定ES</font>
搭建Zipkin容器
导入zipkin启动器(<font color="#ff0000">包含sleuth启动器</font>)
配置文件中配置zipkin的IP和端口<br><font color="#3e9a3e">sleuth:<br> sampler:<br> probability: 1.0 # 指定Slueth收集日志的百分比<br> zipkin:<br> base-url: http://192.168.200.129:9411/<br> sender:<br> type: </font><font color="#ff0000">web(rabbit)</font><br>
ZooKeeper
简介
apache公司开发,在Java<font color="#ff0000">分布式架构</font>中,也会频繁的使用到Zookeeper。
Zookeeper就是一个<font color="#ff0000">文件系统</font> +<font color="#ff0000"> 监听通知机制</font>
架构
每一个节点称为ZNode(<font color="#ff0000">树结构</font>)
节点可以存储数据
节点并称不可以重复
常用命令
<font color="#ff0000">ls / </font> 查看节点
<font color="#ff0000">get /节点名 </font> 查看节点内容
<font color="#ff0000">create /节点名/子节点 内容 -</font>---创建节点
<font color="#ff0000">delete /节点名</font>----删除节点
<font color="#ff0000">deleteall /节点名</font>----删除节点及其子节点<br>
<font color="#3e9a3e">set /节点名 新的内容</font>---修改节点
4种节点类型
永久节点
永久有序节点(<font color="#ff0000">在节点名称后面加上顺序序号</font>)
临时节点
临时有序节点
监听通知机制
<font color="#ff0000">集群搭建zookeeper</font>
<font color="#ff0000">一个leader机</font>和follower从机
<font color="#3e9a3e">Java代码操作zookeeper</font>
创建操作zoo keeper工具类
代码实现节点的基本操作
//获取zookeeper节点操作对象<br> private CuratorFramework cf = ZkUtils.getCf();
cf.create().withMode(CreateMode.PERSISTENT).forPath("/qf2","uuuu".getBytes());---<font color="#ff0000">添加节点</font>
cf.setData().forPath("/qf2","oooo".getBytes());---<font color="#ff0000">修改节点</font>
List<String> list = cf.getChildren().forPath("/");---<font color="#ff0000">查看节点</font>
byte[] bytes = cf.getData().forPath("/qf2");----<font color="#ff0000">查看节点数据</font>
cf.delete().deletingChildrenIfNeeded().forPath("/qf2");---<font color="#ff0000">删除节点</font>
<font color="#ff0000">创建各种类型的节点</font>
<font color="#ff0000">监听通知机制</font>
分布式任务,事务
简介:一群人各自做不同事情,共同完成一件事请
<font color="#ff0000">分布式锁:</font>
<br>- 传统的synchronized以及Lock锁都是基于JVM的,由于在分布式系统中,会有多个Web容器同时运行,导致多个Web容器内部的传统锁已经不存在互斥性了
高并发秒杀问题
zookepper分布式锁
基于<font color="#ff0000">临时有序节点</font>来实现分布式锁
zookeeper实现<font color="#ff0000">分布式锁包</font>
创建zoo keeper连接工具类
//============= <font color="#ff0000">创建zookeeper锁对象</font> ==================<br> InterProcessMutex lock = new InterProcessMutex(cf,"/lock");
//==============<font color="#ff0000">zookeeper加锁</font> ==============<br> if(lock.acquire(1, TimeUnit.SECONDS)) {
//============ <font color="#ff0000">zookeeper释放锁</font> ===============<br> lock.release();<br>
Redis分布式锁
通过<font color="#ff0000">setnx</font>命令,<font color="#ff0000">如果key存在表示已经上锁</font>
<font color="#ff0000"><i>boolean=redisTemplate.opsForValue.setIfAbsent</i></font>(<font color="#3e9a3e">key</font>,value,过期时间(防止死锁));/返回值为<font color="#ff0000">真</font>得到锁
redisTemplate.delete(key)
定时分布式事务
Elastic-job
每个微服务都拥有定时器,一个执行其他不会执行
引入Elastic-job包
<font color="#ff0000">创建分布式定时任务初始化类</font>ElasticJobConfig
配置Zookeeper注册协调中心
子主题
xxl-job
LCN
SpringCloudAlibaba
简介:阿里在Springcloud的基础上进行2次开发封装
主要技术
Nacos(注册及配置中心)
简介:将Eureka与Config封装在一起
配置中带有一个图形化界面
版本对应问题(<font color="#ff0000">springboot也要对应</font>):所有SpringCloudlibaba的<font color="#ff0000">组件版本要配套</font>,<font color="#ff0000">阿里版本要与cloud版本对应</font>
nacos注册中心
nacos服务端
提供者微服务
<font color="#ff0000">nacos注册启动器</font>
<font color="#ff0000">yml配置nacos地址端口</font>
消费者微服务
nacos注册器启动器
yml.配置
远程调用同feigin相同
nacos配置中心
提供者微服务,nacos<font color="#ff0000">配置启动器</font>
bootstrap配置文件
<font color="#ff0000">namespace: 命名空间<br>group:组名</font>
nacos中添加配置yaml
文件名
组
格式yaml
内容
<font color="#ff0000">命名空间</font>
管理大量的微服务<font color="#ff0000">不同开发阶段配置文件</font>
<font color="#ff0000">组</font>
管理大量微服务配置文件<font color="#ff0000">名字可能相同</font>
<font color="#ff0000">动态配置</font>
直接使用提交
<font color="#ff0000">@RefreshScope注解</font>
引入外部配置文件(<font color="#ff0000">将各个配置文件分离</font>)
子主题
sentinel(熔断器的图形化界面)
线程降级
服务降级
熔断器(在<font color="#ff0000">图形化界面做降级处理</font>)
之前需要要controller层上打<font color="#ff0000">熔断器</font>注解
RockerMQ(消息队列)
效率略低于RabbitMQ,支持消息<font color="#ff0000">总线BUS组件</font>
Seatac(分布式事务)
曾经学过LCN分布式事务
Dubbo(远程调用)
服务之间的RPC通讯
0 条评论
下一页