国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4)

這篇具有很好參考價(jià)值的文章主要介紹了構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、說明

????????構(gòu)建一個(gè)微服務(wù)的電影網(wǎng)站,需要Docker、NodeJS、MongoDB,這樣的案例您見過嗎?如果對(duì)此有興趣,您就繼續(xù)往下看吧。

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4),docker,微服務(wù),docker,架構(gòu)

圖片取自網(wǎng)絡(luò) — 封面由我制作

這是??“構(gòu)建 NodeJS 影院微服務(wù)”系列的第二篇文章。

二、對(duì)第一部分的快速回顧

  • 我們討論什么是微服務(wù)。
  • 我們看到了微服務(wù)的優(yōu)點(diǎn)和缺點(diǎn)。
  • 我們定義了一個(gè)影院微服務(wù)架構(gòu)。
  • 我們使用?RAML?設(shè)計(jì)我們的電影服務(wù) API?規(guī)范。
  • 我們使用?NodeJS 和 ExpressJS?開發(fā)我們的電影服務(wù) API
  • 我們對(duì) API 進(jìn)行了單元測(cè)試。
  • 我們編寫我們的 API 以使其成為服務(wù),并將我們的電影服務(wù)運(yùn)行到?Docker?容器中。
  • 我們對(duì)在?Docker?上運(yùn)行的電影服務(wù)進(jìn)行了集成測(cè)試。

如果你還沒有讀過第一章,我會(huì)把鏈接放在下面,所以你可以看看??。

構(gòu)建一個(gè) NodeJS 影院微服務(wù)并使用 docker 部署它 — 第 1 部分

這是“構(gòu)建 NodeJS 影院微服務(wù)”系列的第一章,這個(gè)系列是關(guān)于構(gòu)建 NodeJS...

在本文中,我們將繼續(xù)構(gòu)建我們的電影院微服務(wù),這次我們將開發(fā)電影院目錄服務(wù),以完成下圖。

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4),docker,微服務(wù),docker,架構(gòu)

我們將在本文中使用的是:

  • NodeJS 版本 7.2.0
  • MongoDB 3.4.1
  • Docker for Mac 1.13

跟進(jìn)文章的先決條件:

  • 已完成上一章中的示例。

如果您還沒有,我已經(jīng)在以下 github 存儲(chǔ)庫上傳了存儲(chǔ)庫,因此您可以在分支步驟 1?處獲得最新的存儲(chǔ)庫鏈接。

三、微服務(wù)安全和? HTTP/2?

????????在第一章中,我們做了一個(gè)簡(jiǎn)單的微服務(wù)來實(shí)現(xiàn)HTTP/1.1協(xié)議。HTTP/2 是?15 年來對(duì) HTTP 協(xié)議的首次重大升級(jí),經(jīng)過高度優(yōu)化,性能更好。HTTP/2是新的Web標(biāo)準(zhǔn),最初是Google的SPDY協(xié)議。它已經(jīng)被許多流行的網(wǎng)站使用,并被大多數(shù)主流瀏覽器支持。

HTTP/2 只有一些規(guī)則必須滿足才能實(shí)現(xiàn)它。

  • 它僅適用于HTTPS協(xié)議(我們需要有效的SSL證書)。
  • 它是向后兼容的。如果運(yùn)行應(yīng)用程序的瀏覽器或設(shè)備不支持?HTTP/2,它將回退到 HTTP1.1。
  • 它具有開箱即用的巨大性能改進(jìn)。
  • 它不需要您在客戶端執(zhí)行任何操作,只需在服務(wù)器端執(zhí)行基本實(shí)現(xiàn)即可。
  • 一些新的有趣的功能將加快Web項(xiàng)目的加載時(shí)間,其方式甚至是HTTP1.1實(shí)現(xiàn)無法想象的。

四、為微服務(wù)啟用網(wǎng)絡(luò)架構(gòu)的 HTTP/2

這意味著我們需要在客戶端和服務(wù)器之間啟用單個(gè)連接,然后在“網(wǎng)絡(luò)”中利用 Y 軸分片等功能(更多地談?wù)撓盗兄械目s放立方體)來保持 HTTP/2 對(duì)客戶端的性能優(yōu)勢(shì),同時(shí)實(shí)現(xiàn)微服務(wù)架構(gòu)的所有操作和開發(fā)優(yōu)勢(shì)。

????????那么我們?yōu)槭裁匆獙?shí)施新的HTTP / 2協(xié)議,這是因?yàn)樽鳛閮?yōu)秀的開發(fā)人員,我們必須盡可能保護(hù)我們的應(yīng)用程序,基礎(chǔ)架構(gòu),通信,以防止惡意攻擊,也因?yàn)樽鳛閮?yōu)秀的開發(fā)人員,我們遵循我們認(rèn)為對(duì)我們有益的最佳實(shí)踐,就像這個(gè)。

????????微服務(wù)的一些安全最佳實(shí)踐如下所示:

安全性顯然將在采用和部署微服務(wù)應(yīng)用程序以供生產(chǎn)使用的決定中發(fā)揮重要作用。根據(jù)2016 Research發(fā)布的研究報(bào)告《451年軟件定義的基礎(chǔ)設(shè)施展望》,近45%的企業(yè)已經(jīng)實(shí)施或計(jì)劃在未來12個(gè)月內(nèi)推出基于容器的應(yīng)用程序。隨著 DevOps 實(shí)踐在企業(yè)中站穩(wěn)腳跟,容器應(yīng)用程序變得越來越普遍,安全管理員需要用保護(hù)應(yīng)用程序的專業(yè)知識(shí)武裝自己?!?@Ranga 拉賈戈帕蘭

  • 發(fā)現(xiàn)和監(jiān)視服務(wù)間通信
  • 對(duì)應(yīng)用程序和服務(wù)進(jìn)行分段和隔離
  • 加密傳輸中的數(shù)據(jù)和靜態(tài)數(shù)據(jù)

????????我們要做的是加密我們的微服務(wù)通信以滿足合規(guī)性要求并提高安全性,尤其是當(dāng)流量通過公共網(wǎng)絡(luò)時(shí),這就是我們要實(shí)施HTTP / 2的原因之一,以獲得更好的性能和安全性改進(jìn)。

五、在微服務(wù)中實(shí)現(xiàn) HTTP/2

????????首先,讓我們更新上一章的電影服務(wù)并實(shí)現(xiàn)HTTP?/ 2協(xié)議,但是在我們打算在config文件夾中創(chuàng)建一個(gè)ssl文件夾之后。

movies-service/config:/ $ mkdir ssl
movies-service/config:/ $ cd ssl

????????現(xiàn)在,一旦進(jìn)入?ssl?文件夾,讓我們創(chuàng)建一個(gè)自簽名 SSL 證書,以開始在我們的服務(wù)中實(shí)現(xiàn)?HTTP/2?協(xié)議。

# Let's generate the server pass key

ssl/: $ openssl genrsa -des3 -passout pass:x -out server.pass.key 2048 
# now generate the server key from the pass key

ssl/: $ openssl rsa -passin pass:x -in server.pass.key -out server.key
# we remove the pass key

ssl/: $ rm server.pass.key
# now let's create the .csr file
ssl/: $ openssl req -new -key server.key -out server.csr 
...
Country Name (2 letter code) [AU]:MX
State or Province Name (full name) [Some-State]:Michoacan 
... 
A challenge password []: 
...
# now let's create the .crt file
ssl/: $ openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt

????????接下來我們需要使用以下命令安裝?SPDY

cinema-catalog-service/: $ npm i -S spdy --silent

????????首先讓我們?cè)谖募A中創(chuàng)建一個(gè)文件,使用以下代碼,這里是我們加載密鑰和證書文件的地方,這可能是我們可以使用的少數(shù)情況之一:index.jsssl/fs.readFileSync()

const fs = require('fs')
module.exports = {
  key: fs.readFileSync(`${__dirname}/server.key`),
  cert: fs.readFileSync(`${__dirname}/server.crt`)
}

然后我們需要修改幾個(gè)文件,讓我們先修改config.js

const dbSettings = { ... }
// The first modification is adding the ssl certificates to the 
// serverSettings
const serverSettings = {
  port: process.env.PORT || 3000,
  ssl: require('./ssl')
}
module.exports = Object.assign({}, { dbSettings, serverSettings })

接下來,讓我們修改文件,如下所示:server.js

...
const spdy = require('spdy')
const api = require('../api/movies')
const start = (options) => {
...
 const app = express()
 app.use(morgan('dev'))
 app.use(helmet())
 app.use((err, req, res, next) => {
   reject(new Error('Something went wrong!, err:' + err))
   res.status(500).send('Something went wrong!')
 })
 api(app, options)
 // here is where we made the modifications, we create a spdy
 // server, then we pass the ssl certs, and the express app
 const server = spdy.createServer(options.ssl, app)
      .listen(options.port, () => resolve(server))
  })
}
module.exports = Object.assign({}, {start})

最后讓我們修改主文件:index.js

'use strict'
const {EventEmitter} = require('events')
const server = require('./server/server')
const repository = require('./repository/repository')
const config = require('./config/')
const mediator = new EventEmitter()
...
mediator.on('db.ready', (db) => {
  let rep
  repository.connect(db)
    .then(repo => {
      console.log('Connected. Starting Server')
      rep = repo
      return server.start({
        port: config.serverSettings.port,
        // here we pass the ssl options to the server.js file
        ssl: config.serverSettings.ssl,
        repo
      })
    })
    .then(app => { ... })
})
...

現(xiàn)在我們需要使用以下命令重建我們的 docker 鏡像:

$ docker build -t movies-service .

并使用以下參數(shù)運(yùn)行我們的 docker 映像:movies-service

$ docker run --name movies-service -p 443:3000 -d movies-service

最后,我們使用Chrome瀏覽器對(duì)其進(jìn)行了測(cè)試,我們可以證實(shí)我們的HTTP / 2協(xié)議完全有效。

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4),docker,微服務(wù),docker,架構(gòu)

Chrome 開發(fā)工具

我們還可以證實(shí)使用wireshark進(jìn)行一些網(wǎng)絡(luò)捕獲,我們可以看到SSL確實(shí)有效。

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4),docker,微服務(wù),docker,架構(gòu)

線鯊幀捕獲

5.1 將 JWT 實(shí)現(xiàn)到微服務(wù)

加密和保護(hù)微服務(wù)通信的另一種方法是使用該協(xié)議,但我們將在后面的系列??中看到此實(shí)現(xiàn)。json web token

5.2 構(gòu)建微服務(wù)

好的,現(xiàn)在我們知道了如何實(shí)現(xiàn)?HTTP/2?協(xié)議,讓我們繼續(xù)構(gòu)建電影目錄服務(wù)。?我們將使用與電影服務(wù)相同的項(xiàng)目結(jié)構(gòu),因此 少說話??多編碼 ???? ?????? ?? .

在我們開始設(shè)計(jì) API 之前,這次我們需要為我們的數(shù)據(jù)庫設(shè)計(jì)我們的?Mongo 模式,因?yàn)槲覀儗⑹褂靡韵聝?nèi)容:

  • 地點(diǎn)(國家、州和城市)
  • 電影院(電影院、時(shí)間表、電影)

5.3? 模型數(shù)據(jù)設(shè)計(jì)

????????本文主要專注于創(chuàng)建微服務(wù),因此我不會(huì)花費(fèi)大量時(shí)間為我們的電影院數(shù)據(jù)庫進(jìn)行“模型數(shù)據(jù)設(shè)計(jì)”,而是將重點(diǎn)介紹這些領(lǐng)域和要點(diǎn)。

# posible collections for the cinemas db.
# For locations 
- countries
- states
- cities
# For cinemas
- cinemas
- cinemaRooms
- schedules

????????因此,對(duì)于我們的位置,一個(gè)國家/地區(qū)具有許多州,而州具有一個(gè)國家/地區(qū),因此第一種關(guān)系是一對(duì)多關(guān)系,但這也適用于,一個(gè)州有許多城市,一個(gè)城市具有一個(gè)州,因此讓我們看看我們的關(guān)系示例如何。

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4),docker,微服務(wù),docker,架構(gòu)

國家 — 國家關(guān)系

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4),docker,微服務(wù),docker,架構(gòu)

????????州/城市關(guān)系

????????但是這種關(guān)系也是可能的,一個(gè)城市有很多電影院一個(gè)電影院屬于一個(gè)城市,另一個(gè)關(guān)系我們可以看到就是一個(gè)電影院房間有很多檔期,一個(gè)檔期屬于一個(gè)電影院房間,所以讓我們看看這種關(guān)系是怎樣的。

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4),docker,微服務(wù),docker,架構(gòu)

????????如果電影院陣列或時(shí)間表陣列的增長受到限制,則上圖中的這種引用可能很有用。假設(shè)一個(gè)電影室每天最多有 5 個(gè)時(shí)間表,所以在這里我們可以將時(shí)間表文檔嵌入到電影院文檔中。

嵌入式數(shù)據(jù)模型允許應(yīng)用程序在同一數(shù)據(jù)庫記錄中存儲(chǔ)相關(guān)信息。因此,應(yīng)用程序可能需要發(fā)出較少的查詢和更新來完成常見操作?!?MongoDB Docs

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4),docker,微服務(wù),docker,架構(gòu)

因此,這是我們數(shù)據(jù)庫模式設(shè)計(jì)的最終結(jié)果。

5.4 將數(shù)據(jù)導(dǎo)入我們的數(shù)據(jù)庫

????????我已經(jīng)準(zhǔn)備了一些數(shù)據(jù)示例,其中包含上面看到的模式設(shè)計(jì),這些文件位于 github 存儲(chǔ)庫中,有 4 個(gè) json 文件,因此您可以將其導(dǎo)入電影院數(shù)據(jù)庫,但首先我們需要知道哪個(gè)數(shù)據(jù)庫服務(wù)器是主要的,因此找出并執(zhí)行以下命令:cinema-catalog-service/src/mock

# first we need to copy the files one by one or we can zip it and pass the zip file
$ docker cp countries.json mongoNodeContainer:/tmp
$ docker cp state.json mongoNodeContainer:/tmp
$ docker cp city.json mongoNodeContainer:/tmp
$ docker cp cinemas.json mongoNodeContainer:/tmp

執(zhí)行上述命令后,讓我們將其導(dǎo)入數(shù)據(jù)庫,如下所示:

$ docker exec mongoNode{number} bash -c 'mongoimport --db cinemas --collection countries --file /tmp/countries.json --jsonArray -u $MONGO_USER_ADMIN -p $MONGO_PASS_ADMIN --authenticationDatabase "admin"'

$ docker exec mongoNode{number} bash -c 'mongoimport --db cinemas --collection states --file /tmp/states.json --jsonArray -u $MONGO_USER_ADMIN -p $MONGO_PASS_ADMIN --authenticationDatabase "admin"'

$ docker exec mongoNode{number} bash -c 'mongoimport --db cinemas --collection cities --file /tmp/cities.json --jsonArray -u $MONGO_USER_ADMIN -p $MONGO_PASS_ADMIN --authenticationDatabase "admin"'

$ docker exec mongoNode{number} bash -c 'mongoimport --db cinemas --collection cinemas --file /tmp/cinemas.json --jsonArray -u $MONGO_USER_ADMIN -p $MONGO_PASS_ADMIN --authenticationDatabase "admin"'

????????現(xiàn)在我們已經(jīng)準(zhǔn)備好了數(shù)據(jù)庫模式設(shè)計(jì),數(shù)據(jù)也準(zhǔn)備好了,可以查詢了,所以我們現(xiàn)在可以為電影目錄服務(wù)設(shè)計(jì)我們的 API,定義路由的一種方法是制作一些句子,如下所示:

  • 我們需要一個(gè)城市來展示可用的電影院。
  • 我們需要電影院來展示電影首映式。
  • 我們需要電影首映并顯示時(shí)間表。
  • 我們需要時(shí)間表,以查看是否有可供預(yù)訂的座位。

????????讓我們假設(shè) Cinépolis IT 部門的其他團(tuán)隊(duì)正在執(zhí)行其他 CRUD 操作,我們的任務(wù)是使“R”成為讀取數(shù)據(jù),讓我們假設(shè)一些?Cinépolis?電影院運(yùn)營人員已經(jīng)為電影院制定了計(jì)劃,因此我們的任務(wù)是檢索這些計(jì)劃。

????????電影院目錄服務(wù)所關(guān)注的只是電影院和時(shí)間表,僅此而已,上面我們看到我們進(jìn)行了位置收集,但這是對(duì)另一個(gè)微服務(wù)的關(guān)注,但我們依賴于能夠顯示電影院和時(shí)間表的位置。

????????現(xiàn)在我們已經(jīng)定義了我們的需求,我們可以構(gòu)建我們的 RAML 文件,如下所示:

#%RAML 1.0
title: Cinema Catalog Service
version: v1
baseUri: /
uses:
  object: types.raml
  stack: ../movies-service/api.raml

types:
  Cinemas: object.Cinema []
  Movies: stack.MoviePremieres
  Schedules: object.Schedule []

traits:
  FilterByLocation:
    queryParameters:
      city:
        type: string

resourceTypes:
  GET:
    get:
      responses:
        200:
          body:
            application/json:
              type: <<item>>


/cinemas:
  type:  { GET: {item : Cinemas } }
  get:
    is: [FilterByLocation]
  description: we already have the location defined to display the cinemas

  /cinemas/{cinema_id}:
    type:  { GET: {item : Movies } }
    description: we have selected the cinema to display the movie premieres

    /cinemas/{cinema_id}/{movie_id}:
      type:  { GET: {item : Schedules } }
      description: we have selceted a movie to display the schedules

????????我們已經(jīng)滿足了上面 3 句話中的 4 句,第 4 句話用于在電影院預(yù)訂,但我的朋友屬于預(yù)訂服務(wù),他們負(fù)有這一責(zé)任,所以請(qǐng)繼續(xù)關(guān)注“構(gòu)建 NodeJs 電影院微服務(wù)?— 系列”。

現(xiàn)在我們可以繼續(xù)為電影目錄服務(wù)開發(fā)我們的 NodeJS?API,其結(jié)構(gòu)和配置與電影服務(wù)幾乎相同,所以我將開始向您展示此 API。repository.js

// more code above

const getCinemasByCity = (cityId) => {
    return new Promise((resolve, reject) => {
      const cinemas = []
      const query = {city_id: cityId}
      const projection = {_id: 1, name: 1}
      // example of making a find query to mongoDB, 
      // passign a query and projection objects.
      const cursor = db.collection('cinemas').find(query, projection)
      const addCinema = (cinema) => {
        cinemas.push(cinema)
      }
      const sendCinemas = (err) => {
        if (err) {
          reject(new Error('An error occured fetching cinemas, err: ' + err))
        }
        resolve(cinemas)
      }
      cursor.forEach(addCinema, sendCinemas)
    })
  }

  const getCinemaById = (cinemaId) => {
    return new Promise((resolve, reject) => {
      const query = {_id: new ObjectID(cinemaId)}
      const projection = {_id: 1, name: 1, cinemaPremieres: 1}
      const response = (err, cinema) => {
        if (err) {
          reject(new Error('An error occuered retrieving a cinema, err: ' + err))
        }
        resolve(cinema)
      }
      // example of using findOne method from mongodb, 
      // we do this because we only need one record.
      db.collection('cinemas').findOne(query, projection, response)
    })
  }

  const getCinemaScheduleByMovie = (options) => {
    return new Promise((resolve, reject) => {
      const match = { $match: {
        'city_id': options.cityId,
        'cinemaRooms.schedules.movie_id': options.movieId
      }}
      const project = { $project: {
        'name': 1,
        'cinemaRooms.schedules.time': 1,
        'cinemaRooms.name': 1,
        'cinemaRooms.format': 1
      }}
      const unwind = [{ $unwind: '$cinemaRooms' }, { $unwind: '$cinemaRooms.schedules' }]
      const group = [{ $group: {
        _id: {
          name: '$name',
          room: '$cinemaRooms.name'
        },
        schedules: { $addToSet: '$cinemaRooms.schedules.time' }
      }}, { $group: {
        _id: '$_id.name',
        schedules: {
          $addToSet: {
            room: '$_id.room',
            schedules: '$schedules'
          }
        }
      }}]
      const sendSchedules = (err, result) => {
        if (err) {
          reject('An error has occured fetching schedules by movie, err: ' + err)
        }
        resolve(result)
      }
      // example of using a aggregation method from mongoDB
      // we difine our pipline above, we are using also ES6 spread operator
      db.collection('cinemas').aggregate([match, project, ...unwind, ...group], sendSchedules)
    })
  }


// more code below

要查看完整的文件,您可以在“github 存儲(chǔ)庫分支步驟-2”中檢查它。repository.js

在這里,我們定義了 3 個(gè)函數(shù):

  • getCinemasByCity:這個(gè)函數(shù)將獲取城市中所有可用的電影院,我們通過city_id找到電影院,這個(gè)函數(shù)的結(jié)果幫助我們調(diào)用下一個(gè)電影院。
  • getCinemaById:此函數(shù)將通過cinema_id查詢來檢索可用的名稱、id 和首映電影,該函數(shù)的結(jié)果將幫助我們最終獲得時(shí)間表。
  • getCinemaScheduleByMovie:?此功能將為我們提供城市中所有電影院上可用的電影的所有時(shí)間表。

可能還有另一個(gè)功能,或者我們可以修改getCinemaById,以顯示當(dāng)前電影院的時(shí)間表,這對(duì)您來說可能是一個(gè)很好的挑戰(zhàn),如果您想練習(xí),這不會(huì)那么困難,因?yàn)槲乙呀?jīng)為您提供了所有需要的信息。

下一個(gè)要檢查的文件是我們的 API 文件 .cinemas-catalog.js

'use strict'
const status = require('http-status')

module.exports = (app, options) => {
  const {repo} = options

  app.get('/cinemas', (req, res, next) => {
    repo.getCinemasByCity(req.query.cityId)
      .then(cinemas => {
        res.status(status.OK).json(cinemas)
      })
      .catch(next)
  })

  app.get('/cinemas/:cinemaId', (req, res, next) => {
    repo.getCinemaById(req.params.cinemaId)
      .then(cinema => {
        res.status(status.OK).json(cinema)
      })
      .catch(next)
  })

  app.get('/cinemas/:cityId/:movieId', (req, res, next) => {
    const params = {
      cityId: req.params.cityId,
      movieId: req.params.movieId
    }
    repo.getCinemaScheduleByMovie(params)
      .then(schedules => {
        res.status(status.OK).json(schedules)
      })
      .catch(next)
  })
}

如您所見,這里我們實(shí)現(xiàn)端點(diǎn),正如我們?cè)?RAML?文件中定義的那樣,并根據(jù)路由調(diào)用函數(shù)。repository.js

在我們的第一條路線中,我們用于獲取值并查詢我們的數(shù)據(jù)庫以按城市獲取電影院,而在其他路線中,我們用于獲取值并能夠查詢。 ??req.query.cityIdcity_idreq.paramscinemaIdmovieIdschedules

最后我們可以看到用于測(cè)試的文件:cinema-catalog.spec.js

/* eslint-env mocha */
const request = require('supertest')
const server = require('../server/server')
process.env.NODE = 'test'

describe('Movies API', () => {
  let app = null
  const testCinemasCity = [{
    '_id': '588ac3a02d029a6d15d0b5c4',
    'name': 'Plaza Morelia'
  }, {
    '_id': '588ac3a02d029a6d15d0b5c5',
    'name': 'Las Americas'
  }]

  const testCinemaId = {
    '_id': '588ac3a02d029a6d15d0b5c4',
    'name': 'Plaza Morelia',
    'cinemaPremieres': [
      {
        'id': '1',
        'title': 'Assasins Creed',
        'runtime': 115,
        'plot': 'Lorem ipsum dolor sit amet',
        'poster': 'link to poster...'
      },
      {
        'id': '2',
        'title': 'Aliados',
        'runtime': 124,
        'plot': 'Lorem ipsum dolor sit amet',
        'poster': 'link to poster...'
      },
      {
        'id': '3',
        'title': 'xXx: Reactivado',
        'runtime': 107,
        'plot': 'Lorem ipsum dolor sit amet',
        'poster': 'link to poster...'
      }
    ]
  }

  const testSchedulesMovie = [{
    '_id': 'Plaza Morelia',
    'schedules': [{
      'room': 2.0,
      'schedules': [ '10:15' ]
    }, {
      'room': 1.0,
      'schedules': [ '6:55', '4:35', '10:15' ]
    }, {
      'room': 3.0,
      'schedules': [ '10:15' ]
    }]
  }, {
    '_id': 'Las Americas',
    'schedules': [ {
      'room': 2.0,
      'schedules': [ '3:25', '10:15' ]
    }, {
      'room': 1.0,
      'schedules': [ '12:15', '10:15' ]
    }]
  }]

  let testRepo = {
    getCinemasByCity (location) {
      console.log(location)
      return Promise.resolve(testCinemasCity)
    },
    getCinemaById (cinemaId) {
      console.log(cinemaId)
      return Promise.resolve(testCinemaId)
    },
    getCinemaScheduleByMovie (cinemaId, movieId) {
      console.log(cinemaId, movieId)
      return Promise.resolve(testSchedulesMovie)
    }
  }

  beforeEach(() => {
    return server.start({
      port: 3000,
      repo: testRepo
    }).then(serv => {
      app = serv
    })
  })

  afterEach(() => {
    app.close()
    app = null
  })

  it('can return cinemas by location', (done) => {
    const location = {
      city: '588ababf2d029a6d15d0b5bf'
    }
    request(app)
      .get(`/cinemas?cityId=${location.city}`)
      .expect((res) => {
        res.body.should.containEql(testCinemasCity[0])
        res.body.should.containEql(testCinemasCity[1])
      })
      .expect(200, done)
  })

  it('can get movie premiers by cinema', (done) => {
    request(app)
    .get('/cinemas/588ac3a02d029a6d15d0b5c4')
    .expect((res) => {
      res.body.should.containEql(testCinemaId)
    })
    .expect(200, done)
  })

  it('can get schedules by cinema and movie', (done) => {
    request(app)
      .get('/cinemas/588ababf2d029a6d15d0b5bf/1')
      .expect((res) => {
        res.body.should.containEql(testSchedulesMovie[0])
        res.body.should.containEql(testSchedulesMovie[1])
      })
      .expect(200, done)
  })
})

????????最后,我們可以構(gòu)建我們的 docker 鏡像并在我們的容器中運(yùn)行它,我們將從?movies 服務(wù)中使用相同的鏡像,以使此過程更加自動(dòng)化,讓我們?yōu)榇巳蝿?wù)創(chuàng)建一個(gè) bash 腳本,如下所示:cinema-catalog-servicedockerfilestart-service.sh

#!/usr/bin/env bash
eval `docker-machine env manager1`
docker build -t catalog-service .
docker run --name catalog-service -p 3000:3000 --env-file env -d catalog-service

????????隨著我們開始制作更多服務(wù),我們需要小心我們服務(wù)可用的端口,所以這次,我將使用端口 3000,另外我將使用 a?開始使用我們的?NodeJS?服務(wù)中的配置,我們的 env 文件將如下所示:env fileprocess.env

DB=cinemas
DB_USER=cristian
DB_PASS=cristianPassword2017
DB_REPLS=rs1
DB_SERVERS='192.168.99.100:27017 192.168.99.101:27017 192.168.99.102:27017'
PORT=3000

????????這被認(rèn)為是在 devOps 領(lǐng)域之外的最佳實(shí)踐。

????????最后,我們需要像下面這樣運(yùn)行我們的小 bash 腳本:

# execute our script
$ bash < start-service.sh
# check running docker contianers
$ docker ps

我們需要這樣的東西:

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4),docker,微服務(wù),docker,架構(gòu)

????????碼頭工人狀態(tài)

????????我們可以在Chrome瀏覽器中測(cè)試我們的服務(wù),并驗(yàn)證我們的HTTP / 2協(xié)議是否正常工作,以及我們的服務(wù)是否正常工作。

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4),docker,微服務(wù),docker,架構(gòu)
鉻瀏覽器 — 測(cè)試

????????為了好玩,我們可以使用?JMeter?進(jìn)行壓力測(cè)試,壓力測(cè)試文件也位于 github 存儲(chǔ)庫的文件夾中。integration-test/

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4),docker,微服務(wù),docker,架構(gòu)

JMeter capture

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4),docker,微服務(wù),docker,架構(gòu)

stress test example

5.5?是時(shí)候回顧一下了

????????已經(jīng)實(shí)現(xiàn)的:

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4),docker,微服務(wù),docker,架構(gòu)
休息溝通

????????我們已經(jīng)完成了此圖的微服務(wù),您可能會(huì)說我們沒有在我們的電影院目錄服務(wù)中使用電影服務(wù),是的,這是正確的,我們所做的只是來自我們服務(wù)的?GET?請(qǐng)求,并且在電影院目錄服務(wù)中使用我們的電影服務(wù)是通過進(jìn)行?POST?請(qǐng)求完成影院首映堆棧電影以便能夠制定時(shí)間表,但由于我們的任務(wù)是從我們團(tuán)隊(duì)中的 CRUD 操作制作?R,這就是為什么我們沒有看到這種交互,但稍后在該系列中,我們將在微服務(wù)之間進(jìn)行更多的?CRUD?操作,請(qǐng)耐心等待,:D保持好奇心。

????????因此,我們?cè)诒菊??中了解了HTTP / 2協(xié)議,并看到了如何在微服務(wù)中實(shí)現(xiàn)它。我們還看到了如何設(shè)計(jì) MongoDB 模式,我們沒有深入,但我突出顯示它是為了更好地了解電影院目錄服務(wù)中發(fā)生的事情,然后我們使用?RAML?設(shè)計(jì) API,我們開始構(gòu)建我們的?API?服務(wù),然后我們進(jìn)行了相應(yīng)的單元測(cè)試,最后我們編寫所有內(nèi)容以使我們的微服務(wù)完成。

????????然后我們使用之前微服務(wù)中的相同?dockerfile,并編寫一個(gè)腳本來自動(dòng)化此過程,我們還介紹了如何使用和?env 文件并在?Docker?容器中使用它,準(zhǔn)備好所有設(shè)置后,我向您展示了 JMeter 進(jìn)行壓力測(cè)試以補(bǔ)充集成測(cè)試的簡(jiǎn)短圖片。environment variables

????????我們已經(jīng)在?NodeJS?中看到了很多開發(fā),但我們可以做和學(xué)習(xí)的東西還有很多,這只是一個(gè)先睹為快的高峰。我希望這已經(jīng)展示了一些有趣和有用的東西,你可以在你的工作流程中用于Docker和NodeJS。

5.6 即將推出

????????現(xiàn)在我們已經(jīng)完成了第一個(gè)圖表,我們將開發(fā)第二個(gè)圖表,預(yù)訂服務(wù)圖......??????????????????

構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4),docker,微服務(wù),docker,架構(gòu)

微服務(wù)圖

六、在 Github 上完成代碼

您可以在以下鏈接中查看文章的完整代碼。

Crizstian/cinema-microservice

影院微服務(wù) - 影院微服務(wù)示例

github.com

七、# 參考資料延伸閱讀

為了更好地使用NodeJS,您可以查看此站點(diǎn)

  • 10年成為更好的節(jié)點(diǎn)開發(fā)人員的2017個(gè)技巧
  • NodeJS 教程系列 —?Node Hero(幾乎涵蓋了所有節(jié)點(diǎn)主題)
  • 簡(jiǎn)單的HTTP / 2服務(wù)器與Node.js和Express.js
  • HTTP/2:好的、壞的和丑陋的

克里斯蒂安·拉米雷斯文章來源地址http://www.zghlxwxcb.cn/news/detail-663885.html

到了這里,關(guān)于構(gòu)建 NodeJS 影院微服務(wù)并使用 docker 部署它(02/4)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 從零開始:如何使用Docker構(gòu)建微服務(wù)架構(gòu)

    使用 Docker 構(gòu)建微服務(wù)架構(gòu)是一種流行的方法,因?yàn)?Docker 提供了輕量級(jí)的容器化技術(shù),使得每個(gè)微服務(wù)可以在隔離的環(huán)境中獨(dú)立運(yùn)行。從零開始構(gòu)建這樣的架構(gòu)涉及到多個(gè)步驟,包括理解微服務(wù)架構(gòu)的基本概念、安裝 Docker、創(chuàng)建 Docker 容器和鏡像、配置網(wǎng)絡(luò),以及部署和管理

    2024年04月14日
    瀏覽(28)
  • Jenkins 中部署Nodejs插件并使用,并構(gòu)建前端項(xiàng)目(3)

    Jenkins 中部署Nodejs插件并使用,并構(gòu)建前端項(xiàng)目(3)

    遇到多個(gè)版本nodeJS需要構(gòu)建的時(shí)候 1、第一種就是一個(gè)配置安裝,然后進(jìn)行選中配置 2、第二種就是插件:nvm-wrapper,我們還是選用NodeJS插件: (1)可以加載任意npmrc文件; (2)與Jenkins結(jié)合緊密,封裝少,項(xiàng)目相對(duì)活躍; (3)功能豐富,可全局安裝模塊。 這里的路徑,要把

    2024年02月22日
    瀏覽(24)
  • NodeJs后端項(xiàng)目使用docker打包部署

    NodeJs后端項(xiàng)目使用docker打包部署

    docker安裝看之前的文章 默認(rèn)已經(jīng)安裝好docker并且配置沒有問題 拉取項(xiàng)目 https://gitee.com/coder-msc/docker-node 本地跑一個(gè)看看 pnpm install pnpm start 本地訪問 項(xiàng)目整個(gè)上傳服務(wù)器 查看dockerfile 使用docker打包 進(jìn)入項(xiàng)目目錄里面 docker build . 給鏡像打tag: docker tag b86282a8ba4c node-demo:v1.0.1 啟動(dòng)

    2024年02月15日
    瀏覽(20)
  • Docker構(gòu)建Java服務(wù) docker-compose部署微服務(wù)

    Docker構(gòu)建Java服務(wù) docker-compose部署微服務(wù)

    目錄 1.? 安裝Docker前置準(zhǔn)備 設(shè)置Docker開機(jī)自啟動(dòng) 配置Docker阿里云鏡像加速 安裝Docker-compose 2、鏡像拉取 3、創(chuàng)建docker-comepose.yaml文件 4.? 創(chuàng)建數(shù)據(jù)映射容器掛載目錄 ,以下是nacos?? xxl-job-admin sql腳本文件 5.? docker-comepose 部署 1. 安裝Docker前置準(zhǔn)備 設(shè)置Docker開機(jī)自啟動(dòng) 配置Do

    2024年04月16日
    瀏覽(21)
  • kubernetes(k8s)大白學(xué)習(xí)02:容器和docker基礎(chǔ)、使用、架構(gòu)學(xué)習(xí)

    kubernetes(k8s)大白學(xué)習(xí)02:容器和docker基礎(chǔ)、使用、架構(gòu)學(xué)習(xí)

    簡(jiǎn)單說:容器(container)就是計(jì)算機(jī)上的一個(gè)沙盒進(jìn)程,它與計(jì)算機(jī)上的所有其它進(jìn)程相隔離。 這種隔離是怎么做到的呢?它利用了內(nèi)核提供的 namespace 和 cgroup 這 2 種技術(shù)。這些技術(shù)能力在 Linux 中已經(jīng)存在了很長時(shí)間。而 Docker 或容器技術(shù)致力于將這些功能更易于使用和更

    2024年02月07日
    瀏覽(45)
  • k8s服務(wù)部署核心流程:以Jenkins為核心,從Gitee拉取代碼,然后進(jìn)行maven構(gòu)建,之后使用docker命令打鏡像,并推送鏡像到harbor倉庫,之后遠(yuǎn)程調(diào)用k8s命令創(chuàng)建服務(wù)

    k8s服務(wù)部署核心流程:以Jenkins為核心,從Gitee拉取代碼,然后進(jìn)行maven構(gòu)建,之后使用docker命令打鏡像,并推送鏡像到harbor倉庫,之后遠(yuǎn)程調(diào)用k8s命令創(chuàng)建服務(wù)

    前提是我們?cè)谧约弘娔X上模擬整個(gè)流程。 假設(shè)我們需要搭建一主一從的k8s集群,那就需要安裝VMvare和Centos7(點(diǎn)擊我查看安裝文檔), 然后就可以在這兩個(gè)虛擬機(jī)上搭建k8s集群了(點(diǎn)擊我查看安裝文檔), 一個(gè)最簡(jiǎn)單的devops流程已經(jīng)在標(biāo)題中寫明了, 其中可以搭建gitlab(點(diǎn)

    2024年02月02日
    瀏覽(31)
  • 使用Docker構(gòu)建的MySQL主從架構(gòu):高可用性數(shù)據(jù)庫解決方案

    MySQL主從架構(gòu),我們已經(jīng)在vmware虛擬機(jī)上實(shí)踐過了,接下來我們一起探討在docker中如何使用MySQL主從架構(gòu)。 ??個(gè)人主頁:我是沐風(fēng)曉月 ??個(gè)人簡(jiǎn)介:大家好,我是沐風(fēng)曉月,阿里云社區(qū)博客專家???? ?? 座右銘: 先努力成長自己,再幫助更多的人 ,一起加油進(jìn)步??????

    2024年02月08日
    瀏覽(16)
  • 使用docker構(gòu)建并部署MySQL5.7鏡像

    使用docker構(gòu)建并部署MySQL5.7鏡像

    這幾天在研究如何將服務(wù)器和數(shù)據(jù)庫遷移至 docker容器 ,中間遇到了許多問題,特此寫篇博客記錄一下。 提示:本篇文章主要講解如何在docker容器中構(gòu)建及部署MySQL 從 CentOS 鏡像中構(gòu)建 MySQL 容器 從 MySQL 官方鏡像中構(gòu)建容器 從 CentOS 鏡像中構(gòu)建 MySQL 容器可以更好地控制操作系

    2024年02月03日
    瀏覽(94)
  • [Docker]四.Docker部署nodejs項(xiàng)目,部署Mysql,部署Redis,部署Mongodb

    [Docker]四.Docker部署nodejs項(xiàng)目,部署Mysql,部署Redis,部署Mongodb

    可以到 https://hub.docker.com/ 去搜索node鏡像 , 然后下載,也可以直接通過docker pull node下載鏡像,然后用這個(gè)node鏡像啟動(dòng)容器node,這樣系統(tǒng)就集成了node服務(wù)了,在這里掛載www/node目錄到容器中,并指定端口映射,運(yùn)行nodejs程序,安裝npm,以及對(duì)應(yīng)的依賴,啟動(dòng)node目錄下對(duì)應(yīng)的項(xiàng)目,然后通過瀏

    2024年02月06日
    瀏覽(22)
  • Docker環(huán)境部署Hadoop并使用docker構(gòu)建spark運(yùn)行案列(全網(wǎng)最詳細(xì)教程)

    Docker環(huán)境部署Hadoop并使用docker構(gòu)建spark運(yùn)行案列(全網(wǎng)最詳細(xì)教程)

    Docker部署hadoop 和使用docker構(gòu)建spark運(yùn)行環(huán)境(全網(wǎng)最詳細(xì)教程) 首先查看版本環(huán)境(docker中沒有下載docker和docker-compose的可以看我上一篇博客 Linux 安裝配置Docker 和Docker compose 并在docker中部署mysql和中文版portainer圖形化管理界面) 查看docker和docker-compose版本: OK,環(huán)境沒問題,

    2024年02月03日
    瀏覽(59)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包