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