SpringCloud快速入门及其部分组件
一、SpringCloud大致图解
二、GateWay网关
1)核心:一系列过滤器
2)核心功能:过滤、路由
3)核心概念:
4)代码实现:
(1)创建工程:
(2)添加依赖:
<!-- 载入spring cloud gateway网关组件 -->
<!-- 注意,该依赖会与spring-boot-starter-web依赖产生冲突,故而不能一起引入 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
(3)修改启动器和配置文件:
server:
port: 10010
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
ip-address: 127.0.0.1
spring:
application:
name: api-gateway
cloud:
###################################
## 相当与feign, 不过feign只适用于微服务内部调用; 而gateway适用于微服务内部与外部调用
## 内部用feign或gateway(不过建议使用feign), 外部用gateway(必须)
###################################
gateway:
discovery:
locator:
## 配置后, 可不用后面的routes配置; 但是在请求时需要以 "http://网关地址/服务名称(大写)/**" 的格式
enabled: true
## 可指定上一个配置的 "http://网关地址/服务名称(大写)/**" 格式可以使用服务名称小写
lowerCaseServiceId: true
# routes:
# ## 路由id, 可以任意
# - id: user-service-routes
# ## 代理的服务地址, 即要路由的路径, 此处为user-service
# ## uri: http://127.0.0.1:8085
# ## lb 表示从eureka中获取服务列表, 并进行负载均衡; 后面的user-service为在eureka中注册过的服务名
# uri: lb://user-service
# ## 断言, 相当于判断条件
# predicates:
# ## 表示请求gateway网关的接口路径(不含IP地址与端口)中包含于user, 就转发至user-service
# - Path=/user/**
# - id: consumer-demo-routes
# uri: lb://consumer-demo
# predicates:
# ## - Path=/consumerFeign/**
# - Path=/consumerFeign/**
# ## gateway局部过滤器, 只针对符合断言的请求
# filters:
# ## 添加请求路径的前缀
# ## - PrefixPath=/consumerFeign
# ## 删除请求路径的前缀; 1 表示删除1个路径; 2 表示删除2个路径; 以此类推
# ## - StripPrefix=1
# ## 使用过滤器添加返回头
# ## - AddResponseHeader=authon, chengqb
# ## 配置自定义局部过滤器
# ## 是否需要为其赋值, 需要看对应的自定义过滤器的apply方法中是否使用到Config内部类的变量
# ## 如未使用, 即可配置成 -MyParam
# ## -MyParam
# - MyParam=authon
# ## 配置要使用的过滤器
# - Login=false
## 默认的过滤器, 即对所有请求生效
default-filters:
## 使用过滤器添加返回头; 有多个时,需分开写
- AddResponseHeader=authon, chengqb
- AddResponseHeader=date, 2019-12-06
# 熔断降级配置; 以下配置可放在局部过滤器, 也可放在全局过滤器
- name: Hystrix
args:
name: defaultFallback
fallbackUri: forward:/defaultFallback
globalcors:
## gateway的核心配置
cors-configurations:
## 表示对所有可以访问到网关服务器的请求进行配置(针对跨域问题)
'[/**]':
## 允许的请求来源, 针对跨域问题, 直接指定 * ; 表示全部
## allowedOrigins: *
## 以数组的形式指定规定的域名路径
allowedOrigins:
- "http://www.chengqb.com"
- "http://www.baidu.com"
## 允许的请求方法, 针对跨域问题, 直接指定 * ; 表示全部
## allowedMethods: *
## 以数组的形式指定规定的请求方法
allowedMethods:
- GET
- POST
# hystrix 信号量隔离,3秒后自动超时; 必需同时指定默认的超时回调方法
hystrix:
command:
default:
execution:
isolation:
## 策略: 信号量隔离; 在调用线程上执行,开销相对较小,并发请求收到信号量个数的限制
## strategy: SEMAPHORE
thread:
timeoutInMilliseconds: 3000
## 是否自动配置一个Hystrix并发策略插件,详见https://blog.csdn.net/qincidong/article/details/82725287
## shareSecurityContext: true
ribbon:
## feign: 连接服务超时时长, 单位为毫秒, 默认为1000毫秒
ConnectTimeout: 2000
## feign: 服务之间数据通信超时时长, 单位为毫秒, 默认为1000毫秒
ReadTimeout: 2000
## feign: 当前服务器的重试次数
MaxAutoRetries: 0
## feign: 重试多少次服务
MaxAutoRetriesNextServer: 0
二、Eureka注册中心
三、Ribbon负载均衡
四、Hystrix熔断器
提供保护机制
的组件;已经不再维护,但大多还是使用Hystrix
1)雪崩效应
:
服务调用的时候,出现服务不可用
的情况:
一旦出现长期的不可用
,并且未进行反馈时:
2)Hystrix的保护机制
:
(1)线程隔离:用户请求不直接访问服务,而是使用线程池中的空闲线程
来访问服务;通过是否还有空闲线程来加速失败判断时间
(2)服务降级:及时返回服务调用结果
,让线程不因为等待服务而阻塞
(3)图解:
3)熔断原理:弹性熔断
在断路器未打开
时,只有在请求超时
是会使用失败回调函数,请求正常(不超时)的是可以正常访问的;(非降级)
一旦断路器打开
后,就会将所有调用这个服务
的请求都降级,使用失败回调函数;(降级)
4)代码演示:
- 引入依赖
<!-- 载入Hystrix熔断器组件 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- 开启熔断
启动类中加入以下注解
@EnableCircuitBreaker // 声明开启Hystrix熔断器
注意:SpringBoot、Eureka、Hystrix三者的启动注解,可以合并成一个;如下:
@SpringBootApplication
@EnableDiscoveryClient // 声明开启eureka客户端
@EnableCircuitBreaker // 声明开启Hystrix熔断器
等价于
@SpringCloudApplication // 相当于@SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker的组合注解
- 编写降级逻辑(
第一种方式
)
在调用方法
上加入以下注解(调用方法必须和失败回调方法返回类型一致,也就是字符串类型)
// 声明该方法需要熔断,熔断器设置服务调用出错时的回调方法; 回调方法参数/返回值应与本方法参数/返回值相同
@HystrixCommand(fallbackMethod = "getUserFallback")
在调用方法同类下编写失败回调方法(失败回调方法必须返回字符串类型)
public String getUserFallback(String id) {
log.error("调用user-service的getUser方法失败");
return "调用user-service的getUser方法失败";
}
- 编写降级逻辑(
第二种方式
)
也可以使用全局配置:在调用类
上加上以下注解
// 开启熔断器, 并为整个类的方法设置统一的服务调用失败时的回调方法; 回调方法需是无参的
@DefaultProperties(defaultFallback = "defaultFallback")
全局配置:编写全局的失败回调方法(失败回调方法必须返回字符串类型)
public String defaultFallback() {
return "网络拥挤,无法调用user-service服务";
}
- Hystrix配置
hystrix:
command:
default:
execution:
isolation:
thread:
## Hystrix熔断器设置服务之间的调用超时时间, 单位毫秒, 默认为1000毫秒
timeoutInMilliseconds: 2000
circuitBreaker:
## 触发熔断错误比例阈值, 默认为50, 表示50%
errorThresholdPercentage: 50
## 熔断后的休眠时间, 单位毫秒, 默认为5000毫秒
sleepWindowInMilliseconds: 10000
## 熔断触发最小请求次数, 默认为20次
requestVolumeThreshold: 10
五、OpenFeign
自动拼接http请求(更像是在调用自身方法一样的去调用其他服务)
Feign中集成了Ribbon与Hystrix
1)代码演示:
(1)引入依赖
<!-- 载入Feign组件 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
(2)开启熔断
- 启动类中加入以下注解
@EnableFeignClients // 声明开启Feign客户端功能
(3)Feign应用实现
- 编写Feign客户端
package com.chengqb.consumer.client;
import com.chengqb.consumer.client.fallback.UserClientFallback;
import com.chengqb.consumer.config.FeignConfig;
import com.chengqb.consumer.vo.UserVO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @Author: Chengqb
* @Date: Created in 15:29 2019/12/5
* @ClassName: UserClient
* @Description: 描述
*/
// 声明该类为Feign客户端工具类, 并指定所对应的服务名为user-service
@FeignClient("user-service")
// Feign客户端工具类, 并指定所对应的服务名为user-service 指定调用服务失败时的回调函数类UserClientFallback 指定有关于feign的配置文件FeignConfig
// @FeignClient(value = "user-service", fallback = UserClientFallback.class, configuration = FeignConfig.class)
public interface UserClient {
// Feign会自动帮忙拼接成:http://user-service/user/{id};并进行负载均衡
@GetMapping("/user/{id}")
UserVO getUser(@PathVariable String id);
}
- 在调用方法中注入对应Feign客户端
@Autowired
private UserClient userClient;
- 直接调用Feign客户端的接口方法
@GetMapping("/user/{id}")
public UserVO getUser(@PathVariable String id) {
return userClient.getUser(id);
}
- Feign中Ribbon的配置
ribbon:
## feign: 连接服务超时时长, 单位为毫秒, 默认为1000毫秒
ConnectTimeout: 2000
## feign: 服务之间数据通信超时时长, 单位为毫秒, 默认为1000毫秒
ReadTimeout: 2000
## feign: 当前服务器的重试次数
MaxAutoRetries: 0
## feign: 重试多少次服务
MaxAutoRetriesNextServer: 0
## feign: 是否对所有请求都重试
OkToRetryOnAllOperations: false
- Feign中Hystrix的配置
配置文件配置
feign:
hystrix:
## 开启 feign 中的 Hystrix 熔断功能
enabled: true
编写服务降级类,需实现Feign客户端(但使用Hystrix时,服务降级方法是写在对应的类中;Feign中的服务降级方法,需要实现Feign客户端,并单独编写一个类)
package com.chengqb.consumer.client.fallback;
import com.chengqb.consumer.client.UserClient;
import com.chengqb.consumer.vo.UserVO;
import org.springframework.stereotype.Component;
/**
* @Author: Chengqb
* @Date: Created in 16:26 2019/12/5
* @ClassName: UserClientFallback
* @Description: feign客户端工具类对应的服务调用失败回调函数类; 继承于feign客户端工具类(接口), 两个文件方法相对应
*/
@Component
public class UserClientFallback implements UserClient {
@Override
public UserVO getUser(String id) {
UserVO userVO = new UserVO();
userVO.setId(id);
userVO.setName("调用user-service服务时失败");
return userVO;
}
}
修改Feign客户端
// 声明该类为Feign客户端工具类, 并指定所对应的服务名为user-service
@FeignClient("user-service")
修改为
// Feign客户端工具类, 并指定所对应的服务名为user-service 指定调用服务失败时的回调函数类UserClientFallback
@FeignClient(value = "user-service", fallback = UserClientFallback.class)
- Feign中压缩配置
feign:
## feign中服务之间请求与返回的数据压缩
compression:
request:
## 开启请求数据压缩
enabled: true
## 设置压缩的数据类型
mime-types: text/html, application/xml, application/json
## 设置触发压缩的大小下限
min-request-size: 2048
response:
## 开启返回数据压缩
enabled: true
- Feign中日志级别配置
开启日志级别
## springBoot项目本身的日志输出设置; 此设置不会对feign客户端生效, 需要额外再指定feign客户端日志的输出级别
logging:
level:
com:
chengqb: debug
编写Feign配置类
package com.chengqb.consumer.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author: Chengqb
* @Date: Created in 17:12 2019/12/5
* @ClassName: FeignConfig
* @Description: 描述
*/
@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLoggerLevel() {
// 设置feign的日志输出级别
return Logger.Level.FULL;
}
}
修改Feign客户端
// Feign客户端工具类, 并指定所对应的服务名为user-service 指定调用服务失败时的回调函数类UserClientFallback
@FeignClient(value = "user-service", fallback = UserClientFallback.class)
修改为
// Feign客户端工具类, 并指定所对应的服务名为user-service 指定调用服务失败时的回调函数类UserClientFallback 指定有关于feign的配置文件FeignConfig
@FeignClient(value = "user-service", fallback = UserClientFallback.class, configuration = FeignConfig.class)
六、Config配置中心
分布式系统中,服务数量多,配置文件分散,管理很不方便;Spring Cloud Config组件可以解决这个问题
git仓库中的配置文件命名规则
:{application}-{profile}.yml 或 {application}-{profile}.properties
1)搭建Config-service:
(1)添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
(2)修改启动类:
@EnableConfigServer // 开启spring-cloud-config的config服务
(3)修改配置文件:
server:
port: 12000
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
ip-address: 127.0.0.1
spring:
application:
name: config-service
cloud:
config:
server:
git:
## 关联的git服务器地址
uri: https://gitee.com/chengqb/config-service.git
2)配置其他需要获取配置文件的服务:
(1)添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
(2)删除application文件,添加bootstrap文件:
(3)修改bootstrap文件:
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
ip-address: 127.0.0.1
######################################################################
## bootstrap.yml 和 application.yml 一样, 属于springBoot的默认配置文件
## 不过 bootstrap.yml 配置文件更多的是配置极少更改的配置
## 而 application.yml 配置文件是用于配置需要更改的配置
#####################################################################
spring:
cloud:
config:
discovery:
## 指定springCloud config的服务名; 再加上eureka注册中心,获取对应git的config仓库
service-id: config-service
## 开启配置中心, 默认为false
enabled: true
####################################################################
## git仓库工程的配置文件命名的规则:
## 遵循 application-profile.yml 或者 application-profile.properties
###################################################################
## 仓库工程中配置文件名称的前半部分, 即相当于application
name: user
## 仓库工程中配置文件名称的后半部分, 即相当于profile
profile: dev
## git仓库的工程分支号
label: master
七、Bus消息总线
用轻量级的消息代理将分布式的节点连接起来,可以用与广播配置文件的更改或者服务的监控管理
可选的消息代理有:RabbitMQ 和 Kafka
1)代码实现:
(1)启动RabbitMQ:
(2)修改配置中心服务工程 config-service :
- 添加 Bus 与 RabbitMQ 的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
- 修改配置文件
server:
port: 12000
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
ip-address: 127.0.0.1
spring:
application:
name: config-service
cloud:
config:
server:
git:
## 关联的git服务器地址
uri: https://gitee.com/chengqb/config-service.git
## 配置rabbitmq的信息
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
management:
endpoints:
web:
exposure:
## 暴露触发消息总线的地址; 相当于之后修改git仓库配置文件后, 触发刷新各个服务获取配置文件的请求路径
## 刷新配置文件的请求路径: /actuator/bus-refresh
include: bus-refresh
(3)修改需要获取配置文件的服务工程:
- 添加 Bus 、RabbitMQ 和 actuator(暴露消息总线) 的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
<!-- 引入actuator依赖, 在使用spring-cloud-bus时, 暴露触发消息总线的地址, 为rabbitmq消息总线的刷新提供路径 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 修改配置文件
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
ip-address: 127.0.0.1
######################################################################
## bootstrap.yml 和 application.yml 一样, 属于springBoot的默认配置文件
## 不过 bootstrap.yml 配置文件更多的是配置极少更改的配置
## 而 application.yml 配置文件是用于配置需要更改的配置
#####################################################################
spring:
cloud:
config:
discovery:
## 指定springCloud config的服务名; 再加上eureka注册中心,获取对应git的config仓库
service-id: config-service
## 开启配置中心, 默认为false
enabled: true
####################################################################
## git仓库工程的配置文件命名的规则:
## 遵循 application-profile.yml 或者 application-profile.properties
###################################################################
## 仓库工程中配置文件名称的前半部分, 即相当于application
name: user
## 仓库工程中配置文件名称的后半部分, 即相当于profile在这里插入代码片
profile: dev
## git仓库的工程分支号
label: master
## 配置rabbitmq的信息
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
virtual-host: /MyMQ
- 在使用了配置文件处添加注解
@RefreshScope // 开启spring-cloud-bus的配置文件刷新
- 在修改了仓库中的配置文件后,请求一次暴露消息总线
http://localhost:12000/actuator/bus-refresh