这里先简单介绍下getway网关的大体实现。细节不去详述。这一篇也是最后一篇关于微服务的基础介绍。后面的文章中会介绍具体微服务和中间件的设计、编码和实现
由于我们在开发阶段频繁的修改代码,所以在项目中加入热部署以免频繁的启动
我们在启动的项目中加入maven依赖如下:
并且在nacos的配置中加入spring.devtools.restart.enabled=true。启动项目并且在启动成功之后修改代码发现打出了再次启动的日志。说明加入热部署成功
我们使用Lombok的@Slf4j注解放入我们的控制器类中并且我们在select方法中加入log.info的日志。请求该接口发现日志正常打印。关于设置日志的位置请查阅相关资料。如下图:
![]()
新建一个maven的基于pom的空工程命名为cloud-getway
在主工程添加统一的版本管理如下:
为了简单起见我们之间在项目的资源文件下新建application.yml文件并添加内容如下:
server:
port: 8082
spring:
application:
name: gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://localhost:9090
order: 0
predicates:
- Path=/foo/**
filters:
- StripPrefix=1
Uri 是我们需要路由的地址,也是我们之前搭建的demo的请求地址。
编写WrapperResponseFilter 类实现路由功能
@Component
public class WrapperResponseFilter implements GlobalFilter, Ordered {
@Override
public int getOrder() {
// -1 is response write filter, must be called before that
return -2;
}
@Override
public Mono
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono
if (body instanceof Flux) {
Flux extends DataBuffer> fluxBody = (Flux extends DataBuffer>) body;
return super.writeWith(fluxBody.map(dataBuffer -> {
// probably should reuse buffers
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
// 释放掉内存
DataBufferUtils.release(dataBuffer);
String rs = new String(content, Charset.forName("UTF-8"));
byte[] newRs = "sssss".getBytes(Charset.forName("UTF-8"));
originalResponse.getHeaders().setContentLength(newRs.length);//如果不重新设置长度则收不到消息。
return bufferFactory.wrap(newRs);
}));
}
// if body is not a flux. never got there.
return super.writeWith(body);
}
};
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
}
我们发起请求http://localhost:8082/foo/demo/hello
foo是我们路由的根路径 demo/hello是我们业务系统的路径发起请求结果如下图:

说明我们的请求经过了路由的处理类。控制台如下:

说明我们业务系统的代码也得到了执行。
编写AuthFilter如下:
@Component
public class AuthFilter implements GlobalFilter{
@Override
public Mono
String token = exchange.getRequest().getHeaders().getFirst("token");
if ("token".equals(token)) {
return chain.filter(exchange);
}
ServerHttpResponse response = exchange.getResponse();
// Response data = new Response();
// data.setCode("401");
// data.setMessage("非法请求");
byte[] datas = "fffffff".getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(datas);
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
return response.writeWith(Mono.just(buffer));
}
}
使用postmain发起请求并填写token如下图所示

我们给token填写不同的值观察控制台 发现已经对token进行控制了
我们在yml文件中加入配置如下:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/fallback
编写类FallbackController如下:
@RestController
public class FallbackController {
@GetMapping("/fallback")
public String fallback() {
return "test";
}
}
在postman中发起请求http://localhost:8082/fallback如下图所示:

说明我们的熔断经过了熔断的类
我们在熔断的类中加入接口响应时间超时做熔断的操作。此次不在详述
限流可以根据ip 用户Id.可以通过拦截器自行实现限流的逻辑此处不在详述
我们在路由的时候 添加增删改查的功能即可实现。请自行实现