Ling3

来自ling
跳转至: 导航搜索

目录

总体设计

设计目的

最近重新整理的自己的架构,新的架构基本满足解决下面问题的需要.在这里详细描述新架构,并整理第一版的概要设计

最近项目中遇到如下问题和解决方案

  • 同时面对多个客户,交付客户的产品其实还在研发阶段,从业务和实现上导致同时有多个版本
    • 这种情况比较特殊,每个实施都需要赶进度,在人力和需求都达到极限的情况下确实没有什么好的解决方法,但功能的实现上需要总体管控,那些功能先做,那些功能后实现.通过实现的时间差尽量保证有一个主线版本,或一个功能只在一个地方开发.
    • 当新实施开始的时候,力求在管理上用主线版本去实施,除了按需求去整合需要的需求到主线版本然后给新实施使用外.新实施主要将精力放在数据接口上,bug和可以放在主线上开发,并根据每个实施点人员的空闲程度来安排新功能的开发
  • 项目部署时,一般有dev,uat,prd三个环境,每次打包后都需要调整配置文件
    • 这个解决方案就比较多了,可以使用自动部署工具,或使用ant,maven等编译工具编写脚本
    • 但我始终觉得这不是一个最简单的方式,当环境越来越多的时候,一不小心就会出问题
    • 最好的解决方式当然是每个环境都使用相同的部署文件.通过jvm参数等配置的方式来达到因环境不同参数不同
    • 这种方式需要注意,不能因为新增加参数而需要去更改每个部署的jvm参数等配置,所有jvm中配置的应该主要是"方案"名,而不是具体的参数
    • 这些jvm参数可以配置在容器,比如tomcat的启动脚本上,一旦配置完成,应该不再需要更改,即使需要修改,也应该是业务的变化导致的.修改的应该是部署文件.
    • 即使需要不修改部署文件而达到修改配置目的,也需要良好的覆盖机制,来达到修改jvm参数就能达到效果
    • 最好是能有独立的配置服务,每个模块和环境都从配置服务中获取自己的配置信息,当需要时可以不停机的情况下刷新每个环境配置信息
    • 通过研究发现 spring cloud config模块是最接近以上功能的实现
  • 接口重复开发,没有形成统一规范,也没有使用好的接口管理工具
    • 当产品真正稳定后,实施主要的内容其实就是业务数据的接口开发
    • 实施接口最好是己方给出业务数据接口规范,由对方开发
    • 当必须使用对方给出的接口规范时,需要有一套框架能完成对方数据格式到己方数据格式的配置功能,已完成映射
    • 对方给的数据到实际业务数据必须进行隔离.必须有接口数据表和业务数据的概念,接口数据到业务数据只能有一套程序,实施的时候主要完成上一步的配置映射功能来取数到接口数据表
  • 税控接口,航信和百旺实现方式完全不同(包含服务器版,单机版,webservice版本,dll-xml,dll-javascript-object各种接口),但在我们自己系统中需要业务保持一致
    • 恶心的东西,各种版本,各种规范,总共就2家,还能出来7,8种风格迥异的接口
    • 主要的思路还是各种数据规范,不管是前端接口还是后端接口,直接交给后端进行的挡板进行数据清洗和规范,然后由后端处理后返回统一数据,再由挡板返回给各类接口各自的数据.
    • 实施时根据接口类型选择合适的挡板就行了,当然,前端也有些微变化.
  • 客户全国各地,业务人员不能独立完成系统部署,并完成系统最基础数据的初始化,系统部署过于复杂,比如tomcat安装,数据库初始化,集群安装和配置,开发人员也需要一定经验才能完成
    • 如何简化部署?spring boot,或者docker.以产品形式做一键安装脚本
    • 新的产品即使是发布在云上的,也应该考虑如何封装和打包成一个一键安装的内容
  • 当子系统多了过后,各个子系统间如何管理web静态资源的依赖(java 代码已经由maven和svn完成依赖和版本管理),避免系统间资源通过copy的方式来保持一致.
    • 使用spring boot 可以将静态资源放在classpath下的功能,并合理安排maven依赖来实现

总体思路

  • 依托spring boot的依赖管理技术和命令行启动应用技术
  • 依托sping cloud达到以下基本功能
    • 一个jar包就能组建单个应用的集群环境和通过设置jvm启动参数使用不同的配置
    • 使用一个bat文件或sh文件就能搭建自带配置中心.集群和路由的环境,方便部署
    • 如果有需要使用docker技术简化数据库,mq,等的配置
  • 借鉴ibzsys实现开发配置的可视化和面向BA
  • 使用bootstrap和angurjs实现页面的动态布局,并可以迁移到移动端,并提供移动端开发支持
  • 使用restful方式暴露接口,提供服务.

技术选型

微服务基础设施

  • 服务注册、发现、负载均衡和健康检查
  • 根据应用选择合适的通信协议和数据协议. 例如可以选用thrift, protocol buffer或REST.
  • 服务负载均衡. 一个服务一般会部署多个实例. 如果使压力均匀分布是需要考虑的问题.
  • 网关路由与限流
  • 服务容错
  • 服务框架
  • 配置中心
  • 服务自动化发布
  • 服务监控
  • 服务告警

主流微服务框架

JVM上比较热门的三个微服务框架: Finagle, Spring Cloud(NetflixOSS), Dubbox.更多参考微服务架构的基础框架选择:Spring Cloud还是Dubbo

  • Finagle

是Twitter在2011年开源的一款RPC框架, 在国外使用较多, 例如Pinterest, Nest, Tumblr, 感兴趣的可以Google. Finagle有着较为丰富的生态圈, 例如可以使用Finch很方便的实现REST, 使用Finagle OAuth2实现OAuth认证, 使用zipkin实现服务监控. Finagle使用Scala开发, 官方宣称同时支持Scala和Java语言.

  • Dubbo/Dubbox

Dubbo是阿里巴巴服务化治理的核心框架,并被广泛应用于阿里巴巴集团的各成员站点。Dubbox是当当对Dubbo的一些升级和持续维护

  • Spring Cloud(NetflixOSS)

从命名我们就可以知道,它是Spring Source的产物,Spring社区的强大背书可以说是Java企业界最有影响力的组织了,除了Spring Source之外,还有Pivotal和Netfix是其强大的后盾与技术输出。其中Netflix开源的整套微服务架构套件是Spring Cloud的核心

  • Dubbo与Spring Cloud对比

选择Spring Cloud主要出于

  • Dubbo已经玩过了
  • Spring Cloud比较新,且出身名门,比较适合我当前的技术积累.
  • Dubbo更侧重于性能,Spring Cloud侧重于整合.对个人发展和学习

Dubbo and spring cloud.PNG

微服务架构

Microservice1.png

微服务组件介绍

eureka 服务发现

Eureka1.png

一个RESTful服务,用来定位运行在AWS地区(Region)中的中间层服务。由两个组件组成:Eureka服务器和Eureka客户端。 Eureka服务器用作服务注册服务器。Eureka客户端是一个java客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支 持。Netflix在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡。

Open source service discovery.png

Ribbon 主要提供客户侧的软件负载均衡

Ribbon1.png

主要提供客户侧的软件负载均衡算法。 Ribbon客户端组件提供一系列完善的配置选项,比如连接超时、重试、重试算法等。Ribbon内置可插拔、可定制的负载均衡组件。

下面是用到的一些负载均衡策略:

  • 简单轮询负载均衡
  • 加权响应时间负载均衡
  • 区域感知轮询负载均衡
  • 随机负载均衡

Ribbon中还包括以下功能:

  • 易于与服务发现组件(比如Netflix的Eureka)集成
  • 使用Archaius完成运行时配置
  • 使用JMX暴露运维指标,使用Servo发布
  • 多种可插拔的序列化选择
  • 异步和批处理操作(即将推出)
  • 自动SLA框架(即将推出)
  • 系统管理\/指标控制台(即将推出)
hystrix 断路器

Hystrix1.png

断路器可以防止一个应用程序多次试图执行一个操作,即很可能失败,允许它继续而不等待故障恢复或者浪费 CPU 周期,而它确定该故障是持久的。断路器模式也使应用程序能够检测故障是否已经解决。如果问题似乎已经得到纠正,应用程序可以尝试调用操作。

Hystrix2.png

断路器增加了稳定性和灵活性,以一个系统,提供稳定性,而系统从故障中恢复,并尽量减少此故障的对性能的影响。它可以帮助快速地拒绝对一个操作,即 很可能失败,而不是等待操作超时(或者不返回)的请求,以保持系统的响应时间。如果断路器提高每次改变状态的时间的事件,该信息可以被用来监测由断路器保 护系统的部件的健康状况,或以提醒管理员当断路器跳闸,以在打开状态。

Hystrix3.png

流程图

Hystrix4.png

zuul api-gateway

Zuul1.png

类似nginx,反向代理的功能,不过netflix自己增加了一些配合其他组件的特性。

Spring Cloud Config 分布式配置

提供restful形式的配置信息

配合Spring Cloud Bus实现动态的配置更新

Sping config1.jpeg

Spring Cloud Config1.png

/actuator/refresh methods=[POST]
/actuator/bus-env/{destination}],methods=[POST]
/actuator/bus-env],methods=[POST
/actuator/bus-refresh/{destination}],methods=[POST]
/actuator/bus-refresh],methods=[POST]
feign 客户端

netflix feign是一个类似retrofit进行http调用框架,Feign makes writing Java http clients easier 使得编写Java HTTP 客户端编写更方便

turbine 聚合的monitor

聚集同一个微服务的相同的commandKey、Threadpool、commandGroupKey数据进行聚合

graphite 指标监控

Collectd是一个著名的、持续很久的Linux项目,通常用于监控基础设施级别的度量,比如CPU、内存、I/O利用率、网络吞吐量和延迟,当然Graphite在应用程序级的度量和业务级的度量方面也很不错。

Graphite是一个开源实时的、显示时间序列度量数据的图形系统。Graphite并不收集度量数据本身,而是像一个数据库,通过其后端接收度量数据,然后以实时方式查询、转换、组合这些度量数据。Graphite支持内建的Web界面,它允许用户浏览度量数据和图。

Graphite有三个主要组件组成:

  • Graphite-Web 这是一个基于Django的Web应用,可以呈现图形和仪表板
  • Carbon 这是一个度量处理守护进程
  • Whisper 这是一个基于时序数据库的库

Graphite的整体架构图

Graphite1.png

更多参考Graphite详解

docker 服务自动化发布

概要设计 lv1

总体架构

Spring cloud.png

技术选型

参考

概要设计 lv2

cloud.config

  • 虽然cloud.config支持git,svn形式的配置控制,但为了减少对第三方程序的支持和减少实施部署的难度,cloud.config主要使用文件的方式来管理配置,结合profile来获取需要的配置信息
  • 支持数据库扩展,但无数据库也能运行
  • 提供数据库加密界面,将数据库加密为字符串,供jvm配置
  • 当从jvm获取到数据库配置,并且正常启动后支持数据库形式的配置和相关界面
  • 需提供接口,来展示配置分组,配置值和配置方案等设置

Config server1.png

约定

  • 约定大于配置
  • 跨数据库时,优先使用分模块

模块介绍

集中配置中心

  • 相关技术选型与方案参考
  • 其他方案disconf

基本介绍

  • 模块名称deloitte.cloud.configserver
  • 为各个子模块和各个不同的环境提供统一的配置管理.
  • 更多内容参考deloitte.cloud.configserver

多环境解决方案

配置中心集群方案

  • 启动为集群

window

 set BASE_DIR=D:\workspace\source\deloitte.cloud.parent\deloitte.cloud.configserver
 start java -jar %BASE_DIR%\target\deloitte.cloud.configserver-1.0.0.jar --server.port=8888 /S
 start java -jar %BASE_DIR%\target\deloitte.cloud.configserver-1.0.0.jar --server.port=8889 /S

linux

  • 集群的使用
--spring.cloud.config.uri=http://localhost:8888/

或通过service-id的方式发现注册在集群中的服务使用

spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.service-id=LING-CLOUD-CONFIG
  • 集群环境

将服务以名称LING-CLOUD-CONFIG注册到服务中心

客户端用下面方式使用

spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.service-id=LING-CLOUD-CONFIG

服务注册与发现中心

基本介绍

zookeeper和eureka的使用场景

注册中心的集群环境

  • 集群的使用
eureka.client.serviceUrl.defaultZone=http://<peer1host>:<peer1port>/eureka,http://<peer2host>:<peer2port>/eureka

服务路由与负载均衡

基本介绍

客户端负载均衡

客户端负载均衡原理

基于spring cloud的服务端负载均衡原理与最佳实践

服务路由与负载均衡集群方案

服务监控与控制

服务监控与控制 基本介绍

参考Dapper,大规模分布式系统的跟踪系统 分布式服务追踪 Spring Cloud Sleuth 使用Spring Boot Actuator、Jolokia和Grafana实现准实时监控

微服务架构中完成一项功能经常会在多个服务之间远程调用(RPC),形成调用链。每个服务节点可能在不同的机器上甚至是不同的集群上,需要能追踪整个调用链,以便在服务调用出错或延时较高时准确定位问题。

以下内容引用 Dapper,大规模分布式系统的跟踪系统 译文 ,介绍了分布式服务追踪的重要性以及设计原则:

当代的互联网的服务,通常都是用复杂的、大规模分布式集群来实现的。互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心。因此,就需要一些可以帮助理解系统行为、用于分析性能问题的工具。
举一个跟搜索相关的例子,这个例子阐述了Dapper可以应对哪些挑战。比如一个前段服务可能对上百台查询服务器发起了一个Web查询,每一个查询都有自己的Index。这个查询可能会被发送到多个的子系统,这些子系统分别用来处理广告、进行拼写检查或是查找一些像图片、视频或新闻这样的特殊结果。根据每个子系统的查询结果进行筛选,得到最终结果,最后汇总到页面上。我们把这种搜索模型称为“全局搜索”(universal search)。总的来说,这一次全局搜索有可能调用上千台服务器,涉及各种服务。而且,用户对搜索的耗时是很敏感的,而任何一个子系统的低效都导致导致最终的搜索耗时。如果一个工程师只能知道这个查询耗时不正常,但是他无从知晓这个问题到底是由哪个服务调用造成的,或者为什么这个调用性能差强人意。首先,这个工程师可能无法准确的定位到这次全局搜索是调用了哪些服务,因为新的服务、乃至服务上的某个片段,都有可能在任何时间上过线或修改过,有可能是面向用户功能,也有可能是一些例如针对性能或安全认证方面的功能改进。其次,你不能苛求这个工程师对所有参与这次全局搜索的服务都了如指掌,每一个服务都有可能是由不同的团队开发或维护的。再次,这些暴露出来的服务或服务器有可能同时还被其他客户端使用着,所以这次全局搜索的性能问题甚至有可能是由其他应用造成的。举个例子,一个后台服务可能要应付各种各样的请求类型,而一个使用效率很高的存储系统,比如Bigtable,有可能正被反复读写着,因为上面跑着各种各样的应用。
上面这个案例中我们可以看到,对Dapper我们只有两点要求:无所不在的部署,持续的监控。无所不在的重要性不言而喻,因为在使用跟踪系统的进行监控时,即便只有一小部分没被监控到,那么人们对这个系统是不是值得信任都会产生巨大的质疑。另外,监控应该是7x24小时的,毕竟,系统异常或是那些重要的系统行为有可能出现过一次,就很难甚至不太可能重现。那么,根据这两个明确的需求,我们可以直接推出三个具体的设计目标:
  • 低消耗:跟踪系统对在线服务的影响应该做到足够小。在一些高度优化过的服务,即使一点点损耗也会很容易察觉到,而且有可能迫使在线服务的部署团队不得不将跟踪系统关停。
  • 应用级的透明:对于应用的程序员来说,是不需要知道有跟踪系统这回事的。如果一个跟踪系统想生效,就必须需要依赖应用的开发者主动配合,那么这个跟踪系统也太脆弱了,往往由于跟踪系统在应用中植入代码的bug或疏忽导致应用出问题,这样才是无法满足对跟踪系统“无所不在的部署”这个需求。面对当下想Google这样的快节奏的开发环境来说,尤其重要。
  • 延展性:Google至少在未来几年的服务和集群的规模,监控系统都应该能完全把控住。
  • 一个额外的设计目标是为跟踪数据产生之后,进行分析的速度要快,理想情况是数据存入跟踪仓库后一分钟内就能统计出来。尽管跟踪系统对一小时前的旧数据进行统计也是相当有价值的,但如果跟踪系统能提供足够快的信息反馈,就可以对生产环境下的异常状况做出快速反应。

分布式服务追踪

  • Spring-Cloud-Sleuth是Spring Cloud的组成部分之一,为SpringCloud应用实现了一种分布式追踪解决方案,其兼容了Zipkin, HTrace和log-based追踪
  • 在 spring cloud 技术栈中, spring cloud Sleuth 借鉴了 Google Dapper 的实现, 提供了分布式服务追踪的解决方案。
  • Spring Cloud Sleuth 提供了两种追踪信息收集的方式,一种是通过 http 的方式,一种是通过 异步消息 的方式,生产环境常用的 异步消息 的收集方式。
  • 使用zipkin收集追踪信息并展现,在服务调用的过程中 spring cloud sleuth 自动帮我们添加了 TraceId 、 SpanId 等服务追踪需要的内容。现在还需要集中收集这些信息,并提供可视化界面把这些信息展示出来。
Zipkin 是 Twitter 的一个开源项目,允许开发者收集各个服务上的监控数据,并提供查询接口。spring cloud sleuth 对 zipkin 做了封装,提供了两种数据保存方式:内存和 mysql 更多参考Zipkin

服务暴露于发现

基本介绍

服务暴露

服务的文档化与测试

异构服务整合最佳实践

服务发现

api授权

api监控

消息总线

Cloud构建微服务架构(七)消息总线 Spring Cloud构建微服务架构(七)消息总线(续:Kafka)

消息总线基本介绍

使用Kafka/RabbitMQ做消息总线,更多参考Kafka RabbitMQ

Spring-cloud-bus-configserver.png

MQ选型对比文档

MQ RabbitMQ RocketMQ ActiveMQ Kafka.png

/bus/refresh
/bus/refresh?destination=customers:9000
/bus/refresh?destination=customers:**

基于restful服务的前端最佳实践

基本介绍

服务发现与使用

技术选型

bootstrape与angularjs

移动端程序打包与发布

基础模块

pl.base

pl.core

pl.db

pl.security

  • 采用服务器无用户状态设置
  • 客户端通过localStorage获取用户信息和状态
  • 每次请求将LING-SID写入header
  • 服务器通过LING-SID从缓存中获取用户信息和状态
  • 请求完成,更新localStorage中相关缓存内容,用于更新用户的当前用户信息在集群中传播

web.core

ng-table的最佳使用实践

行编辑

数据导出

form数据导出

基于ng-table的数据导出

autoproject

核心思想

  • 模块管理界面也是用此系统完成开发
  • 类似ibzsys,通过界面驱动开发,让业务人员能看懂,能理解,能参与70%以上开发工作
  • 整合Jenkins,docker等实现自动部署
  • 前后端分离,设计时前端采用npm+mock,实现即时预览.能够在及时预览与完整预览(需要Jenkins发布docker重启)之间切换
  • 将配置时录入的测试数据用于即时预览
  • 模板文件使用git管理.便于版本比较
  • 项目配置最好也能使用文件形式而非数据库形式管理,从而达到能用git管理的目的-->数据库保存配置,输出配置文件用于git管理
  • 能自动完成数据库结构同步(hibernate)
  • 同一网段能完成开发-->测试-->生产的自动部署,不同网段,能下载出相应的发布文件

技术选型

  • ibzsys:设计驱动开发,不断装大程序的能力,并能通过配置解放程序员的时间,并便于传承,减少沟通和学习成本
  • Jenkins:自动编译与发布
  • docker:便于Jenkins实现快速发布,减少配置成本
  • git:管理配置文件和模板文件版本
  • 前后端分离:后台spring boot,前端支持antd-->angular-->vue,并逐步扩展前端的模板

实现

autoproject antd实现

doc

blog程序和gitboot的配合使用

admin

ling3常用代码

ling3常用代码

dubbo版本

ling3-dubbo