egg-從入門到上線 (下)

因為egg知識點(diǎn)豐富誉察,分為上下兩章點(diǎn)擊見上章

egg-從入門到上線 (下)

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ù)

訪問控制臺

控制臺地址: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: [
    // '您的應(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)控了

image.png

獲取swgger地址 輸入瀏覽器

你看到就是文檔了

image.png

點(diǎn)擊try it out

image.png

輸入你傳的值,然后點(diǎn)擊Execute

image.png

結(jié)果

image.png

你就可以獲取到接口傳遞過來的值,效果類似postman,但是清晰程度比postman好

12.5 常見問題

一般情況下都不會有問題粗俱,但是如果你這時候巧妙的用了egg-static,那么你就會報錯了<br />經(jīng)過排查说榆,你就會發(fā)現(xiàn)

/node_modules/egg-swagger2/app.js

image.png

它會是一個數(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 跑起來

image.png

獲取swgger地址 輸入瀏覽器

你看到就是文檔了

image.png

點(diǎn)擊try it out

image.png

輸入你傳的值,然后點(diǎn)擊Execute

image.png

結(jié)果

image.png

你就可以獲取到接口傳遞過來的值,效果類似postman,但是清晰程度比postman好

12.5 常見問題

一般情況下都不會有問題荠卷,但是如果你這時候巧妙的用了egg-static,那么你就會報錯了<br />經(jīng)過排查,你就會發(fā)現(xiàn)

/node_modules/egg-swagger2/app.js

image.png

它會是一個數(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ù)重要性不言而喻所以特別做一個專題來討論

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市沧卢,隨后出現(xiàn)的幾起案子蚁堤,更是在濱河造成了極大的恐慌,老刑警劉巖但狭,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件披诗,死亡現(xiàn)場離奇詭異,居然都是意外死亡立磁,警方通過查閱死者的電腦和手機(jī)呈队,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來唱歧,“玉大人宪摧,你說我怎么就攤上這事÷溃” “怎么了几于?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沿后。 經(jīng)常有香客問我沿彭,道長,這世上最難降的妖魔是什么得运? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任膝蜈,我火速辦了婚禮锅移,結(jié)果婚禮上熔掺,老公的妹妹穿的比我還像新娘饱搏。我一直安慰自己,他們只是感情好置逻,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布推沸。 她就那樣靜靜地躺著,像睡著了一般券坞。 火紅的嫁衣襯著肌膚如雪鬓催。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天恨锚,我揣著相機(jī)與錄音宇驾,去河邊找鬼。 笑死猴伶,一個胖子當(dāng)著我的面吹牛课舍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播他挎,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼筝尾,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了办桨?” 一聲冷哼從身側(cè)響起筹淫,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎呢撞,沒想到半個月后损姜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡殊霞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年摧阅,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脓鹃。...
    茶點(diǎn)故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡逸尖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瘸右,到底是詐尸還是另有隱情娇跟,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布太颤,位于F島的核電站苞俘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏龄章。R本人自食惡果不足惜吃谣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一乞封、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧岗憋,春花似錦肃晚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至监徘,卻和暖如春晋修,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凰盔。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工墓卦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人户敬。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓落剪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親山叮。 傳聞我的和親對象是個殘疾皇子著榴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評論 2 345