《微服务架构与实践》

读《微服务架构与实践》,做一下读书笔记:
传统的架构模式一般采用的是三层架构模式,即大家熟知的MVC架构,MVC架构长期以来是大型系统开发的必备架构,按照高内聚,低耦合的要求分为了表示层,业务逻辑层和数据访问层,这三层从逻辑上来说是分开的,但是在物理部署上却是一体的,因此,仍然属于单块架构模式。
单块架构有一定的优势,比如易于开发、易于测试、易于部署和易于水平伸缩。但是相应带来的挑战则是:

  • 维护成本增加
  • 持续交付周期长
  • 新人的培养周期长
  • 技术选型成本高,难以变化
  • 可扩展性差,均依赖于硬件的提升
  • 构建全功能团队难,康威定律指出:一个组织的设计成果,其结构往往对应于这个组织中的沟通结构。单块架构的分工以技能为单位,如UI、前端、后台、数据、运维,因此沟通成本较高。

那么,什么是微服务架构呢,“微”不是指的代码行数,也不是开发时间。重点在于是否符合以下的几点特征:

  • 单一职责:对于每个模块,尽可能独立完成特定的功能;
  • 轻量级通信:通常使用HTTP/JSON,因此与语言无关;
  • 独立性:意味着微服务需要独立的开发、独立的测试、构建已经部署;
  • 远程隔离:通常每个服务都能运行在一个独立的操作系统进程中。

微服务与SOA有关联也有区别,最大的区别在于粒度问题,服务架构是集中还是松散方面。粒度问题主要是SOA主要面向的是多个大系统之间的协同问题,而微服务是多个服务之间的协同;服务架构方面SOA采用的是集中式的服务架构,存在系统总线,协同都需要通过总线完成,而微服务则是松散的服务架构,没有总线,每个服务之间理论上都可以彼此通信。

从微服务的本质来说,微服务具有以下几个特征:

  • 服务作为组件:与传统的组件不同的是,这里的服务可以独立部署;
  • 围绕业务组织团队:强调团队的多样性;
  • 关注产品而非项目:团队服务则整个服务的全生命周期,包括分析、开发、测试、部署、运维;
  • 技术多样性:因为服务较小,可以用最小的服务来做新技术、新方法尝试;
  • 业务数据独立:对于一个复杂系统,可以依据场景使用不同类型的数据库,包括如内存数据库、NOSQL数据库、关系型数据库等;
  • 基础设施自动化:微服务架构的服务较多,因此管理成本较高,需要借助持续集成、持续交付等自动化工具提升运维效率;
  • 演进式架构:做到业务驱动架构,架构服务于业务;

当然,微服务不是银弹,不能解决所有问题,应用微服务架构带来了以下问题:

  • 分布式系统的复杂度:性能方面的带宽和延迟问题,可靠性方面的故障点增多,异步方面的问题排查困难,数据一致性方面的实现难度增高,工具方面的缺失;
  • 运维成本:每个服务都需要独立的配置、部署、监控;
  • 部署自动化:如何有效地构建自动化部署流水线,降低部署成本、提高部署效率,是微服务架构下需要面临的一个挑战;
  • DevOps与组织架构:微服务不仅表现出一种架构模型,同样也表现出一种组织模型;开发者需要承担起服务整个生命周期的责任;
  • 服务间的依赖测试
  • 服务间的依赖管理

实践

在实践部分,本人使用了springboot来构建helloworld程序,使用IntellJ IDEA创建springboot工程,确实效率较高,很快就运行测试可用了。另外,结合之前搭建的docker环境,很快把springboot发布到docker容器里面。其中,springboot没有使用数据库时,需要调整一下部分代码:
在SpringbootApplication类中,默认的注解@SpringBootApplication改为

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})

即排除掉DataSource的配置。
另外,在application.properties中,加入:

spring.session.store-type=none

否则,springboot默认会使用redis缓存session等,但工程中尚未配置和使用redis。
以上配置后能够成功运行springboot的helloworld程序。

接下来是将helloworld部署到docker环境中。首先将helloworld打包成jar包,可以使用maven package打包,或者使用IDE打包均可,打包后的jar包为springboot-0.0.1-SNAPSHOT.jar。打包后,上传到服务器上的工程目录中,假设工程目录为springbootdemo,以下是在此目录下创建的Dockerfile文件:

FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD springboot-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

以上创建docker镜像的方式继承自frolvlad/alpine-oraclejdk8:slim这个镜像,如果本地没有会自动下载。另外,springboot-0.0.1-SNAPSHOT.jar也在第三行被拷贝到容器中并更名为app.jar。最后,在启动时加入“-Djava.security.egd=file:/dev/./urandom”是为了提高启动的速度。
此时,既可以创建docker镜像,使用以下命令:

docker build -t springbootdemo .

注意最后面有一个点,表示当前目录。
构建后可以使用docker images查看所有镜像。
之后可运行容器:

docker run -p 8080:8080 springbootdemo

其中8080:8080代表将主机的8080端口映射到容器的8080端口。
之后,即可使用浏览器访问主机的8080端口来测试helloworld程序了。

持续集成

在构建过程中,有几个工具可以使用,一个是持续集成的工具,以前使用过jenkins,是个不错的工具。另外,针对java可以与jenkins结合,使用findbugs来做代码检查,提高代码质量。
目前jenkins提供了docker的版本,使用:

docker pull kenkinsci/jenkins:lts

即可获得快速可用的镜像。

docker run -p 8080:8080 -p 50000:50000 jenkinsci/jenkins:lts

可快速运行jenkins。

gitlab

另外,也尝试着使用gitlab的docker镜像搭建gitlab环境。

docker pull gitlab/gitlab-ce

下载好镜像之后启动

docker run --detach \
    --hostname gitlab.tl.com \
    --publish 443:443 --publish 80:80 --publish 10022:22 \
    --name gitlab \
    --restart always \
    --volume /srv/gitlab/config:/etc/gitlab \
    --volume /srv/gitlab/logs:/var/log/gitlab \
    --volume /srv/gitlab/data:/var/opt/gitlab \
    gitlab/gitlab-ce:latest

执行完以后,不会直接进入控制台,需要使用以下命令进入docker容器内:

docker exec -it gitlab /bin/bash

在启动gitlab时,一开始可能会出现以下问题:502 Whoops, GitLab is taking too much time to respond。主要问题可能是unicorn原8080默认端口被容器中别的进程已经占用,必须调整为没用过的。
使用以下命令编辑gitlab配置文件:

docker exec -it gitlab vim /etc/gitlab/gitlab.rb

经试验,应该修改以下配置项:

unicorn['port'] = 8888
gitlab_workhorse['auth_backend'] = "http://localhost:8888" 

注意:unicorn['port']与gitlab_workhorse['auth_backend']的端口必须相同
docker restart gitlab重启gitlab。
之后可使用浏览器进行登录,首次登录会提示需要修改密码,注意,用户名是root。
另外,可以使用

docker logs gitlab

查看日志,gitlab为docker容器名称。

安装gitlab也可以不使用docker的方式,在清华大学开源镜像站中有安装的方法,速度比较快。
安装后执行:sudo gitlab-ctl reconfigure即可完成配置并启动。

日志聚合

想要快速的查找和定位问题,日志是其中的重要手段。使用微服务后,系统分散为多个应用或者服务,日志也是分散的,因此需要借助日志聚合工具来做到快速的问题定位。其中splunk是其中的代表工具。splunk有60天的试用期,60天后会自动变为免费版,免费版功能受限。
splunk分为服务端和客户端。服务端为splunk enterprise,客户端是splunk forwarder。安装都较为简单。再次不再展开描述。

监控和告警

监控和告警与上面的日志聚合的需求类似,都是伴随着微服务的运维场景而来。监控方面一般使用的是Nagios,是一个开源工具。
Nagios开源监控网络和主机,同时提供了告警通知功能,具有web界面,方便易用。

Paste_Image.png

Nagios工作原理图
服务器端必须是linux服务器,客户端则无所谓,主要使用代理的方式(Agent)。另外,Nagios的监控分为主动检测和被动检测。

因为微服务较多且分散,所以最好有一个服务描述文件用来记录这些信息:

  • 服务介绍
  • 维护者信息
  • 服务的SLA:即服务可用期
  • 服务运行环境
  • 开发、测试、构建和部署
  • 监控和告警

微服务的轻量级通信机制

微服务采用分布式的部署方式,因此通信问题是其中的重要一环。
常用的通信机制有RPC,以及REST,微服务一般使用REST,因为REST是一种使用HTTP,与开发语言无关、平台无关的通信机制。
REST有四个关键部分:

  • 资源:信息实体,一般用URI标识
  • 表述:在HTTP的信息头中用Accept和Content-Type指定
  • 状态转移:通过资源表述,来达到操作资源的目的
  • 统一接口:使用GET\POST\PUT\DELETE来统一接口
    当然,使用REST需要考虑到性能的问题,它并不是一个低延时通信的最好选择。这时候你可以选择其他RPC框架。

在这里,不得不提到一个协议,即HAL,它的实现是基于REST标准,但是解决了部分REST的问题。如统一、链接等问题。HAL可以用来统一标准化的接口。HAL包含三个部分:

  • 状态:信息实体
  • 链接:资源和其他资源的关系和链接
  • 子资源:主要是用来解释各个字段的定义。

以上的REST主要还是用来做同步通信,如果要做异步通信,还得使用消息队列的方式。消息队列的核心包括:

  • 持久性
  • 排队标准
  • 安全策略
  • 清理策略
  • 处理通知
    消息队列的访问方式分为拉模式和推模式,一般拉模式为一对一,推模式为一对多,多的一方可以成为订阅者。
    消息队列常用的有RabbitMQ,ActiveMQ和ZeroMQ。

还有一种通信机制,在以上方法都相对复杂时,可以选用后台任务处理系统的方式。常用的有Resque(java使用jesque)、Sidekiq以及Delayed_job。

微服务的测试

测试分为单位测试、接口测试、集成测试、组件测试、端到端测试和探索测试。
java的单元测试使用junit,对于模拟数据可以使用mockito框架。
接口测试(契约测试)常使用的框架有Janus、Pact和Pacto。

遗留系统改造为微服务的建议

本书的作者也提供了改造的一些实施路径:

  1. 最小修改
  2. 功能剥离
  3. 数据解耦
  4. 数据同步
  5. 迭代替换
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容

  • 前言 过去几年中,一直从事微服务架构、DevOps以及持续交付的咨询和交付工作。 在这个过程中,感觉到虽然微服务架...
    想飞就飞WL阅读 313评论 0 3
  • 前言 过去几年中,一直从事微服务架构、DevOps以及持续交付的咨询和交付工作。 在这个过程中,感觉到虽然微服务架...
    想飞就飞WL阅读 490评论 0 3
  • 一、微服务将变得轻量级 架构需要由人去设计,这些人被称为架构师。或许很多人并未授予架构师的头衔,但自己却从事着架构...
    justmilkrain阅读 5,425评论 10 109
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,644评论 18 139
  • 微服务最近非常流行,各大互联网公司纷纷采用微服务架构体系,微服务架构模式正在为敏捷部署以及复杂企业应用实施提供巨大...
    Sting阅读 9,069评论 0 57