egg-从入门到上线 (下)

因为egg知识点丰富,分为上下两章点击见上章

egg-从入门到上线 (下)

10 阿里监控

Node.js 性能平台(alinode)

是面向所有 Node.js 应用提供 性能监控、安全提醒、故障排查、性能优化 等服务的整体性解决方案,提供完善的工具链和服务,协助开发者快速发现和定位线上问题。

npm i nodeinstall -g

提供了egg-alinode 来快速接入,无需安装 agenthub 等额外的常驻服务。

npm i egg-alinode --save
// /config/plugin.js

exports.alinode = {
    enable:true,
    package:'egg-alinode',
},

申请一下服务

访问控制台

控制台地址:https://node.console.aliyun.com

image.png
image.png
// 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: [
    // '您的应用在业务层面产生的异常日志的路径,数组,可选,可配置多个',
    // '例如:/root/.logs/error.#YYYY#-#MM#-#DD#.log',
    // '不更改 Egg 默认日志输出路径可不配置本项目',
  ],// 可选
  agentidMode:'IP',  // 可选,如果设置,则在实例ID中添加部分IP信息,用于多个实例 hostname 相同的场景(以容器为主)
};

然后你就能愉快针对你的egg,进行监控了

image.png

获取swgger地址 输入浏览器

你看到就是文档了

image.png

点击try it out

image.png

输入你传的值,然后点击Execute

image.png

结果

image.png

你就可以获取到接口传递过来的值,效果类似postman,但是清晰程度比postman好

12.5 常见问题

一般情况下都不会有问题,但是如果你这时候巧妙的用了egg-static,那么你就会报错了<br />经过排查,你就会发现

/node_modules/egg-swagger2/app.js

image.png

它会是一个数组,然后报错必须是个字符串,然后你懂得..你给他做成一个字符串即可

11 引入静态文件

11.1 经过测试插件设置

exports.ejs = {
  enable: true,
  package: 'egg-view-ejs',
};

11.2 配置设置

a:静态文件

config.static = {

      prefix: '/',

      dir: path.join(appInfo.baseDir, 'app/public/')

    }

当然此时你会遇到一个问题,你想要多个文件该如何事好

 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:模板设置

config.view = {
  defaultExt: '.html',
  mapping: {
    '.ejs': 'ejs',
    '.html': 'ejs',
  }
}

11.3 路由控制器设置

//将 index.html 放在app/view里,静态文件放在public里

const { ctx } = this;

// render user.html

yield ctx.render('index');

12 egg-swagger2

12.1 运营场景

作为后台,例如有人需要后台提供文档....人家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 , 默认为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 跑起来

image.png

获取swgger地址 输入浏览器

你看到就是文档了

image.png

点击try it out

image.png

输入你传的值,然后点击Execute

image.png

结果

image.png

你就可以获取到接口传递过来的值,效果类似postman,但是清晰程度比postman好

12.5 常见问题

一般情况下都不会有问题,但是如果你这时候巧妙的用了egg-static,那么你就会报错了<br />经过排查,你就会发现

/node_modules/egg-swagger2/app.js

image.png

它会是一个数组,然后报错必须是个字符串,然后你懂得..你给他做成一个字符串即可

13 表单校验机制

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: '参数错误',
      };
    }
  }
};

13.3 使用插件

13.3.1 传入字符串

// app/controller/xx.js
const { query } = this.ctx.request;

拿到验证结果

const validateResult = await this.ctx.validate('user.login', query)

验证不通过时,阻止后面的代码执行

if (!validateResult) return

<br />

注意:不要带上 rules

13.3.2 直接传入验证规则对象

// app/controller/xx.js

// 直接引入 rules 文件下的验证规则,也可以是自己写的验证规则对象

const rule = this.app.rules.user.login

// 数据格式

// const rule = {

//   id: [

//     { required: true },

//     { type: 'number', message: 'id 必须为数字 }

//   ],

//   password: [

//     { required: true },

//     { type: 'string', message: 'password 必须为字符串 }

//   ]

// }



// 从客户端传入的参数

const { query } = this.ctx.request;

// 数据格式:
// query = {

//   username: 123456,

//   password: 'abcdefg'

// }

// 拿到验证结果

const validateResult = await this.ctx.validate(rule, query)

// 验证不通过时,阻止后面的代码执行

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如果没有设置redis缓存,就去请求数据,再设置缓存

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服务重要性不言而喻所以特别做一个专题来讨论

https://juejin.im/post/5cf497a25188254a842503a3

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345