docker+jenkins+seneca構(gòu)建去集中化微服務(wù)架構(gòu)

前言

在微服務(wù)架構(gòu)中,服務(wù)發(fā)現(xiàn)一直是一件比較復(fù)雜的事嫌吠。而且服務(wù)發(fā)現(xiàn)式的架構(gòu)處理不好止潘,容易產(chǎn)生集中化。同時(shí)居兆,微服務(wù)的提供覆山,不可避免的需要一些負(fù)載均衡方案,實(shí)現(xiàn)服務(wù)的高可用和可擴(kuò)展泥栖,這無疑增加了很多復(fù)雜度簇宽。

筆者認(rèn)為勋篓,使用異步、基于消息的方式魏割,可能更適合微服務(wù)架構(gòu)譬嚣。

基于消息的微服務(wù)架構(gòu),對于所有微服務(wù)的部署條件非常簡單钞它,只需要能訪問到消息服務(wù)即可拜银。同時(shí)微服務(wù)節(jié)點(diǎn)的移除和增加不會(huì)影響到服務(wù)的提供。相比服務(wù)發(fā)現(xiàn)的架構(gòu)遭垛,簡單太多了尼桶,簡單即是美。

在這次實(shí)踐中锯仪,使用到了seneca泵督,一個(gè)nodejs 微服務(wù)框架。seneca,使用seneca-amqp-transport插件庶喜,可以輕松構(gòu)建基于消息的微服務(wù)小腊。

下面是架構(gòu)圖:


https://www.processon.com/view/link/59dc2491e4b0ef561379bc25

在這個(gè)架構(gòu)中,我們使用的是標(biāo)準(zhǔn)的seneca定義的命令規(guī)范久窟,這可能是所有微服務(wù)都需要遵守的一個(gè)規(guī)范秩冈,至于說使用其他語言,也很簡單斥扛。封裝一個(gè)seneca命令規(guī)范的庫即可入问。不知道官方有沒開發(fā),開發(fā)起來難度也不會(huì)太大犹赖。

接口層比較靈活队他,可以根據(jù)上層應(yīng)用特性卷仑,來決定如何封裝傳輸協(xié)議峻村,最后將轉(zhuǎn)化成標(biāo)準(zhǔn)命令發(fā)送到消息服務(wù)。不建議直接訪問消息服務(wù)锡凝,上層應(yīng)用應(yīng)保持靈活粘昨。

完整的實(shí)踐代碼:https://github.com/luaxlou/micro-service-practice.git

1 前期準(zhǔn)備

使用docker-machine創(chuàng)建虛擬機(jī)。

關(guān)于docker的一些基本用法窜锯,可以讀上一篇文章:docker+consul基于服務(wù)發(fā)現(xiàn)的極簡web架構(gòu)實(shí)踐张肾,這里就不再贅述。

依次創(chuàng)建3臺(tái)虛擬機(jī):

$ dm create -d "virtualbox” node1
$ dm create -d "virtualbox” node2
$ dm create -d "virtualbox" node3

2 開始構(gòu)建

搭建Rabbitmq消息服務(wù)

消息隊(duì)列服務(wù)锚扎,已經(jīng)成為高并發(fā)應(yīng)用的必備基礎(chǔ)服務(wù)吞瞪。我們選用Rabbitmq,你可以換成任意的驾孔,遵循amqp協(xié)議即可芍秆。

使用docker安裝很方便惯疙,但是生產(chǎn)環(huán)境不建議使用docker安裝。更推薦的是使用云服務(wù)妖啥,這樣能保證足夠高的高可用和擴(kuò)展性霉颠。雖然價(jià)格貴點(diǎn),但是這是唯一的單點(diǎn)荆虱,花點(diǎn)錢還是值得的蒿偎。

直接安裝在宿主機(jī)上:

$ docker search rabbitmq

NAME                                       DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
rabbitmq                                   RabbitMQ is an open source multi-protocol ...   1466      [OK]
tutum/rabbitmq                             Base docker image to run a RabbitMQ server      11
frodenas/rabbitmq                          A Docker Image for RabbitMQ                     11                   [OK]
sysrun/rpi-rabbitmq                        RabbitMQ Container for the Raspberry Pi 2 ...   6
aweber/rabbitmq-autocluster                RabbitMQ with the Autocluster Plugin            5
gonkulatorlabs/rabbitmq                    DEPRECATED: See maryville/rabbitmq              5                    [OK]
letsxo/rabbitmq                            RabbitMQ with Management and MQTT plugins.      4                    [OK]
bitnami/rabbitmq                           Bitnami Docker Image for RabbitMQ               3                    [OK]
$ docker run -d --name rabbit -p   5672:5672  rabbitmq

這樣就啟動(dòng)了一個(gè)消息隊(duì)里服務(wù),并且開放5672端口

安裝jenkins

jenkins用于自動(dòng)集成怀读,不然每次構(gòu)建是個(gè)很麻煩的事诉位。

下面的實(shí)踐是筆者掉了不少坑之后完成的,jenkins在安裝過程中會(huì)有不少麻煩菜枷,而且在mac下安裝也會(huì)遇到麻煩不从。

將jenkins 安裝到 node1

$ dm ssh node1
 
$ mkdir /mnt/sda1/var/jenkins_home
$ sudo chown 1000 /mnt/sda1/var/jenkins_home
$ sudo chown 1000 /var/run/docker.sock

$ docker run -d -v /var/run/docker.sock:/var/run/docker.sock \
                -v /mnt/sda1/var/jenkins_home:/var/jenkins_home \
                -v $(which docker):/usr/bin/docker -p 8080:8080 jenkins

查看初始密碼:
$ cat /mnt/sda1/var/jenkins_home/secrets/initialAdminPassword

安裝私有的Registry

在mac上安裝即可

$ docker run -d -p 5000:5000 registry

文檔參考:https://docs.docker.com/registry/spec/api/

準(zhǔn)備代碼

代碼使用的是seneca官方的例子,完整的Dockerfile也已經(jīng)寫好犁跪。

FROM node:alpine

RUN npm install pm2 -g
WORKDIR /usr/src/app

COPY package.json ./
RUN npm install
COPY . .

CMD ["pm2-docker","process.yml"]

為了讓nodejs能使用到多核cpu椿息,Dockerfile 集成了pm2,使用pm2來管理node進(jìn)程坷衍。

完整代碼:
https://github.com/luaxlou/micro-service-practice.git

配置自動(dòng)集成

這里使用了最新版的jenkins寝优,新版的jenkins使用了pipline。一種新的構(gòu)建方式,使用groovy語法枫耳。

寫起來是挺優(yōu)雅的乏矾,但是學(xué)習(xí)成本頗高。因?yàn)槲臋n不全及有些文檔失效迁杨,筆者不得已反編譯了pipeline插件钻心,才得以調(diào)通。

使用pipeline script

node {
    stage('Preparation') {
        def r = git('https://github.com/luaxlou/micro-service-practice.git')
   }
   stage('Build') {
       dir('seneca-listener') {
          withEnv(["DOCKER_REGISTRY_URL=http://192.168.99.1:5000"]) {

              docker.build("seneca-listener").push("latest")
            
          }
            
       }
               
   }
   
}

開始構(gòu)建铅协,順利的話捷沸,會(huì)看到如下的結(jié)果:

image.png

這是pipeline的特性,可以可視化看到各個(gè)階段的執(zhí)行情況狐史,算是不小的進(jìn)步吧痒给。

訪問私有Registy的API,就可以看到生成的tag骏全。

curl http://192.168.99.1:5000/v2/seneca-listener/tags/list

最后一步苍柏,試試我們的程序

在宿主機(jī)發(fā)布消息:

$ git clone https://github.com/luaxlou/micro-service-practice.git

seneca-clinet 代碼是接口層代碼的示意,可以根據(jù)自己的喜好封裝姜贡。
同時(shí)直接發(fā)送了命令代碼用于測試试吁。

進(jìn)入seneca-clinet 目錄

$  AMQP_URL=192.168.99.1:5672 node index.js

這個(gè)程序會(huì)每隔兩秒發(fā)送一個(gè)命令:

#!/usr/bin/env node
'use strict';

const client = require('seneca')()
    .use('seneca-amqp-transport')
    .client({
        type: 'amqp',
        pin: 'cmd:salute',
        url: process.env.AMQP_URL
    });

setInterval(function() {
    client.act('cmd:salute', {
        name: 'World',
        max: 100,
        min: 25
    }, (err, res) => {
        if (err) {
            throw err;
        }
        console.log(res);
});
}, 2000);

雖然一直在發(fā)命令,你很快就會(huì)發(fā)現(xiàn)命令全部超時(shí)了楼咳。這是因?yàn)檫€沒有消費(fèi)者熄捍,當(dāng)然這些命令也沒有丟失律秃,只不過接口層沒有得到及時(shí)返回。如果應(yīng)用層支持異步的模式治唤,每個(gè)command都有獨(dú)立的id棒动,可以保留id后,以后再過來取宾添。這就很靈活了船惨,一切看需求去封裝接口層即可。

進(jìn)入node2

$ docker run 192.168.99.1:5000/seneca-listener:latest
0|seneca-l | {"kind":"notice","notice":"hello seneca fwunhukrcmzn/1507605332382/16/3.4.2/-","level":"info","seneca":"fwunhukrcmzn/1507605332382/16/3.4.2/-","when":1507605332661}

啟動(dòng)后缕陕,回到seneca-clinet粱锐,發(fā)現(xiàn)之前超時(shí)的命令洒疚,全部接收到了绕德。

{ id: 86,
  message: 'Hello World!',
  from: { pid: 16, file: 'index.js' },
  now: 1507605332699 }
{ id: 44,
  message: 'Hello World!',
  from: { pid: 16, file: 'index.js' },
  now: 1507605332701 }
{ id: 56,
  message: 'Hello World!',
  from: { pid: 16, file: 'index.js' },
  now: 1507605332703 }
{ id: 57,
  message: 'Hello World!',
  from: { pid: 16, file: 'index.js' },
  now: 1507605332706 }
{ id: 58,
  message: 'Hello World!',
  from: { pid: 16, file: 'index.js' },
  now: 1507605332707 }

至此,完整架構(gòu)已經(jīng)構(gòu)建完畢爽醋。

一些未完的事項(xiàng)

1.自動(dòng)集成蔬崩,只需要配置webhook即可恶座。
2.自動(dòng)部署,因?yàn)閐ocker運(yùn)轉(zhuǎn)的方式沥阳,當(dāng)服務(wù)升級時(shí)需要重啟docker進(jìn)程跨琳。方式有很多,比較粗暴的是直接控制宿主機(jī)桐罕,或者類似salt這樣的工具脉让。
目前來說,沒有找到太好的開源方案功炮。個(gè)人傾向于自己開發(fā)agent溅潜,發(fā)布有限的API,用于常規(guī)的部署或者其他任務(wù)薪伏,以及可以定時(shí)收集服務(wù)器的信息滚澜,用于監(jiān)控。這可能會(huì)是筆者的下一個(gè)開源項(xiàng)目毅该。

總結(jié)

這篇文章算是一個(gè)新的里程碑博秫,實(shí)踐的成果將用于后期的架構(gòu)潦牛。docker讓我從傳統(tǒng)的架構(gòu)模式中脫離出來眶掌,同時(shí)也讓我吃了不少苦頭。但這一切都是值得的巴碗。

同時(shí)也是一個(gè)新的開始朴爬,終于從之前的公司出來。未來何去何從橡淆,有很多的未知召噩,但我相信都是美好的母赵。

這也許就是人生的魅力。

Hello World>叩巍凹嘲!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市构韵,隨后出現(xiàn)的幾起案子周蹭,更是在濱河造成了極大的恐慌,老刑警劉巖疲恢,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凶朗,死亡現(xiàn)場離奇詭異,居然都是意外死亡显拳,警方通過查閱死者的電腦和手機(jī)棚愤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來杂数,“玉大人宛畦,你說我怎么就攤上這事∽嵋疲” “怎么了刃永?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長羊精。 經(jīng)常有香客問我斯够,道長,這世上最難降的妖魔是什么喧锦? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任读规,我火速辦了婚禮,結(jié)果婚禮上燃少,老公的妹妹穿的比我還像新娘束亏。我一直安慰自己,他們只是感情好阵具,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布碍遍。 她就那樣靜靜地躺著,像睡著了一般阳液。 火紅的嫁衣襯著肌膚如雪怕敬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天帘皿,我揣著相機(jī)與錄音东跪,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛虽填,可吹牛的內(nèi)容都是我干的丁恭。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼斋日,長吁一口氣:“原來是場噩夢啊……” “哼牲览!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起恶守,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤竭恬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后熬的,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痊硕,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年押框,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了岔绸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡橡伞,死狀恐怖盒揉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情兑徘,我是刑警寧澤刚盈,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站挂脑,受9級特大地震影響藕漱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜崭闲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一肋联、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧刁俭,春花似錦橄仍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至如孝,卻和暖如春宪哩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背暑竟。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工斋射, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留育勺,地道東北人但荤。 一個(gè)月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓罗岖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親腹躁。 傳聞我的和親對象是個(gè)殘疾皇子桑包,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 本博文主要向大家介紹如何使用Spring Cloud和Docker構(gòu)建微服務(wù)平臺(tái)。 什么是Spring Cloud...
    0dd5ba4532c8閱讀 1,150評論 2 15
  • 1. 微服務(wù)架構(gòu)介紹 1.1 什么是微服務(wù)架構(gòu)纺非? 形像一點(diǎn)來說哑了,微服務(wù)架構(gòu)就像搭積木,每個(gè)微服務(wù)都是一個(gè)零件烧颖,并使...
    靜修佛緣閱讀 6,633評論 0 39
  • 一弱左、微服務(wù)將變得輕量級 架構(gòu)需要由人去設(shè)計(jì),這些人被稱為架構(gòu)師炕淮〔鸹穑或許很多人并未授予架構(gòu)師的頭銜,但自己卻從事著架構(gòu)...
    justmilkrain閱讀 5,419評論 10 109
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理涂圆,服務(wù)發(fā)現(xiàn)们镜,斷路器,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • 前言 Docker微服務(wù)架構(gòu)润歉,已漸漸成為服務(wù)器架構(gòu)的主流 模狭。 但是對于Docker在生產(chǎn)環(huán)境的部署方案,目前沒有一...
    luax閱讀 1,274評論 0 4