微服务技术解决方案.docx
《微服务技术解决方案.docx》由会员分享,可在线阅读,更多相关《微服务技术解决方案.docx(74页珍藏版)》请在冰豆网上搜索。
微服务技术解决方案
微服务技术解决方案
微服务是目前最先进的开发方式,使用springcloud、boot开发微服务非常成熟,如何对一个产品进行微服务开发,这里给出详细指导。
1.微服务需求分析和架构设计
微服务是目前最先进的架构设计思想,在许多国内外大互联网公司得到成功的应用,其核心是化繁为简、化整为零,把应用分解为小的服务模块进行独立开发。
微服务的这一特点使其便于部署到容器,对整个开发、测试、运维都发生了革命性影响,有力地支持了devops开发,便于敏捷开发和自动化测试,利于独立部署、维护升级和故障处理,提高效率和质量,带来了一系列优势。
那么,微服务有哪些奥秘呢?
下面从技术原理上进行剖析。
化整为零的思路不是开发一个巨大的单体式的应用,而是将应用分解为小的、互相连接的微服务。
一个微服务一般完成某个特定的功能,比如下单管理、客户管理等等。
每一个微服务都是微型六角形应用,都有自己的业务逻辑和适配器。
一些微服务还会发布API给其它微服务和应用客户端使用。
其它微服务完成一个WebUI,运行时,每一个实例可能是一个云VM或者是Docker容器。
SpringCloud是微服务开发的优秀框架,在springBoot的基础上进行开发,SpringCloud为开发者提供了在分布式系统(如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性Token、全局锁、决策竞选、分布式会话和集群状态)操作的开发工具。
使用SpringCloud开发者可以快速实现上述这些模式。
微服务的特点在于根据业务提炼不同的服务,系统经过拆分,根据不同的功能划分出基础服务和核心服务。
各子系统调用多个核心服务完成功能,核心服务调用多个基础服务。
核心服务之间和基础服务之间不能互相调用。
一般服务模块只能访问自己的数据库,对其他数据库的数据,通过调用其服务提供的接口完成。
要搞好服务抽象,确定服务边界,确定合适的服务粒度,服务高内聚、低耦合,充分复用,还需要合理划分服务的数据库,实现高度自治。
服务的访问分3种方式:
1.采用rest方式同步调用服务,支持不同语言和环境。
2.采用消息方式异步并行调用服务,提高性能和可用性。
3.采用asynTemplate异步调用服务,通过future获取结果。
4.使用rpc方法访问,性能最优,google的grpc很棒。
根据业务的特点,灵活采用上面的方法调用服务,有效地提升系统性能。
微服务支持OOD、DDD,根据业务场景而定架构模式,ODD对于简单业务应用合适,对于复杂的业务应用,采用面向领域设计DDD合适,Axon支持DDD的CQRS模式,和springcloud一起开发。
采用springboot开发功能、springcloudribbon实现负载均衡、config处理配置、zuul做api网关、eureka做服务注册、histrix限流、Sleuth处理log、dashbord、actuator、elk监控、mysql存储、rabbitmq处理消息、redis处理缓存、前端用ngnix实现负载均衡和缓存、rancher+k8s实现docker部署运行、太极框架处理分布式事务。
•复杂度可控:
在将应用分解的同时,规避了原本复杂度无止境的积累。
每一个微服务专注于单一功能,并通过定义良好的接口清晰表述服务边界。
由于体积小、复杂度低,每个微服务可由一个小规模开发团队完全掌控,易于保持高可维护性和开发效率。
•独立部署:
由于微服务具备独立的运行进程,所以每个微服务也可以独立部署。
当某个微服务发生变更时无需编译、部署整个应用。
由微服务组成的应用相当于具备一系列可并行的发布流程,使得发布更加高效,同时降低对生产环境所造成的风险,最终缩短应用交付周期。
•技术选型灵活:
微服务架构下,技术选型是去中心化的。
每个团队可以根据自身服务的需求和行业发展的现状,自由选择最适合的技术栈。
由于每个微服务相对简单,当需要对技术栈进行升级时所面临的风险较低,甚至完全重构一个微服务也是可行的。
•容错:
当某一组建发生故障时,在单一进程的传统架构下,故障很有可能在进程内扩散,形成应用全局性的不可用。
在微服务架构下,故障会被隔离在单个服务中。
若设计良好,其他服务可通过重试、平稳退化等机制实现应用层面的容错。
•扩展:
单块架构应用也可以实现横向扩展,就是将整个应用完整的复制到不同的节点。
当应用的不同组件在扩展需求上存在差异时,微服务架构便体现出其灵活性,因为每个服务可以根据实际需求独立进行扩展。
做微服务架构设计规划,主要分为以下步骤:
•1整体架构设计
•2业务领域抽象、建模
•3服务规划与层次划分、数据库设计与划分
•4服务内流程、数据、契约(接口)定义和技术选型。
在基础交付设施自动化上,如下图所示,体现在自动化、容器化交付这个流程中,在平台化的背景下把团队思维转换为DevOps式的,依托Docker和k8s完成了PaaS平台的对接,同时和QA一起协作完成持续交付流程的建立。
基于对业务的抽象分解,在计算服务层内部,就可以进行更加细分的层次规划,先是垂直拆分为展现层、计算层、数据资源3大纵层,核心的计算层又细分为3个层次,包括业务流程处理层,通过组装下层服务完成功能;业务逻辑组件是自包含,跨产品线、高度复用的组件;下面公共服务组件是一些通用服务。
然后水平划分为多个服务簇。
如下图所示。
2.微服务分布式事务处理
目前微服务事务解决方案有3个:
一、结合MQ消息中间件实现的可靠消息最终一致性二、TCC补偿性事务解决方案三、最大努力通知型方案第一种方案:
可靠消息最终一致性,需要业务系统结合MQ消息中间件实现,在实现过程中需要保证消息的成功发送及成功消费。
即需要通过业务系统控制MQ的消息状态第二种方案:
TCC补偿性,分为三个阶段TRYING-CONFIRMING-CANCELING。
每个阶段做不同的处理。
TRYING阶段主要是对业务系统进行检测及资源预留CONFIRMING阶段是做业务提交,通过TRYING阶段执行成功后,再执行该阶段。
默认如果TRYING阶段执行成功,CONFIRMING就一定能成功。
CANCELING阶段是回对业务做回滚,在TRYING阶段中,如果存在分支事务TRYING失败,则需要调用CANCELING将已预留的资源进行释放。
第三种方案:
最大努力通知型,这种方案主要用在与第三方系统通讯时,比如:
调用微信或支付宝支付后的支付结果通知。
这种方案也是结合MQ进行实现,例如:
通过MQ发送http请求,设置最大通知次数。
达到通知次数后即不再通知。
微服务的关键难点在于分布式事务处理,根据CAP理论,微服务架构采用最终一致性EventualConsistency实现数据的一致性,这需要采用基于Eventprocess分布式事务处理完成。
为此需要创新地设计新的方法来完成事务的处理。
我设计并开发了基于EP的业务系统补偿事务处理框架—太极分布式事务处理框架(TJDTH),可以有效地解决这个问题,其优势在于提高了事务的成功率,故障一键恢复,开发方便,简单实用。
现在的项目都是OOD架构,可以很简单地转换为微服务架构,也都可以采用TJDTH太极分布式事务处理框架处理事务。
当建立微服务时,我们被强迫面对状态的最终一致性问题,这是因为每个微服务都拥有自己的数据库资源,每个数据库都配置了不同的一致性和可用性权衡策略。
最终一致性是一种用于描述在分布式系统中数据的操作模型,在分布式系统中状态是被复制然后跨网络多节点保存,在关系数据库集群中,最终一致性被用来在集群多个节点之间协调数据复制的写操作,数据库集群中这种写操作挑战是:
各个节点接受到的写操作必须严格按照复制的次序进行,这个次序是有时间损耗的,从这个角度看,数据库在集群节点之间的这种状态复制还是可以被认为是
一种最终一致性,所有节点状态在未来某个时刻最终汇聚到一个一致性状态,也就是说,最终达成状态一致性。
当构建微服务时,最终一致性是开发者DBA和架构师频繁打交道的问题,当开始在分布式系统中进行状态处理时,头疼问题更加严重。
结合目前事务处理的精华,开发了太极分布式事务处理框架TJDPH,采用可靠消息服务和补偿处理机制,巧妙地运用数据库的事务处理能力,对服务操作结果进行判断,调用应用系统自身的事务处理功能,从而有效地解决微服务的分布式事务处理问题。
通过使用缓存,解决服务调用的冥等性和消息的冥等性,在事务处理时,采用异步并行调用和消息调用对应的服务,提高了性能。
TJDPH是一个非常优秀的框架,优势在于提高了应用的成功率,自动进行分布式事务处理,事务处理速度快,提高了数据的一致性,把对事务的处理由不可控变为可控,需要人工处理的故障可一键完成,简单快捷,实现事务处理的自动化,框架提供SDK,开发使用方便,高效实用,可以支持任何微服务架构的项目,而且可以运用于任何其他项目,是一个业界领先的世界级成果。
3.自动化测试框架
自动化测试可以一定程度上减轻测试人员负担,提高测试效率,并且通过自动化还可以实现可靠性测试和性能测试。
微服务对devops、jenkins提供良好的支持,利于自动化测试和快速构建发布,支持故障的快速排出。
自动化测试可以快速自动完成大量测试用例,节约巨大的人工测试成本;同时它需要拥有专业开发技能的人才能完成开发,且需要大量时间进行维护(在需求经常变化的情况下)。
安全测试很重要,可以采用CAL9000等工具测试web安全。
用Selenium+Cucumber来完成自动化测试,采用BDD方式进行微服务自动化测试,主要用到下面的软件:
语言:
Java8
框架:
SpringBoot、cloud
构建工具:
maven
WebDriver:
Selenium、Cucumber
单元测试框架:
Junit
3.1.说明
Selenium是目前用的最广泛的WebUI自动化测试框架。
Selenium也是一个用于Web应用程序测试的工具。
Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。
支持的浏览器包括IE、MozillaFirefox、chorme等。
这个工具的主要功能包括:
测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。
测试系统功能——创建衰退测试检验软件功能和用户需求。
支持自动录制动作和自动生成。
Net、Java、Perl等不同语言的测试脚本。
Selenium 是ThoughtWorks专门为Web应用程序编写的一个验收测试工具。
Selenium是一套完整的Web应用程序测试系统,它包含了测试的录制(Selenium IDE)、编写及运行(Selenium RemoteControl)和测试的并行处理(Selenium Grid)。
Selenium的核心Selenium Core基于JsUnit,完全由JavaScript编写,因此可运行于任何支持JavaScript的浏览器上。
与WatiN相同,Selenium也是一款同样使用ApacheLicense2.0协议发布的开源框架。
Selenium 测试直接在浏览器中运行,就像真实用户所做的一样。
Selenium 测试可以在Windows、Linux和MacintoshAnd上的InternetExplorer、Mozilla和Firefox、chrome中运行。
其他测试工具都不能覆盖如此多的平台。
使用 Selenium 和在浏览器中运行测试还有很多其他好处。
下面是主要的两大好处:
通过编写模仿用户操作的 Selenium 测试脚本,可以从终端用户的角度来测试应用程序。
通过在不同浏览器中运行测试,更容易发现浏览器的不兼容性。
Selenium 的核心,也称 browserbot,是用JavaScript编写的。
这使得测试脚本可以在受支持的浏览器中运行。
browserbot负责执行从测试脚本接收到的命令,测试脚本要么是用HTML的表布局编写的,要么是使用一种受支持的编程语言编写的。
使用junit对服务进行单元测试,再先使用Selenium写一个简单的行为级别的ui测试,然后再结合Cucumber完成测试,进行自动化测试。
Android测试.使用UIAutomator测试自动化框架 。
这款工具是谷歌最近发布的。
它支持从4.1开始的安卓版本。
这样就得再选择另一个安卓应用测试工具来做早期版本自动化测试。
UIAutomator能够与各种Android软件产品交互,包括系统中的应用。
这使UIAutomator可以锁定和解锁智能手机或平板电脑。
通过这个工具创建的脚本可以在许多不同的安卓平台上执行。
它可以重现复杂的用户操作动作。
UIAutomator也可以利用一个设备的外部按键,如回放键、音量调节键、开关键来控制。
它可以集成测试框架TestNG。
在这种情况下,UIAutomator可以生成丰富和详细的报告,类似于Ranorex生成报告。
另外,这个工具搜索功能非常快。
软件测试专家发现UIAutomator是一款适用于许多Android平台的移动应用测试。
它是一款最适合安卓应用测试的工具之一,因为它是由谷歌专门为这个操作系统发布的。
目前,安卓操作系统设备上约66%使用的是安卓4.1。
这就是为什么许多自动化测试工程师决定UIAutomator是最合适的解决方案。
自动化从冒烟测试做起,用例设计要尽可能简洁,多做封装,以便降低维护成本。
同时实现自动化的持续集成,更早介入测试,更早发现问题。
在此基础之上,我们还可以通过自动化配合获取性能数据的脚本来实现对应用程序的性能测试。
这些工作可以使得我们的测试覆盖更广,测试力度更深,更好的检测和监控产品质量。
3.2.使用
info.cukes
cucumber-spring
1.2.5
org.seleniumhq.selenium
selenium-java
2.52.0
4.微服务监控
Spring-Cloud-Sleuth是SpringCloud的组成部分之一,为SpringCloud应用实现了一种分布式追踪解决方案,其兼容了Zipkin,HTrace和log-based追踪。
Google的普罗米修斯proemtheus是一个优秀的监控平台,这是一个开源的服务监控系统和时间序列数据库,支持物理机、虚拟机、容器的监控,使用方便灵活,报警、展示功能丰富。
特性:
∙高维度数据模型
∙自定义查询语言
∙可视化数据展示
∙高效的存储策略
∙易于运维
∙提供各种客户端开发库
∙警告和报警
∙数据导出
Springcloud的sleuth特点:
Span:
基本工作单元,例如,在一个新建的span中发送一个RPC等同于发送一个回应请求给RPC,span通过一个64位ID唯一标识,trace以另一个64位ID表示,span还有其他数据信息,比如摘要、时间戳事件、关键值注释(tags)、span的ID、以及进度ID(通常是IP地址)
span在不断的启动和停止,同时记录了时间信息,当你创建了一个span,你必须在未来的某个时刻停止它。
Trace:
一系列spans组成的一个树状结构,例如,如果你正在跑一个分布式大数据工程,你可能需要创建一个trace。
Annotation:
用来及时记录一个事件的存在,一些核心annotations用来定义一个请求的开始和结束
产品需要产生log,记录产品的运行情况,使用elasticsearch+logstash+kibba来完成监控。
Logstash的Grok模式:
filter{
#patternmatchinglogbackpattern
grok{
match=>{"message"=>"%{TIMESTAMP_ISO8601:
timestamp}\s+%{LOGLEVEL:
severity}\s+\[%{DATA:
service},%{DATA:
trace},%{DATA:
span},%{DATA:
exportable}\]\s+%{DATA:
pid}---\s+\[%{DATA:
thread}\]\s+%{DATA:
class}\s+:
\s+%{GREEDYDATA:
rest}"}
}
}
JSONLogbackwithLogstash
为了方便获取Logstash,通常保存log在JSON文件中而不是text文件中,配置方法如下:
依赖建立
∙确保Logback在classpath中(ch.qos.logback:
logback-core)
∙增加LogstashLogback编码 -version4.6的例子:
net.logstash.logback:
logstash-logback-encoder:
4.6
Logback建立
以下是一个Logback配置的例子:
∙使用JSON格式记录应用信息到build/${spring.application.name}.json文件
∙有两个添加注释源-console和标准log文件
∙与之前章节使用相同的log模式
xmlversion="1.0"encoding="UTF-8"?
>
--Exampleforloggingintothebuildfolderofyourproject-->
-build}/${springAppName}"/>
value="%clr(%d{yyyy-MM-ddHH:
mm:
ss.SSS}){faint}%clr(${LOG_LEVEL_PATTERN:
-%5p})%clr([${springAppName:
-},%X{X-B3-TraceId:
-},%X{X-B3-SpanId:
-},%X{X-Span-Export:
-}]){yellow}%clr(${PID:
-}){magenta}%clr(---){faint}%clr([%15.15t]){faint}%clr(%-40.40logger{39}){cyan}%clr(:
){faint}%m%n${LOG_EXCEPTION_CONVERSION_WORD:
-%wEx}"/>
--Appendertologtoconsole-->
--Minimumloggingleveltobepresentedintheconsolelogs-->
INFO
${CONSOLE_LOG_PATTERN}
utf8
--Appendertologtofile-->
${LOG_FILE}
${LOG_FILE}.%d{yyyy-MM-dd}.gz
7
${CONSOLE_LOG_PATTERN}
utf8
--AppendertologtofileinaJSONformat-->
${LOG_FILE}.json
${LOG_FILE}.json.%d{yyyy-MM-dd}.gz
7
UTC
{
"se