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

如何構(gòu)建一個(gè) NodeJS 影院微服務(wù)并使用 Docker 部署

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

如何構(gòu)建一個(gè) NodeJS 影院微服務(wù)并使用 Docker 部署,實(shí)戰(zhàn)源碼,實(shí)戰(zhàn),微服務(wù),docker,架構(gòu),原力計(jì)劃

前言

如何構(gòu)建一個(gè) NodeJS 影院微服務(wù)并使用 Docker 部署。在這個(gè)系列中,將構(gòu)建一個(gè) NodeJS 微服務(wù),并使用 Docker Swarm 集群進(jìn)行部署。

以下是將要使用的工具:

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

在嘗試本指南之前,應(yīng)該具備:

  • NodeJS 的基本知識
  • Docker 的基本知識(并且已經(jīng)安裝了 Docker)
  • MongoDB 的基本知識(并且數(shù)據(jù)庫服務(wù)正在運(yùn)行)

什么是微服務(wù)?

微服務(wù)是一個(gè)單獨(dú)的自包含單元,與其他許多單元一起構(gòu)成一個(gè)大型應(yīng)用程序。通過將應(yīng)用程序拆分為小單元,每個(gè)部分都可以獨(dú)立部署和擴(kuò)展,可以由不同的團(tuán)隊(duì)和不同的編程語言編寫,并且可以單獨(dú)進(jìn)行測試。

微服務(wù)架構(gòu)意味著應(yīng)用程序由許多較小的、獨(dú)立的應(yīng)用程序組成,這些應(yīng)用程序能夠在自己的內(nèi)存空間中運(yùn)行,并且可以在可能的多個(gè)獨(dú)立計(jì)算機(jī)上獨(dú)立擴(kuò)展。

微服務(wù)的好處:

  • 應(yīng)用程序啟動更快,這使得開發(fā)人員更具生產(chǎn)力,并加快了部署速度。
  • 每個(gè)服務(wù)可以獨(dú)立于其他服務(wù)部署 — 更容易頻繁部署服務(wù)的新版本。
  • 更容易擴(kuò)展開發(fā),也可能具有性能優(yōu)勢。
  • 消除對技術(shù)棧的長期承諾。在開發(fā)新服務(wù)時(shí),可以選擇新的技術(shù)棧。
  • 微服務(wù)通常更好組織,因?yàn)槊總€(gè)微服務(wù)有一個(gè)非常具體的工作,不涉及其他組件的工作。
  • 解耦的服務(wù)也更容易重新組合和重新配置,以服務(wù)不同應(yīng)用程序的目的(例如,同時(shí)為 Web 客戶端和公共 API 提供服務(wù))。

微服務(wù)的缺點(diǎn):

  • 開發(fā)人員必須處理創(chuàng)建分布式系統(tǒng)的額外復(fù)雜性。
  • 部署復(fù)雜性。在生產(chǎn)環(huán)境中,部署和管理許多不同服務(wù)類型的系統(tǒng)也會帶來操作復(fù)雜性。
  • 在構(gòu)建新的微服務(wù)架構(gòu)時(shí),可能會發(fā)現(xiàn)許多交叉關(guān)注點(diǎn),這些交叉關(guān)注點(diǎn)在設(shè)計(jì)時(shí)沒有預(yù)料到。

構(gòu)建電影目錄微服務(wù)

如何構(gòu)建一個(gè) NodeJS 影院微服務(wù)并使用 Docker 部署,實(shí)戰(zhàn)源碼,實(shí)戰(zhàn),微服務(wù),docker,架構(gòu),原力計(jì)劃

假設(shè)正在一家電影院的 IT 部門工作,給了我們一個(gè)任務(wù),將他們的電影票務(wù)和雜貨店從單體系統(tǒng)重構(gòu)為微服務(wù)。

因此,在“構(gòu)建 NodeJS 電影目錄微服務(wù)”系列中,將僅關(guān)注電影目錄服務(wù)。

在這個(gè)架構(gòu)中,可以看到有 3 種不同的設(shè)備使用該微服務(wù),即 POS(銷售點(diǎn))、移動設(shè)備/平板電腦和計(jì)算機(jī)。POS 和移動設(shè)備/平板電腦都有自己的應(yīng)用程序(在 electron 中開發(fā)),并直接使用微服務(wù),而計(jì)算機(jī)則通過 Web 應(yīng)用程序訪問微服務(wù)(一些專家也將 Web 應(yīng)用程序視為微服務(wù))。

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

現(xiàn)在,來模擬在最喜歡的電影院預(yù)訂一場電影首映的過程。

首先,想看看電影院目前正在上映哪些電影。以下圖表顯示了通過 REST 進(jìn)行的內(nèi)部通信,通過此 REST 通信,可以使用 API 來獲取目前正在上映的電影。

如何構(gòu)建一個(gè) NodeJS 影院微服務(wù)并使用 Docker 部署,實(shí)戰(zhàn)源碼,實(shí)戰(zhàn),微服務(wù),docker,架構(gòu),原力計(jì)劃

電影服務(wù)的 API 將具有以下 RAML 規(guī)范:

#%RAML 1.0
title: cinema
version: v1
baseUri: /

types:
  Movie:
    properties:
      id: string
      title: string
      runtime: number
      format: string
      plot: string
      releaseYear: number
      releaseMonth: number
      releaseDay: number
    example:
      id: "123"
      title: "Assasins Creed"
      runtime: 115
      format: "IMAX"
      plot: "Lorem ipsum dolor sit amet"
      releaseYear : 2017
      releaseMonth: 1
      releaseDay: 6

  MoviePremieres:
    type: Movie []


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

/movies:
  /premieres:
    type:  { Collection: {item : MoviePremieres } }

  /{id}:
    type:  { Collection: {item : Movie } }

如果不了解 RAML,可以查看這個(gè)很好的教程。

API 項(xiàng)目的結(jié)構(gòu)將如下所示:

  • api/ # 我們的API
  • config/ # 應(yīng)用程序配置
  • mock/ # 不是必需的,僅用于數(shù)據(jù)示例
  • repository/ # 抽象出數(shù)據(jù)庫
  • server/ # 服務(wù)器設(shè)置代碼
  • package.json # 依賴項(xiàng)
  • index.js # 應(yīng)用程序的主入口

首先要看的部分是 repository。這是對數(shù)據(jù)庫進(jìn)行查詢的地方。


'use strict'
// factory function, that holds an open connection to the db,
// and exposes some functions for accessing the data.
const repository = (db) => {
  
  // since this is the movies-service, we already know
  // that we are going to query the `movies` collection
  // in all of our functions.
  const collection = db.collection('movies')

  const getMoviePremiers = () => {
    return new Promise((resolve, reject) => {
      const movies = []
      const currentDay = new Date()
      const query = {
        releaseYear: {
          $gt: currentDay.getFullYear() - 1,
          $lte: currentDay.getFullYear()
        },
        releaseMonth: {
          $gte: currentDay.getMonth() + 1,
          $lte: currentDay.getMonth() + 2
        },
        releaseDay: {
          $lte: currentDay.getDate()
        }
      }
      const cursor = collection.find(query)
      const addMovie = (movie) => {
        movies.push(movie)
      }
      const sendMovies = (err) => {
        if (err) {
          reject(new Error('An error occured fetching all movies, err:' + err))
        }
        resolve(movies)
      }
      cursor.forEach(addMovie, sendMovies)
    })
  }

  const getMovieById = (id) => {
    return new Promise((resolve, reject) => {
      const projection = { _id: 0, id: 1, title: 1, format: 1 }
      const sendMovie = (err, movie) => {
        if (err) {
          reject(new Error(`An error occured fetching a movie with id: ${id}, err: ${err}`))
        }
        resolve(movie)
      }
      // fetch a movie by id -- mongodb syntax
      collection.findOne({id: id}, projection, sendMovie)
    })
  }
  
  // this will close the database connection
  const disconnect = () => {
    db.close()
  }

  return Object.create({
    getAllMovies,
    getMoviePremiers,
    getMovieById,
    disconnect
  })
}

const connect = (connection) => {
  return new Promise((resolve, reject) => {
    if (!connection) {
      reject(new Error('connection db not supplied!'))
    }
    resolve(repository(connection))
  })
}
// this only exports a connected repo
module.exports = Object.assign({}, {connect})

可能已經(jīng)注意到,向 repository 的 connect ( connection ) 方法提供了一個(gè) connection 對象。在這里,使用了 JavaScript 的一個(gè)重要特性“閉包”,repository 對象返回了一個(gè)閉包,其中的每個(gè)函數(shù)都可以訪問 db 對象和 collection 對象,db 對象保存著數(shù)據(jù)庫連接。在這里,抽象了連接的數(shù)據(jù)庫類型,repository 對象不知道數(shù)據(jù)庫是什么類型的,對于這種情況來說,是一個(gè) MongoDB 連接。甚至不需要知道是單個(gè)數(shù)據(jù)庫還是復(fù)制集連接。雖然使用了 MongoDB 語法,但可以通過應(yīng)用 SOLID 原則中的依賴反轉(zhuǎn)原則,將存儲庫功能抽象得更深,將 MongoDB 語法轉(zhuǎn)移到另一個(gè)文件中,并只調(diào)用數(shù)據(jù)庫操作的接口(例如,使用 mongoose 模型)。

有一個(gè) repository/repository.spec.js 文件來測試這個(gè)模塊,稍后在文章中會談到測試。

接下來要看的是 server.js 文件。

'use strict'
const express = require('express')
const morgan = require('morgan')
const helmet = require('helmet')
const movieAPI = require('../api/movies')

const start = (options) => {
  return new Promise((resolve, reject) => {
    // we need to verify if we have a repository added and a server port
    if (!options.repo) {
      reject(new Error('The server must be started with a connected repository'))
    }
    if (!options.port) {
      reject(new Error('The server must be started with an available port'))
    }
    // let's init a express app, and add some middlewares
    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!')
    })
    
    // we add our API's to the express app
    movieAPI(app, options)
    
    // finally we start the server, and return the newly created server 
    const server = app.listen(options.port, () => resolve(server))
  })
}

module.exports = Object.assign({}, {start})

在這里,創(chuàng)建了一個(gè)新的 express 應(yīng)用程序,驗(yàn)證是否提供了 repository 和 server port 對象,然后為 express 應(yīng)用程序應(yīng)用一些中間件,例如用于日志記錄的 morgan,用于安全性的 helmet,以及一個(gè)錯(cuò)誤處理函數(shù),最后導(dǎo)出一個(gè) start 函數(shù)來啟動服務(wù)器。

Helmet 包含了整整 11 個(gè)軟件包,它們都用于阻止惡意方破壞或使用應(yīng)用程序來傷害其用戶。

好的,現(xiàn)在既然服務(wù)器使用了電影的 API,繼續(xù)查看 movies.js 文件。

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

module.exports = (app, options) => {
  const {repo} = options
  
  // here we get all the movies 
  app.get('/movies', (req, res, next) => {
    repo.getAllMovies().then(movies => {
      res.status(status.OK).json(movies)
    }).catch(next)
  })
  
  // here we retrieve only the premieres
  app.get('/movies/premieres', (req, res, next) => {
    repo.getMoviePremiers().then(movies => {
      res.status(status.OK).json(movies)
    }).catch(next)
  })
  
  // here we get a movie by id
  app.get('/movies/:id', (req, res, next) => {
    repo.getMovieById(req.params.id).then(movie => {
      res.status(status.OK).json(movie)
    }).catch(next)
  })
}

在這里,為API創(chuàng)建了路由,并根據(jù)監(jiān)聽的路由調(diào)用了 repo 函數(shù)。repo 在這里使用了接口技術(shù)方法,在這里使用了著名的“為接口編碼而不是為實(shí)現(xiàn)編碼”,因?yàn)?express 路由不知道是否有一個(gè)數(shù)據(jù)庫對象、數(shù)據(jù)庫查詢邏輯等,它只調(diào)用處理所有數(shù)據(jù)庫問題的 repo 函數(shù)。

所有文件都有與源代碼相鄰的單元測試,看看 movies.js 的測試是如何進(jìn)行的。

可以將測試看作是對正在構(gòu)建的應(yīng)用程序的安全保障。不僅會在本地機(jī)器上運(yùn)行,還會在 CI 服務(wù)上運(yùn)行,以確保失敗的構(gòu)建不會被推送到生產(chǎn)系統(tǒng)。

為了編寫單元測試,必須對所有依賴項(xiàng)進(jìn)行存根,即為模塊提供虛擬依賴項(xiàng)??纯?spec 文件。

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

describe('Movies API', () => {
  let app = null
  let testMovies = [{
    'id': '3',
    'title': 'xXx: Reactivado',
    'format': 'IMAX',
    'releaseYear': 2017,
    'releaseMonth': 1,
    'releaseDay': 20
  }, {
    'id': '4',
    'title': 'Resident Evil: Capitulo Final',
    'format': 'IMAX',
    'releaseYear': 2017,
    'releaseMonth': 1,
    'releaseDay': 27
  }, {
    'id': '1',
    'title': 'Assasins Creed',
    'format': 'IMAX',
    'releaseYear': 2017,
    'releaseMonth': 1,
    'releaseDay': 6
  }]

  let testRepo = {
    getAllMovies () {
      return Promise.resolve(testMovies)
    },
    getMoviePremiers () {
      return Promise.resolve(testMovies.filter(movie => movie.releaseYear === 2017))
    },
    getMovieById (id) {
      return Promise.resolve(testMovies.find(movie => movie.id === id))
    }
  }

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

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

  it('can return all movies', (done) => {
    request(app)
      .get('/movies')
      .expect((res) => {
        res.body.should.containEql({
          'id': '1',
          'title': 'Assasins Creed',
          'format': 'IMAX',
          'releaseYear': 2017,
          'releaseMonth': 1,
          'releaseDay': 6
        })
      })
      .expect(200, done)
  })

  it('can get movie premiers', (done) => {
    request(app)
    .get('/movies/premiers')
    .expect((res) => {
      res.body.should.containEql({
        'id': '1',
        'title': 'Assasins Creed',
        'format': 'IMAX',
        'releaseYear': 2017,
        'releaseMonth': 1,
        'releaseDay': 6
      })
    })
    .expect(200, done)
  })

  it('returns 200 for an known movie', (done) => {
    request(app)
      .get('/movies/1')
      .expect((res) => {
        res.body.should.containEql({
          'id': '1',
          'title': 'Assasins Creed',
          'format': 'IMAX',
          'releaseYear': 2017,
          'releaseMonth': 1,
          'releaseDay': 6
        })
      })
      .expect(200, done)
  })
})
/* eslint-env mocha */
const server = require('./server')

describe('Server', () => {
  it('should require a port to start', () => {
    return server.start({
      repo: {}
    }).should.be.rejectedWith(/port/)
  })

  it('should require a repository to start', () => {
    return server.start({
      port: {}
    }).should.be.rejectedWith(/repository/)
  })
})

可以看到,為 movies API 存根了依賴項(xiàng),并驗(yàn)證了需要提供一個(gè) server port 和一個(gè) repository 對象。

繼續(xù)看一下如何創(chuàng)建傳遞給 repository 模塊的 db 連接對象,現(xiàn)在定義說每個(gè)微服務(wù)都必須有自己的數(shù)據(jù)庫,但是對于示例,將使用一個(gè) MongoDB 復(fù)制集服務(wù)器,但每個(gè)微服務(wù)都有自己的數(shù)據(jù)庫。

從 NodeJS 連接到 MongoDB 數(shù)據(jù)庫

以下是需要從 NodeJS 連接到 MongoDB 數(shù)據(jù)庫的配置。

const MongoClient = require('mongodb')

// here we create the url connection string that the driver needs
const getMongoURL = (options) => {
  const url = options.servers
    .reduce((prev, cur) => prev + `${cur.ip}:${cur.port},`, 'mongodb://')

  return `${url.substr(0, url.length - 1)}/${options.db}`
}

// mongoDB function to connect, open and authenticate
const connect = (options, mediator) => {
  mediator.once('boot.ready', () => {
    MongoClient.connect( getMongoURL(options), {
        db: options.dbParameters(),
        server: options.serverParameters(),
        replset: options.replsetParameters(options.repl)
      }, (err, db) => {
        if (err) {
          mediator.emit('db.error', err)
        }

        db.admin().authenticate(options.user, options.pass, (err, result) => {
          if (err) {
            mediator.emit('db.error', err)
          }
          mediator.emit('db.ready', db)
        })
      })
  })
}

module.exports = Object.assign({}, {connect})

這里可能有更好的方法,但基本上可以這樣創(chuàng)建與 MongoDB 的復(fù)制集連接。

傳遞了一個(gè) options 對象,其中包含 Mongo 連接所需的所有參數(shù),并且傳遞了一個(gè)事件 — 中介者對象,當(dāng)通過認(rèn)證過程時(shí),它將發(fā)出 db 對象。

注意 在這里,使用了一個(gè)事件發(fā)射器對象,因?yàn)槭褂?promise 的方法在某種程度上并沒有在通過認(rèn)證后返回 db 對象,順序變得空閑。所以這可能是一個(gè)很好的挑戰(zhàn),看看發(fā)生了什么,并嘗試使用 promise 的方法。

現(xiàn)在,既然正在傳遞一個(gè) options 對象來進(jìn)行參數(shù)設(shè)置,讓我們看看這是從哪里來的,因此要查看的下一個(gè)文件是 config.js。

// simple configuration file

// database parameters
const dbSettings = {
  db: process.env.DB || 'movies',
  user: process.env.DB_USER || 'cristian',
  pass: process.env.DB_PASS || 'cristianPassword2017',
  repl: process.env.DB_REPLS || 'rs1',
  servers: (process.env.DB_SERVERS) ? process.env.DB_SERVERS.split(' ') : [
    '192.168.99.100:27017',
    '192.168.99.101:27017',
    '192.168.99.102:27017'
  ],
  dbParameters: () => ({
    w: 'majority',
    wtimeout: 10000,
    j: true,
    readPreference: 'ReadPreference.SECONDARY_PREFERRED',
    native_parser: false
  }),
  serverParameters: () => ({
    autoReconnect: true,
    poolSize: 10,
    socketoptions: {
      keepAlive: 300,
      connectTimeoutMS: 30000,
      socketTimeoutMS: 30000
    }
  }),
  replsetParameters: (replset = 'rs1') => ({
    replicaSet: replset,
    ha: true,
    haInterval: 10000,
    poolSize: 10,
    socketoptions: {
      keepAlive: 300,
      connectTimeoutMS: 30000,
      socketTimeoutMS: 30000
    }
  })
}

// server parameters
const serverSettings = {
  port: process.env.PORT || 3000
}

module.exports = Object.assign({}, { dbSettings, serverSettings })

這是配置文件,大部分配置代碼都是硬編碼的,但正如看到的,一些屬性使用環(huán)境變量作為選項(xiàng)。環(huán)境變量被視為最佳實(shí)踐,因?yàn)檫@可以隱藏?cái)?shù)據(jù)庫憑據(jù)、服務(wù)器參數(shù)等。

最后,對于構(gòu)建電影服務(wù) API 的最后一步是使用 index.js 將所有內(nèi)容組合在一起。

'use strict'
// we load all the depencies we need
const {EventEmitter} = require('events')
const server = require('./server/server')
const repository = require('./repository/repository')
const config = require('./config/')
const mediator = new EventEmitter()

// verbose logging when we are starting the server
console.log('--- Movies Service ---')
console.log('Connecting to movies repository...')

// log unhandled execpetions
process.on('uncaughtException', (err) => {
  console.error('Unhandled Exception', err)
})
process.on('uncaughtRejection', (err, promise) => {
  console.error('Unhandled Rejection', err)
})

// event listener when the repository has been connected
mediator.on('db.ready', (db) => {
  let rep
  repository.connect(db)
    .then(repo => {
      console.log('Repository Connected. Starting Server')
      rep = repo
      return server.start({
        port: config.serverSettings.port,
        repo
      })
    })
    .then(app => {
      console.log(`Server started succesfully, running on port: ${config.serverSettings.port}.`)
      app.on('close', () => {
        rep.disconnect()
      })
    })
})
mediator.on('db.error', (err) => {
  console.error(err)
})

// we load the connection to the repository
config.db.connect(config.dbSettings, mediator)
// init the repository connection, and the event listener will handle the rest
mediator.emit('boot.ready')

在這里,組合了所有的電影 API 服務(wù),添加了一些錯(cuò)誤處理,然后加載配置、啟動存儲庫,并最后啟動服務(wù)器。

因此,到目前為止,已經(jīng)完成了與 API 開發(fā)相關(guān)的所有內(nèi)容。

下面是項(xiàng)目中需要用到的初始化以及運(yùn)行命令:

  • npm install # 設(shè)置Node依賴項(xiàng)
  • npm test # 使用mocha進(jìn)行單元測試
  • npm start # 啟動服務(wù)
  • npm run node-debug # 以調(diào)試模式運(yùn)行服務(wù)器
  • npm run chrome-debug # 使用chrome調(diào)試Node
  • npm run lint # 使用standard進(jìn)行代碼lint

最后,第一個(gè)微服務(wù)已經(jīng)在本地運(yùn)行,并通過執(zhí)行 npm start 命令啟動。

現(xiàn)在是時(shí)候?qū)⑵浞湃?Docker 容器中。

首先,需要使用“使用 Docker 部署 MongoDB 復(fù)制集”的文章中的 Docker 環(huán)境,如果沒有,則需要進(jìn)行一些額外的修改步驟,以便為微服務(wù)設(shè)置數(shù)據(jù)庫,以下是一些命令,進(jìn)行測試電影服務(wù)。

首先創(chuàng)建 Dockerfile,將 NodeJS 微服務(wù)制作成 Docker 容器。

# Node v7作為基本映像以支持ES6
FROM node:7.2.0
# 為新容器創(chuàng)建一個(gè)新用戶,并避免root用戶
RUN useradd --user-group --create-home --shell /bin/false nupp && \
    apt-get clean
ENV HOME=/home/nupp
COPY package.json npm-shrinkwrap.json $HOME/app/
COPY src/ $HOME/app/src
RUN chown -R nupp:nupp $HOME/* /usr/local/
WORKDIR $HOME/app
RUN npm cache clean && \
    npm install --silent --progress=false --production
RUN chown -R nupp:nupp $HOME/*
USER nupp
EXPOSE 3000
CMD ["npm", "start"]

使用 NodeJS 鏡像作為 Docker 鏡像的基礎(chǔ),然后為鏡像創(chuàng)建一個(gè)用戶以避免非 root 用戶,接下來,將 src 復(fù)制到鏡像中,然后安裝依賴項(xiàng),暴露一個(gè)端口號,并最后實(shí)例化電影服務(wù)。

接下來,需要構(gòu)建 Docker 鏡像,使用以下命令:

$ docker build -t movies-service .

首先看一下構(gòu)建命令。

  • docker build 告訴引擎要?jiǎng)?chuàng)建一個(gè)新的鏡像。
  • -t movies-service 用標(biāo)記 movies-service 標(biāo)記此鏡像。從現(xiàn)在開始,可以根據(jù)標(biāo)記引用此鏡像。
  • .:使用當(dāng)前目錄來查找 Dockerfile。

經(jīng)過一些控制臺輸出后,新鏡像中就有了 NodeJS 應(yīng)用程序,所以現(xiàn)在需要做的就是使用以下命令運(yùn)行鏡像:

$ docker run --name movie-service -p 3000:3000 -e DB_SERVERS="192.168.99.100:27017 192.168.99.101:27017 192.168.99.100:27017" -d movies-service

在上面的命令中,傳遞了一個(gè)環(huán)境變量,它是一個(gè)服務(wù)器數(shù)組,需要連接到 MongoDB 復(fù)制集的服務(wù)器,這只是為了說明,有更好的方法可以做到這一點(diǎn),比如讀取一個(gè)環(huán)境變量文件。

現(xiàn)在,容器已經(jīng)運(yùn)行起來了,獲取 docker-machine IP地址,以獲取微服務(wù)的 IP 地址,現(xiàn)在準(zhǔn)備對微服務(wù)進(jìn)行一次集成測試,另一個(gè)測試選項(xiàng)可以是JMeter,它是一個(gè)很好的工具,可以模擬HTTP請求。

這是集成測試,將檢查一個(gè) API 調(diào)用。

/* eslint-env mocha */
const supertest = require('supertest')

describe('movies-service', () => {

  const api = supertest('http://192.168.99.100:3000')

  it('returns a 200 for a collection of movies', (done) => {

    api.get('/movies/premiers')
      .expect(200, done)
  })
})

總結(jié)

創(chuàng)建了用于查詢電影院正在上映的電影的 movies 服務(wù),使用 RAML 規(guī)范設(shè)計(jì)了 API,然后開始構(gòu)建 API,并進(jìn)行了相應(yīng)的單元測試,最后,組合了所有內(nèi)容,使微服務(wù)完整,并能夠啟動 movies 服務(wù)服務(wù)器。

然后,將微服務(wù)放入 Docker 容器中,以進(jìn)行一些集成測試。

微服務(wù)架構(gòu)可以為大型應(yīng)用程序帶來許多好處,但也需要小心管理和設(shè)計(jì),以處理分布式系統(tǒng)的復(fù)雜性和其他挑戰(zhàn)。使用 Docker 容器可以簡化微服務(wù)的部署和管理,使其更加靈活和可擴(kuò)展。文章來源地址http://www.zghlxwxcb.cn/news/detail-650342.html

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

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

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

相關(guān)文章

  • 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)目相對活躍; (3)功能豐富,可全局安裝模塊。 這里的路徑,要把

    2024年02月22日
    瀏覽(24)
  • 如何使用 Docker 部署 FreeGPT-WebUI:一個(gè)簡單的教程

    如何使用 Docker 部署 FreeGPT-WebUI:一個(gè)簡單的教程

    目錄 1. FreeGPT-WebUI 項(xiàng)目簡介 2. 安裝 Docker 3. 從 Docker Hub 拉取 FreeGPT-WebUI 鏡像 4. 使用 Docker 運(yùn)行 FreeGPT-WebUI 應(yīng)用程序 5. 訪問 FreeGPT-WebUI 應(yīng)用程序 總結(jié) 在本教程中,我們將了解如何使用 Docker 部署 FreeGPT-WebUI,一個(gè)基于 Python 的開源項(xiàng)目,它為 GPT 模型提供了一個(gè)簡單的 Web 用戶界

    2024年02月16日
    瀏覽(27)
  • 如何使用Docker本地部署一個(gè)開源網(wǎng)址導(dǎo)航頁并分享好友公網(wǎng)使用

    如何使用Docker本地部署一個(gè)開源網(wǎng)址導(dǎo)航頁并分享好友公網(wǎng)使用

    ??????歡迎來到我的博客,很高興能夠在這里和您見面!希望您在這里可以感受到一份輕松愉快的氛圍,不僅可以獲得有趣的內(nèi)容和知識,也可以暢所欲言、分享您的想法和見解。 推薦:kwan 的首頁,持續(xù)學(xué)習(xí),不斷總結(jié),共同進(jìn)步,活到老學(xué)到老 導(dǎo)航 檀越劍指大廠系列:全面總

    2024年02月03日
    瀏覽(18)
  • 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 啟動

    2024年02月15日
    瀏覽(20)
  • 如何使用Docker部署Nacos服務(wù)?Nacos Docker 快速部署指南: 一站式部署與配置教程

    如何使用Docker部署Nacos服務(wù)?Nacos Docker 快速部署指南: 一站式部署與配置教程

    ???? 博主貓頭虎(????)帶您 Go to New World??? ?? 博客首頁 ——????貓頭虎的博客?? ?? 《面試題大全專欄》 ?? 文章圖文并茂??生動形象??簡單易學(xué)!歡迎大家來踩踩~?? ?? 《IDEA開發(fā)秘籍專欄》 ?? 學(xué)會IDEA常用操作,工作效率翻倍~?? ?? 《100天精通Golang(基礎(chǔ)

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

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

    目錄 1.? 安裝Docker前置準(zhǔn)備 設(shè)置Docker開機(jī)自啟動 配置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ī)自啟動 配置Do

    2024年04月16日
    瀏覽(21)
  • Docker與微服務(wù):構(gòu)建和部署微服務(wù)架構(gòu)的完整指南

    Docker與微服務(wù):構(gòu)建和部署微服務(wù)架構(gòu)的完整指南

    微服務(wù)架構(gòu)已經(jīng)成為現(xiàn)代應(yīng)用開發(fā)的主要范式之一,而Docker容器技術(shù)則為微服務(wù)的構(gòu)建、部署和管理提供了理想的解決方案。本文將深入探討如何使用Docker構(gòu)建和部署微服務(wù)架構(gòu),提供更多示例代碼和細(xì)致的指南,以幫助大家更全面地理解和運(yùn)用這些關(guān)鍵概念。 微服務(wù)架構(gòu)是

    2024年02月02日
    瀏覽(51)
  • 如何使用Docker將.Net6項(xiàng)目部署到Linux服務(wù)器(一)

    如何使用Docker將.Net6項(xiàng)目部署到Linux服務(wù)器(一)

    目錄 一 配置服務(wù)器環(huán)境 1.1 配置yum? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? 1.1.1 更新yum包 1.1.2 yum命令 1.2 配置docker? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

    2024年02月04日
    瀏覽(21)
  • 如何在CentOS使用Docker部署Traefik服務(wù)并創(chuàng)建固定公網(wǎng)地址遠(yuǎn)程訪問

    如何在CentOS使用Docker部署Traefik服務(wù)并創(chuàng)建固定公網(wǎng)地址遠(yuǎn)程訪問

    博主貓頭虎的技術(shù)世界 ?? 歡迎來到貓頭虎的博客 — 探索技術(shù)的無限可能! 專欄鏈接 : ?? 精選專欄 : 《面試題大全》 — 面試準(zhǔn)備的寶典! 《IDEA開發(fā)秘籍》 — 提升你的IDEA技能! 《100天精通鴻蒙》 — 從Web/安卓到鴻蒙大師! 《100天精通Golang(基礎(chǔ)入門篇)》 — 踏入

    2024年04月15日
    瀏覽(25)
  • CentOS如何使用Docker部署Plik服務(wù)并實(shí)現(xiàn)公網(wǎng)訪問本地設(shè)備上傳下載文件

    CentOS如何使用Docker部署Plik服務(wù)并實(shí)現(xiàn)公網(wǎng)訪問本地設(shè)備上傳下載文件

    本文介紹如何使用Linux docker方式快速安裝Plik并且結(jié)合Cpolar內(nèi)網(wǎng)穿透工具實(shí)現(xiàn)遠(yuǎn)程訪問,實(shí)現(xiàn)隨時(shí)隨地在任意設(shè)備上傳或者下載或者共享文件! Plik是一個(gè)可擴(kuò)展且友好的臨時(shí)文件上傳系統(tǒng),類似于wetransfer。它具有強(qiáng)大的命令行客戶端和易于使用的Web UI,支持多個(gè)數(shù)據(jù)后端(文

    2024年04月17日
    瀏覽(28)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包