美文网首页
《微服务架构与实践》

《微服务架构与实践》

作者: 飞飞的蜗牛 | 来源:发表于2017-07-30 00:35 被阅读1635次

    读《微服务架构与实践》,做一下读书笔记:
    传统的架构模式一般采用的是三层架构模式,即大家熟知的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](https://img.haomeiwen.com/i5263185/800b5ca5b8c4aef6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    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. 迭代替换
    

    相关文章

      网友评论

          本文标题:《微服务架构与实践》

          本文链接:https://www.haomeiwen.com/subject/vpcphxtx.html