- Spring-Cloud和Spring-Boot有依赖性,共同使用时,需在Spring-Cloud确认他们合适的版本关系。(https://start.spring.io/actuator/info获取详细的json结果,再用json在线工具(或者用火狐浏览器搜索)处理一下就能看到了)。
- 技术模块学习:服务注册中心(Nacos)、服务调用2(OpenFeign)、服务降级(sentienl)、服务网关(gateway)、服务配置(nacos)、服务总线(nacos)。
- 项目一开始,先确定编码形式;
再注解生效激活。
java编译版本选择
文件类型过滤(将不想看到的没什么用的文件过滤掉)
-
构建支付模块。(建module、改POM、写YML、主启动、业务类)
-
多个模块需要Run DashBoard(启动全部),因为每个模块都有一个Run。
-
热部署。
<!-- 添加devtools依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- 打包时不要它 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
勾勾全部打上。
ctrl+alt+shift+/ 后点击Register,把下面两个勾勾打上。
- Run Dashboard(没有自动生成解决):在项目的.idea文件中的workspace.xml文件里面的component 里的RunDashboard中加入下面的配置再重启idea即可。
<option name="configurationTypes" />
<set>
<option value="SpringBootApplicationConfigurationType"/>
</set>
</option>
- 工程重构(提取公共部分做成依赖),其中groupId和artifactId为公共模块的值.
<dependency>
<groupId>com.syf.study</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
- 使用Eureka服务注册。下面的这个name就是注册进服务的名字,确定了之后尽量不要修改。
spring:
application:
name: cloud-pay-service
在引入了spring-cloud依赖的前提下:
客户端
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
服务端
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
注册进eureka
eureka:
client:
#表示是否将自己注册进EurekaServer默认为ture
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
如果是eureka的server端,则上面两个ture可以都改为false。(如果是在一台电脑上测试集群需在C:\Windows\System32\drivers\etc\hosts下修改配置:在最后面加上映射####################springCloud2021########################
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com)
eureka、zookeeper、consul
- CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。
- eureka是ap,zookeeper、consul是cp
- ribbon负载均衡
- openfeign微服务调用,默认超时1s.
压力测试
jmeter.bat
服务异常处理
- 服务降级:相当于,返回等待页面,等待一段时间再访问。
- 服务熔断:相当于直接拉闸断电,停止访问,然后再慢慢恢复。
- 服务限流:相当于排队,来的多了就排队,或者不给服务。
如果没有处理机制,会导致慢的将快的反应也拖慢
Hystrix对以上问题处理。
服务降级
- List item
- 指定异常方法
@HystrixCommand(fallbackMethod = "payment_errorhandler",//如果这个方法出问题了(不管超时还是其他异常),找那个方法兜底
commandProperties = @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000"))//设置超时时间,这里设置3秒,超过3秒就算异常
public String payment_ERROR(Integer id){
int time=5;
try {
TimeUnit.SECONDS.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "线程池"+Thread.currentThread().getName()+"payment_ERROR,id="+id+"`````````````````````````";
}
public String payment_errorhandler(Integer id){
return "线程池"+Thread.currentThread().getName()+"payment_ERROR,id="+id+"??????????????????????????";
}
- 默认异常方法,只在方法上加@HystrixCommand标签,
在类上写@DefaultProperties(defaultFallback = “payment_globalHandler”)//全局的异常处理方法,payment_globalHandler为处理全局异常的方法。注意:全局方法不能传参 - 集中处理,写一个类实现业务接口,然后在实现的方法里写上处理错误的机制,然后在业务的FeignClient标签里填写fallback = 写的那个类的class。
服务熔断
- 熔断打开,请求不再进行调用当前服务,当打开时长达到所设时钟进入半熔断状态。
- 熔断关闭,熔断关闭不会对服务进行熔断。
- 熔断半开,根据请求规则调用当前服务,如果请求成功且符合规则认为当前服务恢复,关闭熔断。
网关GateWay
- 路由:构建网关的基本模块,由ID、目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由。
- 断言:请求与断案相匹配进行路由。
- 过滤 :使用过滤器,可以在请求被路由前或者路由后对请求进行修改。
- 配置文件和代码两种方式写路由(最好配置),断言写配置,过滤实现GlobalFilter, Ordered这两个接口。
- 使用cmd命令 curl 测试
配置中心
- 将每个微服务中的公共部分抽取出来,方便管理。
- 读取规则
#搭建好后访问该网址http://config-3344.com:3344/master/application-dev.yaml的意义为
# 其中config-3344.com:3344为访问ip+port,master为分支,application-dev.yaml为访问的文件
文件名字的减号也要遵循
- application.yaml是用户级,bootstrap.yml是系统级,优先级更高。
- git上的信息修改后,如何动态使其他客户端生效,暴露端口和添加注解,需发送post的http://ip:port/actuator/refresh请求先刷新,这样客户端才能在不重启的基础上,拿到最新的
RabbitMQ
- 一次刷新处处生效,全局通知。
先post请求通知中心http://localhost:3344/actuator/bus-refresh
中心
# rabbitmq的相关配置
rabbitmq:
host: 116.62.34.43
port: 5672
username: guest
password: guest
# rabbitmq的相关配置 暴露刷新配置的端点
management:
endpoints:
web:
exposure:
include: 'bus-refresh'
客户
# rabbitmq的相关配置
rabbitmq:
host: 116.62.34.43
port: 5672
username: guest
password: guest
- 定点通知。
在网址后加上需定点通知的spring-application-name:端口号,其余配置不变。
http://localhost:3344/actuator/bus-refresh/config-client:3355
cloud Stream
- 屏蔽差异,构建中间件,不去关注每一种消息的技术,类似于jdbc
- 遵循的是发布订阅的模式。
- Binder 连接中间件,屏蔽差异
- Channel 通道,是队列Queue的一种抽象,在消息通讯系统中就是实现存储和转发的媒介。通过channel对队列进行配置。
- Source和Sink,相当于Spring Cloud Stream自己,从Stream发布消息就是输出,接受消息就是输入。
- 将消费者分组,解决重复消费问题。不同组的,发送方发送几条就会收到几条,同组的会竞争,发送方发两条,在统一组内的接收方只会接受两次,这两次会在组内竞争分配。
- 持久化,如果没有设置Group,当消费者宕机后重新启动会丢失数据,设置了的可以得到数据。
springcloud Sleuth
请求链路跟踪
- 添加pom和配置文件即可。
Nacos
- 注册中心 默认8848端口号。ap和cp切换。
- 配置中心,bootstrap>application 配置文件名字的公式为: s p r i n g . a p p l i c a t i o n . n a m e − {spring.application.name}- spring.application.name−{spring.profiles.active}.后缀。
- 默认情况Namespace=public,Group=DEFAULT_GROUP,默认Cluster是DEFAULT。
- 可以用文件名区分获取配置文件,也可以用组来区分获取配置文件(配置文件中加一个group参数就行),还可以命名空间。
- 持久化和集群,docker中ip需为容器中的ip。
docker run -d \
-e PREFER_HOST_MODE=hostname \
-e MODE=cluster \
-e NACOS_SERVER_PORT=8846 \ #本次端口
-e NACOS_SERVERS="192.168.1.131:8846 192.168.1.131:8847 192.168.1.131:8848" \ #集群
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_SERVICE_HOST=192.168.1.131 \
-e MYSQL_SERVICE_PORT=3306 \
-e MYSQL_SERVICE_USER=root \
-e MYSQL_SERVICE_PASSWORD=123456 \
-e MYSQL_SERVICE_DB_NAME=nacos_config \
-e NACOS_SERVER_IP=192.168.1.131 \
-p 8846:8846 \
--name my-nacos1 \
nacos/nacos-server:1.2.1
原文链接:https://blog.csdn.net/BDawn/article/details/106234675
设置好内容后重启可能不生效,直接使用挂载。
mkdir -p /mydata/nacos/logs/ # 新建logs目录
mkdir -p /mydata/nacos/init.d/
vim /mydata/nacos/init.d/custom.properties # 修改配置文件
server.contextPath=/nacos
server.servlet.contextPath=/nacos
server.port=8848
spring.datasource.platform=mysql
db.num=1
# 这里要对应ip,以及对应的数据库
db.url.0=jdbc:mysql://dockermysqlIP:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=sql用户名
db.password=sql密码
nacos.cmdb.dumpTaskInterval=3600
nacos.cmdb.eventTaskInterval=10
nacos.cmdb.labelTaskInterval=300
nacos.cmdb.loadDataAtStart=false
management.metrics.export.elastic.enabled=false
management.metrics.export.influx.enabled=false
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i
nacos.security.ignore.urls=/,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/login,/v1/console/health/**,/v1/cs/**,/v1/ns/**,/v1/cmdb/**,/actuator/**,/v1/console/server/**
nacos.naming.distro.taskDispatchThreadCount=1
nacos.naming.distro.taskDispatchPeriod=200
nacos.naming.distro.batchSyncKeyCount=1000
nacos.naming.distro.initDataRatio=0.9
nacos.naming.distro.syncRetryDelay=5000
nacos.naming.data.warmup=true
nacos.naming.expireInstance=true
- 配置Nginx,修改它的conf文件,首先修改监听端口为1111(任意),然后访问http://ip+1111分流。
分流到以下3个服务器
总的大概就是这个样子。
此外,调用者中采用的端口号要变为nginx监听的端口号。
sentinel
这里面有一个坑,如果sentinel放在外网,微服务放在内网测试的时候,能连接成功,但是监测不到。报Failed to fetch metric from http://183.230.12.227:8719/metric?startTime=1637209907000&endTime=1637209913000&refetch=false (ConnectionException: Connection timed out)错误。要么把他们放本地,要么把微服务放云。
- qps:每秒的请求数;线程数:相当于起多少网页。
- 关联:关联其他的访问,比如支付卡顿了就限制下订单的服务。
- DefaultController关联的直接失败
- Warm Up 冷启动(预热),例如QPS阈值设定为10,设定时长为5,相当于没人访问一开始qps只有3,5秒之后才升级为10。WarmUpController。
- 排队等待RateLimiterController,超时时间,排队超过了这个时间的就不处理了。
- 降级规则,一秒放5个进来,RT为平均响应时间,当放进来的超过5个且每个的处理时间大于RT时就断开,直到时间窗口的时间结束,才继续服务。
- 异常数的时间窗口要设置为大于60
- 热点模式,BlockException(限流的错误),资源名SentinelResource标签中的不加斜杠和它的mapping匹配唯一,可以限制参数访问。
Nacos+Sentinel+OpenFeign
这里需注意如果使用OpenFeign跑时,如果mapping中没有fallback,只有
openFeign的全局捕获和控制台错误捕获是捕获不了运行时异常的。
"resource":"/rateLimit/byUrl", #资源名称
"limitApp":"default", #来源应用
"grade":1, #阈值类型,0表示线程数,1表示QPS
"count":0, #单机阈值
"strategy":0, #流控模式,0表示直接,1表示关联,2表示链路
"controlBehavior":0, #流控效果,0表示快速失败,1表示Warm Up,2表示排队等待
"clusterMode":false #是否集群