提交 1da1755a 编写于 作者: zlt2000's avatar zlt2000

增加服务限流降级熔断功能

上级 ebdc9456
# microservices-platform
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
## 如果您觉得有帮助,请点右上角 "Star" 支持一下谢谢
[TOC]
## 1. 项目介绍
* 技术交流群 [250883130](http://shang.qq.com/wpa/qunwpa?idkey=17544199255998bda0d938fb72b08d076c40c52c9904520b76eb5eb0585da71e)
* 技术交流群 [250883130](http://shang.qq.com/wpa/qunwpa?idkey=17544199255998bda0d938fb72b08d076c40c52c9904520b76eb5eb0585da71e) <a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=d6d7089596a656c397818a2dcbfb83c9c068ac3417951ad71304d615051e74a5"><img border="0" src="//pub.idqqimg.com/wpa/images/group.png" alt="微服务技术交流群" title="微服务技术交流群"></a>
* **详细在线文档** [点击查看](https://www.kancloud.cn/zlt2000/microservices-platform/919412)
* 前后端分离的企业级微服务架构
* 基于`Spring Boot 2.0.X``Spring Cloud Finchley``Spring Cloud Alibaba`
......@@ -24,17 +27,24 @@
* 支持手机号加密码登录
* 支持openId登录
* 支持第三方系统单点登录
* **分布式系统基础支撑**
* 服务注册发现、路由与负载均衡
* 服务降级与熔断
* 服务调用链监控
* 服务限流(url/方法级别)
* 统一配置中心
* 统一日志中心
* 统一分布式缓存操作类、cacheManager配置扩展
* 分布式锁
* 分布式任务调度器
* **系统监控功能**
* 服务调用链监控
* 应用监控(应用健康、JVM、内存、线程)
* 错误日志查询
* 慢查询SQL监控
* 应用吞吐量监控(qps、rt)
* 服务降级、熔断监控
* 服务限流监控
* **业务基础功能支撑**
* 高性能方法级幂等性支持
* RBAC权限管理,实现细粒度控制(方法、url级别)
......@@ -59,10 +69,11 @@ central-platform -- 父项目,公共依赖
├─zlt-common-spring-boot-starter -- 封装通用操作逻辑
├─zlt-db-spring-boot-starter -- 封装数据库通用操作逻辑
├─zlt-log-spring-boot-starter -- 封装log通用操作逻辑
├─zlt-mq-spring-boot-starter -- 封装mq通用操作逻辑
├─zlt-redis-spring-boot-starter -- 封装Redis通用操作逻辑
├─zlt-ribbon-spring-boot-starter -- 封装Ribbon和Feign的通用操作逻辑
├─zlt-sentinel-spring-boot-starter -- 封装Sentinel的通用操作逻辑
├─zlt-swagger2-spring-boot-starter -- 封装Swagger通用操作逻辑
├─zlt-mq-spring-boot-starter -- 封装mq通用操作逻辑
├─zlt-config -- 配置中心
├─zlt-doc -- 项目文档
├─zlt-gateway -- api网关一级工程
......
......@@ -111,6 +111,11 @@
<artifactId>zlt-auth-client-spring-boot-starter</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-sentinel-spring-boot-starter</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-config</artifactId>
......
......@@ -10,6 +10,10 @@
<description>文件中心</description>
<dependencies>
<!-- 公共实体类模块 -->
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-config</artifactId>
</dependency>
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-common-spring-boot-starter</artifactId>
......@@ -24,7 +28,7 @@
</dependency>
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-config</artifactId>
<artifactId>zlt-sentinel-spring-boot-starter</artifactId>
</dependency>
<dependency>
......
......@@ -10,6 +10,10 @@
<description>用户中心</description>
<dependencies>
<!-- 公共实体类模块 -->
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-config</artifactId>
</dependency>
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-common-spring-boot-starter</artifactId>
......@@ -26,14 +30,14 @@
<groupId>com.zlt</groupId>
<artifactId>zlt-ribbon-spring-boot-starter</artifactId>
</dependency>
<!-- swagger -->
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-swagger2-spring-boot-starter</artifactId>
<artifactId>zlt-sentinel-spring-boot-starter</artifactId>
</dependency>
<!-- swagger -->
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-config</artifactId>
<artifactId>zlt-swagger2-spring-boot-starter</artifactId>
</dependency>
<dependency>
......
......@@ -9,7 +9,7 @@ spring:
host: ${zlt.redis.host}
port: ${zlt.redis.port}
timeout: ${zlt.redis.timeout}
mybatis-plus:
mapper-locations: classpath:/mapper/*Mapper.xml
#实体扫描,多个package用逗号或者分号分隔
......@@ -30,4 +30,4 @@ zlt:
- key: menu
second: 600
- key: user
second: 1800
\ No newline at end of file
second: 1800
......@@ -19,5 +19,6 @@
<module>zlt-ribbon-spring-boot-starter</module>
<module>zlt-auth-client-spring-boot-starter</module>
<module>zlt-mq-spring-boot-starter</module>
<module>zlt-sentinel-spring-boot-starter</module>
</modules>
</project>
\ No newline at end of file
......@@ -12,7 +12,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
......@@ -21,7 +20,6 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.*;
import java.time.Duration;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
......@@ -31,7 +29,6 @@ import java.util.Map;
* @author zlt
* @date 2018/11/6 11:02
*/
@Configuration
@ConditionalOnClass(RedisRepository.class)
@EnableConfigurationProperties({RedisProperties.class, CacheManagerProperties.class})
@EnableCaching
......
......@@ -19,35 +19,14 @@
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<exclusions>
<exclusion>
<artifactId>HdrHistogram</artifactId>
<groupId>org.hdrhistogram</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<exclusions>
<exclusion>
<artifactId>HdrHistogram</artifactId>
<groupId>org.hdrhistogram</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
......@@ -2,7 +2,6 @@ package com.central.common.ribbon;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Feign统一配置
......@@ -10,7 +9,6 @@ import org.springframework.context.annotation.Configuration;
* @author zlt
* @date 2018/9/18 14:04
*/
@Configuration
public class FeignAutoConfigure {
/**
......
......@@ -15,7 +15,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
......@@ -24,7 +23,6 @@ import org.springframework.web.client.RestTemplate;
* @author zlt
* @date 2018/11/17
*/
@Configuration
@EnableConfigurationProperties(RestTemplateProperties.class)
public class RestTemplateAutoConfigure {
@Autowired
......
......@@ -2,10 +2,8 @@ package com.central.common.ribbon;
import com.central.common.ribbon.config.RestTemplateProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.ribbon.DefaultPropertiesFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Ribbon扩展配置类
......@@ -13,11 +11,8 @@ import org.springframework.context.annotation.Configuration;
* @author zlt
* @date 2018/11/17 9:24
*/
@Configuration
@EnableCircuitBreaker
@EnableConfigurationProperties(RestTemplateProperties.class)
public class RibbonAutoConfigure {
@Bean
public DefaultPropertiesFactory defaultPropertiesFactory() {
return new DefaultPropertiesFactory();
......
/target/
*.iml
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.zlt</groupId>
<artifactId>zlt-commons</artifactId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>zlt-sentinel-spring-boot-starter</artifactId>
<description>服务降级、熔断和限流通用组件</description>
<dependencies>
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-common-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
package com.central.sentinel.config;
import cn.hutool.json.JSONUtil;
import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler;
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.central.common.model.Result;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Sentinel配置类
*
* @author zlt
* @date 2019/1/22
*/
public class SentinelAutoConfigure {
public SentinelAutoConfigure() {
WebCallbackManager.setUrlBlockHandler(new CustomUrlBlockHandler());
}
/**
* 限流、熔断统一处理类
*/
public class CustomUrlBlockHandler implements UrlBlockHandler {
@Override
public void blocked(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws IOException {
Result result = Result.failed("flow-limiting");
httpServletResponse.getWriter().print(JSONUtil.toJsonStr(result));
}
}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.central.sentinel.config.SentinelAutoConfigure
......@@ -10,7 +10,6 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
......@@ -38,7 +37,6 @@ import java.util.stream.Collectors;
* @author zlt
* @date 2018/11/18 9:22
*/
@Configuration
@Import( {
Swagger2Configuration.class
})
......
......@@ -17,4 +17,7 @@ zlt.redis.timeout=5000
##### elasticsearch配置
zlt.elasticsearch.cluster-name=docker-cluster
zlt.elasticsearch.cluster-nodes=120.77.169.48:9300
\ No newline at end of file
zlt.elasticsearch.cluster-nodes=120.77.169.48:9300
##### sentinel配置
zlt.sentinel.dashboard=localhost:6999
\ No newline at end of file
......@@ -30,7 +30,8 @@ ribbon.ReadTimeout=15000
##### feign配置
feign.hystrix.enabled=true
feign.sentinel.enabled=true
feign.hystrix.enabled=false
feign.okhttp.enabled=true
feign.httpclient.enabled=false
feign.client.config.feignName.connectTimeout=30000
......@@ -39,12 +40,27 @@ feign.compression.request.enabled=true
feign.compression.response.enabled=true
##### hystrix配置
hystrix.threadpool.default.coreSize=100
hystrix.threadpool.default.maxQueueSize=1000
hystrix.threadpool.default.queueSizeRejectionThreshold=800
# 断路器的超时时间,断路器的超时时间需要大于ribbon的超时时间,不然不会触发重试
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=60000
##### sentinel配置
spring.cloud.sentinel.transport.dashboard=${zlt.sentinel.dashboard}
spring.cloud.sentinel.eager=true
### 动态配置规则
# 系统负载保护
spring.cloud.sentinel.datasource.ds1.nacos.server-addr=${zlt.nacos.server-addr}
spring.cloud.sentinel.datasource.ds1.nacos.dataId=sentinel-system
spring.cloud.sentinel.datasource.ds1.nacos.groupId=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds1.nacos.rule-type=system
# 限流
spring.cloud.sentinel.datasource.ds2.nacos.server-addr=${zlt.nacos.server-addr}
spring.cloud.sentinel.datasource.ds2.nacos.dataId=sentinel-flow
spring.cloud.sentinel.datasource.ds2.nacos.groupId=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds2.nacos.data-type=json
spring.cloud.sentinel.datasource.ds2.nacos.rule-type=flow
# 熔断
spring.cloud.sentinel.datasource.ds3.nacos.server-addr=${zlt.nacos.server-addr}
spring.cloud.sentinel.datasource.ds3.nacos.dataId=sentinel-degraderule
spring.cloud.sentinel.datasource.ds3.nacos.groupId=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds3.nacos.data-type=json
spring.cloud.sentinel.datasource.ds3.nacos.rule-type=degrade
##### druid配置
......@@ -84,6 +100,7 @@ spring.datasource.druid.stat-view-servlet.reset-enable=true
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=admin
##### redis-jedis连接池配置
#最大等待时间
spring.redis.jedis.pool.max-wait=1000ms
......
......@@ -11,6 +11,10 @@
<dependencies>
<!-- 公共实体类模块 -->
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-config</artifactId>
</dependency>
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-auth-client-spring-boot-starter</artifactId>
......@@ -21,7 +25,7 @@
</dependency>
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-config</artifactId>
<artifactId>zlt-sentinel-spring-boot-starter</artifactId>
</dependency>
<dependency>
......
......@@ -9,6 +9,10 @@
<artifactId>zlt-uaa</artifactId>
<description>认证中心</description>
<dependencies>
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-config</artifactId>
</dependency>
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-auth-client-spring-boot-starter</artifactId>
......@@ -27,8 +31,9 @@
</dependency>
<dependency>
<groupId>com.zlt</groupId>
<artifactId>zlt-config</artifactId>
<artifactId>zlt-sentinel-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
......
......@@ -10,7 +10,6 @@ import com.central.common.utils.SpringUtil;
import com.central.oauth.mobile.MobileAuthenticationToken;
import com.central.oauth.openid.OpenIdAuthenticationToken;
import com.central.oauth.service.impl.RedisClientDetailsService;
import com.central.oauth2.common.properties.SecurityProperties;
import com.central.oauth2.common.util.AuthUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
......@@ -19,8 +18,6 @@ import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.*;
......@@ -71,19 +68,15 @@ public class OAuth2Controller {
@Resource
private UserService userService;
@Autowired
private SecurityProperties securityProperties;
@Value("${test2:}")
private String test2;
@GetMapping("/oauth/test")
public String[] testNacos() {
return securityProperties.getCode().getIgnoreClientCode();
public SysUser testNacos() {
return userService.selectByUsername("admin");
}
@GetMapping("/oauth/test2")
public String test2() {
return test2;
public String testNacos2() throws InterruptedException {
Thread.sleep(5000);
return "success";
}
@ApiOperation(value = "用户名密码获取token")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册