成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

高質(zhì)量 Node.js 微服務(wù)的編寫(xiě)和部署

Michael_Ding / 2893人閱讀

摘要:編寫(xiě)代碼的開(kāi)發(fā)人員必須負(fù)責(zé)代碼的生產(chǎn)部署。構(gòu)建和部署鏈需要重大更改,以便為微服務(wù)環(huán)境提供正確的關(guān)注點(diǎn)分離。該對(duì)象會(huì)在之后的時(shí)被這時(shí)的回調(diào)函數(shù)會(huì)被調(diào)用,并輸出。微服務(wù)部署及集成部署微服務(wù)時(shí)有一個(gè)原則一個(gè)容器中只放一個(gè)服務(wù),可以使用編

前幾天在微信群做的一次分享,整理出來(lái)分享給大家,相關(guān)代碼請(qǐng)戳 https://github.com/Carrotzpc/docker_web_app

微服務(wù)架構(gòu)是一種構(gòu)造應(yīng)用程序的替代性方法。應(yīng)用程序被分解為更小、完全獨(dú)立的組件,這使得它們擁有更高的敏捷性、可伸縮性和可用性。一個(gè)復(fù)雜的應(yīng)用被拆分為若干微服務(wù),微服務(wù)更需要一種成熟的交付能力。持續(xù)集成、部署和全自動(dòng)測(cè)試都必不可少。編寫(xiě)代碼的開(kāi)發(fā)人員必須負(fù)責(zé)代碼的生產(chǎn)部署。構(gòu)建和部署鏈需要重大更改,以便為微服務(wù)環(huán)境提供正確的關(guān)注點(diǎn)分離。后續(xù)我們會(huì)聊一下如何在時(shí)速云平臺(tái)上集成 DevOps。

Node.js? is a JavaScript runtime built on Chrome"s V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js" package ecosystem, npm, is the largest ecosystem of open source libraries in the world. --- https://nodejs.org

Node.js 是構(gòu)建微服務(wù)的利器,為什么這么說(shuō)呢,我們先看下 Node.js 有哪些優(yōu)勢(shì):

Node.js 采用事件驅(qū)動(dòng)、異步編程,為網(wǎng)絡(luò)服務(wù)而設(shè)計(jì)

Node.js 非阻塞模式的IO處理給 Node.js 帶來(lái)在相對(duì)低系統(tǒng)資源耗用下的高性能與出眾的負(fù)載能力,非常適合用作依賴其它IO資源的中間層服務(wù)

Node.js輕量高效,可以認(rèn)為是數(shù)據(jù)密集型分布式部署環(huán)境下的實(shí)時(shí)應(yīng)用系統(tǒng)的完美解決方案。

這些優(yōu)勢(shì)正好與微服務(wù)的優(yōu)勢(shì):敏捷性、可伸縮性和可用性相契合(捂臉笑),再看下 Node.js 的缺點(diǎn):

單進(jìn)程,單線程,只支持單核CPU,不能充分的利用多核CPU服務(wù)器。一旦這個(gè)進(jìn)程 down 了,那么整個(gè) web 服務(wù)就 down 了

異步編程,callback 回調(diào)地獄

第一個(gè)缺點(diǎn)可以通過(guò)啟動(dòng)多個(gè)實(shí)例來(lái)實(shí)現(xiàn)CPU充分利用以及負(fù)載均衡,話說(shuō)這不是 K8s 的原生功能嗎。第二個(gè)缺點(diǎn)更不是事兒,現(xiàn)在可以通過(guò) generator、promise等來(lái)寫(xiě)同步代碼,爽的不要不要的。

下面我們主要從 Docker 和 Node.js 出發(fā)聊一下高質(zhì)量Node.js微服務(wù)的編寫(xiě)和部署:

Node.js 異步流程控制:generator 與 promise

Express、Koa 的異常處理

如何編寫(xiě) Dockerfile

微服務(wù)部署及 DevOps 集成

1. Node.js 異步流程控制:Generator 與 Promise

Node.js 的設(shè)計(jì)初衷為了性能而異步,現(xiàn)在已經(jīng)可以寫(xiě)同步的代碼了,你造嗎?目前 Node.js 的LTS版本早就支持了Generator, Promise這兩個(gè)特性,也有許多優(yōu)秀的第三方庫(kù) bluebird、q 這樣的模塊支持的也非常好,性能甚至比原生的還好,可以用 bluebird 替換 Node.js 原生的 Promise:

global.Promise = require("bluebird")

blurbird 的性能是 V8 里內(nèi)置的 Promise 3 倍左右(bluebird 的優(yōu)化方式見(jiàn) https://github.com/petkaanton... )。

1.1 ES2015 Generator

Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances. --- https://developer.mozilla.org...*

generator 就像一個(gè)取號(hào)機(jī),你可以通過(guò)取一張票來(lái)向機(jī)器請(qǐng)求一個(gè)號(hào)碼。你接收了你的號(hào)碼,但是機(jī)器不會(huì)自動(dòng)為你提供下一個(gè)。換句話說(shuō),取票機(jī)“暫?!敝钡接腥苏?qǐng)求另一個(gè)號(hào)碼(next()),此時(shí)它才會(huì)向后運(yùn)行。下面我們看一個(gè)簡(jiǎn)單的示例:

function* idMaker(){
  var index = 0
  while(index < 3)
    yield index++
}

var gen = idMaker()

gen.next() // {value: 0, done: false}
gen.next() // {value: 1, done: false}
gen.next() // {value: 2, done: false}
gen.next() // {value: undefined, done: true}
// ...

從上面的代碼的輸出可以看出:

generator 函數(shù)的定義,是通過(guò) function *(){} 實(shí)現(xiàn)的

對(duì) generator 函數(shù)的調(diào)用返回的實(shí)際是一個(gè)遍歷器,隨后代碼通過(guò)使用遍歷器的 next() 方法來(lái)獲得函數(shù)的輸出

通過(guò)使用yield語(yǔ)句來(lái)中斷 generator 函數(shù)的運(yùn)行,并且可以返回一個(gè)中間結(jié)果

每次調(diào)用next()方法,generator 函數(shù)將執(zhí)行到下一個(gè)yield語(yǔ)句或者是return語(yǔ)句。

下面我們就對(duì)上面代碼的每次next調(diào)用進(jìn)行一個(gè)詳細(xì)的解釋:

第1次調(diào)用next()方法的時(shí)候,函數(shù)執(zhí)行到第一次循環(huán)的yield index++語(yǔ)句停了下來(lái),并且返回了0這個(gè)value,隨同value返回的done屬性表明 generator 函數(shù)的運(yùn)行還沒(méi)有結(jié)束

第2次調(diào)用next()方法的時(shí)候,函數(shù)執(zhí)行到第二循環(huán)的yield index++語(yǔ)句停了下來(lái),并且返回了1這個(gè)value,隨同value返回的done屬性表明 generator 函數(shù)的運(yùn)行還沒(méi)有結(jié)束

... ...

第4次調(diào)用next()方法的時(shí)候,由于循環(huán)已經(jīng)結(jié)束了,所以函數(shù)調(diào)用立即返回,done屬性表明 generator 函數(shù)已經(jīng)結(jié)束運(yùn)行,valueundefined的,因?yàn)檫@次調(diào)用并沒(méi)有執(zhí)行任何語(yǔ)句

PS:如果在 generator 函數(shù)內(nèi)部需要調(diào)用另外一個(gè) generator 函數(shù),那么對(duì)目標(biāo)函數(shù)的調(diào)用就需要使用yield*

1.2 ES2015 Promise

The Promise object is used for asynchronous computations. A Promise represents an operation that hasn"t completed yet, but is expected in the future. --- https://developer.mozilla.org...

所謂 Promise,就是一個(gè)對(duì)象,用來(lái)傳遞異步操作的消息。它代表了某個(gè)未來(lái)才會(huì)知道結(jié)果的事件(通常是一個(gè)異步操作),并且這個(gè)事件提供統(tǒng)一的 API,可供進(jìn)一步處理。

一個(gè) Promise 一般有3種狀態(tài):

pending: 初始狀態(tài),不是fulfilled,也不是rejected.

fulfilled: 操作成功完成.

rejected: 操作失敗.

一個(gè) Promise 的生命周期如下圖:

下面我們看一段具體代碼:

function asyncFunction() {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve("Async Hello world")
    }, 16)
  })
}

asyncFunction().then(function (value) {
  console.log(value)  // => "Async Hello world"
}).catch(function (error) {
  console.log(error)
})

asyncFunction 這個(gè)函數(shù)會(huì)返回 Promise 對(duì)象, 對(duì)于這個(gè) Promise 對(duì)象,我們調(diào)用它的then 方法來(lái)設(shè)置resolve后的回調(diào)函數(shù),catch方法來(lái)設(shè)置發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)。

該 Promise 對(duì)象會(huì)在setTimeout之后的16ms時(shí)被resolve, 這時(shí)then的回調(diào)函數(shù)會(huì)被調(diào)用,并輸出 "Async Hello world"。

在這種情況下catch的回調(diào)函數(shù)并不會(huì)被執(zhí)行(因?yàn)?Promise 返回了resolve), 不過(guò)如果運(yùn)行環(huán)境沒(méi)有提供 setTimeout 函數(shù)的話,那么上面代碼在執(zhí)行中就會(huì)產(chǎn)生異常,在 catch 中設(shè)置的回調(diào)函數(shù)就會(huì)被執(zhí)行。

小結(jié)

如果是編寫(xiě)一個(gè) SDK 或 API,推薦使用傳統(tǒng)的 callback 或者 Promise,不使用 generator 的原因是:

generator 的出現(xiàn)不是為了解決異步問(wèn)題

使用 generator 是會(huì)傳染的,當(dāng)你嘗試yield一下的時(shí)候,它要求你也必須在一個(gè) generator function 內(nèi)

(《如何用 Node.js 編寫(xiě)一個(gè) API 客戶端》@leizongmin)

由此看來(lái)學(xué)習(xí) Promise 是水到渠成的事情。

2. Express、Koa 的異常處理

一個(gè)友好的錯(cuò)誤處理機(jī)制應(yīng)該滿足三個(gè)條件:

對(duì)于引發(fā)異常的用戶,返回 500 頁(yè)面

其他用戶不受影響,可以正常訪問(wèn)

不影響整個(gè)進(jìn)程的正常運(yùn)行

下面我們就以這三個(gè)條件為原則,具體介紹下 Express、Koa 中的異常處理:

2.1 Express 異常處理

在 Express 中有一個(gè)內(nèi)置的錯(cuò)誤處理中間件,這個(gè)中間件會(huì)處理任何遇到的錯(cuò)誤。如果你在 Express 中傳遞了一個(gè)錯(cuò)誤給next(),而沒(méi)有自己定義的錯(cuò)誤處理函數(shù)處理這個(gè)錯(cuò)誤,這個(gè)錯(cuò)誤就會(huì)被 Express 默認(rèn)的錯(cuò)誤處理函數(shù)捕獲并處理,而且會(huì)把錯(cuò)誤的堆棧信息返回到客戶端,這樣的錯(cuò)誤處理是非常不友好的,還好我們可以通過(guò)設(shè)置NODE_ENV環(huán)境變量為production,這樣 Express 就會(huì)在生產(chǎn)環(huán)境模式下運(yùn)行應(yīng)用,生產(chǎn)環(huán)境模式下 Express 不會(huì)把錯(cuò)誤的堆棧信息返回到客戶端。

在 Express 項(xiàng)目中可以定義一個(gè)錯(cuò)誤處理的中間件用來(lái)替換 Express 默認(rèn)的錯(cuò)誤處理函數(shù):

app.use(errorHandler)
function errorHandler(err, req, res, next) {
  if (res.headersSent) {
    return next(err)
  }
  res.status(500)
  switch(req.accepts(["html", "json"])) {
    case "html":
      res.render("error", { error: err })
      break
    default:
      res.send("500 Internal Server Error")
  }
}

在所有其他app.use()以及路由之后引入以上代碼,可以滿足以上三個(gè)友好錯(cuò)誤處理?xiàng)l件,是一種非常友好的錯(cuò)誤處理機(jī)制。

2.2 Koa 異常處理

我們以Koa 1.x為例,看代碼:

app.use(function *(next) {
  try {
    yield next
  } catch (err) {
    this.status = err.status || 500
    this.body = err
    this.app.emit("error", err, this)
  }
})

把上面的代碼放在所有app.use()函數(shù)前面,這樣基本上所有的同步錯(cuò)誤均會(huì)被 try{} catch(err){} 捕獲到了,具體原理大家可以了解下 Koa 中間件的機(jī)制。

2.3 未捕獲的異常 uncaughtException

上面的兩種異常處理方法,只能捕獲同步錯(cuò)誤,而異步代碼產(chǎn)生的錯(cuò)誤才是致命的,uncaughtException錯(cuò)誤會(huì)導(dǎo)致當(dāng)前的所有用戶連接都被中斷,甚至不能返回一個(gè)正常的HTTP 錯(cuò)誤碼,用戶只能等到瀏覽器超時(shí)才能看到一個(gè)no data received錯(cuò)誤。

這是一種非常野蠻粗暴的異常處理機(jī)制,任何線上服務(wù)都不應(yīng)該因?yàn)?b>uncaughtException 導(dǎo)致服務(wù)器崩潰。在Node.js 我們可以通過(guò)以下代碼捕獲 uncaughtException錯(cuò)誤:

process.on("uncaughtException", function (err) {
  console.error("Unexpected exception: " + err)
  console.error("Unexpected exception stack: " + err.stack)
  // Do something here: 
  // Such as send a email to admin
  // process.exit(1)
})

捕獲uncaughtException后,Node.js 的進(jìn)程就不會(huì)退出,但是當(dāng) Node.js 拋出 uncaughtException 異常時(shí)就會(huì)丟失當(dāng)前環(huán)境的堆棧,導(dǎo)致 Node.js 不能正常進(jìn)行內(nèi)存回收。也就是說(shuō),每一次、uncaughtException 都有可能導(dǎo)致內(nèi)存泄露。既然如此,退而求其次,我們可以在滿足前兩個(gè)條件的情況下退出進(jìn)程以便重啟服務(wù)。當(dāng)然還可以利用domain模塊做更細(xì)致的異常處理,這里就不做介紹了。

3. 如何編寫(xiě) Dockerfile 3.1 基礎(chǔ)鏡像選擇

我們先選用 Node.js 官方推薦的node:argon官方LTS版本最新鏡像,鏡像大小為656.9 MB(解壓后大小,下文提到的鏡像大小沒(méi)有特殊說(shuō)明的均指解壓后的大小)

The first thing we need to do is define from what image we want to build from. Here we will use the latest LTS (long term support) version argon of node available from the Docker Hub --- https://nodejs.org/en/docs/gu...

我們事先寫(xiě)好了兩個(gè)文件package.json, app.js

{
  "name": "docker_web_app",
  "version": "1.0.0",
  "description": "Node.js on Docker",
  "author": "Zhangpc ",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "^4.13.3"
  }
}
// app.js
"use strict";

const express = require("express")

// Constants
const PORT = 8080

// App
const app = express()
app.get("/", function (req, res) {
  res.send("Hello world
")
})

app.listen(PORT)
console.log("Running on http://localhost:" + PORT)

下面開(kāi)始編寫(xiě) Dockerfile,由于直接從 Dockerhub 拉取鏡像速度較慢,我們選用時(shí)速云的docker官方鏡像 docker_library/node,這些官方鏡像都是與 Dockerhub 實(shí)時(shí)同步的:

# Dockerfile.argon
FROM index.tenxcloud.com/docker_library/node:argon

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

# Expose port
EXPOSE 8080
CMD [ "npm", "start" ]

執(zhí)行以下命令進(jìn)行構(gòu)建:

docker build -t zhangpc/docker_web_app:argon .

最終得到的鏡像大小是660.3 MB,體積略大,Docker 容器的優(yōu)勢(shì)是輕量和可移植,所以承載它的操作系統(tǒng)即基礎(chǔ)鏡像也應(yīng)該迎合這個(gè)特性,于是我想到了Alpine Linux,一個(gè)面向安全的,輕量的 Linux 發(fā)行版,基于 musl libcbusybox。

下面我們使用alpine:edge作為基礎(chǔ)鏡像,鏡像大小為4.799 MB

# Dockerfile.alpine
FROM index.tenxcloud.com/docker_library/alpine:edge

# Install node.js by apk
RUN echo "@edge http://nl.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories
RUN apk update && apk upgrade
RUN apk add --no-cache nodejs-lts@edge

# If you have native dependencies, you"ll need extra tools
# RUN apk add --no-cache make gcc g++ python

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# If your project depends on many package, you can use cnpm instead of npm
# RUN npm install cnpm -g --registry=https://registry.npm.taobao.org
# RUN cnpm install

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

# Expose port
EXPOSE 8080

CMD [ "npm", "start" ]

執(zhí)行以下命令進(jìn)行構(gòu)建:

docker build -t zhangpc/docker_web_app:alpine .

最終得到的鏡像大小是31.51 MB,足足縮小了20倍,運(yùn)行兩個(gè)鏡像均測(cè)試通過(guò)。

3.2 還有優(yōu)化的空間嗎?

首先,大小上還是可以優(yōu)化的,我們知道 Dockerfile 的每條指令都會(huì)將結(jié)果提交為新的鏡像,下一條指令將會(huì)基于上一步指令的鏡像的基礎(chǔ)上構(gòu)建,所以如果我們要想清除構(gòu)建過(guò)程中產(chǎn)生的緩存,就得保證產(chǎn)生緩存的命令和清除緩存的命令在同一條 Dockerfile 指令中,因此修改 Dockerfile 如下:

# Dockerfile.alpine-mini
FROM index.tenxcloud.com/docker_library/alpine:edge

# Create app directory and bundle app source
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY . /usr/src/app

# Install node.js and app dependencies
RUN echo "@edge http://nl.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories 
  && apk update && apk upgrade 
  && apk add --no-cache nodejs-lts@edge 
  && npm install 
  && npm uninstall -g npm 
  && rm -rf /tmp/* 
  && rm -rf /root/.npm/
  
# Expose port
EXPOSE 8080

CMD [ "node", "app.js" ]

執(zhí)行以下命令進(jìn)行構(gòu)建:

docker build -t zhangpc/docker_web_app:alpine .

最終得到的鏡像大小是21.47 MB,縮小了10M。

其次,我們發(fā)現(xiàn)在構(gòu)建過(guò)程中有一些依賴是基本不變的,例如安裝 Node.js 以及項(xiàng)目依賴,我們可以把這些不變的依賴集成在基礎(chǔ)鏡像中,這樣可以大幅提升構(gòu)建速度,基本上是秒級(jí)構(gòu)建。當(dāng)然也可以把這些基本不變的指令集中在 Dockerfile 的前面部分,并保持前面部分不變,這樣就可以利用緩存提升構(gòu)建速度。

最后,如果使用了 Express 框架,在構(gòu)建生產(chǎn)環(huán)境鏡像時(shí)可以設(shè)置NODE_ENV環(huán)境變量為production,可以大幅提升應(yīng)用的性能,還有其他諸多好處,下面會(huì)有介紹。

小結(jié)

我們構(gòu)建的三個(gè)鏡像大小對(duì)比見(jiàn)上圖,鏡像的大小越小,發(fā)布的時(shí)候越快捷,而且可以提高安全性,因?yàn)楦俚拇a和程序在容器中意味著更小的攻擊面。使用node:argon作為基礎(chǔ)鏡像構(gòu)建出的鏡像(tag 為 argon)壓縮后的大小大概為254 MB,也不是很大,如果對(duì)Alpine Linux心存顧慮的童鞋可以選用 Node.js 官方推薦的node:argon作為基礎(chǔ)鏡像構(gòu)建微服務(wù)。

4. 微服務(wù)部署及 devops 集成

部署微服務(wù)時(shí)有一個(gè)原則:一個(gè)容器中只放一個(gè)服務(wù),可以使用stack 編排把各個(gè)微服務(wù)組合成一個(gè)完整的應(yīng)用:

4.1 Dokcer 環(huán)境微服務(wù)部署

安裝好 Docker 環(huán)境后,直接運(yùn)行我們構(gòu)建好的容器即可:

docker run -d --restart=always -p 8080:8080 --name docker_web_app_alpine zhangpc/docker_web_app:alpine
4.2 使用時(shí)速云平臺(tái)集成 DevOps

時(shí)速云目前支持github、gitlab、bitbucket、coding 等代碼倉(cāng)庫(kù),并已實(shí)現(xiàn)完全由API接入授權(quán)、webhook等,只要你開(kāi)發(fā)時(shí)使用的是這些代碼倉(cāng)庫(kù),都可以接入時(shí)速云的 CI/CD 服務(wù):

下面我們簡(jiǎn)單介紹下接入流程:

創(chuàng)建項(xiàng)目,參考文檔 http://doc.tenxcloud.com/doc/...

開(kāi)啟CI

更改代碼并提交,項(xiàng)目自動(dòng)構(gòu)建

用構(gòu)建出來(lái)的鏡像(tagmaster)創(chuàng)建一個(gè)容器

開(kāi)啟CD,并綁定剛剛創(chuàng)建的容器

更改代碼,測(cè)試 DevOps

我們可以看到代碼更改已經(jīng)經(jīng)過(guò)構(gòu)建(CI)、部署(CD)體現(xiàn)在了容器上。

參考資料

《微服務(wù)、SOA 和 API:是敵是友?》http://www.ibm.com/developerw...

《解析微服務(wù)架構(gòu)(一):什么是微服務(wù)》 http://t.cn/RtXiKLS

《微服務(wù)選型之Modern Node.js》 https://github.com/i5ting/mod...

帥龍攻城獅《鏡像構(gòu)建優(yōu)化之路》 http://blog.tenxcloud.com/?p=...

《微容器:更小的,更輕便的Docker容器》 http://blog.tenxcloud.com/?p=...

黃鑫攻城獅的內(nèi)部分享《Dockerfile技巧分享》

《Node 出現(xiàn) uncaughtException 之后的優(yōu)雅退出方案》 http://www.infoq.com/cn/artic...

《Express Error handling》 https://expressjs.com/en/guid...

《Promise 迷你書(shū)》 http://liubin.org/promises-book/

《如何把 Callback 接口包裝成 Promise 接口》 http://www.75team.com/post/ho...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/26652.html

相關(guān)文章

  • 質(zhì)量 Node.js 服務(wù)編寫(xiě)部署

    摘要:編寫(xiě)代碼的開(kāi)發(fā)人員必須負(fù)責(zé)代碼的生產(chǎn)部署。構(gòu)建和部署鏈需要重大更改,以便為微服務(wù)環(huán)境提供正確的關(guān)注點(diǎn)分離。該對(duì)象會(huì)在之后的時(shí)被這時(shí)的回調(diào)函數(shù)會(huì)被調(diào)用,并輸出。微服務(wù)部署及集成部署微服務(wù)時(shí)有一個(gè)原則一個(gè)容器中只放一個(gè)服務(wù),可以使用編 前幾天在微信群做的一次分享,整理出來(lái)分享給大家,相關(guān)代碼請(qǐng)戳 https://github.com/Carrotzpc/docker_web_app sho...

    szysky 評(píng)論0 收藏0
  • 超長(zhǎng)干貨:基于DockerDevOps CI/CD實(shí)踐——來(lái)自iHealth分享

    摘要:在貓屎氤氳的霧氣里角仰望天花板,手機(jī)微信提醒這次構(gòu)建成功或失敗,并附帶污言穢語(yǔ)。這時(shí)他可以開(kāi)始往工位走,坐下時(shí),微信又會(huì)提醒本次部署到成功或失敗。與企業(yè)微信的集成在決定使用之前,需要知道的是,是一個(gè)高度依賴社區(qū)的項(xiàng)目。 前言 相信我,一切事情的發(fā)生都是趕鴨子上架,沒(méi)有例外。人類所有偉大的變革都是迫不得已,可又是那么順其自然。比如容器(docker)技術(shù)的誕生,比如箭在弦上的創(chuàng)業(yè),比如野...

    Dongjie_Liu 評(píng)論0 收藏0
  • 前端每周清單半年盤(pán)點(diǎn)之 Node.js

    摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開(kāi)發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開(kāi)發(fā)教程工程實(shí)踐深度閱讀開(kāi)源項(xiàng)目巔峰人生等欄目。對(duì)該漏洞的綜合評(píng)級(jí)為高危。目前,相關(guān)利用方式已經(jīng)在互聯(lián)網(wǎng)上公開(kāi),近期出現(xiàn)攻擊嘗試爆發(fā)的可能。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開(kāi)發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開(kāi)發(fā)教程、工程實(shí)踐、深度閱讀、開(kāi)源項(xiàng)目、巔峰人生等欄目。歡...

    kid143 評(píng)論0 收藏0
  • 一個(gè)小時(shí)快速搭建信小程序

    摘要:第一步搭開(kāi)發(fā)環(huán)境首先,我們需要在本地搭建好微信小程序的開(kāi)發(fā)環(huán)境。在微信小程序中,所有的網(wǎng)絡(luò)請(qǐng)求受到嚴(yán)格限制,不滿足條件的域名和協(xié)議無(wú)法請(qǐng)求。第五步配置微信小程序云端示例鏡像中,已經(jīng)部署好了,但是還需要在下修改配置中的域名證書(shū)私鑰。 「小程序」這個(gè)劃時(shí)代的產(chǎn)品發(fā)布快一周了,互聯(lián)網(wǎng)技術(shù)人都在摩拳擦掌,躍躍欲試??墒切〕绦蚰壳斑€在內(nèi)測(cè),首批只發(fā)放了 200 個(gè)內(nèi)測(cè)資格(淚流滿面)。本以為沒(méi)有...

    izhuhaodev 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<