gitlab?ci?cd?命令的使用不完全指南
gitlab 可能大家很常用,CI、CD 也應(yīng)該早有耳聞,但是可能還沒有去真正地了解過,這篇文章就是我對(duì) gitlab CI、CD 的一些理解,以及踩過的一些坑,希望能幫助到大家。
什么是 CI、CD
CI(Continuous Integration)持續(xù)集成,CD(Continuous Deployment)持續(xù)部署(也包含了持續(xù)交付的意思)。
CI 指的是一種開發(fā)過程的的自動(dòng)化流程,在我們提交代碼的時(shí)候,一般會(huì)做以下操作:
lint檢查,檢查代碼是否符合規(guī)范- 自動(dòng)運(yùn)行測試,檢查代碼是否能通過測試
這個(gè)過程我們可以稱之為 CI,也就是持續(xù)集成,這個(gè)過程是自動(dòng)化的,也就是說我們不需要手動(dòng)去執(zhí)行這些操作,只需要提交代碼,這些操作就會(huì)自動(dòng)執(zhí)行。
CD 指的是在我們 CI 流程通過之后,將代碼自動(dòng)發(fā)布到服務(wù)器的過程,這個(gè)過程也是自動(dòng)化的。 在有了前面 CI 的一些操作之后,說明我們的代碼是可以安全發(fā)布到服務(wù)器的,所以就可以進(jìn)行發(fā)布的操作。
為什么要使用 CI、CD
實(shí)際上,就算沒有 CI、CD 的這些花里胡哨的概念,對(duì)于一些重復(fù)的操作,我們也會(huì)盡量想辦法會(huì)讓它們可以自動(dòng)化實(shí)現(xiàn)的,只不過可能效率上沒有這么高,但是也是可以的。
CI、CD 相比其他方式的優(yōu)勢(shì)在于:
- 一次配置,多次使用:我們需要做的所有操作都通過配置固定下來了,每次提交代碼我們都可以執(zhí)行相同的操作。
- 可觀測性:我們可以通過 CI、CD 的日志來查看每次操作的執(zhí)行情況,而且每一次的 CI、CD 執(zhí)行的日志都會(huì)保留下來,這樣我們就可以很方便地查看每一次操作的執(zhí)行情況。
- 自動(dòng)化:我們不需要手動(dòng)去執(zhí)行 CI、CD 的操作,只需要提交代碼,CI、CD 就會(huì)自動(dòng)執(zhí)行。
- 少量配置:一般的代碼托管平臺(tái)都會(huì)提供 CI、CD 的功能,我們只需要簡單的配置一下就可以使用了。同時(shí)其實(shí)不同平臺(tái)的 CI、CD 配置也是有很多相似之處的,所以我們只需要學(xué)習(xí)一種配置方式,就可以在不同平臺(tái)上使用了。
gitlab CI、CD
在開始之前,我們可以通過下圖來了解一下 CI、CD 的整體流程:

- 在開發(fā)人員提交代碼之后,會(huì)觸發(fā) gitlab 的 CI 流水線。也就是上圖的
CI PIPELINE,也就是中間的部分。 - 在 CI 流水線中,我們可以配置多個(gè)任務(wù)。比如上圖的
build、unit test、integration tests等,也就是構(gòu)建、單元測試、集成測試等。 - 在 CI 流水線都通過之后,會(huì)觸發(fā) CD 流水線。也就是上圖的
CD PIPELINE,也就是右邊的部分。 - 在 CD 流水線中,我們可以配置多個(gè)任務(wù)。比如上圖的
staging、production等,也就是部署到測試環(huán)境、部署到生產(chǎn)環(huán)境等。
在 CD 流程結(jié)束之后,我們就可以在服務(wù)器上看到我們的代碼了。
gitlab CI、CD 中的一些基本概念
在開始之前,我們先來了解一下 gitlab CI、CD 中的一些基本概念:
pipeline:流水線,也就是 CI、CD 的整個(gè)流程,包含了多個(gè)stage,每個(gè)stage又包含了多個(gè)job。stage: 一個(gè)階段,一個(gè)階段中可以包含多個(gè)任務(wù)(job),這些任務(wù)會(huì)并行執(zhí)行,但是下一個(gè)stage的job只有在上一個(gè)stage的job執(zhí)行通過之后才會(huì)執(zhí)行。job:一個(gè)任務(wù),這是 CI、CD 中最基本的概念,也是最小的執(zhí)行單元。一個(gè)stage中可以包含多個(gè)job,同時(shí)這些job會(huì)并行執(zhí)行。runner:執(zhí)行器,也就是執(zhí)行job的機(jī)器,runner跟 gitlab 是分離的,runner需要我們自己去安裝,然后注冊(cè)到 gitlab 上(不需要跟 gitlab 在同一個(gè)服務(wù)器上,這樣有個(gè)好處就是可以很方便實(shí)現(xiàn)多個(gè)機(jī)器來同時(shí)處理 gitlab 的 CI、CD 的任務(wù))。tag:runner和job都需要指定標(biāo)簽,job可以指定一個(gè)或多個(gè)標(biāo)簽(必須指定,否則job不會(huì)被執(zhí)行),這樣job就只會(huì)在指定標(biāo)簽的runner上執(zhí)行。cache: 緩存,可以緩存一些文件,這樣下次流水線執(zhí)行的時(shí)候就不需要重新下載了,可以提高執(zhí)行效率。artifacts: 這代表這構(gòu)建過程中所產(chǎn)生的一些文件,比如打包好的文件,這些文件可以在下一個(gè)stage中使用,也可以在pipeline執(zhí)行結(jié)束之后下載下來。variables:變量,可以在pipeline中定義一些變量,這些變量可以在pipeline的所有stage和job中使用。services:服務(wù),可以在pipeline中啟動(dòng)一些服務(wù),比如mysql、redis等,這樣我們就可以在pipeline中使用這些服務(wù)了(常常用在測試的時(shí)候模擬一個(gè)服務(wù))。script: 腳本,可以在job中定義一些腳本,這些腳本會(huì)在job執(zhí)行的時(shí)候執(zhí)行。
CI、CD 的工作模型
我們以下面的配置為例子,簡單說明一下 pipeline、stage、job 的工作模型,以及 cache 和 artifacts 的作用:
ci 配置文件(也就是一個(gè) pipeline 的所有任務(wù)):
# 定義一個(gè) `pipeline` 的所有階段,一個(gè) `pipeline` 可以包含多個(gè) `stage`,每個(gè) `stage` 又包含多個(gè) `job`。
# stage 的順序是按照數(shù)組的順序來執(zhí)行的,也就是說 stage1 會(huì)先執(zhí)行,然后才會(huì)執(zhí)行 stage2。
stages:
- stage1 # stage 的名稱
- stage2
# 定義一個(gè) `job`,一個(gè) `job` 就是一個(gè)任務(wù),也是最小的執(zhí)行單元。
job1:
stage: stage1 # 指定這個(gè) `job` 所屬的 `stage`,這個(gè) `job` 只會(huì)在 `stage1` 執(zhí)行。
script: # 指定這個(gè) `job` 的腳本,這個(gè)腳本會(huì)在 `job` 執(zhí)行的時(shí)候執(zhí)行。
- echo "hello world" > "test.txt"
tags: # 指定這個(gè) `job` 所屬的 `runner` 的標(biāo)簽,這個(gè) `job` 只會(huì)在標(biāo)簽為 `tag1` 的 `runner` 上執(zhí)行。
- tag1
# cache 可以在當(dāng)前 `pipeline` 后續(xù)的 `job` 中使用,也可以在后續(xù)的 `pipeline` 中使用。
cache: # 指定這個(gè) `job` 的緩存,這個(gè)緩存會(huì)在 `job` 執(zhí)行結(jié)束之后保存起來,下次執(zhí)行的時(shí)候會(huì)先從緩存中讀取,如果沒有緩存,就會(huì)重新下載。
key: $CI_COMMIT_REF_SLUG # 緩存的 key
paths: # 緩存的路徑
- node_modules/
artifacts: # 指定這個(gè) `job` 的構(gòu)建產(chǎn)物,這個(gè)構(gòu)建產(chǎn)物會(huì)在 `job` 執(zhí)行結(jié)束之后保存起來??梢栽谙乱粋€(gè) stage 中使用,也可以在 pipeline 執(zhí)行結(jié)束之后下載下來。
paths:
- test.txt
job2:
stage: stage1
script:
- cat test.txt
tags:
- tag1
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- node_modules/
# 指定這個(gè) `job` 的緩存策略,只會(huì)讀取緩存,不會(huì)寫入緩存。默認(rèn)是既讀取又寫入,在 job 開始的時(shí)候讀取,在 job 結(jié)束的時(shí)候?qū)懭搿?
# 但是實(shí)際上,只有在安裝依賴的時(shí)候是需要寫入緩存的,其他 job 都使用 pull 即可。
policy: pull
# job3 和 job4 都屬于 stage2,所以 job3 和 job4 會(huì)并行執(zhí)行。
# job3 和 job4 都指定了 tag2 標(biāo)簽,所以 job3 和 job4 只會(huì)在標(biāo)簽為 tag2 的 runner 上執(zhí)行。
# 同時(shí),在 job1 中,我們指定了 test.txt 作為構(gòu)建產(chǎn)物,所以 job3 和 job4 都可以使用 test.txt 這個(gè)文件。
job3:
stage: stage2
script:
- cat test.txt
tags:
- tag1
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- node_modules/
policy: pull
job4:
stage: stage2
script:
- cat test.txt
tags:
- tag1
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- node_modules/
policy: pull
上面的配置文件的 pipeline 執(zhí)行過程可以用下面的圖來表示:

說明:
- 上面的圖有兩個(gè)
pipeline被執(zhí)行了,但是pipeline2沒有全部畫出來 - 其中,在
pipeline 1中,stage1中的job會(huì)先被執(zhí)行,然后才會(huì)執(zhí)行stage2中的job。 stage1中的job1和job2是可以并行執(zhí)行的,這也就是stage的本質(zhì)上的含義,表示了一個(gè)階段中不同的任務(wù),比如我們做測試的時(shí)候,可以同時(shí)對(duì)不同模塊做測試。job1和job2都指定了tag1標(biāo)簽,所以job1和job2只會(huì)在標(biāo)簽為tag1的runner上執(zhí)行。job1中,我們創(chuàng)建了一個(gè)test.txt文件,這個(gè)文件會(huì)作為stage1的構(gòu)建產(chǎn)物,它可以在stage2中被使用,也就是job3和job4都可以讀取到這個(gè)文件。一種實(shí)際的場景是,前端部署的時(shí)候,build 之后會(huì)生成可以部署的靜態(tài)文件,這些靜態(tài)文件就會(huì)被保留到部署相關(guān)的 stage 中。需要注意的是,artifacts只會(huì)在當(dāng)前pipeline后續(xù)的stage中共享,不會(huì)在pipeline之間共享。- 同時(shí),在
job1中,我們也指定了cache,這個(gè)cache會(huì)在job1執(zhí)行結(jié)束之后保存起來,不同于artifacts,cache是可以在不同的pipeline之間共享的。一種很常見的使用場景就是我們代碼的依賴,比如node_modules文件夾,它可以加快后續(xù)pipeline的執(zhí)行流程,因?yàn)楸苊饬酥貜?fù)的依賴安裝。
需要特別注意的是:cache 是跨流水線共享的,而 artifacts 只會(huì)在當(dāng)前流水線的后續(xù) stage 共享。
其他一些在個(gè)人實(shí)踐中的一些經(jīng)驗(yàn)
gitlab 的 CI、CD 是一個(gè)很龐大的話題,同時(shí)很多內(nèi)容可能比較少用,所以本文只是介紹個(gè)人在實(shí)踐中用到的一些內(nèi)容,其他的東西如果有需要,可以自行查閱官方文檔。
指定特定分支才會(huì)執(zhí)行的 job
這個(gè)算是基本操作了,我們可以通過 only 來指定特定分支才會(huì)執(zhí)行的 job,也有其他方法可以實(shí)現(xiàn),比如 rules,具體請(qǐng)參考官方文檔。
deploy-job:
stage: deploy
# 當(dāng)前的這個(gè) job 只會(huì)在 master 分支代碼更新的時(shí)候會(huì)執(zhí)行
only:
- "master"
不同 job 之間的依賴
這個(gè)也是基本操作,我們可以通過 needs 來指定不同 job 之間的依賴關(guān)系,比如 job1 依賴 job2,那么 job1 就會(huì)在 job2 執(zhí)行完畢之后才會(huì)執(zhí)行。
job1:
stage: deploy
needs:
- job2
指定執(zhí)行 job 的 runner
我們可以通過 tags 來指定 job 執(zhí)行的 runner,比如我們可以指定 job 只能在 api 標(biāo)簽的 runner 上執(zhí)行。
build-job:
stage: build
tags:
- api
如果我們沒有標(biāo)簽為 api 的 runner,那么這個(gè) job 就會(huì)一直不會(huì)被執(zhí)行,所以需要確保我們配置的 tag 有對(duì)應(yīng)的 runner。
指定 job 的 docker image
注意:這個(gè)只在我們的 runner 的 executor 為 docker 的時(shí)候才會(huì)生效。也就是我們的 runner 是一個(gè) docker 容器。
有時(shí)候,我們需要執(zhí)行一些特定命令,但是我們?nèi)值?docker 鏡像里面沒有,可能只需要一個(gè)特定的 docker 鏡像,這個(gè)時(shí)候我們可以通過 image 來指定 job 的 docker 鏡像。
deploy-job:
stage: deploy
tags:
- api
# 指定 runner 的 docker image
image: eleven26/rsync:1.3.0
script:
# 下面這個(gè)命令只在上面指定的 docker 鏡像中存在
- rsync . root@example.com:/home/www/foo
為我們的集成測試指定一個(gè) service
在我們的 CI 流程中,可能會(huì)有一些集成測試需要使用到一些服務(wù),比如我們的 mysql,這個(gè)時(shí)候我們可以通過 services 來指定我們需要的服務(wù)。
test_rabbitmq:
# 這會(huì)啟動(dòng)一個(gè) rabbitmq 3.8 的 docker 容器,我們的 job 就可以使用這個(gè)容器了。
# 我們的 job 可以連接到一個(gè) rabbitmq 的服務(wù),然后進(jìn)行測試。
# 需要注意的是,這個(gè)容器只會(huì)在當(dāng)前 job 執(zhí)行的時(shí)候存在,執(zhí)行完畢之后就會(huì)被刪除。所以產(chǎn)生的數(shù)據(jù)不會(huì)被保留。
services:
- rabbitmq:3.8
stage: test
only:
- master
tags:
- go
script:
# 下面的測試命令會(huì)連接到上面啟動(dòng)的 rabbitmq 服務(wù)
- "go test -v -cover ./pkg/rabbitmq"
復(fù)用 yaml 配置片段
在 yaml 中,有一種機(jī)制可以讓我們復(fù)用 yaml 配置片段,比如:
# 發(fā)布代碼的 job
.deploy-job: &release-job
tags:
- api
image: eleven26/rsync:1.3.0
script:
- rsync . root@example.com:/home/www/foo
deploy-release:
<<: *release-job
stage: deploy
only:
- "release"
deploy-master:
<<: *release-job
stage: deploy
only:
- "master"
上面的代碼中,我們定義了一個(gè) release-job 的配置片段,然后在 deploy-release 和 deploy-master 中,我們都引用了這個(gè)配置片段,這樣我們就可以復(fù)用這個(gè)配置片段了。 等同于下面的代碼:
# 發(fā)布代碼的 job
.deploy-job: &release-job
tags:
- api
image: eleven26/rsync:1.3.0
script:
- rsync . root@example.com:/home/www/foo
deploy-release:
tags:
- api
image: eleven26/rsync:1.3.0
script:
- rsync . root@example.com:/home/www/foo
stage: deploy
only:
- "release"
deploy-master:
tags:
- api
image: eleven26/rsync:1.3.0
script:
- rsync . root@example.com:/home/www/foo
stage: deploy
only:
- "master"
在 yaml 的術(shù)語中,這一種機(jī)制叫做 anchor。
cache vs artifacts
初次使用的人,可能會(huì)對(duì)這個(gè)東西有點(diǎn)迷惑,因?yàn)樗鼈兒孟穸际蔷彺妫菍?shí)際上,它們的用途是不一樣的。
cache是用來緩存依賴的,比如node_modules文件夾,它可以加快后續(xù)pipeline的執(zhí)行流程,因?yàn)楸苊饬酥貜?fù)的依賴安裝。artifacts是用來緩存構(gòu)建產(chǎn)物的,比如build之后生成的靜態(tài)文件,它可以在后續(xù)的stage中使用。表示的是單個(gè) pipeline 中的不同 stage 之間的共享。
指定 artifacts 的過期時(shí)間
我們可以通過 expire_in 來指定 artifacts 的過期時(shí)間,比如:
job1:
stage: build
only:
- "release"
image: eleven26/apidoc:1.0.0
tags:
- api
artifacts:
paths:
- public
expire_in: 1 hour
因?yàn)槲覀兊?artifacts 有時(shí)候只是生成一些需要部署到服務(wù)器的東西,然后在下一個(gè) stage 使用,所以是不需要長期保留的。所以我們可以通過 expire_in 來指定一個(gè)比較短的 artifacts 的過期時(shí)間。
cache 只 pull 不 push
gitlab CI 的 cache 有一個(gè) policy 屬性,它的值默認(rèn)是 pull-push,也就是在 job 開始執(zhí)行的時(shí)候會(huì)拉取緩存,在 job 執(zhí)行結(jié)束的時(shí)候會(huì)將緩存指定文件夾的內(nèi)容上傳到 gitlab 中。
但是在實(shí)際使用中,我們其實(shí)只需要在安裝依賴的時(shí)候上傳這些緩存,其他時(shí)候都只是讀取緩存的。所以我們?cè)诎惭b依賴的 job 中使用默認(rèn)的 policy,而在后續(xù)的 job 中,我們可以通過 policy: pull 來指定只拉取緩存,不上傳緩存。
job:
tags:
- api
image: eleven26/rsync:1.3.0
cache:
key:
files:
- composer.json
- composer.lock
paths:
- "vendor/"
policy: pull # 只拉取 vendor,在 job 執(zhí)行完畢之后不上傳 vendor
cache 的 key 使用文件
這一個(gè)特性是非常有用的,在現(xiàn)代軟件工程的實(shí)踐中,往往通過 *.lock 文件來記錄我們使用的額依賴的具體版本,以保證在不同環(huán)境中使用的時(shí)候保持一致的行為。
所以,相應(yīng)的,我們的緩存也可以在 *.lock 這類文件發(fā)生變化的時(shí)候,重新生成緩存。上面的例子就使用了這種機(jī)制。
script 中使用多行命令
在 script 中,我們可以使用多行命令,比如:
job:
script:
# 我們可以通過下面這種方式來寫多行的 shell 命令,也就是以一個(gè)豎線開始,然后換行
- |
if [ "$release_host" != "" ]; then
host=$release_host
fi
CD - 如何同步代碼到服務(wù)器
如果我們的項(xiàng)目需要部署到服務(wù)器上,那么我們還需要做一些額外的操作,比如同步代碼到服務(wù)器上。 如果我們的 gitlab 是通過容器執(zhí)行的,或者我們的 runner 的 executor 是 docker,那么有一種比較常見的方法是通過 ssh 私鑰來進(jìn)行部署。
我們可以通過以下流程來實(shí)現(xiàn):
- 新建一對(duì) ssh key,比如
id_rsa和id_rsa.pub。 - 將
id_rsa.pub的內(nèi)容添加到服務(wù)器的authorized_keys文件中。 - 將
id_rsa上傳到 gitlab 中(在項(xiàng)目的 CI/CD 配置中,配置一個(gè)變量,變量名為PRIVATE_KEY,內(nèi)容為id_rsa的內(nèi)容,類型為file)。 - 在我們的
ci配置文件中,添加如下配置即可:
before_script:
- chmod 600 $PRIVATE_KEY
deploy:
stage: deploy
image: eleven26/rsync:1.3.0
script:
# $user 是 ssh 的用戶
# $host 是 ssh 的主機(jī)
# $port 是 ssh 的端口
# $PRIVATE_KEY 是我們?cè)?gitlab 中配置的私鑰
- rsync -az -e "ssh -o StrictHostKeyChecking=no -p $port -i $PRIVATE_KEY" --delete --exclude='.git' . $user@$host:/home/www
這里的 rsync 命令中,我們使用了 -o StrictHostKeyChecking=no 參數(shù),這是為了避免每次都需要手動(dòng)輸入 yes 來確認(rèn)服務(wù)器的指紋。
安全最佳實(shí)踐:
- 為每一個(gè) project 配置 ssh key 變量,如果是全局變量的話,其他 project 可以在未授權(quán)的情況下,訪問到這個(gè)私鑰,這是非常危險(xiǎn)的。
- 使用單獨(dú)的倉庫來保存 ci 配置文件,防止其他人未經(jīng)授權(quán)就修改 ci 配置文件,這也是非常危險(xiǎn)的。
必須嚴(yán)格遵循以上兩步,否則會(huì)造成嚴(yán)重的安全問題。
總結(jié)
最后,總結(jié)一下本文中一些比較關(guān)鍵的內(nèi)容:
- gitlab 中的一些基本概念:
pipeline:代表了一次 CI 的執(zhí)行過程,它包含了多個(gè)stage。stage:代表了一組job的集合,stage會(huì)按照順序執(zhí)行。job:代表了一個(gè)具體的任務(wù),比如build、test、deploy等。
- 一個(gè)
stage中的多個(gè)job是可以并行執(zhí)行的。但是下一個(gè)stage的job必須要等到上一個(gè)stage的所有job都執(zhí)行完畢之后才會(huì)執(zhí)行。 cache和artifacts的區(qū)別:cache是用來緩存依賴的,比如node_modules文件夾,它可以加快后續(xù)pipeline的執(zhí)行流程,因?yàn)楸苊饬酥貜?fù)的依賴安裝。artifacts是用來緩存構(gòu)建產(chǎn)物的,比如build之后生成的靜態(tài)文件,它可以在后續(xù)的stage中使用。表示的是單個(gè) pipeline 中的不同 stage 之間的共享。
cache在安裝依賴的job中才需要使用默認(rèn)的policy,也就是pull-push,在其他不需要安裝依賴的job中使用pull就可以了,不需要上傳緩存。cache的key可以指定多個(gè)文件,這樣在指定的文件變動(dòng)的時(shí)候,緩存會(huì)失效,這往往用在依賴相關(guān)的文件中。- 可以使用
services關(guān)鍵字來指定需要啟動(dòng)的服務(wù),比如mysql、redis等,在 job 中可以連接到這些 services,從而方便進(jìn)行測試。 - 可以使用
yaml的anchor機(jī)制來復(fù)用一些配置片段,可以少寫很多重復(fù)的配置。 - 一個(gè)
job必須運(yùn)行在某個(gè)runner上,job和runner的關(guān)聯(lián)是通過tag來指定的。
以上就是gitlab ci cd 不完全指南的詳細(xì)內(nèi)容,更多關(guān)于gitlab ci cd 的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
一個(gè)SSL證書在線轉(zhuǎn)換工具以及IIS7環(huán)境下開通https的方法
公司只能提供 Nginx 下的 SSL 證書,卻要在 IIS 里面開啟 https 這個(gè)問題,那么就需要將pem轉(zhuǎn)換為pfx,這里為大家分享一下幾種方法2024-02-02
網(wǎng)站控制臺(tái)directadmin中文手冊(cè) Linux下虛擬主機(jī)管理
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn),本站所提供的攝影照片,插畫,設(shè)計(jì)作品,如需使用,請(qǐng)與原作者聯(lián)系2009-11-11
git標(biāo)簽管理_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了git標(biāo)簽管理的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
理解web服務(wù)器和數(shù)據(jù)庫的負(fù)載均衡以及反向代理
這里的“負(fù)載均衡”是指在網(wǎng)站建設(shè)中應(yīng)該考慮的“負(fù)載均衡”。假設(shè)我們要搭建一個(gè)網(wǎng)站:aaa.me,我們使用的web服務(wù)器每秒能處理100條請(qǐng)求,而aaa.me這個(gè)網(wǎng)站最火的時(shí)候也只是每秒99條請(qǐng)求,那么我們使用一個(gè)服務(wù)器是完全可以的2014-04-04
centos6.4+nginx+mysql+php+phpmyadmin整合過程詳解
這篇文章主要介紹了centos6.4+nginx+mysql+php+phpmyadmin整合過程,較為詳細(xì)的分析了centos6.4+nginx+mysql+php+phpmyadmin整合的具體步驟、操作指令與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-11-11
HTTP與HTTP協(xié)作的Web服務(wù)器訪問流程圖解
記得以前剛接觸網(wǎng)站的時(shí)候,很奇怪一臺(tái)服務(wù)器上可以放很多個(gè)網(wǎng)站,不用的域名就可以訪問不同的目錄,今天看起來的理所當(dāng)然以前真是不可思議,今天剛好看到了這篇文章就為大家分享一下2018-10-10
MSXML2.XMLHTTP 800401F3 錯(cuò)誤的解決方法
今天ASP調(diào)用Web Service報(bào)錯(cuò),錯(cuò)誤代碼為800401F3,錯(cuò)誤提示為:Server.CreateObject失敗。2009-08-08

