本项目基于Netty搭建一个非阻塞的微服务网关,作为http客户端和thrift后台服务的隔离层层,把得到的http请求转换成thrift请求,再将收到的thrift结果转换成http响应,将不同的后台服务对http客户端透明化。网关作为一个IO heavy的应用,高吞吐量是非常重要的(所以选择Netty作为底层IO框架)
其他的主要功能包括:
- 服务发现/负载均衡
- 服务连接池
- 过滤器
- Spring风格的路由配置
- 使用gradle构建项目
- Netty 4.1
- Thrift 0.10.0
- CuratorFramework
-
NIO
-
可动态更新路由
路由加载方式
-
网关启动时通过加载配置文件
routing.yaml
thriftServices: - http: POST /echo # http请求 convertor: # 解析请求和生成响应的类 service: echoservice # 下游服务名(zookeeper中的名字) method: echo # 下游服务方法名 clazz: # thrift生成的类名 - http: .... ... xxxServices:
-
Spring风格路由配置
@ThriftRouter(http = {"POST", "/echo"}, service = "echoservice", method = "echo", args = EchoService.echo_args.class, result = EchoService.echo_result.class) public class EchoConvertor{ @RequestParser public Object[] parse(FullHttpRequest request) { return new Object[] {request.content().toString(CharsetUtil.UTF_8)}; } @ResponseGenerator public String generate(String result) { return result; } }
-
Routing匹配解析模版,路径参数注入:
@RequestParser public Object[] parse(FullHttpRequest request, @PathVar("id") int id) { ... }
-
通过客户端工具运行时更改路由配置 (未完成)
作为一种特殊的请求,同样在netty中处理。
-
路由的数据结构保证读取的速度,对路由的更新通过创建一个新的hashmap实例的方式防止线程阻塞。
-
-
http和rpc转换
thrift: thrift使用的协议暂时是hard code的
- protocol:TMultiplexedProtocol, TCompactProtocol
- transport: TFramedTransport
-
服务发现/负载均衡
- 服务发现和netty线程分开,作为一个background thread运行。
- 使用一个zookeeper连接,配置所有的服务,每个服务对应一个本地缓存实例,缓存实时从zookeeper获得更新。
- 负载均衡默认采用轮询。负载均衡的数据结构保证获取服务实例的速度,节点更新的操作在zookeeper线程中串行执行。
-
动态添加(删除)过滤器
网关提供两种类型的过滤器。preRouting, routing和postRouting过滤器。(和Zuul过滤器类似)
- preRouting: 刚解析完http请求后
- routing: 调用下游服务前 (未完成)
- postRouting: 生成http响应后
加载过滤器方式:
- 网关启动前通过代码配置
- 运行时通过客户端工具 (未完成)
- 加载新的filter
- disable已加载的filter
- enable被disable的filter
-
熔断 (未完成)
熔断完全基于过滤器实现。通过记录下游服务响应的不同状态的次数(成功,失败,超时等),决定对于之后请求的操作(例:直接返回)。(原理和hystrix类似)
-
错误处理
request运行过程中抛出异常 和 请求被过滤器过滤等特殊情况,自动快速产生一个对应的http响应。
- 从数据流中解码,得到的http请求
- preRouting过滤器。
- 查询http请求对应的下游服务,选择服务节点(服务发现,负载均衡)
- routing过滤器
- 将http请求转换成thrift请求参数(这里内部调用配置的http请求解析器)
- 连接服务节点(生成rpc channel),将thrift请求参数编码成数据流发送至下游服务
- 从数据流中解码,得到的thrift响应
- 将thrift响应转换成http响应(这里内部调用配置的http响应生成器)
- postRouting过滤器
- 将http响应编码成数据流发送回客户端
关于如何扩展