因為egg知識點(diǎn)豐富誉察,分為上下兩章點(diǎn)擊見上章
10 阿里監(jiān)控
Node.js 性能平臺(alinode)
是面向所有 Node.js 應(yīng)用提供 性能監(jiān)控讶泰、安全提醒、故障排查随珠、性能優(yōu)化
等服務(wù)的整體性解決方案蝶俱,提供完善的工具鏈和服務(wù),協(xié)助開發(fā)者快速發(fā)現(xiàn)和定位線上問題侨把。
npm i nodeinstall -g
提供了egg-alinode 來快速接入犀变,無需安裝 agenthub
等額外的常駐服務(wù)。
npm i egg-alinode --save
// /config/plugin.js
exports.alinode = {
enable:true,
package:'egg-alinode',
},
申請一下服務(wù)
訪問控制臺
// config/config.default.js
exports.alinode = {
enable: true,
appid: '***', // Node.js 性能平臺給您的項目生成的 appid
secret: '***', // Node.js 性能平臺給您的項目生成的 secret
logdir: '***', //可選秋柄,Node.js 性能平臺日志輸出地址絕對路徑贱纠,與 NODE_LOG_DIR 保持一致坑填。如:/tmp/,也可以不寫
error_log: [
// '您的應(yīng)用在業(yè)務(wù)層面產(chǎn)生的異常日志的路徑,數(shù)組,可選,可配置多個',
// '例如:/root/.logs/error.#YYYY#-#MM#-#DD#.log',
// '不更改 Egg 默認(rèn)日志輸出路徑可不配置本項目',
],// 可選
agentidMode:'IP', // 可選,如果設(shè)置,則在實例ID中添加部分IP信息雹舀,用于多個實例 hostname 相同的場景(以容器為主)
};
然后你就能愉快針對你的egg,進(jìn)行監(jiān)控了
獲取swgger地址 輸入瀏覽器
你看到就是文檔了
點(diǎn)擊try it out
輸入你傳的值,然后點(diǎn)擊Execute
結(jié)果
你就可以獲取到接口傳遞過來的值,效果類似postman,但是清晰程度比postman好
12.5 常見問題
一般情況下都不會有問題粗俱,但是如果你這時候巧妙的用了egg-static,那么你就會報錯了<br />經(jīng)過排查说榆,你就會發(fā)現(xiàn)
/node_modules/egg-swagger2/app.js
它會是一個數(shù)組,然后報錯必須是個字符串,然后你懂得..你給他做成一個字符串即可
11 引入靜態(tài)文件
11.1 經(jīng)過測試插件設(shè)置
exports.ejs = {
enable: true,
package: 'egg-view-ejs',
};
11.2 配置設(shè)置
a:靜態(tài)文件
config.static = {
prefix: '/',
dir: path.join(appInfo.baseDir, 'app/public/')
}
當(dāng)然此時你會遇到一個問題寸认,你想要多個文件該如何事好
config.static = {
prefix: '/',
dir: [ path.join(appInfo.baseDir, 'app/view/'),
path.join(appInfo.baseDir, 'app/public/uploads/'),
path.join(appInfo.baseDir, 'app/public/swagger/') ],
};
b:模板設(shè)置
config.view = {
defaultExt: '.html',
mapping: {
'.ejs': 'ejs',
'.html': 'ejs',
}
}
11.3 路由控制器設(shè)置
//將 index.html 放在app/view里签财,靜態(tài)文件放在public里
const { ctx } = this;
// render user.html
yield ctx.render('index');
12 egg-swagger2
12.1 運(yùn)營場景
作為后臺,例如有人需要后臺提供文檔....人家java都有swagger,egg在 egg-swagger2 支持下,我們也可以使用废麻。
12.2 安裝
npm i egg-swagger2 -S
12.3 開啟插件
// config/plugin.js
exports.swagger2 = {
enable: true,
package: 'egg-swagger2',
};
12.4 插件配置
config.default.js 中配置
config.swagger2 = {
enable: true, // 禁用swagger , 默認(rèn)為true
base: {
/* default config,support cover
schemes: [
'http',
],
host: '127.0.0.1:7001',
basePath: '/',
consumes: [
'application/json',
],
produces: [
'application/json',
],
*/
info: {
description: '文檔介紹,
version: '1.0.0',
title: '文檔名稱',
contact: {
email: 'caandoll@aliyun.com',
},
license: {
name: 'Apache 2.0',
url: 'http://www.apache.org/licenses/LICENSE-2.0.html',
},
},
tags: [{
name: 'admin',
description: 'Admin desc',
},
{
name: 'role',
description: 'Role desc',
},
],
definitions: {
// model definitions
},
securityDefinitions: {
// security definitions
}
},
};
12.4 例子
在 /app/router.js文件中
12.4.1 post請求
module.exports = app => {
const { router, controller, swagger } = app;
router.post('/login', controller.test.postLogin);
swagger.post('/login', {
tags: [
'admin',
],
summary: 'Login a admin',
description: '',
parameters: [
{
in: 'body',
name: 'body',
description: 'admin\'s username & password',
required: true,
schema: {
type: 'object',
required: [ 'username', 'password' ],
properties: {
username: {
type: 'string',
description: 'admin\'s username',
},
password: {
type: 'string',
description: 'admin\'s password',
},
},
},
},
],
responses: {
200: {
description: 'SUCCEED',
schema: {
type: 'object',
properties: {
status: {
type: 'string',
description: 'status',
},
data: {
type: 'object',
description: 'data',
properties: {
token: {
type: 'string',
description: 'token',
},
},
},
},
},
},
},
});
}
12.4.2 get請求
module.exports = app => {
const { router, controller, swagger } = app;
router.get('/roles', controller.test.getRoles);
swagger.get('/roles', {
tags: ['role',],
summary: 'search role by page',
description: '',
parameters: [{
in: 'query',
name: 'name',
description: 'role\'s name',
},
{
in: 'query',
name: 'pageIndex',
description: 'pageIndex',
},
{
in: 'query',
name: 'pageSize',
description: 'pageSize',
},
],
responses: {
200: {
description: 'SUCCEED',
schema: {
type: 'object',
properties: {
status: {
type: 'string',
description: 'status',
},
datas: {
type: 'array',
description: 'result datas',
properties: {
token: {
type: 'string',
description: 'token',
},
},
},
pageIndex: {
type: 'number',
description: 'pageIndex',
},
pageSize: {
type: 'number',
description: 'pageSize',
},
totalCount: {
type: 'number',
description: 'totalCount',
},
},
},
},
},
});
}
12.4.3 swagger的使用
npm run dev 跑起來
獲取swgger地址 輸入瀏覽器
你看到就是文檔了
點(diǎn)擊try it out
輸入你傳的值,然后點(diǎn)擊Execute
結(jié)果
你就可以獲取到接口傳遞過來的值,效果類似postman,但是清晰程度比postman好
12.5 常見問題
一般情況下都不會有問題荠卷,但是如果你這時候巧妙的用了egg-static,那么你就會報錯了<br />經(jīng)過排查,你就會發(fā)現(xiàn)
/node_modules/egg-swagger2/app.js
它會是一個數(shù)組烛愧,然后報錯必須是個字符串,然后你懂得..你給他做成一個字符串即可
13 表單校驗機(jī)制
npm egg-validate-plus --save
13.1 開啟插件
// config/plugin.{env}.js
exports.validatePlus = {
enable: true,
package: 'egg-validate-plus',
};
13.2 配置插件
// config/config.{env}.js
config.validatePlus = {
resolveError(ctx, errors) {
if (errors.length) {
ctx.type = 'json';
ctx.status = 400;
ctx.body = {
code: 400,
error: errors,
message: '參數(shù)錯誤',
};
}
}
};
13.3 使用插件
13.3.1 傳入字符串
// app/controller/xx.js
const { query } = this.ctx.request;
拿到驗證結(jié)果
const validateResult = await this.ctx.validate('user.login', query)
驗證不通過時油宜,阻止后面的代碼執(zhí)行
if (!validateResult) return
<br />
注意:不要帶上 rules
13.3.2 直接傳入驗證規(guī)則對象
// app/controller/xx.js
// 直接引入 rules 文件下的驗證規(guī)則,也可以是自己寫的驗證規(guī)則對象
const rule = this.app.rules.user.login
// 數(shù)據(jù)格式
// const rule = {
// id: [
// { required: true },
// { type: 'number', message: 'id 必須為數(shù)字 }
// ],
// password: [
// { required: true },
// { type: 'string', message: 'password 必須為字符串 }
// ]
// }
// 從客戶端傳入的參數(shù)
const { query } = this.ctx.request;
// 數(shù)據(jù)格式:
// query = {
// username: 123456,
// password: 'abcdefg'
// }
// 拿到驗證結(jié)果
const validateResult = await this.ctx.validate(rule, query)
// 驗證不通過時怜姿,阻止后面的代碼執(zhí)行
if (!validateResult) return
14 連接redis
Redis client(support redis portocal) based on ioredis for egg framework
14.1 安裝
npm i egg-redis --save
14.2 配置
Change ${app_root}/config/plugin.js
to enable redis plugin:
exports.redis = {
enable: true,
package: 'egg-redis',
};
Configure redis information in ${app_root}/config/config.default.js
:<br />Single Client
config.redis = {
client: {
port: 6379, // Redis port
host: '127.0.0.1', // Redis host
password: 'auth',
db: 0,
}
}
14.3 使用方法
14.3.1 service
app/service/redis.js
if(this.app.redis)
判斷是否有啟用redis
'use strict';
const Service = require('egg').Service;
class RedisService extends Service {
async set(key, value, seconds) {
value = JSON.stringify(value);
if (this.app.redis) {
if (!seconds) {
await this.app.redis.set(key, value);
} else {
await this.app.redis.set(key, value, 'EX', seconds);
}
}
}
async get(key) {
if (this.app.redis) {
const data = await this.app.redis.get(key);
if (!data) return;
return JSON.parse(data);
}
}
}
module.exports = RedisService;
14.3.2 controller
app/controller/default/index.js如果沒有設(shè)置redis緩存慎冤,就去請求數(shù)據(jù),再設(shè)置緩存
var topNav = await this.ctx.service.cache.get('index_topNav');
if (!topNav) {
topNav = await this.ctx.model.Nav.find({
"position": 1
});
await this.ctx.service.cache.set('index_topNav', topNav, 60 * 60);
}
15 egg-mongoose專題
mongodb 對于node服務(wù)重要性不言而喻所以特別做一個專題來討論