springCloud笔记
知识点
-
dependencyManagement和Dependencies:dependencyManagement一般出现在夫工程中,用来指明一些包的版本或者说用来规定一些包的版本,当它的子工程在引入依赖的时候如果没有写版本号,则从下往上以此挨个找父工程中有没有规定这个包的版本,找到的第一个就用它不再往上找了。但是父工程只是一种规定,它的子工程,不是说继承了父工程在子工程中就有了父工程的依赖,子工程必须使用Dependencies自己引入依赖,在子工程中才有相应的依赖,注意:必须是自己引入才行,父工程只是提供版本的规定,并不是继承了父工程在子工程中有有了依赖了,子工程自己引入了才有相应的依赖
-
热部署:该功能只在开发阶段开启,生产上线必须关闭,要不你每改一次代码,系统整个重启一次,系统跳一次,在上线后是不能这样的
-
将微服务的消费者即cloud-consumer-order80端口设置为80原因:就是想当客户端访问我们的这个服务的时候不需要输入端口号,直接输入ip就行了,因为当客户端在地址栏输入地址的时候如果只输入ip则默认端口号为80,也就是客户端在地址栏输入地址的时候如果只输入ip,默认其访问的是ip:80,所以我们将我们的面向客户的服务端口号设置成80,当客户端访问我们的服务的时候,只输入ip即可
-
@Resource
注解和@Autowired
注解功能一样,都是用来注入的,@Resource
是java自带的,@Autowired
是spring提供的 -
当把一个项目clean然后install以后,这个项目就被打包到我们本地的仓库中了,这样其他项目就可以在自己的pom.xml文件中写上要引入的包的gav(每个项目在自己的pom中都会写自己的gav);所以就可以把多个微服务都要用的类和方法单独提出来放到一个项目中,然后将该项目打包,需要用到的其他项目只需要引入该项目即可
-
在application.yaml中,
service-url:
的defaultZone
是用来指明当前这个服务(项目)是注册在哪个注册中的,这里就写要注册进的注册中心的地址,如果注册中心是个集群,则需要注册进该集群的所有注册中心上,也就是这里要写上该集群中的所有注册中心的地址eureka: service-url: #defaultZone: http://localhost:7001/eureka defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
-
服务提供者的Controller中,写这个是为了我们观察具体是服务提供者集群中的谁(哪个机器)给我们提供了此次服务
@Value("${server.port}") //可以读取配置文件application.yml中的sever.post的值 private String serverPort;
-
因为服务提供者是集群提供服务,所以服务消费者在请求提供者的服务时,不再写死,也就是不再具体指定服务提供者的具体ip和端口,只需要指定服务的名字就行,提供同意服务的机器中配置的服务名字是一样的(也就是同一个服务集群中的机子配置的服务名是一样的),服务名配置在application.xml中
spring: application: name: cloud-payment-service #服务名称,当其注册在注册中心中时,注册中心显示的这个服务的名称就是这里配置的,同一个服务的集群的各机子上的服务名称(该名称)是一样的
服务消费者在找服务时,写的就不是服务提供者具体的地址了,而是服务名
public static final String PAYMENT_URL="http://CLOUD-PAYMENT-SERVICE"; //CLOUD-PAYMENT-SERVICE为服务名
-
当服务提供者是集群时,需要使用@LoadBalanced注解赋予RestTemplate负载均衡的能力,也就是在服务配置类ApplicationContextConfig的生成restTemplate对象的方法上面写上@LoadBalanced
-
当给服务提供者的application.xml中写上配置
instance: instance-id: payment8001
在注册中心显示这个服务提供者的时候,就不会显示其默认的情况即主机名跟上服务名跟上端口,如下:
而是会显示你配置的
instance-id
后面写的东西,配置完显示如下:
-
当给服务提供者的application.xml中写上配置
prefer-ip-address=true
,就是当鼠标放在配置了这个属性的服务的服务名上,可以显示服务的ip地址,而不是显示主机名instance: instance-id: payment8001 prefer-ip-address: true #访问路径可以显示IP地址
如果不配置,则鼠标放在服务名上,显示如下:
配置后,当鼠标放在配置了这个属性的服务的服务名上,显示如下:
-
当给一个服务提供者配置上服务发现功能后,就可以在该服务提供者的代码中直接注入DiscoveryClient,然后使用该discoveryClient对象去得到在注册中心注册了的服务的相关信息,比如:discoveryClient.getServices(),得到的就是所有注册在注册中心的服务的名字组成的list集合,discoveryClient.getInstances(”服务名“)得到的就是所有这个服务(就是你指定的服务名)所有的提供者ServiceInstance组成的list集合
-
Eureka自我保护:默认情况是开启,而且时间是90s,也就是说任何一个服务90s之内没有心跳,则注销该服务,如果在某个短时间之内注销的服务太多,此时Eureka就开始自我保护了,也就是从此时开始不再注销任何服务
-
springboot和zookeeper整合需要用到包
spring-cloud-starter-zookeeper-discovery
这个包中自带了一个zookeeper3.5.3版本,但是当服务器的zookeeper版本不是3.5.3的话用3.5.3.就不行,要引入服务器上的zookeeper的版本,但是如果直接引入的话项目中就有两个zookeeper的包了,只不过版本不同,此时就会出现版本冲突,所以在引入时要排除掉自带的版本,引入需要的,我的服务器上的zookeeper版本是3.7.1,则包引入如下:<!-- SpringBoot整合zookeeper客户端 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> <!--先排除自带的zookeeper3.5.3--> <exclusions> <exclusion> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </exclusion> </exclusions> </dependency> <!--添加zookeeper3.7.1版本,添加的版本要和服务器上zookeeper的版本一致--> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.7.1</version> </dependency>
-
经典的CAP理论图,三个不可能全占,只能占两个
-
Ribbon本地负载均衡客户端 VS Nginx服务端负载均衡区别:说白了就是Nginx是在服务器端,就是你只管发请求,至于最终是哪个机器给你提供服务的你不用管,你也管不着,最终哪个机器提供服务,各机器之间怎么提供服务(也就是负载均衡策略)都是由nginx负责的;而Ribbon就是你在发请求的时候就可以知道提供这个服务的所有机子,你可以指定具体的机子给你提供服务,你也可以指定各机子负载均衡策略
-
替换负载均衡策略时的自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化定制的目的了。也就是不能和放在主启动类所在的包及其子包,与因为主启动类上有@SpringBootApplication而这个注解自带@ComponentScan注解,而@ComponentScan这个注解在哪个类上就表明它会扫描该类所在的包及其子包,现在@ComponentScan在主启动类上就表明它会主启动类所在的包及其子包,而替换负载均衡策略是自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,所以自定义配置类不能放在主启动类所在的包及其子包下
-
Feign日志是监控feign接口的调用情况,所以日志的配置要写在服务消费方
-
JMeter:压力测试工具
-
Hystrix既可以用在服务消费端也可以用在服务提供端,但是一般是用在服务消费端
-
hutool工具包:可以用
</dependency>
引入,官网:hutool.cn -
服务降级和服务服务熔断是不同的:服务降级是一旦出问题就去到兜底函数,而一旦是正确的请求就去正确的函数;而服务熔断是,出现问题(满足熔断条件:在快照时间窗内,必须满足请求总数阀值才有资格熔断。默认为20,意味着在时间窗内,如果该hystrix命令的调用次数不足20次,即使所有的请求都超时或其他原因失败,断路器都不会打开。)先服务降级就是去兜底函数,一旦变成了熔断,在一段时间内(也就是服务没恢复的时间内)即便你的请求是正确的,它也会到兜底函数去,然后会慢慢试图恢复,也就是随着请求的正确率提高了,会慢慢恢复,看能不能调正确的那个函数而不是兜底的函数,如果可以,则服务就恢复过来了,也就是后面调又是正确的函数了不是兜底函数了,如果后面又出现熔断了,则再进行相应的处理
-
GateWay的Predict的常用Route Predict中的Host Route Predict是指请求中的请求头中的host属性得和配置的这里匹配上才能通过
-
GateWay的自带的GatewayFilter常常是无法很好的满足我们的需求的,一般情况下我们都会使用自定义Filter
-
SpringCloud Config分布式配置中心的配置文件读取规则是指,你想要读取那个文件你就要按照人家的规则,比如,人家说你的请求如果这样写
/{label}/{application}-{profile}.yml
就表示要读取你在yml中配的仓库下的label分支下的xxx-zzz.yml文件,一般配置文件起名时,xxx写服务名,zzz写环境,就是label那里要写你要找的分支,后面具体文件只要格式对了且你要找的和仓库中的名字一样就行,但是一般配置文件都会起名为“服务名-环境” -
引入actuator是用来是说,当我自己发生变化了,我能够被别人监控到(除了网关不加,其他基本都加)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
actuator一般和web包一起出现,即一般一起引入
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
-
在使用配置中心config时,
-
对于config client中的配置bootstrap.yml,是说我指定从uri处(这里的uri是你要从哪个配置中心中拿配置,你就写那个配置中心的地址),告诉uri为
http://localhost:3344
的配置中心我要仓库下的label指定的分支在这里是master分支下的文件名为name-profile在这里是config-dev的配置文件,然后得到配置文件后就自动引入了我的这个项目,也就是用config标签指定你想要远程拉取的配置文件后,远程配置文件找到后就引到你的这个工程中了,就像是你在工程中写了一个配置文件一样,所以拉去过来的远程配置文件就可以直接用了,就像自己写在工程中的配置文件一样,该生效生效,该用啥用啥,该咋用咋用;config: label: master #分支名称 name: config #配置文件名称 profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml uri: http://localhost:3344 #配置中心地址k
-
对于config server,其实它的主要作用就是去指定连接哪个github仓库,当然它自己也指定了分支,主要就是如果连接它的客户端没有指定分支就用server自己指定的,如果连接它的客户端指定了分支就用人家指定的;其次,config server可以通过相应的地址(就是按照官网指定的格式,写出你想访问的文件的地址)去访问相应的文件
-
-
springCloud stream目前只支持RabbitMQ和kafka
-
stream的消费者是一种监听模式,也就是并不是消费者主动去调方法去拿channel里面的东西,而是处于一种监听模式,就是你配置好了你的这个消费者消费的是哪个channel,然后每当这个channel中有消息的时候就会自动调用@streamListener所注释的方法
-
每个微服务连接到MQ的时候,如果没有配置组信息,则MQ会为每个接进来的微服务自动生成一个组,且该微服务处于这个组中;而每个消息可以被不同的组消费但每个组消费同一个消息只能消费一次,也就是说一个消息能被不同的组消费,但对于同一个组来说一个消息只能被该组中的一个消费者消费一次
-
当给一个消费微服务配置上group后,如果它断开了,在它断开期间生产者向该组所在的队列发送了消息,然后又重新启动该微服务,则在启动后该微服务还是能够去(有资格,有能力)消费在它断开期间发送到队列中的还未被消费的消息的;如果一个消费微服务没有配置group,如果它断开了,在它断开期间生产者向该组所在的队列发送了消息,然后又重新启动该微服务,则在启动后它没有能力去(不能)消费在它断开期间发送到队列中的还没有被消费掉的消息
-
sentinel:QPS和线程数
- QPS:就是指设置时间内只能有多少个请求数,如果来的请求数一旦超过设置的请求数,则限流
- 线程数:是指能处理请求的线程有多少个,就是在设置时间内我不管你来多少个请求,我能处理请求的线程数就这么些,如果我能处理就处理,处理不了的就限制
-
sentinel关联流控模式:
如果选择的流控模式是关联,则配置的阈值类型和单机阈值是对关联资源,在这里就是对/testB进行配置的,也就是当/testB的访问超过配置的阈值的时候,/testA就会有所配置的流控效果
- sentinel:预热流控:默认 coldFactor 为 3,即请求QPS从(threshold / 3) 开始,经多少预热时长才逐渐升至设定的 QPS 阈值。也就是系统刚开始的单机阈值是(threshold / 3),单机阈值是(threshold / 3)也就表示系统每秒能接受的请求数,经过设置的预热时长后,系统的单机阈值变成自己设置的(填的)单机阈值,也就是系统每秒能接受的请求数变成了自己设置的单机阈值
比如这里,系统单机阈值刚开始是10 / 3 约等于3,也就是刚开始系统每秒能接受的请求数为3,如果超过3则进行流控;然后过了5秒后系统单机阀值才慢慢升高恢复到10,此时系统每秒能接受的请求数为10,如果超过3则进行流控
-
sentine热点key限流:
注意:要在需要热点限流的方法上面写上@SentinelResource而这个注解里面的参数value是唯一标识这个方法的,也就是在sentinel控制台给这个方法配置热点限流的时候,资源名就是@SentinelResource注解里的value的值,就表示是给@SentinelResource注解里的value的值是该资源名的方法配置的热点限流,@SentinelResource而这个注解里面的参数blockHandler就表示当在进入限流状态中有发给/testHotKey的请求全部执行方法名为blockHandler配置的名字。
然后配置的参数索引是从0开始,这里就是你想对这个方法的哪个参数进行监控限流,你就写对应参数的下标,注意,写的下标是你想对相应方法中的下标为几的参数进行监控,而不是真正请求中的参数下标,是这个方法中的,然后配置上单机阈值和统计窗口时长,如上图,就表示,我对@SentinelResource注解里的value的值为testHotKey的方法中的下标为0的参数进行监控,也就是对图中testHotKey方法中的p1参数进行监控,当1s内带有p1参数的/testHotKey的请求数大于1时就限流,也就是在统计窗口时长1s,也就是在下一秒中,所有发给来(就是发给/testHotKey)的请求,是所有发过来的,不管带不带参数p1,只要是发给/testHotKey的所有请求都执行方法dealHandler_testHotKey
-
sentinel如果对blockHandler 和 fallback 都进行了配置,则这两种错误(就是java内部错误和超出sentinel配置的流量)同时出现时会执行blockHandler指定的兜底函数也就是超出sentinel配置的流量的兜底函数
-
在启动seata时候,如果你用的seata是0.9版本的,数据库是5.7版本的,则会报错,解决方法参考:http://www.javashuo.com/article/p-swjxabid-uo.html
其他
- 在线工具(可以进行json文件格式化):tool.lu
- 用IDEA生成类的继承树
- zuul是Netflix的,geteWay是spring社区的