DockOne微信分享(一八四):基于Spring Cloud的微服务容器化实践

【编者的话】近几年,互联网飞速发展的同时,也推动了云计算、大数据、人工智能的快速落地,数据本身价值也得到提升。互联网发展对应用开发提出了更高要求。首先数据采集的量级和效率提高,传统的单体架构将出现瓶颈,其次是数据联通性的需求,对数据对接必须保证高性能、高安全、高标准。使用微服务架构恰好解决了大部分痛点。 本次主要介绍基于Spring Cloud构建微服务,以及配套的DevOps思路,并着重介绍在Docker容器里如何部署基于Spring Cloud的微服务。 #1、基于Spring Cloud构建微服务 历史总是惊人的相似,合久必分,分久必合。我们经历了“合”:单体架构(软)、计算能力超强的小型机(硬)到“分”:分布式架构的转变,后期可能会将分发挥到了极致(去中心化的分布式,如区块链),最后很可能再经历“合”:计算和存储能力超强的“智人”(集超级计算和存储一身的人工智能)。 单体架构也有自身优势,这里不做详细介绍,大家在做架构选型时可以根据公司组织架构和业务需求综合考虑。 Spring Cloud作为Java语言的微服务框架,它依赖于Spring Boot,是由Pivotal团队提供的全新Web框架。有快速开发、持续交付和容易部署等特点。Spring Cloud提供了开发分布式服务系统的一些常用组件,例如服务注册和发现、配置中心、熔断器、智能路由、微代理、控制总线、全局锁、分布式会话等。 先看看我们使用的一个架构:
图片1.png
  • 服务发现中心(Service Discovery):服务注册与发现组件(选用Erueka)
  • 监控面板(Monitor Dashboard):整合了熔断监控(选用Hystrix)、服务调用链路监控(选用Spring Cloud Sleuth)
  • 日志分析面板(Logging Analyses):基于efk构建的日志采集系统
  • 服务网关(Edge Server):服务网关组件(Zuul & Spring Cloud Security)
  • OAuth认证服务器(OAuth Authorization Server):授权认证模块(Spring Cloud security OAuth2)
  • 配置服务器(Configuration Server):配置中心(Spring Cloud Config & Spring Cloud Bus)
#2、基于微服务架构体系的DevOps思路DevOps带来的不仅是技术挑战,还受公司组织架构和文化影响,这里是从技术角度去实现的思路。先看两个微服务应用案例:##案例1:基于微服务架构的接口开发平台主要提供Restful API服务,服务方式多样,其中一个最简单的案例流程如下:
  • 首先企业通过申请账号、密码和需要调用的API
  • 平台针对申请企业创建可调用API的账号和密码,并将该企业调用端IP加入服务白名单,用户可在平台下载文档、SDK,并进行测试
  • 企业根据用户名、密码去获取token,并在请求header中加入申请的token调用接口
图片2.png
##案例2:基于微服务架构的应用开发Web应用开发采用前后端分离方式,前端采用AngularJS,后端仍是基于Spring Cloud的微服务,整套系统部署到容器云实现CI/CD,架构如下图所示:
图片3.png
微服务引入增加了团队配合、测试、运维等后续一系列操作的复杂度,必须考虑自动化,因此需要有一套CI/ CD方案应对:
图片4.png
大致流程:[list=1]
  • 研发完成本地开发和测试提交代码
  • 代码连同Dockerfile等构建文件一起push到GitLab(可以自己搭建)
  • 代码提交触发Jenkins自动构建
  • Jenkins调用单元测试、代码检查等测试任务,如果测试通过自动构建Docker镜像
  • Jenkins将构建好的镜像推送到私有镜像仓库(自己搭建Harbor镜像库)
  • Jenkins调用容器管理平台(我们使用的Rancher)的接口进行升级
  • 容器管理平台拉取镜像完成部署(测试环境or生产环境)
  • 说明:这里我们不仅使用了Docker,还选用容器编排工具构建了容器云平台,以方便我们快速实现CI/CD。大家可以根据自己情况选择,如Kubernetes、Rancher(Rancher 2.0以后底层使用的编排工具也是Kubernetes)等。#3、Spring Cloud基于Docker的实践我们使用Docker,主要因为以下4点:[list=1]
  • Docker提供一个简单、轻量的建模方式
  • Docker使团队职责的逻辑分离
  • 可以实现快速高效的开发生命周期
  • 团队使用面向服务的架构
  • 以下介绍如何构建Docker镜像和配置细节。##1. 项目目录Dockerfile及相关文件一般放到项目子目录,由开发维护。这种方式对研发提出了更高的技能要求,这也是近期全栈工程师比较火的一个原因。当然,具体协作方式还是根据公司情况定。以下是我们的项目目录:
    图片5.png
    ##2、编写Dockerfile(供参考)注:配合自动化工具使用效果更好。
    FROM harbor.jry.com/library/alpine-jdk-time:slimADD *.jar service.jarCOPY formFile /ENTRYPOINT [ "sh", "-c", "java -jar service.jar" ] 
    ##3、模块配置我们将Spring Cloud相关的配置放到了bootstrap.yml文件,需要注意的配置如下:
    图片6.png
    注意标红部分,服务要以IP地址方式注册到注册中心,否则注册中心无法做心跳检测,因为容器之间默认无法通过hostname通信。我们也可以搭建内部DNS方式解决此问题。服务发现中心建议配置成高可用(比如两个注册中心互相注册),也需要上图配置。##4、打包构建这里截取了Jenkins里的打包及构建命令:[list=1]
  • 打包
  • 图片7.png
    [list=1]
  • 构建
  • 图片8.png
    ##5、容器启动配置(docker-compose.yml)
    version: '2'services:  zipkin:    image: harbor.jry.com/zipkin:v1.0.1    environment:      eureka.client.service-url.defaultZone: http://discovery:8761/eureka/    stdin_open: true    tty: true     links:    - discovery2:discovery     volumes:    - /data/log:/target/log    ports:    - 9411:9411/tcp
      service-config:    image: harbor.jry.com/service-config:v1.0.1    hostname: config    environment:      eureka.client.service-url.defaultZone: http://discovery:8761/eureka/    stdin_open: true    tty: true    links:    - discovery2:discovery    volumes:    - /data/log:/target/log    ports:    - 8889:8889/tcp
      service-monitor:    image: harbor.jry.com/service-monitor:v1.0.1    environment:      eureka.client.service-url.defaultZone: http://discovery:8761/eureka/    stdin_open: true    tty: true    links:    - discovery1:discovery    volumes:    - /data/log:/target/log
      discovery2:    image: harbor.jry.com/service-discovery    environment:      eureka.client.service-url.defaultZone: http://discovery:8761/eureka/    stdin_open: true    tty: true    links:    - discovery1:discovery    volumes:    - /data/log:/target/log    ports:    - 8762:8761/tcp
      discovery1:    image: harbor.jry.com/service-discovery:v1.0.1    environment:      eureka.client.service-url.defaultZone: http://discovery:8761/eureka/    stdin_open: true    tty: true    links:    - discovery2:discovery    volumes:    - /data/log:/target/log
      daas-monitor:    image: harbor.jry.com/daas-monitor:v1.0.1    environment:      eureka.client.service-url.defaultZone: http://discovery:8761/eureka/    stdin_open: true    tty: true    links:    - discovery1:discovery    volumes:    - /data/log:/target/log    ports:    - 9080:9080/tcp
      proxy-server:    image: harbor.jry.com/service-proxy:v1.0.1    environment:      eureka.client.serviceUrl.defaultZone: http://discovery:8761/eureka/    stdin_open: true    links:    - discovery1:discovery    tty: true    links:    - oauth2-server:oauth    volumes:    - /data/log:/target/log    ports:    - 8111:8443/tcp
      oauth2-server:    image: harbor.jry.com/oauth2-cg:v1.0.1    environment:      eureka.client.serviceUrl.defaultZone: http://discovery:8761/eureka/    stdin_open: true    links:    - discovery2:discovery    volumes:    - /data/log:/target/log    tty: true    ports:    - 9999:9999/tcp
    说明:
    • Zipkin:服务调用链路监控
    • service-config:配置中心服务
    • service-monitor:断路监控服务
    • discovery1, discovery2:高可用的服务发现中心
    • daas-monitor:自研的监控面板,整合其他监控服务
    • proxy-server:服务网关
    • oauth2-server:OAuth认证服务器
    注:[list=1]
  • 虽然使用的配置文件,但维护起来还是很麻烦,所以建议使用编排工具,一般会提供部分DevOps工具集
  • 上述各服务模块可以根据实际情况启动多个相同容器,以保证高可用
  • 以上各服务模块做了磁盘映射,主要为采集日志,这里我们使用的EFK,时间关系暂不展开。
  • #Q&A Q:WSO2的API Manager会将所有流量都统一到他这里进出,如何解决统一API网关的大流量问题?

    A:API Manager是可以拆开的,分开部署,比如调用你接口走网关模块,可以做高可用。当然不拆开也可以做高可用,前面加负载均衡。

    Q:Eureka在生产上的Kubernetes中是如何做到高可用和动态扩容的?

    A :好问题,Eureka我们目前是指定数量,可以结合脚本(或代码)做动态扩容和高可用。目前我们Hadoop就是结合代码做到的。

    Q:服务之间二阶段事务控制一般怎么做?或者说有没有现成工具或代码?服务间用http靠谱还是其他协议靠谱?

    A:这个网上有一些思路比如补偿的方式,还有就是通过流数据库(Kafka),事件驱动的方式。我们目前正在尝试这种方式。

    未标题-1.jpg

    以上内容根据2018年7月31日晚微信群分享内容整理。分享人刘凯,现就职于中金云金融(北京)大数据科技股份有限公司,负责应用架构设计及大数据平台建设。2015年开始实践微服务架构,参与基于Dubbo的微服务搭建,并实现部分源码优化、实现安卓端SDK,2016年参与公司区块链应用预研,同年开始进行基于Spring Cloud的微服务架构实践,2017年作为团队核心人员完成容器云搭建、大数据平台搭建及实践、DevOps工具集优化。DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesd,进群参与,您有想听的话题或者想分享的话题都可以给我们留言。

    0 个评论

    要回复文章请先登录注册