docker+jenkins+seneca构建去集中化微服务架构

文章目录

[隐藏]

  • 前言
  • 一、前期准备
  • 二、开始构建
    • 1、搭建Rabbitmq消息服务
    • 2、安装jenkins
    • 3、安装私有的Registry
    • 4、准备代码
    • 5、配置自动集成
    • 6、最后一步,试试我们的程序
    • 7、一些未完的事项
  • 三、总结
前言

在微服务架构中,服务发现一直是一件比较复杂的事。而且服务发现式的架构处理不好,容易产生集中化。同时,微服务的提供,不可避免的需要一些负载均衡方案,实现服务的高可用和可扩展,这无疑增加了很多复杂度。

笔者认为,使用异步、基于消息的方式,可能更适合微服务架构。

基于消息的微服务架构,对于所有微服务的部署条件非常简单,只需要能访问到消息服务即可。同时微服务节点的移除和增加不会影响到服务的提供。相比服务发现的架构,简单太多了,简单即是美。

在这次实践中,使用到了seneca,一个nodejs 微服务框架。seneca,使用seneca-amqp-transport插件,可以轻松构建基于消息的微服务。

下面是架构图:

https://www.processon.com/view/link/59dc2491e4b0ef561379bc25
在这个架构中,我们使用的是标准的seneca定义的命令规范,这可能是所有微服务都需要遵守的一个规范,至于说使用其他语言,也很简单。封装一个seneca命令规范的库即可。不知道官方有没开发,开发起来难度也不会太大。

接口层比较灵活,可以根据上层应用特性,来决定如何封装传输协议,最后将转化成标准命令发送到消息服务。不建议直接访问消息服务,上层应用应保持灵活。

完整的实践代码:https://github.com/luaxlou/micro-service-practice.git

一、前期准备

使用docker-machine创建虚拟机。

关于docker的一些基本用法,可以读上一篇文章:docker+consul基于服务发现的极简web架构实践,这里就不再赘述。

依次创建3台虚拟机:

$ dm create -d "virtualbox” node1  $ dm create -d "virtualbox” node2  $ dm create -d "virtualbox" node3  
二、开始构建

1、搭建Rabbitmq消息服务

消息队列服务,已经成为高并发应用的必备基础服务。我们选用Rabbitmq,你可以换成任意的,遵循amqp协议即可。

使用docker安装很方便,但是生产环境不建议使用docker安装。更推荐的是使用云服务,这样能保证足够高的高可用和扩展性。虽然价格贵点,但是这是唯一的单点,花点钱还是值得的。

直接安装在宿主机上:

$ 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  

这样就启动了一个消息队里服务,并且开放5672端口

2、安装jenkins

jenkins用于自动集成,不然每次构建是个很麻烦的事。

下面的实践是笔者掉了不少坑之后完成的,jenkins在安装过程中会有不少麻烦,而且在mac下安装也会遇到麻烦。

将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  

3、安装私有的Registry

在mac上安装即可

$ docker run -d -p 5000:5000 registry  

文档参考:https://docs.docker.com/registry/spec/api/

4、准备代码

代码使用的是seneca官方的例子,完整的Dockerfile也已经写好。

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进程。

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

5、配置自动集成

这里使用了最新版的jenkins,新版的jenkins使用了pipline。一种新的构建方式,使用groovy语法。

写起来是挺优雅的,但是学习成本颇高。因为文档不全及有些文档失效,笔者不得已反编译了pipeline插件,才得以调通。

使用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")              }           }       }    }  

开始构建,顺利的话,会看到如下的结果:

这是pipeline的特性,可以可视化看到各个阶段的执行情况,算是不小的进步吧。

访问私有Registy的API,就可以看到生成的tag。

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

6、最后一步,试试我们的程序

在宿主机发布消息:

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

seneca-clinet 代码是接口层代码的示意,可以根据自己的喜好封装。
同时直接发送了命令代码用于测试。

进入seneca-clinet 目录

$  AMQP_URL=192.168.99.1:5672 node index.js  

这个程序会每隔两秒发送一个命令:

#!/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);  

虽然一直在发命令,你很快就会发现命令全部超时了。这是因为还没有消费者,当然这些命令也没有丢失,只不过接口层没有得到及时返回。如果应用层支持异步的模式,每个command都有独立的id,可以保留id后,以后再过来取。这就很灵活了,一切看需求去封装接口层即可。

进入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}  

启动后,回到seneca-clinet,发现之前超时的命令,全部接收到了。

{ 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 }  

至此,完整架构已经构建完毕。

7、一些未完的事项

  1. 自动集成,只需要配置webhook即可。

  2. 自动部署,因为docker运转的方式,当服务升级时需要重启docker进程。方式有很多,比较粗暴的是直接控制宿主机,或者类似salt这样的工具。

目前来说,没有找到太好的开源方案。个人倾向于自己开发agent,发布有限的API,用于常规的部署或者其他任务,以及可以定时收集服务器的信息,用于监控。这可能会是笔者的下一个开源项目。

三、总结

这篇文章算是一个新的里程碑,实践的成果将用于后期的架构。docker让我从传统的架构模式中脱离出来,同时也让我吃了不少苦头。但这一切都是值得的。

同时也是一个新的开始,终于从之前的公司出来。未来何去何从,有很多的未知,但我相信都是美好的。

这也许就是人生的魅力。

Hello World!!

原文出处:简书 -> http://www.jianshu.com/p/c41bb7383da8

本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如果侵犯你的利益,请发送邮箱到 [email protected],我们会很快的为您处理。