01 背景

让每一个用户获取到稳定、及时的页面体会,是前端工程师们一直以来极力的方向。

作为一个具有丰盛内容资源的视频网站,爱奇艺官网主站需求再三进行节目上线或许下线、各种活动装备等操作调整,关于页面SSR服务的可用性及稳定性,都有着极axios封装高的要求。

在2019年之前,爱奇艺官网主站页面的SSR选用的是在CMS途径中书写Velocity模板elasticsearch倒排索引,由Java编译,长处是烘托速度快,但缺陷也非常明显

(1elasticsearch面试在C前端和后端的差异MS途径中开发体会欠好:没有传统IDE可视化东西便利,不能装备快捷键、不能设备插件等等,导致开发功率低下。

(2)前后axios发音端代码不同构前端和后端哪个薪酬高因为后端运用Veaxios阻挠locity模板,而前端需求运用Vue,导致前后nginx怎样读端代码不同构。

(3)损坏Vue组件封装性:因为Java无法编译Vue组件,全部的Vue组件都需求用Slot的方法在CMS途径中书写以到达SEO和SSR的意图。

依据以上全部原因,咱们决议运用Node来进行SSR。因为咱们的前端结构是Vue,因而elasticsearch运用场景咱们选择了配套的Nuxtnginx是什么意思结构进行SSR。

运用Nuxt进行SSR,难点可视化数据图表并不在于怎样运用Nuxt,而在于怎样保护这个服务,保证其功用、稳定性等,因而,本文将不会介绍Nuxt的运用,其语法能够参考官网,这儿将首要从功用、缓存、限流、灾备、日志等几个方axios阻挠面来介绍咱们是怎样保证Nuxt服务的可用性及稳定性的。

02 Nuxt 稳定性前进之路

2.1 页面装备

首要介绍一个很重要的装备文件。在咱们的项目根目录下,创建了一个页面装备文件,用来存放每个页面的通用装备,例如页面的缓存装备、Purge信息、主题色装备、广告信息装备等等,该文件导出一可视化大屏个Object, 键值为页面的Router Name,axios和ajax差异Value值为页面的装备信息:

// coelasticsearch面试nfigs/pageinfo.js
export defaul前端开发t {
'daxios翻译ianelasticsearch怎样读shiju-id': {...},
'zongyi': {
theme: 'dark', // 页面主题色装备
},
'home2020': {...},
'rank-hot': {...}
}

然后咱们在Nuxt插件中依据央求的路由信息,读取对应的页面配axios用法备,并将其注入到全部的组件实例中,便利随时取用:

//前端框架 plugins/pageinfo.js
import config from 'configsaxios封装/pageinfo.js'
export default ({ routnginx是什么意思e }, inject) => {
inject('pageInfo', config[route.n可视化是什么意思ame]) // 注入页面装备信息
}

因而你能够在组件的任何地方获取到页面装备信息而不需求经过Props一层层传递,页面通用装备也不会散落在项目各个地方,便利一致处理。

&elasticsearch怎样读lt;div :class="$pageInfo.theme">我是综艺页面</di可视化图表怎样做v>

2.2 浏览器兼容性

尽管Nuxt理论上能够支撑IE9elasticsearch面试,但IE9在许多方面都需求增加Polyfill,例如对History API的支撑等,为了坚持代码的简洁性,咱们扔掉了支撑IE9-,但咱们仍然在结构中保留了一套机制来支撑jQuery,使得凹凸版别能够共用HTML,而不需求独自为低版别写模板,然后最大程度的减少兼容前端和后端哪个薪酬高低版别浏览器的成本。

大致思路为,Nuxt供给了一个’render.route’的钩子函数,该钩子函数的实行机遇在生成HTML后,回来给用户之前。在这个钩子函数中,咱们能够依据用户央求的UA信息判别用户版别**,假定是低版别浏览器用户则移除HT可视化图表怎样做ML中高版别JS并注入低版别打包后的进口文件即可。

// nuxt.config.js
'render:ro前端学什么ute': (url, result, { req }) => {
if (isLonginx发动指令wBrowseelasticsearch运用场景r(req)nginx怎样读) { // 依据用户可视化东西ua信息判别是否是低版别
const $ = cheerio.load(result.html)
$('body script[src*='pcw/ssr']').remove() // 移除高版别js
$('body').append('<script src="https://stc.iqiyipic.com/jquery.jnginx是什么意思s"&axios原理gt;&lt前端开发需求学什么;/script') // 增加jquery
$('body').append('<script src="https:elasticsearch面试//stc.iqiyipic.com/index.js"></scripnginx面试题t') // 增加低版别进口js
result.html = $.html()
}
},

2.3 功用优化

2.3.1 数据过滤

Nuxt有一个很重要的机制在于,它会将全部asyncData函数回来的数据挂在windoElasticsearchw.__NUXT__,经过HTML回来给客户端,然后避免客户端再次央求这些数据前端开发需求学什么,因而,asyncData函数中回来的数据量对功用的影响变得愈加重要,它可视化编程不只影响了接口数据的传输时间,还影响了HTML的体积,因而,咱们需求对这些数据进行紧缩,在NUXT中,咱们尝试了三种计划elasticsearch倒排索引

  1. 在asyncD前端面试题ata中做数据过滤

  2. GraphQLelasticsearch运用场景

  3. 数据过滤途径

在asnginx面试题yncData中做数据过滤仅减少了HTML体nginx负载均衡策略积,却并无法减少冗余数据的传可视化教育监导渠道输。

Gr前端学什么aqhQL尽管解nginx重启决了冗余数据的传输问题,但代码不利于保护,因为它需求写许多的查询参数, 查询参数太长时还需求运用POST。

// 非常不利于保护的查询字符串
const query = `
query {
qipuGetVideoBrelasticsearch面试题iefList (
album_id: "${params.album_id}"
type: "EPISODE_LIST"
play_platform: "PC_QIYI"
order: "DESC"
) {
rpc_statelasticsearch倒排索引us
episodnginx怎样读e {
id
g_corner_可视化教育监导渠道mark_s
brief {
title
short_title
subtitle
page_url
}
release {
publish_time
}
}
}
}
`
axios.get(`http://xxx.inginx负载均衡qiyi.com/graphql?query=${query}`)

究竟,我nginx是什么意思们树立了一个数据过滤途径,以可视化的方法来配axios跨域备接口数据源、数据的字段过滤和映射,究竟生成一个接口,该接口从装备的数据源获取数据,然后经过字段映射和字段过滤,仅仅回来咱们需求的字段,这样既过滤了冗余数据又不需求保护GraphQL的axios查询参数,而是将GraphQL的查询串可视化为装备。

开发功率提高50%以上,爱奇艺官网主站的Nuxt实践

2.3.2 Layout

Nelasticsearch运用场景uxt供给了Layout装备项,看似非常的便利,但经过剖析Nuxt生成的.nuxt/App.js进口文件,咱们发现全部的Layout不管有没有被运用到,都会被打包进来,例如A页面运用了LayoutA, B页elasticsearch怎样读面运用了LayoutB, C页面运用了LayoutC,则A、B、C三个页面的进口JS会可视化有LayoutA、LayoutB、LayoutC的全部代码。

// .nuxt/App.js
import _8daa19aa from '../src/layouts/a.vue'
import _8daa19a8 f前端开发是干什么的rom '../src/layoElasticsearchuts/b.vue'
import _8daa1可视化9a6 from '前端和后端的差异../src/layoutsaxios和ajax差异/c.vue'
import _6f6c098b from './lay可视化的效果outs/default.vue'

因而,假定Layout的逻辑很凌乱,并且假定代码量很大,全部页面的nginx怎样读JS体积就会变大许多。依据以上原因,咱们扔掉了运用Nuxt的Layout,而是自己封装了一个I71Layout组件来供给全部页面的通用功用,以减少冗余代码。
因为Vue SSR是依据虚拟DOM,而Java是依据字符串,所以功用上相比之前会慢一些,因而咱们从页面和组件两个粒度上做了缓存战略。

2.4 缓存

咱们运用Nginx反向署理来操控页面等级的缓存,nginx反向署理许每个页面缓存5分钟,当Nuxt回来非200时,Nginx则运用过期缓存回来。

组件缓存咱们运用的是官方的@nuxtjs/component-cache模块,它供给了一个serverCacheKey装备项,Nuxt会以这个装备项的值作为缓存的Key。因而咱们为每个需求缓存的组件定义了一个cache-key的Props, 传递后则会依据传递的值做缓存,未传递则无缓存。这样关于全部无缓存的可视化管理页面在调用组件时,能够传递一个cache-key来使可视化编程得组件被缓存,然后加快页面的SSR。前端面试题

2.5 pur可视化是什么意思ge

elasticsearch面试题于有缓存的页面,咱们需求对应的Purge接口来铲除页面缓存。页面的Purge分为两个部分,一部分是咱们Nginx反向署理的缓存Purge, 另一部分是前端面试题CDN缓存的Purge,他们的Purge原理相同,因而这儿咱们只讲Nuxt服务的Nginx反向署理的缓存Purge。elasticsearch怎样读

咱们期望供给一个Purge接口,经过传递页面名参数来Purge指定的页面。咱们的Nuaxios发音xt结构本身是依据Koa树立,所以咱们只需求在SSR之前刺进koa-router,就能够供给咱们的Purge接口。

// server/index.js
const app = new Koa()
const ronginx反向署理uter = new Router()
router.get('/api/purge/page/:pageName', async (ctx) => { // 定义purge接口,支撑传递pagelasticsearch面试eName
ctx.body = await purgePage(ctx)nginx重启 // purge nginx缓存和cdn缓存
})
app.use(router.routes()) // 刺进咱们需求的api
app.use(ctx => { // nuxt 进行 ssr
nuxt.render(ctx.reqelasticsearch教程, ctx.res)
})

那咱们怎样知道每个pageName要Purge哪些URL呢?这儿咱们需求在之前说到的页面装备文件中进行装备来将pageName和Purge URL相关起来:

// configs/前端和后端的差异pageinfo.js
zongyi: {
purge: {
purgeUrl: [
'https://zongaxios发音yi.iqiyi.com/',
'https://www.iqiyi.com/zongyi'
],
},
}

接下来咱们只需求Purge全部服务上的这些URL,服务安置在公司的运用途径,一共有4个集群,上百个Docker容器,咱们需前端开发是干什么的求Purnginx重启ge全部宿主机上的Nginx缓存,具体操作如下。

首要咱们需求在Nginx中装备让其支撑Purge:

location / {
proxy_cache_purge PURGE from all;
}

这样就能够经过调用http://{宿主机的域名elasticsearch查询}:{宿主机的端口}/purge/{uri}来Purge该宿主机上uri对应的缓存了。

接下来咱们只需求逐个调用全部宿主机上的Pu前端开发是干什么的rge接口就能够Purge全部的宿主机上的页面缓nginx反向署理存了。

2.6 限流

关于无缓存页面,为了谨防恶意刷量行为,要进行限流。咱们从WAF, 单IP限流, IP黑名单进行了三方面的束缚。

2.6.1 WAF(Web Applicataxios跨域ion Firewall)

首要咱们接入了公司的防火墙途径,经过智能识别以过滤掉一些恶意央求。其次,关于一些动态路由的页面,咱们对央求的URL进行了正则匹配,不契合正则的央求全部回绝拜访并回来403。

2.6.2 单IP限流

为了避免单IP脚本刷量,咱们在Nginx反向署理运用limit_req模块进行单IP限流。关于普通用户和爬虫,咱们设置了不同的拜访频次,逾越频可视化次的央求nginx菜鸟教程回绝拜访并回来503。

2.6.3 IP黑名单

除此之外,咱们经过日志剖析会发现一些很明显的刷量IP,关于这样的IP,咱们期望直接封禁。

假定直接在Nnginx反向署理ginx装备中增加可视化的效果Deny语句,会发现Deny并不会收效,是因为央求nginx是什么意思经过了网关,到咱们的Nginx服务时,Remote Address变成了网关的IP,而咱们Deny的是真是用户的IP可视化的效果,所以咱们需elasticsearch倒排索引求想办法nginx反向署理让Nginx知道用户elasticsearch怎样读的实在IP是什么。

一般用户的实在IP存储在x-forwarded-for字段中,为了拿到用户的实在IP,咱们需求在Nginx中做以下装备:

# nginx.conf
server可视化东西 {
r可视化东西eal_ip_header X-Forward可视化教育监导渠道ed-For; # 奉告Nginx,用户的实在IP存储在x-forwarded-for字段中
real_ip_r前端框架ecursive on;
}

但光有以上装备还不行,因为x-forwarded-for字段为一个字符串,每elasticsearch查询经过一个节点,这个节点就会向里面追加一个IP,所以抵达咱们的Ngin前端x时,该字段的值为x-forwarded-for: {用户的实在IP},{网关的IP},而Nginx读取IP时,会默许从后往前读取IP, 假nginx负载均衡设这个IP是受信赖的IP,则会继可视化的效果续往前读取,直到不被信赖的IP就会作为是用户的实在IP,因而,假定没有额外装备,Nginx读取到的IP仍然是网关的IP,因而,咱们还需求将全部网关IP增加到信赖IP的列表中,Nginx才调持续往前读取到用户的实在IP。咱们能够将整个内网网段都设置成信赖IP:

# nginx.conf
server {
set_real_ip_from xxx.0.0.0/8; # 设置内网网段为信赖IP
real_ip_heade前端开发需求学什么r X-Forwar前端开发是干什么的ded-For; # 奉告Nginx,用户的实在IP存储在x-forwarded-for字段中
real_ip_recursive on;
}

现在Nginx能够读取到用户的实在IP了,这时候咱们只需求创建一个IP黑名单即可:

#前端和后端的差异 nginx.conf
server {
set_real_ip_from xxx.0.0.0/8; # 设置内网网段为信赖IP
real_ip_he可视化ader X-Forwarded-Forelasticsearch运用场景; # 奉告前端和后端的差异Nginx,用户的实在IP存储在x-forwaxios用法arded-for字段中
real_ip_recursive on;
inclu可视化剖析de ip-blacklist.conf # 导入IP黑名单
}
# ip-blacklist.conf
deny xx.xx.xx.xx;

2.7 灾备

开发功率提高50%以上,爱奇艺官网主站的Nuxt实践
关于无缓存的页面,除了限流以外,我前端和后端的差异们还需求有灾备计划,否则一旦服务犯错可视化编程回来非200,用户将看到过失页面。

咱们安置了一套独立的灾备服务,运用Nodelasticsearch教程e脚本每隔三分钟从线上服务拉取全部重要页面,假定页面回来200,则将其存储为HTML文件,否则扔掉该页面,elasticsearch倒排索引然后运用Nginx做反可视化向署理来Serve灾备页面。

CDN先从线上服务前端开发需求学什么拉取页面,若回来非200,则从灾备服务拉取对应的页面回来nginx负载均衡给用户,以此保证用户永久前端工程师不会看见犯错的页面

2axios用法.8 服务端日志

服务端日志首要用来记载Nuxt烘托页面的记载、过失信息等,它们关于排查问题、核算流量来说是非常重要的,咱们的服务端日志分为两大部分:页面烘托日志、接口央求日志。

页面烘托日志即每一次elasticsearch教程来一个页面央求,则写一条日志,记载页面的URL、elasticsearch倒排索引Referer、用户Co前端开发需求学什么okie、用户IP等信息,若页面烘托未犯错则写入到logs/page/info.log中,nginx发动指令若页面烘托犯错,则写一条日志到logs/page/error.log中。

接口日志是每一次页面烘托中宣布的央求前端和后端的差异日志,封装在底层发送央求的HTTP函数中,记载了调用该接口的页面URL、接口URL、接口参数等信息,若央求成功,则写一条nginx怎样读日志到lelasticsearch怎样读ogs/api/info.log, 若央求失利,则写一条日志到logs/api/error.log中。axios翻译

// nuxt.config.jnginx重启s
hooks: {
'render:setaxios恳求upMiddleware': app => { // 在nuxt初nginx发动指令始化时刺进一个中间件,每次央求都生成一个logParams目标
app.use(async (req, res, next) => {
req.logPelasticsearch官网arams = {
requestId: generateRandomString()elasticsearch面试, // 生成requestId随机串
pageUrl: req.url
}
next()
})
},
'render:routeDone': (url, result, { req, res }) => { // 烘托完毕
logger.page.info({ type: 'render', ...req.loelasticsearch官网gParams}, req) // 写日志时带上requestId
},
'render:errorMiddleware': app =&g可视化图表怎样做t; app.use(asyaxios翻译nc (error, req, res, nextelasticsearch倒排索引) => { // 烘托过失
logger.page.error({ type: 'render', error, ...req.loaxiosgParams }, reqaxios跨域) // 过失日志带上requelasticsearch运用场景estId
next(error)
}),
}

为了让页面烘托日志、这一次烘托的接口日志相关起来,咱们会在烘托前生成一个仅有的RequestId, 然后在该次烘托的全部日志中都带上这个RequestId,就能够经过一个RequestId查询到页面烘托日志,以及这个页面宣布去的全部央求日志了。

class Resource {
as前端和后端哪个薪酬高ync http (opts)
let data
try {
data = await axios(opts)
process.server && logger.api.info(opts, this.req.logParams) // api日志带上requestid
} catch (error) {
process.server && loggeaxios和ajax差异r.api.error(opts, error, this.req.logParams) // api过失日志带上reqaxios发音uesti可视化的效果d
}
return data
}
}

2.9 日志收集

咱们nginx反向署理选用了Filebeat + Elasticsearch + Kibaxios用法ana进行日志处理,首要经过Filebeat进行实时日志收集,然后上报至指定 kafka 集群,然后对日志进行剖析并树立索引,究竟生成一个前端开发可视化的日志查询页面,这样咱们axios翻译就能够检查一段时间内契合查询条件的日志了。

2.10 流量监控

依据服务端日志,就能够据此核算流量经由了CDN的elasticsearch面试缓存、WAF的阻挠、Nginx反向署理的缓存,终究核算出抵达我elasticsearch面试们的Nuxt服务的实践流量到底有多少。咱们能够依据日志的time字段选择出指定时间段且type= ‘render’的日志,便是该时间段内Nuxt服务承受的总流量了,假定想看各个页面的流量axios跨域,还能够进一步对日志中的pageUrl字段进行选择。

03 总结

Nuxt从根本上解决了之前在CMS途径运用Velaxios封装ocity开发遇到的全部问题,但一起也带来了一些其他问题,例如域名抵触的问题、服务端变量同享的问题、烘托功用问题等。不过整体来说,瑕不nginx重启掩瑜,开发体会得到了质的前进,开发功率前进了50%以上;组件复用率更高、组件封装性更好,代码可读性、可保护性都得到了腾跃性的前进;在CDN缓存、Nginx反向署理缓存、组件缓存的强力加持下,页面的烘托功用也并没有下降;因为移除了一些因为前后端代码不一致、许多运用Slot等一些凌乱逻辑后前端开发需求学什么,首屏烘托功用反而前进了许多,服务器响应时axios面试题刻维持在均匀0.5s左右,过失率维持在0.2%左右,而在有灾备服务axios阻挠兜底的情况下,可拜访性也几乎到达100%。

终究,等待Nuxt3的到来以及功用和开发体会上的进一步前进。