这个过程是异步的 , 请求的线程不用一直等待数据的返回 。它在请求完毕以后 , 就直接返回了 , 这时它可以做其他的事情 。
当请求数据被 CPU 内核获取 , 并且发送到指定的数据缓冲区时 , 请求的线程会接到“数据返回”的通知 , 然后就直接使用数据 , 不用自己去做取数据的操作 。

文章插图
异步请求处理 , CPU 处理数据以后通知请求端
实现异步处理请求有两种模式 , 分别是:
- Reactor
- Proactor

文章插图
Reactor 工作原理流水图
Reactor:通过 handle_events 事件循环处理请求 。用户线程注册事件处理器之后 , 可以继续执行其他的工作(异步) , 而 Reactor 线程负责调用内核的 Select 函数检查 Socket 状态 。
当有 Socket 被激活时(获取网络数据) , 则通知相应的用户线程 , 执行 handle_event 进行数据读取、处理的工作 。

文章插图
Proactor 工作原理流水图
Proactor:用户线程使用 CPU 内核提供的异步 IO 发起请求 , 请求发起以后立即返回 。CPU 内核继续执行用户请求线程代码 。
此时用户线程已将 AsynchronousOperation(异步处理)和 CompletionHandler(完成获取资源)注册到内核 。之后操作系统开启独立的内核线程去处理 IO 操作 。
当请求的数据到达时 , 由内核负责读取 Socket(网络请求)中的数据 , 并写入用户指定的缓冲区中 。
最后内核将数据和用户线程注册的 CompletionHandler 分发给内部 Proactor , Proactor 将 IO 完成的信息通知给用户线程(一般通过调用用户线程注册的完成事件处理函数) , 完成异步 IO 。
API 网关实现功能
说起对 API 网关的使用 , 我们还是对具体功能更加感兴趣 。让我们一起来看看它实现了哪些功能 。
负载均衡
当网关后面挂接同一应用的多个副本时 , 每次用户的请求都会通过网关的负载均衡算法 , 路由到对应的服务上面 。例如:随机算法 , 权重算法 , Hash 算法等等 。
如果上游服务采取微服务的架构 , 也可以和注册中心合作实现动态的负载均衡 。
当微服务动态挂载(动态扩容)的时候 , 可以通过服务注册中心获取微服务的注册信息 , 从而实现负载均衡 。

文章插图
Nginx+Lua+服务注册中心实现动态负载均衡
路由选择
这个不言而喻 , 网关可以根据请求的 URL 地址解析 , 知道需要访问的服务 。再通过路由表把请求路由到目标服务上去 。
有时候因为网络原因 , 服务可能会暂时的不可用 , 这个时候我们希望可以再次对服务进行重试 。

文章插图
Zuul 作为 API 网关将请求路由到上游服务器
例如:Zuul 与 Spring Retry 合作完成路由重试 。
#是否开启重试功能 zuul.retryable=true #对当前服务的重试次数 ribbon.MaxAutoRetries=2 流量控制
限流是 API 网关常用的功能之一 , 当上游服务超出请求承载范围 , 或者服务因为某种原因无法正常使用 , 都会导致服务处理能力下滑 。
这个时候 , API 网关作为“看门人” , 就可以限制流入的请求 , 让应用服务器免受冲击 。
限流实际上就是限制流入请求的数量 , 其算法不少 , 有令牌桶算法 , 漏桶算法 , 连接数限制等等 。这里我们就介绍三个常用的 , 一般通过 Nginx+Lua 来实现 。

文章插图
令牌桶限流
统一鉴权
访问应用服务器的请求都需要拥有一定权限 , 如果说每访问一个服务都需要验证一次权限 , 这个对效率是很大的影响 。可以把权限认证放到 API 网关来进行 。
目前比较常见的做法是 , 用户通过登录服务获取 Token , 把它存放到客户端 , 在每次请求的时候把这个 Token 放入请求头 , 一起发送给服务器 。
推荐阅读
- 合理饮食 喝汤的讲究有哪些
- 穿衣搭配|气质优雅的女人,春夏都会穿西装,这样搭干练又高级
- 老板办公室风水有哪些讲究
- 铁观音茶叶有什么功效,铁观音的冲泡时间有什么讲究
- 女人上半身肥胖怎么减,女人睡眠不好怎么调理其实女人失眠的治疗方法是这样
- 陈皮的食用方法,陈皮的功效与作用及食用方法陈皮这样吃才能治病
- 风水玄机 床上风水有讲究 床上风水会危害身体健康
- 风水趣谈厕所风水有讲究 看看几种常见破财厕所风水
- 客厅沙发风水有哪些讲究?
- 新房风水装修禁忌和入住讲究
