什么是网关层(getway)?
技术选型fastify
速度快适合网关层 fastify教程上一章有讲
网关层是位于客户端和后端服务之间的中间层,用于处理和转发请求。它充当了请求的入口点,并负责将请求路由到适当的后端服务,并将后端服务的响应返回给客户端。网关层在分布式系统和微服务架构中起到了关键的作用。
以下是一些网关层的主要功能和优势:
- 路由:网关层可以根据请求的URL路径或其他条件将请求转发到不同的后端服务。它可以根据特定的路由规则来决定请求应该被发送到哪个服务处理。
- 负载均衡:当有多个后端服务提供相同的功能时,网关层可以通过负载均衡算法将请求分发到这些服务中,以达到分散负载、提高系统性能和可用性的目的。
- 缓存和性能优化:网关层可以缓存一些经常请求的数据或响应,以减少后端服务的负载和提高响应速度。通过缓存静态内容或频繁请求的数据,可以减少对后端服务的请求,从而提升整体性能。
- 信道加密:网关层可以提供对请求和响应数据的加密和解密功能,以确保数据在传输过程中的安全性和保密性。通过使用加密算法和安全证书,网关层可以保护敏感数据免受未经授权的访问和窃听。
- 熔断技术:当后端服务出现故障或异常时,网关层可以使用熔断技术来防止请求继续发送到出现问题的服务上。通过监控后端服务的状态和性能指标,网关层可以自动切换到备用服务或返回错误响应,以提高系统的容错性和可靠性。
- 限流:网关层可以实施请求限制策略,以防止对后端服务的过度请求造成的负载过载。通过限制每个客户端的请求速率或总请求数量,网关层可以保护后端服务免受滥用或恶意攻击。
安装依赖
npm install fastify
npm install express
npm install @fastify/caching #缓存
npm install @fastify/http-proxy #代理/负载均衡
npm install @fastify/rate-limit #限流
npm install opossum #熔断技术
目录结构
src/config/index.jsproxy/index.jsindex.js
package.json
server.js
先编写外层的server.js 启动一个简单的服务
process.argv[2]这里使用process接受端口号这样就可以方便开启多个服务
import express from 'express'const app = express()app.get('/info', (req, res) => {res.json({code:200,port: process.argv[2],})
})app.get('/', (req, res) => {res.json({code: 200})
})app.listen(process.argv[2], () => console.log(`Server running on port ${process.argv[2]}`))
启动服务
node server.js 9001
node server.js 9002
网关层编写
src/index.js
核心功能实现
- 代理服务(代理服务做成了配置项是个数组 循环注册,这样可以统一入口)
- 熔断技术(检测服务是否正常运行,如果挂掉或者超时一定阈值就熔断)
- 缓存技术(底层其实也是
协商缓存
|强缓存
) - 限流技术(规定在多少时间内,只能发起几次请求,防止DDOS)
温馨提示 不是必须按照我这个实现,只是个参考,一般场景是需要实现这些功能的
import fastify from 'fastify'
import proxy from '@fastify/http-proxy' //负载代理技术
import rateLimit from '@fastify/rate-limit' //限流技术
import proxyConfig from './proxy/index.js' //请往下翻
import caching from '@fastify/caching' //缓存技术
import CircuitBreaker from 'opossum' //熔断技术
import { rateLimitConfig, cachingConfig, breakerConfig } from './config/index.js' //请往下翻
const app = fastify({logger: false
})
//熔断技术
const breaker = new CircuitBreaker((url) => {return fetch(url).then((res) => res.json()) //检测服务是否挂掉
}, breakerConfig)app.register(caching, cachingConfig) //注册缓存服务app.register(rateLimit, rateLimitConfig) //注册限流proxyConfig.forEach(({ upstream, prefix, rewritePrefix, httpMethods }) => {app.register(proxy, {//请求代理服务之前触发熔断preHandler: (request, reply, done) => {//检测这个服务 如果服务挂掉立马熔断breaker.fire(upstream).then(() => done()).catch(() => reply.code(503).send('Circuit breaker tripped'))},upstream,prefix,rewritePrefix,httpMethods})
})//启动服网关
app.listen({ port: 3000 }).then(() => console.log('server running on port 3000'))
proxy/index.js
代理服务配置文件
我们的系统还可以根据设备的不同实现多个网关层
温馨提示 网关层不一定只有一个
export default [{upstream: 'http://localhost:9001', //代理地址prefix: '/pc', //前缀rewritePrefix: '', //实际请求将pc 替换成 '' 因为后端服务器没有pc这个路由httpMethods: ['GET', 'POST'], //允许的请求方式},{upstream: 'http://localhost:9002',prefix: '/mobile',rewritePrefix: '',httpMethods: ['GET', 'POST'],}
]
config/index.js
其他配置项
export const rateLimitConfig = {max: 5, //每 1 分钟最多允许 5 次请求timeWindow: '1 minute', //一分钟
}export const cachingConfig = {privacy: 'private', //缓存客户端服务器 禁止缓存代理服务器expiresIn: 1000 //缓存1s
}export const breakerConfig = {errorThresholdPercentage: 40, //超过 40% 会触发熔断timeout: 1000, //超过 1s 会触发熔断resetTimeout: 5000, //熔断后 5s 会重置
}
启动服务
nodemon src/index.js