日200亿次调用,喜马拉雅网关的架构设计( 二 )


文章插图

注意:请点击图像以查看清晰的视图!
从上图中 , 我们能够明显观察到 , Tomcat 的封装功能相当完善 , 但在内部默认设置下 , 会有三次 copy 。
HttpNioClient 的问题:在获取和释放连接的过程中都需要进行加锁 , 针对类似网关这样的代理服务场景 , 会导致频繁地建立和关闭连接 , 这无疑会对性能产生负面影响 。
鉴于 Tomcat 存在的这些难题 , 我们在后续对接入端进行了优化 , 采用 Netty 作为接入层和服务调用层 , 也就是我们的第二版 , 成功地解决了上述问题 , 实现了理想的性能 。
2、第2版:Netty+全异步基于 Netty 的优势 , 我们构建了全异步、无锁、分层的架构 。
先看下我们基于 Netty 做接入端的架构图:

日200亿次调用,喜马拉雅网关的架构设计

文章插图
注意:请点击图像以查看清晰的视图!
2.1 接入层Netty 的 IO 线程主要负责 HTTP 协议的编解码工作 , 同时也监控并报警协议层面的异常情况 。
我们对 HTTP 协议的编解码进行了优化 , 并对异常和攻击性请求进行了监控和可视化处理 。
例如 , 我们对 HTTP 请求行和请求头的大小都有限制 , 而 Tomcat 是将请求行和请求头一起计算 , 总大小不超过 8K , 而 Netty 是分别对两者设置大小限制 。
如果客户端发送的请求超过了设定的阀值 , 带有 cookie 的请求很容易超过这个限制 , 一般情况下 , Netty 会直接响应 400 给客户端 。
在优化后 , 我们只取正常大小的部分 , 并标记协议解析失败 , 这样在业务层就可以判断出是哪个服务出现了这类问题 。
对于其他攻击性的请求 , 例如只发送请求头而不发送 body 或者只发送部分内容 , 都需要进行监控和报警 。
2.2 业务逻辑层这一层负责实现一系列支持业务的公共逻辑 , 包括 API 路由、流量调度等 , 采用责任链模式 , 这一层不会进行 IO 操作 。
在业界和大型企业的网关设计中 , 业务逻辑层通常都被设计成责任链模式 , 公共的业务逻辑也在这一层实现 。
在这一层 , 我们也执行了相似的操作 , 并支持以下功能: