springcloud-各服务配置中心_springcloud配置中心有哪些_李钟意·
1 springcloud注册中心——Euraka
1.1 EurakaServer
1.1.1 依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
1.1.2?properties.yml配置
server:
port: 9000 #端口
eureka:
instance:
hostname: localhost #主机地址
client:
register-with-eureka: false #是否将自己注册到注册中心(搭建集群改为true)
fetch-registry: false #是否从eureka中获取注册信息(搭建集群改为true)
service-url: #配置暴露给Eureka Client的请求地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server: #客户端30s发送心跳,服务端90s验证是否有该服务,15分钟心跳低于85%开启保护模式
enable-self-preservation: false #关闭自我保护
eviction-interval-timer-in-ms: 4000 #剔除服务间隔
1.1.3?注解
@EnableEurekaServer
2.1 EurakaClient
1.2.1 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
1.2.2 properties.yml配置
eureka:
client:
service-url:
defaultZone: http://localhost:9000/eureka/ #搭建集群时用逗号隔开注册中心地址
instance:
prefer-ip-address: true #使用ip地址注册
instance-id: ${spring.cloud.client.ip-address}:${server.port} #向注册中心中注册服务id
lease-expiration-duration-in-seconds: 10 #eureka client发送心跳给server端后,续约到期时间(默认90秒)
lease-renewal-interval-in-seconds: 5 #发送心跳续约间隔(默认三十秒)
1.2.3?注解
@EnableEurekaClient
@EnableDiscoveryClient
1.2.4?使用案列
@RequestMapping(value = "/buy/{id}",method = RequestMethod.GET)
public Product findById(@PathVariable Long id) {
/**
* 注入DiscoveryClient :
* springcloud提供的获取原数组的工具类
* 调用方法获取服务的元数据信息
*
*/
//调用discoveryClient方法
//已调用服务名称获取所有的元数据
List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
//获取唯一的一个元数据
ServiceInstance instance = instances.get(0);
//根据元数据中的主机地址和端口号拼接请求微服务的URL
Product product = null;
//如何调用商品服务?
product = restTemplate.getForObject("http://"+instance.getHost()+":"+instance.getPort()+"/product/1",Product.class);
return product;
2 springcloud注册中心——Consul
2.1 EurakaClient
2.1.1 依赖
<!--springcloud 提供的对基于consul的服务发现-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!--actuator的健康检查-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.1.2?properties.yml配置
###开始配置consul的服务注册
cloud:
consul:
host: 127.0.0.1 #consul服务器的主机地址
port: 8500 #consul服务器的ip地址
discovery:
#是否需要注册
register: true
#注册的实例ID (唯一标志)
instance-id: ${spring.application.name}-1
#服务的名称
service-name: ${spring.application.name}
#服务的请求端口
port: ${server.port}
#指定开启ip地址注册
prefer-ip-address: true
#当前服务的请求ip
ip-address: ${spring.cloud.client.ip-address}
2.1.3?注解
无
2.1.4?使用案列
由于 SpringCloud 对 Consul 进行了封装。对于在消费者端获取服务提供者信息和 Eureka 是一致的。同样使用 DiscoveryClient 完成调用获取微服务实例信息。
@RequestMapping(value = "/buy/{id}",method = RequestMethod.GET)
public Product findById(@PathVariable Long id) {
/**
* 注入DiscoveryClient :
* springcloud提供的获取原数组的工具类
* 调用方法获取服务的元数据信息
*
*/
//调用discoveryClient方法
//已调用服务名称获取所有的元数据
List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
//获取唯一的一个元数据
ServiceInstance instance = instances.get(0);
//根据元数据中的主机地址和端口号拼接请求微服务的URL
Product product = null;
//如何调用商品服务?
product = restTemplate.getForObject("http://"+instance.getHost()+":"+instance.getPort()+"/product/1",Product.class);
return product;
3 springcloud注册中心——Ribbon
3.1 EurakaServer
3.1.1 依赖
在 springcloud 提供的服务发现的 jar 中以及包含了 Ribbon 的依赖。所以这里不需要导入任何额外的坐标。
<!-- 引入重试的坐标-->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
3.1.2?properties.yml配置
#修改ribbon的负载均衡策略 服务名 - ribbon - NFLoadBalancerRuleClassName : 策略
service-product:
ribbon:
ConnectTimeout: 250 # Ribbon的连接超时时间
ReadTimeout: 1000 # Ribbon的数据读取超时时间
OkToRetryOnAllOperations: true # 是否对所有操作都进行重试
MaxAutoRetriesNextServer: 1 # 切换实例的重试次数
MaxAutoRetries: 1 # 对当前实例的重试次数
3.1.3?注解
@LoadBalanced : 是ribbon提供的负载均衡的注解,加在restTemplate类上
@LoadBalanced
3.1.4 使用案列
/**
* 基于ribbon的形式调用远程微服务
* 1.使用@LoadBalanced声明RestTemplate
* 2.使用服务名称替换ip地址
*/
@RequestMapping(value = "/buy/{id}",method = RequestMethod.GET)
public Product findById(@PathVariable Long id) {
Product product = null;
product = restTemplate.getForObject("http://service-product/product/1",Product.class);
return product;
}
4 springcloud注册中心——Feign
4.1 Feign
4.1.1 依赖
<!--springcloud整合的openFeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
4.1.2?properties.yml配置
#配置feign日志的输出
#日志配置 NONE : 不输出日志(高) BASIC: 适用于生产环境追踪问题
#HEADERS : 在BASIC的基础上,记录请求和响应头信息 FULL : 记录所有
feign:
client:
config:
service-product: #需要调用的服务名称
#配置Feign的日志级别,相当于代码配置的Logger
loggerLevel: FULL
#Feign错误码解析器,相当于代码配置方式的ErrorDecoder
errorDecoder: com.example.SimpleErrorDecoder
#配置重试,相当于代码配置方式中的retryer
retryer: com.example.Example.SimpleRetryer
#配置拦截器,相当于代码配置方式中的RequestInterceptor
requestInterceptors:
- com.example.FooRequestInterceptor
- com.example.BarRequestInterceptor
decode404: false
compression:
request:
enabled: true # 开启请求压缩
mime-types: text/html,application/xml,application/json # 设置压缩的数据类型
min-request-size: 2048 # 设置触发压缩的大小下限
response:
enabled: true # 开启响应压缩
logging:
level:
cn.itcast.order.feign.ProductFeignClient: debug#配置feign日志的输出
#日志配置 NONE : 不输出日志(高) BASIC: 适用于生产环境追踪问题
#HEADERS : 在BASIC的基础上,记录请求和响应头信息 FULL : 记录所有
feign:
client:
config:
service-product: #需要调用的服务名称
#配置Feign的日志级别,相当于代码配置的Logger
loggerLevel: FULL
#Feign错误码解析器,相当于代码配置方式的ErrorDecoder
errorDecoder: com.example.SimpleErrorDecoder
#配置重试,相当于代码配置方式中的retryer
retryer: com.example.Example.SimpleRetryer
#配置拦截器,相当于代码配置方式中的RequestInterceptor
requestInterceptors:
- com.example.FooRequestInterceptor
- com.example.BarRequestInterceptor
decode404: false
compression:
request:
enabled: true # 开启请求压缩
mime-types: text/html,application/xml,application/json # 设置压缩的数据类型
min-request-size: 2048 # 设置触发压缩的大小下限
response:
enabled: true # 开启响应压缩
logging:
level:
cn.itcast.order.feign.ProductFeignClient: debug
4.1.3?注解
@EnableFeignClients
4.1.4 使用案列
1、创建调用方法Feign接口
/**
* 声明需要调用的微服务名称
* @FeignClient
* * name : 服务提供者的名称
*/
@FeignClient(name="service-product")
public interface ProductFeignClient {
/**
* 配置需要调用的微服务接口
*/
@RequestMapping(value="/product/{id}",method = RequestMethod.GET)
public Product findById(@PathVariable("id") Long id);
}
2、调用服务
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private ProductFeignClient productFeignClient;
/**
*/
@RequestMapping(value = "/buy/{id}",method = RequestMethod.GET)
public Product findById(@PathVariable Long id) {
Product product = null;
product = productFeignClient.findById(id);
return product;
}
}
5 springcloud注册中心——Hystrix
5.1 RestTemplate-Hystrix
5.1.1 依赖
<!--引入hystrix依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
5.1.2?properties.yml配置
hystrix:
command:
default:
execution:
isolation:
strategy: ExecutionIsolationStrategy.SEMAPHORE #信号量隔离
#strategy: # ExecutionIsolationStrategy.THREAD 线程池隔离
thread:
timeoutInMilliseconds: 3000 #默认的连接超时时间1秒,若1秒没有返回数据,自动的触发降级逻辑
circuitBreaker:
requestVolumeThreshold: 5 #触发熔断的最小请求次数,默认20 /10秒
sleepWindowInMilliseconds: 10000 #熔断多少秒后去尝试请求 默认 5 打开状态的时间
errorThresholdPercentage: 50 #触发熔断的失败请求最小占比,默认50%
#开启所以健康检查的服务
management:
endpoints:
web:
exposure:
include: '*'
5.1.3?注解
//激活hystrix
@EnableCircuitBreaker
5.1.4 使用案列
@RestController
@RequestMapping("/order")
/**
* @DefaultProperties : 指定此接口中公共的熔断设置
* 如果过在@DefaultProperties指定了公共的降级方法
* 在@HystrixCommand不需要单独指定了
*/
//@DefaultProperties(defaultFallback = "defaultFallBack")
public class OrderController {
@Autowired
private RestTemplate restTemplate;
/**
* 使用注解配置熔断保护
* fallbackmethod : 配置熔断之后的降级方法
*/
@HystrixCommand(fallbackMethod = "orderFallBack")
@RequestMapping(value = "/buy/{id}",method = RequestMethod.GET)
public Product findById(@PathVariable Long id) {
if(id != 1) {
throw new RuntimeException("服务器异常");
}
return restTemplate.getForObject("http://service-product/product/1",Product.class);
}
/**
* 降级方法
* 和需要收到保护的方法的返回值一致
* 方法参数一致
*/
public Product orderFallBack(Long id) {
Product product = new Product();
product.setProductName("触发降级方法");
return product;
}
}
5.2 Feign-Hystrix
5.2.1 依赖
<!--引入hystrix依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
5.2.2?properties.yml配置
#配置feign日志的输出
#日志配置 NONE : 不输出日志(高) BASIC: 适用于生产环境追踪问题
#HEADERS : 在BASIC的基础上,记录请求和响应头信息 FULL : 记录所有
feign:
client:
config:
service-product: #需要调用的服务名称
loggerLevel: FULL
#开启对hystrix的支持
hystrix:
enabled: true
#hystrix对外暴露的所有端点
management:
endpoints:
web:
exposure:
include: '*'
#hystrix相关配置
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000 #默认的连接超时时间1秒,若1秒没有返回数据,自动的触发降级逻辑
circuitBreaker:
enabled: true
requestVolumeThreshold: 5
errorThresholdPercentage: 10
sleepWindowInMilliseconds: 10000
5.2.3?注解
@EnableCircuitBreaker
//激活hytrix的web监控平台
5.2.4 使用案列
(1)基于?Feign?实现熔断降级,那么降级方法需要配置到?FeignClient?接口的实现类中。
@Component
public class ProductFeignClientCallBack implements ProductFeignClient {
/**
* 熔断降级的方法
*/
public Product findById(Long id) {
Product product = new Product();
product.setProductName("feign调用触发熔断降级方法");
return product;
}
}
(2)?修改?FeignClient?添加?hystrix?熔断
/**
* 声明需要调用的微服务名称
* @FeignClient
* * name : 服务提供者的名称
* * fallback : 配置熔断发生降级方法
* 实现类
*/
@FeignClient(name="service-product",fallback = ProductFeignClientCallBack.class)
public interface ProductFeignClient {
/**
* 配置需要调用的微服务接口
*/
@RequestMapping(value="/product/{id}",method = RequestMethod.GET)
public Product findById(@PathVariable("id") Long id);
}
5.3 Hystrix Stream
5.3.1 依赖
<!--引入hystrix的监控信息-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
5.3.2?properties.yml配置
#hystrix对外暴露的所有端点
management:
endpoints:
web:
exposure:
include: '*'
5.3.3?注解
//激活hytrix的web监控平台
@EnableHystrixDashboard
5.3.4 使用案列
重启项目,访问?http://localhost:9003/actuator/hystrix.stream?,?即可看到实时的监控数据。
5.4?Hystrix DashBoard?Turbine
5.4.1 依赖
<!--引入hystrix的监控信息-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
5.4.2?properties.yml配置
无
5.4.3?注解
//激活hystrix
@EnableCircuitBreaker
//激活hytrix的web监控平台
@EnableHystrixDashboard
5.4.4 使用案列
http://localhost:9003/hystrix
5.5?Hystrix DashBoard?Turbine
5.5.1 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
5.5.2?properties.yml配置
server:
port: 8031
spring:
application:
name: hystrix-turbine
eureka:
client:
service-url:
defaultZone: http://localhost:9000/eureka/
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${server.port}
turbine:
# 要监控的微服务列表,多个用,分隔
appConfig: service-order
clusterNameExpression: "'default'"
5.5.3?注解
//trubin配置
@EnableTurbine
@EnableHystrixDashboard
5.5.4 使用案列
浏览器访问 http://localhost:8031/hystrix 展示 HystrixDashboard 。并在 url 位置输入 http://localhost:8031/turbine.stream ,动态根据 turbine.stream 数据展示多个微服务的监控数据。
6 springcloud注册中心——Sentinel
6.1?SentinelServer
6.1.1 获取 Sentinel 控制台
您可以从官方 网站中 下载最新版本的控制台 jar 包,下载地址如下:
https://github.com/alibaba/Sentinel/releases/download/1.6.3/sentinel-dashboard-1.6.3.jar
6.1.2 启动
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 - Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
6.1.3 访问
Sentinel?控制台引入基本的登录功能,默认用户名和密码都是?sentinel?。
localhost:8080
6.2 Rest-SentinelClient
6.2.1 依赖
<!--springcloud整合的openFeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
6.2.2?properties.yml配置
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 #sentinel控制台的请求地址
datasource: #加载本地资源配置
ds1:
file:
file: classpath:flowrule.json
data-type: json
rule-type: flow
eager: true #立即加载
6.2.3?注解
@SentinelRestTemplate
6.2.4 使用案列
(1)编写异常回调方法
public class ExceptionUtils {
/**
* 静态方法
* 返回值: SentinelClientHttpResponse
* 参数 : request , byte[] , clientRquestExcetion , blockException
*/
//限流熔断业务逻辑
public static SentinelClientHttpResponse handleBlock(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) {
return new SentinelClientHttpResponse("abc");
}
//异常降级业务逻辑
public static SentinelClientHttpResponse handleFallback(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) {
return new SentinelClientHttpResponse("def");
}
}
(2)在启动类RestTemplate中加载@SentinelRestTemplate即可
@SpringBootApplication
@EntityScan("cn.itcast.order.entity")
public class RestOrderApplication {
/**
* sentinel支持对restTemplate的服务调用使用sentinel方法.在构造
* RestTemplate对象的时候,只需要加载@SentinelRestTemplate即可
*
* 资源名:
* httpmethod:schema://host:port/path :协议、主机、端口和路径
* httpmethod:schema://host:port :协议、主机和端口
*
* @SentinelRestTemplate:
* 异常降级
* fallback : 降级方法
* fallbackClass : 降级配置类
* 限流熔断
* blockHandler
* blockHandlerClass
*/
@LoadBalanced
@Bean
@SentinelRestTemplate(fallbackClass = ExceptionUtils.class,fallback = "handleFallback",
blockHandler = "handleBlock" ,blockHandlerClass = ExceptionUtils.class
)
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RestOrderApplication.class,args);
}
}
6.3?Feign-SentinelClient
6.3.1 依赖
<!--feign对sentinel的支持-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
6.3.2?properties.yml配置
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 #sentinel控制台的请求地址
#激活sentinel的支持
feign:
sentinel:
enabled: true
6.3.3?注解
无
6.3.4 使用案列
(1?)配置?FeignClient
和使用?Hystrix?的方式基本一致,需要配置?FeignClient?接口以及通过?fallback?指定熔断降级方法
/**
* 声明需要调用的微服务名称
* @FeignClient
* * name : 服务提供者的名称
* * fallback : 配置熔断发生降级方法
* 实现类
*/
@FeignClient(name="service-product",fallback = ProductFeignClientCallBack.class)
public interface ProductFeignClient {
/**
* 配置需要调用的微服务接口
*/
@RequestMapping(value="/product/{id}",method = RequestMethod.GET)
public Product findById(@PathVariable("id") Long id);
}
(?2?)配置熔断方法
@Component
public class ProductFeignClientCallBack implements ProductFeignClient {
/**
* 熔断降级的方法
*/
public Product findById(Long id) {
Product product = new Product();
product.setProductName("feign调用触发熔断降级方法");
return product;
}
}
7 springcloud网关——zuul
7.1 zuul
7.1.1 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
7.1.2?properties.yml配置
server:
port: 8080 #端口
spring:
application:
name: api-zuul-server #服务名称
##路由配置方式一-----通过url简单配置
#zuul:
# routes:
# #已商品微服务
# product-service: #路由id,随便写
# path: /product-service/** #映射路径 #localhost:8080/product-service/sxxssds
# url: http://127.0.0.1:9001 #映射路径对应的实际微服务url地址
##路由配置方式二-----通过ServerID从Euraka拉取服务
#zuul:
# routes:
# #已商品微服务
# product-service: #路由id,随便写
# path: /product-service/** #映射路径 #localhost:8080/product-service/sxxssds
# serviceId: service-product #配置转发的微服务的服务名称
##路由配置方式一-----通过ServerID从Euraka拉取服务
zuul:
routes:
#已商品微服务
#如果路由id 和 对应的微服务的serviceId一致的话
service-product: /product-service/**
#zuul中的默认路由配置
#如果当前的微服务名称 service-product , 默认的请求映射路径 /service-product/**
# /service-order/
#配置Eureka
eureka:
client:
service-url:
defaultZone: http://localhost:9000/eureka/
instance:
prefer-ip-address: true #使用ip地址注册
7.1.3?注解
//开启zuul网关功能
@EnableZuulProxy
//eureka的服务发现
@EnableDiscoveryClient
7.1.4 使用案列
服务端接收客户端请求,验证是否合法在进行转发。
/**
* 自定义的zuul过滤器
* 继承抽象父类
*/
@Component
public class LoginFilter extends ZuulFilter {
/**
* 定义过滤器类型
* pre
* routing
* post
* error
*/
@Override
public String filterType() {
return "pre";
}
/**
* 指定过滤器的执行顺序
* 返回值越小,执行顺序越高
*/
@Override
public int filterOrder() {
return 1;
}
/**
* 当前过滤器是否生效
* true : 使用此过滤器
* flase : 不使用此过滤器
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 指定过滤器中的业务逻辑
* 身份认证:
* 1.所有的请求需要携带一个参数 : access-token
* 2.获取request请求
* 3.通过request获取参数access-token
* 4.判断token是否为空
* 4.1 token==null : 身份验证失败
* 4.2 token!=null : 执行后续操作
* 在zuul网关中,通过RequestContext的上下问对象,可以获取对象request对象
*/
@Override
public Object run() throws ZuulException {
//System.out.println("执行了过滤器");
//1.获取zuul提供的上下文对象RequestContext
RequestContext ctx = RequestContext.getCurrentContext();
//2.从RequestContext中获取request
HttpServletRequest request = ctx.getRequest();
//3.获取请求参数access-token
String token = request.getParameter("access-token");
//4.判断
if (token ==null) {
//4.1 如果token==null ,拦截请求,返回认证失败
ctx.setSendZuulResponse(false); // 拦截请求
ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
//4.2 如果token!=null ,继续后续操作
return null;
}
}
8 springcloud网关——Gateway
8.1 Gateway
8.1.1 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
8.1.2?properties.yml配置
spring:
application:
name: api-gateway-server #服务名称
redis:
host: localhost
pool: 6379
database: 0
cloud: #配置SpringCloudGateway的路由
gateway:
routes: #路由ID,路由到微服务的uri,断言(判断条件)
- id: order-service
uri: lb://service-order #从Eureka注册中心拉取服务
# uri: 127.0.0.1:9002 #简单路由配置
predicates:
- Path=/order-service/**
filters: #路径从写过滤器
- RewritePath=/order-service/(?<segment>.*), /$\{segment}
- id: product-service
uri: lb://service-product
# uri: 127.0.0.1:9001 #简单路由配置
predicates:
- Path=/product-service/**
filters:
- name: RequestRateLimiter #基于rides的配置
args:
# 使用SpEL从容器中获取对象
key-resolver: '#{@pathKeyResolver}'
# 令牌桶每秒填充平均速率
redis-rate-limiter.replenishRate: 1
# 令牌桶的上限
redis-rate-limiter.burstCapacity: 3
- RewritePath=/product-service/(?<segment>.*), /$\{segment}
discovery: #简化路由配置方式
locator:
enabled: true #开启根据服务名称自动转发
lower-case-service-id: true #微服务名称已小写形式呈现
# RequestRateLimiter : 使用限流过滤器,是springcloud gateway提供的
# 参数 replenishRate : 向令牌桶中填充的速率
# burstCapacity :令牌桶的容量
8.1.3?注解
无
8.1.4 使用案列
全局过滤器
/**
* 自定义一个全局过滤器
* 实现 globalfilter , ordered接口
*/
//@Component
public class LoginFilter implements GlobalFilter,Ordered {
/**
* 执行过滤器中的业务逻辑
* 对请求参数中的access-token进行判断
* 如果存在此参数:代表已经认证成功
* 如果不存在此参数 : 认证失败.
* ServerWebExchange : 相当于请求和响应的上下文(zuul中的RequestContext)
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("执行了自定义的全局过滤器");
//1.获取请求参数access-token
String token = exchange.getRequest().getQueryParams().getFirst("access-token");
//2.判断是否存在
if(token == null) {
//3.如果不存在 : 认证失败
System.out.println("没有登录");
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete(); //请求结束
}
//4.如果存在,继续执行
return chain.filter(exchange); //继续向下执行
}
/**
* 指定过滤器的执行顺序 , 返回值越小,执行优先级越高
*/
@Override
public int getOrder() {
return 0;
}
}
局部过滤器
基本限流
@Configuration
public class KeyResolverConfiguration {
/**
* 编写基于请求路径的限流规则
* //abc
* //基于请求ip 127.0.0.1
* //基于参数
*/
@Bean
public KeyResolver pathKeyResolver() {
//自定义的KeyResolver
return new KeyResolver() {
/**
* ServerWebExchange :
* 上下文参数
*/
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just( exchange.getRequest().getPath().toString());
}
};
}
/**
* 基于请求参数的限流
*
* 请求 abc ? userId=1
*/
// @Bean
public KeyResolver userKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getQueryParams().getFirst("userId")
// 基于请求ip的限流
// exchange.getRequest().getHeaders().getFirst("X-Forwarded-For")
);
}
}
sentinel限流
/**
* sentinel限流的配置
*/
@Configuration
public class GatewayConfiguration {
private final List<ViewResolver> viewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer;
public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,
ServerCodecConfigurer serverCodecConfigurer) {
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
}
/**
* 配置限流的异常处理器:SentinelGatewayBlockExceptionHandler
*/
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
}
/**
* 配置限流过滤器
*/
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
/**
* 配置初始化的限流参数
* 用于指定资源的限流规则.
* 1.资源名称 (路由id)
* 2.配置统计时间
* 3.配置限流阈值
*/
@PostConstruct
public void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("product-service")
.setCount(1)
.setIntervalSec(1)
);
rules.add(new GatewayFlowRule("product_api")
.setCount(1).setIntervalSec(1)
);
GatewayRuleManager.loadRules(rules);
}
/**
* 自定义API限流分组
* 1.定义分组
* 2.对小组配置限流规则
*/
@PostConstruct
private void initCustomizedApis() {
Set<ApiDefinition> definitions = new HashSet<>();
ApiDefinition api1 = new ApiDefinition("product_api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
add(new ApiPathPredicateItem().setPattern("/product-service/product/**"). //已/product-service/product/开都的所有url
setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
ApiDefinition api2 = new ApiDefinition("order_api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
add(new ApiPathPredicateItem().setPattern("/order-service/order")); //完全匹配/order-service/order 的url
}});
definitions.add(api1);
definitions.add(api2);
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
}
/**
* 自定义限流处理器
*/
@PostConstruct
public void initBlockHandlers() {
BlockRequestHandler blockHandler = new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
Map map = new HashMap();
map.put("code",001);
map.put("message","不好意思,限流啦");
return ServerResponse.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(map));
}
};
GatewayCallbackManager.setBlockHandler(blockHandler);
}
}
9 springcloud链路追踪——?Sleuth
9.1 ?Sleuth
9.1.1 依赖
9.1.2?properties.yml配置
9.1.3?注解
9.1.4 使用案列
10 springcloud配置中心——?Config
1.1 Hystrix DashBoard?Turbine
1.1.1 依赖
1.1.2?properties.yml配置
1.1.3?注解
1.1.4 使用案列
11 springcloud配置中心——?Apollo
1.1 Hystrix DashBoard?Turbine
1.1.1 依赖
1.1.2?properties.yml配置
1.1.3?注解
1.1.4 使用案列
1.1 Hystrix DashBoard?Turbine
1.1.1 依赖
1.1.2?properties.yml配置
1.1.3?注解
1.1.4 使用案列
1.1 Hystrix DashBoard?Turbine
1.1.1 依赖
1.1.2?properties.yml配置
1.1.3?注解
1.1.4 使用案列
1.1 Hystrix DashBoard?Turbine
1.1.1 依赖
1.1.2?properties.yml配置
1.1.3?注解
1.1.4 使用案列
1.1 Hystrix DashBoard?Turbine
1.1.1 依赖
1.1.2?properties.yml配置
1.1.3?注解
1.1.4 使用案列
相关文章
- 四、Plugin Request and Sometimes pads_李尔阳
- linux nginx配置stream后启动报异常 /usr/lib64/nginx/modules/ngx_stream_module.so: undefined symbol: SSL_CTX_s
- Windows10 安装ElasticStack8.6.1_永宁河
- Java微服务开发流程及详细案例_小G黑
- 最优化学习 KKT条件(最优解的一阶必要条件)_风信子的猫Redamancy_一阶最优条件
- 【前端杂货铺】一个普通人在CSDN创作的一周年_前端杂货铺
- For artifact {org.springframework.cloud:spring-cloud-starter-config:null:jar}: The version cannot be
- 【JavaScript速成之路】JavaScript变量_小杨MiManchi
- 2023年前端开发趋势未来可期_2023前端技术_经海路大白狗
- 基于FPGA的任意字节数的串口接收(含源码工程)_fpga接收串口数据包_孤独的单刀
- 报错:java.io.IOException: 你的主机中的软件中止了一个已建立的连接。_lwj_07
- I2C总线协议详解(特点、通信过程、典型I2C时序)_zhangduang_KHKW_i2c
- MySQL中常用的排序函数_mysql排序函数_小成小成小成
- 高并发系统设计-Feed流系统设计_胡桃姓胡,蝴蝶也姓胡_feed流设计
- 没有选品经验的电商卖家该在TikTok上卖什么商品?超店有数来帮你_超店有数
- JAVAWEB实现图片文件上传_weixin_45469367_javaweb上传图片
- 是时候为您的银行机构选择构建一个知识库了!_小浣熊e
- 开通腾讯位置服务_邱秋Elena
- Linux如何记录运行的Bash命令?_sta@ma@brain
- Linux系统点亮LED_行稳方能走远
- 【python学习笔记】:文本处理案例(二)_姜子牙大侠
- OpenFeign负载均衡配置_openfeign 负载均衡_一只散修道友
- Oracle数据库 - oracle数据库、实例、服务名、SID、表空间_oracle的实例名,数据库名,服务名_森!!仔
- Spring Bean生命周期,好像人的一生。。_三分恶
- Android Studio_平查斯
- Elasticsearch7.8.0版本入门——JavaAPI操作(环境准备)_小志
- 下载网上压缩包(包含多行json)并将其转换为字典的解决方案_爱编程的喵喵
- rk3588 rkaiq_3A_server 无法解析json文件记录_neardi临滴科技
- (三)Alian 的 Spring Cloud Eureka Server(服务注册中心)_嘉禾嘉宁papa
- 使用Docker模拟实现两台MySQL主从同步复制_彭世瑜