前言
妹子图架构发布以后,不少小伙伴在后台问路由网关、鉴权、限流怎么搞得?这不热乎乎的教程马上就出来了。
架构
架构基本这么一个组合,如果是个人开发或者小团队项目,其实各个组件服务完全可以单机部署,因为集群费银子也没必要。
基础组件
- 路由网关:
GateWay
- 注册中心:
Nacos
- 负载均衡:
Ribbon
- 熔断器:
Hystrix
配置
网关 pom.xml
引入:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
注意 Gateway
默认使用的是 webflux
,不要引入 web
,否则启动会报错。
启动配置 bootstrap.yml
,请自行安装 Nacos
:
server:
port: 8080
spring:
application:
name: tools-gateway
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
discovery:
server-addr: 127.0.0.1:8848
gateway:
routes:
- id: sys
uri: lb://tools-sys
predicates:
- Path=/api/sys/**
filters:
- StripPrefix=2
- name: Hystrix
args:
name: fallback
fallbackUri: forward:/fallback # 熔断回调
- id: weChat
uri: lb://tools-meizi
predicates:
- Path=/api/meizi/**
filters:
- StripPrefix=2
# 跨域请求
filter:
remove-hop-by-hop:
headers:
- trailer
- te
- keep-alive
- transfer-encoding
- upgrade
- proxy-authenticate
- connection
- proxy-authorization
- x-application-context
- access-control-allow-credentials
- access-control-allow-headers
- access-control-allow-methods
- access-control-allow-origin
- access-control-max-age
- vary
globalcors:
corsConfigurations:
'[/**]':
allowCredentials: true
allowedHeaders: '*'
allowedMethods: '*'
allowedOrigins: '*'
maxAge: 3628800
# 熔断
hystrix:
command:
default:
circuitBreaker:
enabled: true
errorThresholdPercentage: 50
forceClosed: false
forceOpen: false
requestVolumeThreshold: 4
sleepWindowInMilliseconds: 10000
execution:
isolation:
semaphore:
maxConcurrentRequests: 2
strategy: SEMAPHORE
thread:
timeoutInMilliseconds: 3000
metrics:
healthSnapshot:
intervalInMilliseconds: 500
rollingPercentile:
bucketSize: 100
enabled: true
numBuckets: 6
timeInMilliseconds: 60000
rollingStats:
numBuckets: 10
timeInMilliseconds: 5000
requestCache:
enabled: false
requestLog:
enabled: false
shareSecurityContext: true
threadpool:
default:
coreSize: 1
maxQueueSize: 200
queueSizeRejectionThreshold: 2
鉴权
/**
* 鉴权
* @Author 小柒2012
* @Date 2020/6/12
*/
@Configuration
public class AuthFilter implements GlobalFilter, Ordered {
private static final Logger logger = LoggerFactory.getLogger(AuthFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getHeaders().getFirst("token");
String path = exchange.getRequest().getPath().toString();
/**
* 排除
*/
if(patterns.contains(path)){
return chain.filter(exchange);
}
/**
* 判断 token 是否为空
*/
if (StringUtils.isBlank(token)) {
logger.info( "token is empty..." );
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}else{
/**
* 验证真伪
*/
CheckResult checkResult = JwtUtils.validateJWT(token);
if (!checkResult.isSuccess()) {
logger.info( "token is error..." );
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -100;
}
private static List<String> patterns =
Arrays.asList(new String[] {"/api/sys/login","/error","/api/sys/v2/api-docs"});
}
熔断
一般是指软件系统中,由于某些原因使得服务出现了过载现象,为防止造成整个系统故障,从而采用的一种保护措施,所以很多地方把熔断亦称为过载保护。
适用场景
防止应用程序直接调用那些很可能会调用失败的远程服务或共享资源。
服务降级
当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。
核心配置:
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
routes:
- id: sys
uri: lb://tools-meizi
predicates:
- Path=/api/meizi/**
filters:
- StripPrefix=2
- name: Hystrix
args:
name: fallback
fallbackUri: forward:/fallback # 熔断回调
主要参数:
# 熔断
hystrix:
command:
default:
circuitBreaker:
enabled: true
errorThresholdPercentage: 50
forceClosed: false
forceOpen: false
requestVolumeThreshold: 4
sleepWindowInMilliseconds: 10000
execution:
isolation:
semaphore:
maxConcurrentRequests: 2
strategy: SEMAPHORE
thread:
timeoutInMilliseconds: 3000
metrics:
healthSnapshot:
intervalInMilliseconds: 500
rollingPercentile:
bucketSize: 100
enabled: true
numBuckets: 6
timeInMilliseconds: 60000
rollingStats:
numBuckets: 10
timeInMilliseconds: 5000
requestCache:
enabled: false
requestLog:
enabled: false
shareSecurityContext: true
threadpool:
default:
coreSize: 1
maxQueueSize: 200
queueSizeRejectionThreshold: 2
核心代码 DefaultHystrixController
:
/**
* 降级处理
*/
@RestController
public class DefaultHystrixController {
@RequestMapping("/fallback")
public Map<String,String> fallback(){
Map<String,String> map = new HashMap<>(8);
map.put("code","fail");
map.put("msg","服务异常");
return map;
}
}
小结
以上基本能满足项目的常用需求,如果想更加灵活的使用,建议使用 Alibaba Sentinel
,阿里巴巴团队开源的一款熔断限流神器,配合控制台更加灵活实用。