目录
一、面向服务架构SOA
1.SOA概念
SOA所解决的问题
SOA的特性
SOA的特征
SOA组成要素
2.SOA服务设计原则
3.SOA协作模式
4.SOMA开发方法
SOMA生命周期
敏捷开发
服务外包与众包
5.ESB原理与机制
ESB解决的问题
ESB的功能
ESB关键技术
ESB的优势
6.服务组合与BPEL
服务编制
服务编排
BPEL
BPMN
Web2.0
Web3.0
服务Mashup
7.面向服务架构技术演进
8.Dubbo(携程)
Dubbo落地
Cdubbo功能扩展
二、面向服务开发技术
1.面向服务开发基础
①Web开发基础
②Web开发技术演进
③Spring Boot
2.RPC(远程过程调用)
概念
RPC分类
主流的Web服务实现方案
常见的RPC技术和框架
XML-RPC
JSON-RPC
3.WebService
概念
WebService体系结构
WebService三种基本元素
WebService栈
WebService开发
WebService与RPC
WSDL
UDDI
SOAP
4.RESTful WebService
REST特性
REST优点
软件服务开发技术对比
三、分布式服务框架
1.分布式服务框架理论
背景
分布式服务框架
分布式服务框架特性
分布式服务框架可靠性
2.Zookeeper
ZooKeeper的元素
ZooKeeper中的角色
ZooKeeper的消息同步
ZooKeeper的服务注册
分布式CAP理论
3.Dubbo
Dubbo基本概念
Dubbo总体架构
基于Dubbo的服务系统开发
4.Netty
四、微服务架构
1.微服务基本理论
概念
微服务与SOA
微服务设计原则
2.微服务消息机制
同步消息与异步消息
消息接口
3.Docker
服务器运行环境
Docker概念
Docker的特点
Docker架构
4.调度工具
Kubernetes
5.DevOps
概念
微服务与持续集成
五、服务质量评估
1.服务质量概念
2.服务质量特征
3.服务质量指标
4.服务质量监控与评价
5.服务级协议
一、面向服务架构SOA
把信息系统中需要整合的业务使用服务联系起来。
解决企业级信息系统中“信息孤岛” “重复造轮子” 等问题
1.SOA概念
SOA所解决的问题
竖井式应用架构
重复开发所带来的大量浪费和效率损失
产生复杂的基础设施和繁杂的系统架构
系统间集成是一个巨大的挑战
SOA面向服务、面向集成,是建设企业级应用系统的有效解决方案。
SOA是一种范式,目的是实现和维护跨越大型分布式系统的业务流程,通过企业服务总线达成互操作性,将各业务系统的衔接松耦合。
在SOA环境中,网络上的节点以独立服务的形式将自己的资源开放给网络上其他参与者,其他参与者按一种标准的方式使用资源。
与传统点对点架构不同,各种SOA都由松耦合、高度可互操作的应用服务构成。
SOA是一种面向服务的架构,是由不同的技术、模型和事件组成的结合体。
S 是指各种编程语言实现的Web服务,Web服务仅仅是SOA拼图中的一块。
A是指一种架构。如何将上述Web服务组合成符合客户需求的业务模型。
SOA是一种范式、概念、方法,主要是针对各异的大型分布式系统。
SOA的特性
业务驱动:定义一个以业务为中心的技术架构,可以与业务演化随着时间的推移不断同步。
供应商中立:SOA源于主要的技术平台,但与各供应商保持中立。
企业中心化:服务被定位为企业资源,不属于任何一个应用程序或解决方案。
组合中心化:SOA更注重将软件程序设计为不仅仅是可重用的资源,而是作为更加灵活的资源,服务必须是可组合的。
SOA的特征
可从外部访问
松散耦合
可重用的服务
服务接口设计管理
标准化的服务接口
支持各种消息模式
精确定义的服务契约
SOA组成要素
2.SOA服务设计原则
(1)标准化服务合约原则
§ 合约:任何两个程序或程序逻辑单元之间需要连接时,就需要某种类型的技术合约。
§ 在同一个服务库中的服务遵循共同的合约设计标准。
§ 使用一致的数据模型,将会减少对数据转换的需要。
§ 使得服务的目标和能力能够比较容易和直观地理解。
§ 服务易于被调用。
(2)服务松散耦合原则
§ 耦合:软件程序组件之间的依赖关系。
§ 降低服务合约对消费者的耦合要求。
§ 降低耦合程序可以增强服务自身的内聚性。
§ 降低服务和消费者之间的影响,有利于其各自的演化。
(3)服务抽象原则
§ 抽象:隐藏在程序中而其他程序不绝对需要的信息。
§ 服务合约仅包含必要的信息。
§ 保持合约的数量,以及合约内容细节的简练和平衡,防止对额外服务细节不必要的访问。
(4)服务可复用性原则
§ 服务是可复用的企业资源。
§ 服务允许被不断的利用,获得更高的使用回报。
§ 服务可以被不同的消费者调用,实现不同的业务任务。
§ 服务的可复用性是设计的核心原则,是实现与SOA相关的许多战略目标的关键
(5)服务自治原则
§ 自治:服务可以独立执行自身核心逻辑的能力。
§ 服务在其底层的运行时环境中拥有高级别的控制权。
§ 应提高一个服务运行时的可靠性、性能和可预测性,尤其是当该服务被复用和组合时。
(6)服务无状态性原则
§ 状态:状态管理是指对运行过程中暂时的、活动特定的数据的管理。
§ 服务应尽量减少对状态的管理。
§ 服务不需要设计来为上层业务逻辑流程保留状态信息。
§ 服务合约受更少的限制,增加解释性程序,由此可以发送和接收范围更广的状态数据。
(7)服务可发现性原则
§ 发现:在特定环境中搜索和查找的过程。
§ 服务具有用于交流的信息描述,通过这些描述可以有效地发现和解释这些服务。
§ 每个服务的目标和能力都被清晰地表示,可以被人和软件程序所解释。
§ 服务易于要定位。
(8)服务可组合性原则
§ 组合:将程序组件重组为新的配置来解决不同的问题。
§ 服务是可组合的,无论其大小和复杂程度如何。
§ 服务的合约应尽量灵活,以支持不同的消费者调用。
§ 组合是服务复用的一种形式。
3.SOA协作模式
角色
Provider:提供服务
Consumer:使用服务
Registry:注册服务
过程
Publish:发布服务
Find:查找服务
Bind and Invoke:绑定并调用服务
4.SOMA开发方法
SOMA:Service-Oriented Modeling and Architecture
SOMA生命周期
SOMA提供了端到端的SOA方法论,从服务识别、规范、实现决策到具体实现
SOMA第一步是识别出服务和构件,并确定服务和构件的规范
通过多次迭代精炼出结果
敏捷开发
快速形成原型系统,引导用户的需求,实现需求的快速迭代更新,逼近用户的实际期望。
小幅增量,快速迭代,在不断的沟通中实现对变化的应对,以最小的代价来拥抱变化。
要求:适应变化、灵活应对、善于重用、聆听反馈
互联网服务是典型需要敏捷开发的软件应用
§ 策划、描述一个“用户故事”。(访谈、调查问卷、头脑风暴)。
§ 利用已有服务构件,快速形成Demo或试用版。
§ 主动监视服务系统的运行情况,积极收集用户反馈,以求服务系统的合理化、快速、迭代优化。
§ 追求“情境感知、个性化定制、随事件动态重构”能最大限度、准确满足用户需求的智能服务
服务外包与众包
软件众包就是企业为了专注核心竞争力业务和降低软件项目成本,将软件项目中的全部或部分工作以自由自愿的形式外包给非特定的(而且通常是大型的)大众网络的做法模式。
众包的任务通常是由个人来承担,但如果涉及到需要多人协作完成的任务,也有可能以依靠开源的团体生产的形式出现。
外包与众包均是为了控制风险、降低成本、提高效率,将不会或不擅长的软件开发部分交由第三方来开发。
外包强调的是高度专业化,它是社会专业化分工的规模经济产物,他信赖的是专业化的机构和人士,主张让专业人干专业事。
众包相信“劳动人民的智慧是无穷的”,主张 “三个臭皮匠顶个诸葛亮”,是更加个体化的行为。
5.ESB原理与机制
总线:计算机各种功能部件之间传送信息的公共通信干线
总线种类:数据总线、地址总线、控制总线、扩展总线、局部总线
ESB:Enterprise Service Bus
§ 传统中间件技术与XML、Web服务等技术结合
§ 一种消息和服务集成的中间件平台
§ 是构建SOA解决方案中基础架构的关键部分
ESB解决的问题
§ 提供SOA所需的统一的、基于标准的基础结构视图
§ 提供服务提供者和请求者之间的连接,即使它们并不完全匹配,也能够使它们进行交互
ESB的功能
(1)通信:路由、寻址、通信技术、协议和标准(如MQ、HTTP等)、发布/订阅、响应/请求、事件触发、同步和异步消息传递
(2)服务交互:服务接口定义(如WSDL)、支持替代服务实现、服务消息传递模型(如SOAP)、服务目录和发现
(3)集成:数据库、服务聚合、遗留系统和应用程序适配器、EAI中间件、服务映射、协议转换、应用程序服务器环境、服务调用的语言接口
(4)服务质量:事务(原子事务、补偿、Web服务事务)、各种确定的传递泛型(如WS-ReliableMessaging)
(5)安全性:身份验证和授权、不可抵赖性、机密性、安全标准(如WS-Security)
(6)服务级别:性能、吞吐量、可用性
(7)消息处理 :消息和数据转换、有效性、中介、数据压缩
(8)管理和自治:服务预置和注册、发现、记录、测量和监控、自监控和自管理
ESB关键技术
适配器(Adapter):用于连接应用组件与外部应用程序。
§ 消息连接器:适配器的核心,控制消息接收器/发送器和消息转换器。
§ 消息接收器/消息发送器:定义接收端点和发送端点,指定消息从哪里接收或发送到何处。
§ 消息转换器:将接收或要发送的消息进行转换。
消息中间件(MQ)
§ 提供可靠传输的产品;
§ 是消息总线的基础;
§ 建立网络通信的通道,进行数据发送,屏蔽网络通信的复杂度。
MQ的基本概念
§ 队列:用于存储消息的数据结构
§ 队列管理器:资源的容器
§ 通道:提供从一个队列管理器到另一个队列管理器的通信路径
§ 侦听器:开放的端口
§ 消息:传输的数据
ESB的优势
可用性和可靠性
§ 支持集群部署来保证系统的高可用性
性能和可伸缩性
§ 保证性能指标并留有余量
扩展性和灵活性
§ 支持系统扩展部署和多逻辑单元分离部署
安全性
§ 提供安全认证和授权机制,提供不可否认和机密性
6.服务组合与BPEL
服务编制
§ 一个中央流程(可以是另一个 Web 服务)控制相关的Web 服务并协调对操作所涉及 Web 服务的不同操作的执行。相关的 Web 服务并不“知道”(也无需知道)它们参与了组合流程并在参与更高级别的业务流程。
§ 只有编制的中央协调员知道此目标,因此编制主要集中于操作的显式定义以及 Web 服务的调用顺序。
服务编排
§ 编排所涉及的每个 Web 服务完全知道执行其操作的时间以及交互对象。编排是一种强调在公共业务流程中交换消息的协作方式。
§ 所有参与者都需要知道业务流程、要执行的操作、要交换的消息以及消息交换的时间
编制相比编排而言,更具有灵活性
§ 组件流程的协调由某个已知的协调员集中管理
§ 可以组合 Web 服务而不必使它们知道它们正在参与更大的业务流程
§ 可以准备其他方案以防发生故障
服务组合(编制和编排)可以通过BPEL来支持实现
BPEL
BPEL:Business Process Execution Language
§ 一种使用 Web 服务定义和执行业务流程的语言。
§ 通过组合、编排和协调 Web服务自上而下地实现面向服务的体系结构。
§ 提供了一种相对简单易懂的方法,可将多个 Web服务组合到一个新的复合服务(称作业务流程)中。
BPEL语言的操作
§ 赋值操作:由〈assign〉操作完成
§ 循环操作:由〈while〉操作完成
§ 选择操作:由〈switch〉和〈case〉操作完成
§ 远程调用操作:由〈invoke〉操作完成
§ 错误抛出操作:由〈throw〉操作完成
§ 错误捕捉操作:由〈catchfault〉和〈catchall〉操作完成
§ <receive>:业务流程的起点,允许业务流程阻塞等待匹配消息的到达,该活动当消息到达时完成。
§ <reply>:业务流程的终点,把业务流程的结果返回给服务请求。
§ <wait>:等待一段给定的时间或等到某一时刻,需指定到期时间。
§ <empty>:在业务流程中插入“no-op”指令。例如,这个构造可被用于并行活动的同步。
§ <exit>:立刻终止业务流程实例。
BEPL结构
PartnerLinkType:伙伴链接类型
§ 为了描述两个服务之间的会话关系,伙伴链接类型定义了会话中每个服务所扮演的“角色”,并且指定了每个角色所提供的portType。
§ 可以是独立于任何一个服务的WSDL文档的单独构件,也可以被放在定义portType的WSDL文档中。
§ PartnerLinkType不是在BPEL文件中定义的,而是在WSDL文件中定义的。
partnerLinks:合作伙伴链接
与业务流程交互的服务被描述成伙伴链接。每个伙伴链接由partnerLinkType来描述。每个伙伴链接都被命名,这个名称用于与这个伙伴的所有服务交互。
每个合作伙伴链接可以有一个或两个角色。属性myRole指出了业务流程本身的角色,而属性partnerRole指出了伙伴的角色。
通常同步请求/响应操作仅能指定一个角色;对于异步操作,它指定两个角色。
variables:变量定义
业务流程指定了涉及伙伴之间消息交换的有状态交互。业务流程的状态不仅包括被交换的消息,而且还包括用于业务逻辑和构造发送给伙伴的消息的中间数据,这些中间数据可以通过变量来存储。
每个变量的类型可以是WSDL消息类型、XML Schema简单类型或XML Schema元素。
correlationSets:相关集定义
faultHandlers:故障处理程序
故障处理是因发生故障而切换到撤销发生故障的作用域中的部分或不成功的工作。
故障处理程序提供了定义一组自定义的故障处理活动的方法,句法上定义为catch活动,每个catch活动能拦截某种特性的故障。
compensationHandlers:补偿处理程序
eventHandlers:事件处理程序
整个流程以及每个作用域可以与一组在相应的事件发生时并发调用事件处理程序相关联。
事件包括两种类型:与WSDL中请求/响应或单向操作对应的传入消息;用户设置的时间过后发出的警报
activity:流程主体
由一些列的基本活动和结果活动组成
BPEL语言的基本单位是活动,其活动按作用可分如下几类:
• 基本活动:实现基本功能
基本活动是与外界进行交互最简单的形式。它们是无序的个别步骤,与服务进行交互、操作、传输数据或者处理异常等。包括:
• 和外界交互:receive、invoke、reply
• 数据赋值:assign
• 通过throw发出故障信号
• 通过terminate放弃所有流程实例的执行
• 通过empty不执行任何的动作
• 通过compensate做补偿动作
• 结构活动:控制流程结构
结构化的活动规定了一组活动发生的顺序。描述了业务流程是怎样通过基本活动组成结构而创建的。包括:
• 活动件一般顺序控制由sequence、switch和while提供
• 活动间达到并发和同步有flow提供
• 基于外部事件的不确定的选择由pick来提供
结构化的活动可以被任意的嵌套和组合
• 故障处理
• 特殊活动
构建BPEL步骤
§ 熟悉相关的 Web 服务
§ 为此 BPEL 流程定义 WSDL
§ 定义合作伙伴链接类型
§ 开发此 BPEL 流程:
• 定义合作伙伴链接
• 声明变量
• 编写流程逻辑定义
BPMN
BPMN:Business Process Model and Notation
§ 一套图形化的标准方法,用于业务流程建模与详细说明业务流程。
§ 提供一套既直观又能表现复杂流程语义的标记法,使各种业务开发者(创造与梳理流程的业务分析师、负责实施流程的技术开发者管理和监督流程的经理人、使用流程的用户)易于理解。
§ BPEL本身没有定义描写过程模型的图像表达,但是BMPN标准可以用来描写BPEL的模型。
BPMN图形化元素:流对象
§ 事件:用圆圈来描述,表示业务流程期间发生的事件。
§ 活动:用圆角矩形表示,是要处理工作的一般术语。
§ 条件:用菱形表示,用于控制序列流的分支与合并。
BPMN图形化元素:连接对象
§ 顺序流:用实心线表示,用于指定活动执行的顺序。
§ 消息流:用虚线表示,用于描述两个独立的业务参与者之间发送和接受的消息流动。
§ 关联:用点线表示,用于展示活动的输入和输出。
BPMN图形化元素:泳道
§ 池:描述流程中的一个参与者,将一系列活动区别于其他池的一个图形容器。
§ 泳道:在池里面再细分,用于组织和分类活动。
BPMN图形化元素:人工信息
§ 数据对象:显示活动是如何需要或产生数据的。
§ 组:用虚线的圆角矩形表示,用于记录或分析的目的。
§ 注释:建模者为BPMN图读者提供的附加文本信息。
BPMN建模的价值
§ BPMN的开发是减少众多已存在的业务建模工具和标记断层的重要的一步。一个好的标准建模标记将会减少业务与IT用户之间的混乱。
§ 由业务人员做出来的业务流程建模从需要系统设计与执行的流程描述中隔离出来。
§ 开发BPMN的重要目标就是要创建面向业务流程建模标记到面向IT执行语言的一座桥梁。
Web2.0
Web2.0 更注重用户的交互作用,用户既是网站内容的浏览者,也是网站内容的制造者。由被动接收互联网信息向主动创造互联网信息发展,从而更加人性化。
典型应用:Blog、Wiki、新闻聚合
Web2.0以去中心化、开放、共享为显著特征
§ 用户分享:用户可以得到自己需要的信息也可以发布自己的观点。
§ 信息聚合:信息在网络上不断积累,不会丢失。
§ 以兴趣为聚合点的社群:在Web2.0模式下,聚集的是对某个或者某些问题感兴趣的群体。
§ 平台开放,用户活跃:平台对于用户来说是开放的,而且用户因为兴趣而保持比较高的忠诚度,他们会积极的参与其中。
Web2.0与Web1.0
§ Web1.0:以商业公司为主体,通过少数的人将大量的信息编辑整理并发布到网站,网站编辑决定了用户看到的内容。
§ Web2.0:以用户为主,让用户参与信息的收集、编辑、发布。人们可以自由的分享彼此看到的信息,并共同合作,把知识有机的组织起来。通过Ajax等技术使用户可以更加便捷的贡献内容、传播内容。
§ Web3.0:由用户来控制的互联网。
Web2.0主要技术
RSS(Really Simple Syndication):简易信息聚合
§ 一种基于XML标准,在互联网上被广泛采用的内容包装和投递协议。
§ 是一种描述和同步网站内容的格式。RSS中包含的信息能直接被其他站点调用。
§ RSS目前广泛用于网上新闻频道,Blog和Wiki。
§ 使用RSS订阅能更快地获取信息,网站提供RSS输出,有利于让用户获取网站内容的最新更新。
§ 网络用户可以借助于RSS聚合工具,在不打开网站内容页面的情况下阅读支持RSS输出的网站内容。
页面交互技术
Ajax(Asynchronous Javascript And XML)
§ 一种创建交互式网页应用的网页开发技术,在无需重新加载整个网页的情况下,能够更新部分网页。
§ 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。
§ 因特网应用程序更小、更快,更友好。
§ 实现用户交互式页面的重要技术手段。
Ajax过程
§ 创建XMLHttpRequest对象,也就是创建一个异步调用对象
§ 创建一个新的HTTP请求,并指定其请求的方法、URL及验证信息
§ 设置响应 HTTP 请求状态变化的函数
§ 发送 HTTP 请求
§ 获取异步调用返回的数据
§ 使用 JavaScript 和 DOM 实现局部刷新
Web3.0
Web3.0特征
§ 网站内的信息可以直接和其他网站相关信息进行交互,能通过第三方信息平台同时对多家网站的信息进行整合使用。
§ 用户在互联网上拥有自己的数据,并能在不同网站上使用。
§ 完全基于Web,用浏览器即可实现复杂系统程序才能实现的系统功能。
§ 互联网价值的重新分配。
服务Mashup
Mashup表示通过多种渠道将多个源的数据、应用功能糅合起来创建全新的服务。
Mashup运用Web2.0技术,通过开放API、RSS等方式把不同内容源聚合起来,并使用Ajax等技术增强与用户的交互。
API/内容提供者:聚合来源
Mashup站点:聚合逻辑
客户机浏览器:结果呈现
Mashup应用
§ 视频图像Mashup:利用与图像相关的元数据(如照片内容、地点等)对视频和图像资源进行关联。
§ 搜索购物Mashup:通过信息爬取或调用API的方式将购物网站的信息进行整合。
§ 新闻Mashup:根据用户兴趣聚合新闻内容,创建个性化的新闻应用。
§ 地图Mashup:基于在线地图API利用位置信息在地图上实现组合的业务功能。
Mashup实现技术
§ Web服务:SOAP或REST
§ Ajax
§ 客户端事件处理
§ 语义Web和RDF
§ RSS和ATOM
Mashup特点
§ 资源共享
§ 个性化
§ 终端用户参与
§ 快速创建服务
§ 资源重用
§ 简单
Mashup开发步骤
1.定义数据源
2.定义地图对象
3.资源糅合
7.面向服务架构技术演进
最初架构:单机架构
第一次演进:Tomcat与数据库分开部署
§ Tomcat和数据库竞争资源,单机性能不足支撑业务
第二次演进:引入本地缓存和分布式缓存
§ 并发的读写数据库成为瓶颈
§ 使用memcached作为本地缓存,或使用Redis作为分布式缓存
第三次演进:引入反向代理实现负载均衡
§ 并发压力主要落在单机的Tomcat上,响应逐渐变慢
§ 在多台服务器上分别部署Tomcat,使用反向代理软件(Nginx)把请求均匀分发到每个Tomcat 中
第四次演进:数据库读写分离
§ 并发量的增长使单机的数据库成为新的瓶颈
§ 把数据库划分为读库和写库,读库可以有多个,通过同步机制把写库的数据同步到读库
第五次演进:数据库按业务分库
§ 不同业务之间的访问量差距较大,相互影响性能
§ 对于访问量大的业务,可部署更多的服务器来支撑
第六次演进:大表拆分为小表
§ 单机的写库逐渐达到性能瓶颈
§ 将字段多、数据量大的数据表拆分为小表
第七次演进:使用LVS或F5来使多个Nginx负载均衡
§ 单机的Nginx成为瓶颈
第八次演进:通过DNS轮询实现机房间的负载均衡
§ LVS服务器达到瓶颈
§ 在DNS服务器中可配置一个域名对应多个IP地址,每个IP地址对应到不同的机房里的虚拟IP
第九次演进:引入NoSQL数据库和搜索引擎等技术
§ 当数据多到一定规模时,数据库不再适用于复杂查询
第十次演进:大应用拆分为小应用
§ 按照业务板块来划分应用代码,使单个应用的职责更清晰,相互之间可以做到独立升级迭代
第十一次演进:复用的功能抽离成微服务
第十二次演进:引入ESB屏蔽服务接口的访问差异
第十三次演进:容器化技术实现运行环境隔离与动态服务管理
§ 服务部署、 运维困难
第十四次演进:以云平台承载系统
§ 机器自身成本和运维成本都极高,资源利用率低
成熟的架构方案不是一步搭建完成的,都是逐渐迭代演进而成。
不同业务系统演进路线并不完全一致。
分布式服务架构是构建大型应用软件系统的有效技术手段之一。
8.Dubbo(携程)
Dubbo落地
服务治理
§ 在服务治理这方面,携程现有的 SOA 框架已经有了一套完整的服务注册中心和服务治理系统。对于服务注册中心,大家比较常用的可能是 Apache Zookeeper 。而我们使用的是参考 Netflix 开源的 Eureka 自行研发的注册中心 Artemis 。
服务监控
§ 统计数据:对各种服务调用数据的定期汇总,比如调用量、响应时间、请求体和响应体的大小以及请求出现异常的情况等等。
§ 监控服务:使用 CAT 。CAT 是美团点评开源的一个实时的应用监控平台,它通过树形的 Transaction 和Event 节点,可以将整个请求的处理过程记录下来。
初版发布
§ 在解决了服务治理和监控对接这两个问题后,完成了Dubbo 在携程初步的一个本地化。在 2018 年 3 月,发布了 Dubbo 携程定制版的首个可用版本。
§ 在正式发布前需要给这个产品起个新名字。既然是携程(Ctrip)加 Dubbo ,就把这个定制版称为 CDubbo 。
Cdubbo功能扩展
Callback 增强
§ 对于全局唯一的callback接口实例,想要拿到请求上下文信息比较困难。
§ 增加了 Stream 功能。
序列化扩展
§ 一些业务部门在之前开发 SOA 服务的时候,使用的是Google Protocol Buffer 契约编写的请求数据模型。
§ 为了便于将 SOA 服务迁移到Dubbo ,也在 Dubbo 中增加了 GooglePB 序列化方式的支持。
§ 后续为了便于用户自行扩展,在PB序列化器的实现上增加了扩展接口,允许用户在外围继续增加数据压缩的功能
请求熔断
§ 当客户端或服务端出现大范围请求出错或超时的时候,系统会自动执行 fail-fast 逻辑,不再继续发送和接受请求,而是直接返回错误信息。
§ 使用业界成熟的解决方案:Netflix 开源的 Hystrix 。它不仅包含熔断的功能,还支持并发量控制、不同的调用间隔离等功能。
§ CDubbo的服务端和客户端通过集成 Hystrix 来做请求的异常情况进行处理,避免发生雪崩效应。
服务测试工具
§ 让测试人员在无需编写代码的前提下测试一个 Dubbo 服务,需要解决的三个问题:如何编写测试请求、如何发送测试请求和如何查看响应数据。
§ 开发服务测试平台,用户可以在上面直接选择服务和实例,编写和发送测试请求。
二、面向服务开发技术
1.面向服务开发基础
①Web开发基础
Web系统体系结构
Web服务端:提供Web页面或资源
Web客户端:访问Web资源的系统(一般是浏览器)
通信协议:客户端和服务器之间采用HTTP协议通信
Web容器
服务环境程序,在其中运行Web服务端应用程序,使应用程序能够直接跟容器中的环境变量交互,不必关心其它系统问题
服务器接收到客户端请求后,将请求交给容器,由容器调用应用程序处理
常用Web容器:Tomcat、Docker……
Web客户端
主要指浏览器,主要功能是将用户向服务器请求的Web资源呈现出来
Web客户端也包括移动端应用
HTML & XML
HTML用来显示数据,标记是预定义的;
XML用来描述数据的性质和结构,标记可自定义
HTTP超文本传输协议
客户端与服务端之间请求和应答的标准(TCP)
HTTP无状态性,每个请求完全独立,包含处理该请求所需的完整数据
②Web开发技术演进
静态内容
通过浏览器访问服务器上编写好的HTML页面
HTML+URL+HTTP
动态内容CGI
CGI定义了Web服务器与外部应用程序之间的通信接口标准,因此Web服务器可以通过CGI执行外部程序,让外部程序根据Web请求内容生成动态的内容
模板引擎(PHP/ASP/JSP)
把程序(动态内容)嵌入到HTML中去执行
JavaEE&ASP.net
基于分布式、安全性、事务性等方面的要求
主要技术:EJB、RMI、JDBC、JNDI、JMS…
Web层框架
为提高工作效率避免重复造轮子,Web层框架应运而生。
MVC框架:模型Model、视图View、控制器Controller。
MVC框架
模型Model:封装与业务逻辑相关的数据和处理方法
视图View:负责数据的HTML展示
控制器Controller:负责响应请求,协调Model和View
前端MVC:Angular、React、Vue
解决前端开发的复杂度,提供一套前端代码结构框架
前后端解耦,分离开发
③Spring Boot
概念
Spring框架:开源的J2EE应用程序框架,为了解决企业级开发中的复杂性问题。
Spring Boot框架进一步简化Spring框架的配置以及复杂的依赖管理。开发人员不仅不再需要编写XML,有时甚至不需要写import语句。
Spring Boot策略:开箱即用、约定优于配置。
特性
独立运行的jar项目
内嵌Servlet容器(Tomcat、Jetty等)
提供starter简化Maven配置(POMS项目对象模型)
提供大量的自动配置,简化项目开发
自带应用监控
无代码生成和XML配置
2.RPC(远程过程调用)
概念
简单的说,RPC就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法(可以统称为服务)并得到返回的结果。
RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯)
RPC 是一个请求响应模型。客户端发起请求,服务器返回响应(类似于Http的工作方式)
RPC 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)。
序列化:将对象的状态信息转换为可以存储或传输的形式的过程
RPC分类
从通信协议的层面分为
基于HTTP协议的(例如基于文本的SOAP(XML)、Rest(JSON),基于二进制Hessian(Binary))
基于TCP/IP协议的(通常会借助Mina、Netty等高性能网络框架)
Mina(Apache Mina Server): 是一个网络通信应用框架,为开发高性能和高可用性的网络应用程序提供了非常便利的框架。
Mina特点:异步的NIO框架,将UDP当成“面向连接”的协议,底层依赖的主要是Java NIO库,上层提供的是基于事件的异步接口
Netty:是由JBOSS提供的一个java开源框架,是一个异步的事件驱动网络应用程序框架,
Netty特点:基于BIO和NIO的UDP传输,对Java NIO库进行了封装。易于开发的同时还保证了其应用的性能,稳定性和伸缩性。
从不同的开发语言和平台层面分为
单种语言或平台特定支持的通信技术(例如Java平台的RMI、.NET平台Remoting)
支持跨平台通信的技术(例如HTTP Rest、Thrift等)
从调用过程分为
远程数据共享(例如:共享远程文件,共享数据库等实现不同系统通信)
消息队列
RPC(远程过程调用)
主流的Web服务实现方案
XML-RPC(Remote Procedure Call):远程过程调用协议,通过XML将调用函数封装,并使用HTTP协议作为传送机制。
JSON-RPC(Remote Procedure Call):远程过程调用协议,通过JSON将调用函数封装,并使用HTTP协议作为传送机制。
SOAP(Simple Object Access Protocol):简单对象访问协议, 是交换数据的一种协议规范,是一种轻量的、简单的、基于XML(标准通用标记语言下的一个子集)的协议,它被设计成在WEB上交换结构化的和固化的信息。
REST(Representational State Transfer):一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等。
方案的简单比较
RPC出现较早,实现方式多样,但有被SOAP取代的趋势
成熟度上:SOAP在成熟度上优于REST
效率和易用性上:REST更胜一筹
安全性上:SOAP安全性高于REST,因为REST更关注的是效率和性能问题
总体上,因为REST模式的Web服务与复杂的SOAP和XMLRPC对比来讲明显的更加简洁,越来越多的web服务开始采用REST风格设计和实现。
常见的RPC技术和框架
应用级的服务框架:Dubbo/Dubbox、ZeroC ICE、GRpc、Spring Boot/Spring Cloud
基础通信框架:Prorocol Buffers、Thrift
远程通信协议:RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)
第3代 RPC –XML RPC
XML-RPC(RPCXML Remote Procedure Call)是通过HTTP传输XML来实现远程过程调用的RPC
基于HTTP、并且使用XML文本的方式传输命令和数据,所以兼容性更好,能够跨域不同的操作系统、不同的编程语言进行远程过程调用
在兼容性好的同时速度也会慢下来。
第3代 RPC –JSON RPC
是一个无状态且轻量级的远程过程调用(RPC)传送协议,其传递内容采用JSON 格式。
JSON-RPC 直接在内容中定义了欲调用的函数名称(如 {“method”: “getUser”})。
它能够运行在基于 Socket、HTTP 等诸多不同消息传输环境的同一进程中。其使用 JSON(RFC 4627)作为数据格式。
XML-RPC
一般一个RPC系统包括两个部分:RPC Client和RPC Server
Client向Server发送一个请求体为XML的HTTP POST请求,被调用的方法在Server端执行后将执行结果以XML格式返回
与平常的方法调用所不同就是接口“作用域”更大,并且多了一层数据的包装和转换
工作原理
RPCclient的工作原理
RPCclient根据URL找到RPCserver
构造命令包
调用RPCserver上的某个服务的某个方法
接收到RPCserver的返回
解析响应包,拿出调用的返回结果。
RPCserver的工作原理
启动一个webserver(在使用内置的webserver的情况下)
注册每个能提供的服务,每个服务对应一个Handler
进入服务监听状态。
XML-RPC实现
Apache XML-RPC是XML-RPC的一个Java实现,其底层是基于Helma的
Helma是一个用来开发快速、稳定的Web应用程序的开源框架
XML-RPC Server端
有两种启动XML-RPC的方式
一种是集成在Web Servlet环境中,一般应用在Web环境,要有Tomcat 之类的web服务器
一种是启动独立的内嵌Web Server,内嵌的Web Server可以被嵌入到任意的Java应用中(见例子中的WebServer 类)
XML-RPC Client端
客户端有两种调用方式:同步调用和异步调用
如果某个被调用的远程过程执行的很慢,就可能会导致我们的程序处于假死状态,又或者我们只是调用它一下,对其返回结果并不是很关心,这个时候比较适合使用异步调用。
JSON-RPC
是一个无状态且轻量级的远程过程调用(RPC)传送协议
JSON-RPC协议中的客户端一般是为了向远程系统请求执行某个方法向实现了JSON-RPC协议的服务端发送请求
多个输入参数能够通过数组或者对象传递到远程方法,这个远程方法也能返回多个输出数据
JSON-RPC序列化采用JSON的形式。(RESTful通常采用HTTP+JSON实现)
JSON-RPC和XML-RPC相比具有很多优点。
首先XML-RPC是以XML作为消息格式,XML具有体积大,格式复杂,传输占用带宽。
程序对XML的解析也比较复杂,并且耗费较多服务器资源。
JSON相比XML体积小巧,并且解析相对容易很多。
使用JSON-RPC
所有的传输都是单个对象,用JSON格式进行序列化。
请求包含三个特定属性:
method方法,是等待调用的远程方法名,字符串类型
params参数,对象类型或者是数组,向远程方法传递的多个参数值
id 任意类型值,用于和最后的响应进行匹配,也就是这里设定多少,后面响应里这个值也设定为相同的
接收者必须能够给出所有请求的正确的响应
响应也有三个属性:
result结果,是方法的返回值,如果方法执行时出现了错误,那么这个值必须为空
error错误,当出现错误时,返回一个特定的错误编码,没有错误就为空值
id就是请求带的那个id值,用于匹配
调用的JSON格式, 向服务端传输数据格式如下:
{ "method": "方法名", "params": ["参数数组"], "id": 方法ID}
说明:
第一个参数: 是方法的名值对
第二个参数: 是参数数组
第三个参数: 是方法ID(可以随意填)
输出的JSON格式
{ "jsonrpc": "2.0", "id": "1234", "result": null}
3.WebService
概念
是一种跨编程语言和跨操作系统的远程调用技术
是一个平台独立的,低耦合的,基于可编程的Web的应用程序
可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序
stub:为屏蔽客户调用远程主机上的对象,必须提供某种方式来模拟本地对象,这种本地对象称为存根(stub),存根负责接收本地方法调用,并将它们委派给各自的具体实现对象
WebService体系结构
涉及到三个角色:Web 服务提供者、Web 服务中介者、Web 服务请求者
涉及到三类动作:即发布、查找、绑定
Web 服务提供者
可以发布 Web 服务,并且对使用自身服务的请求进行响应
Web 服务的拥有者,它会等待其他服务或者是应用程序访问
Web 服务请求者
即 Web 服务功能的使用者
它通过服务注册中心也就是 Web 服务中介者查找到所需要的服务,再利用 SOAP 消息向 Web 服务提供者发送请求以获得服务
Web 服务中介者
也称为服务代理,用来注册已经发布的 Web服务提供者,并对其进行分类,同时提供搜索服务
充当一个管理者的角色,一般是通过 UDDI来实现
发布
通过发布操作,可以使 Web服务提供者向 Web 服务中介者注册自己的功能以及访问的接口
发现(查找)
使得 Web 服务请求者可以通过 Web 服务中介者来查找到特定的种类的 Web 服务
绑定
让服务请求者能够使用服务提供者提供的服务
WebService三种基本元素
SOAP 即 Simple Object Access Protocol 也就是简单对象访问协议,是一种用于访问 Web 服务的协议。
WSDL 即Web Services Description Language也就是 Web 服务描述语言。WSDL 描述了 Web服务的三个基本属性:
服务所提供的操作
如何访问服务
服务位于何处(通过 URL 来确定)
UDDI 即 Universal Description,Discovery and Integration,也就是通用的描述,发现以及整合。
WebService栈
发现服务层:用来帮助客户端解析远程服务的位置
描述服务层:为客户端程序提供与远程服务交互的描述信息
消息格式层:保证客户端应用程序和服务器在格式设置上保持一致
编码格式层:为客户端和服务器之间提供一个标准的、独立于平台的数据交换编码格式
传输协议层:为客户端和服务器之间提供交互的网络通信协议
发现服务 | UDDI、DISCO |
描述服务 | WSDL、XML、Schema |
消息格式层 | SOAP |
编码格式层 | XML |
传输协议层 | HTTP、TCP/IP、SMTP等 |
WebService开发
服务端开发
把系统业务功能开发成WebService服务,供远程调用
通常借助一些WebService框架来实现。Java方面的典型WebService框架包括:axis、xfire、cxf 等。Java EE服务器通常也支持发布WebService服务,例如JBoss。
客户端开发
调用别人发布的WebService服务
可使用服务提供商的WSDL2Java之类的工具生成静态调用的代理类代码;服务提供商的客户端编程API类;使用SUN公司早期标准的jax-rpc开发包;使用 SUN公司最新标准的jax-ws开发包等。
WebService 的工作调用原理
客户端
给WebService客户端API传递WSDL文件的URL地址,这些API就会创建出底层的代理类
我们调用这些代理,就可以访问到Webservice服务
代理类把客户端的方法调用变成SOAP格式的请求数据再通过HTTP协议发出去,并把接收到的SOAP 数据变成返回值返回
服务端
各类WebService框架的本质就是一个大大的Servlet,当远程调用客户端给它通过HTTP协议发送过来 SOAP格式的请求数据时,它分析这个数据,就知道要调用哪个Java类的哪个方法,于是去查找或创建这个对象,并调用其方法
再把方法返回的结果包装成SOAP格式的数据,通过HTTP响应消息回给客户端
流行的WebService框架
开发webservice应用程序中离不开框架的支持
性能是Webservice的关键要素,不同的框架性能上存在较大差异
下面是比较流行的几个框架:Apache Axis1、Apache Axis2、Codehaus XFire、Apache CXF、Apache Wink、Jboss RESTEasy、sun JAX-WS(最简单、方便)、阿里巴巴 Dubbo
WebService与RPC
两者类似,在组件层次和交互时序上没有差别,实际上承担的职责却是完全对应的。
Web Service接口就是RPC中的stub组件,规定了Server能够提供的服务(Web Service),这在Server和Client上是一致的。
Web Service能更好的跨语言跨平台。由于Web Service规范中的WSDL文件的存在,各平台的Web Service框架,都可以基于WSDL文件,自动生成web service接口。
常见的RPC框架
Hessian、Thrift、Hetty、阿里的Dubbo等
JAVA中共有三种WebService规范
JAXM(Java API for XML Messaging)&SAAJ(SOAP with Attachments API for JAVA)
JAX-WS(JAX-RPC)
JAX-RS
支持WebService的框架
支持JAX-WS服务规范的框架有:CXF、Axis、Xfire、Axis2。结合java语言均可可实现JAX-WS
支持JAX-RS服务规范的框架有:
CXF——XFire和Celtix的合并
Jersey——Sun公司的JAX-RS参考实现
RESTEasy——JBoss的JAX-RS项目
Restlet——也许是最早的REST框架了,在JAX-RS之前就有了
WSDL
网络服务描述语言,Web Services Description Language
基于 XML 的语言,用于描述 Web Services 以及如何对它们进行访问
它包含一系列描述某个 web service 的定义
WSDL文档结构
元素 | 定义 |
<portType> | WebService执行的操作 |
<message> | WebService使用的消息 |
<types> | WebService使用的数据类型 |
<binding> | WebService使用的通信协议 |
XML
XML 指可扩展标记语言(EXtensible Markup Language)
XML 是一种标记语言,很类似 HTML
XML 的设计宗旨是传输数据,而非显示数据
XML 标签没有被预定义。您需要自行定义标签。
XML 被设计为具有自我描述性。
XML 是 W3C 的推荐标准
一个 WSDL 文档的主要结构是类似这样的
<definitions>
<types>
definition of types........
</types>
<message>
definition of a message....
</message>
<portType>
definition of a port.......
</portType>
<binding>
definition of a binding....
</binding>
</definitions>
WSDL 文档可包含其它的元素,比如 extension 元素,以及一个 service 元素,此元素可把若干个 web services 的定义组合在一个单一的 WSDL 文档中。
WSDL 端口
<portType> 元素是最重要的 WSDL 元素。它可描述一个 web service可被执行的操作以及相关的消息。可以把 <portType> 元素比作传统编程语言中的一个函数库(或一个模块、或一个类)
WSDL 消息
<message> 元素定义一个操作的数据元素。每个消息均由一个或多个部件组成。可以把这些部件比作传统编程语言中一个函数调用的参数。
WSDL types
<types> 元素定义 web service 使用的数据类型。为了最大程度的平台中立性,WSDL 使用 XML Schema 语法来定义数据类型。
<types>元素包含了Types栏。如果没有需要声明的数据类型,这栏可以缺省。在WSDL范例中,没有应用程序特定的types声明,但我仍然使用了Types栏,只是为了声明Schema namespaces。
操作(operation )类型
WSDL 定义了四种类型,请求-响应是最普通的操作类型
类型 | 定义 |
One-way | 服务端接收消息 |
Request-response | 服务端点接收请求消息,然后发送响应消息; |
Solicit-response | 服务访问端发送要求消息,然后接收应答消息。 |
Notification | 服务访问端发送通知消息 |
<!--One-Way 操作例子-->
<!--例子中端口"glossaryTerms"定义了一个名为"setTerm"的 oneway 操作。-->
<!--这个 “setTerm” 操作可接受消息的输入,这些消息使用一条名为 “newTermValues” 的消息,此消息带有输入参数“term”和 “value”。不过,没有为这个操作定义任何输出-->
<message name="newTermValues">
<part name="term" type="xs:string"/>
<part name="value" type="xs:string"/>
</message>
<portType name="glossaryTerms">
<operation name="setTerm">
<input name="newTerm" message="newTermValues"/>
</operation>
</portType >
<!--Request-Response 操作例子-->
<!--例子中端口"glossaryTerms"定义了一个名为"getTerm"的 request-response 操作。-->
<!--“getTerm” 操作会请求一个名为 “getTermRequest” 的输入消息,有一个名为“term” 的参数;返回一个名为“getTermResponse” 的输出消息,此消息带有一个名为 "value" 的参数。-->
<message name="getTermRequest">
<part name="term" type="xs:string"/>
</message>
<message name="getTermResponse">
<part name="value" type="xs:string"/>
</message>
<portType name="glossaryTerms">
<operation name="getTerm">
<input message="getTermRequest"/>
<output message="getTermResponse"/>
</operation>
</portType>
WSDL绑定
为porttype中的operation和message指定一个具体的传输协议(SOAP协议)和数据格式
use属性描述了消息序列化的方式
<message name="getTermRequest">
<part name="term" type="xs:string" />
</message>
<message name="getTermResponse">
<part name="value" type="xs:string" />
</message>
<portType name="glossaryTerms">
<operation name="getTerm">
<input message="getTermRequest" />
<output message="getTermResponse" />
</operation>
</portType>
<binding type="glossaryTerms" name="b1">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<operation>
<soap:operation
soapAction="http://example.com/getTerm" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
binding 元素有两个属性 - name 属性和 type 属性
name 属性定义 binding 的名称
type 属性指向用于 binding 的端口,在这个例子中是 "glossaryTerms" 端口。
soap:binding 元素有两个属性 - style 属性和 transport 属性
style 属性可取值 “rpc” 或 “document”,在这个例子中我们使用 document。
transport 属性定义了要使用的 SOAP 协议,在这个例子中我们使用 HTTP。
operation 元素定义了每个端口提供的操作符
对于每个操作,相应的 SOAP 行为都需要被定义。
同时必须指定如何对输入和输出进行编码,在这个例子中我们使用了 "literal"。
UDDI
英文为 “Universal Description, Discovery and Integration”,可译为“通用描述、发现与集成服务”
是一种用于存储有关 web services 信息的目录
UDDI标准定义了企业注册服务的框架,但是它并没有指定任何注册服务实现的细节
是一种由 WSDL 描述的 Web Services 界面的目录
经由 SOAP 进行通信
UDDI 如何被使用
行业发布一套某服务的 UDDI 标准和目录
同行业的提供服务的公司就可以把它们要发布的服务注册到这个 UDDI 目录中
然后服务使用者就能够搜索这个 UDDI 目录以找到相关服务。
服务找到后,使用者就能够与此服务进行通信,使用相关服务。
SOAP
RPC:
可使用多种协议(包括HTTP以及在TCP的自定义协议)和序列化方式(Json/xml/二进制),组件之间的耦合度比较高。服务管理的机制相对较弱
RPC 会产生兼容性以及安全问题;防火墙和代理服务器通常会阻止此类流量。
SOAP
SOAP使不同的操作系统上的不同编程语言的应用程序可以互相进行通信
SOAP 很简单,基本上是一个用 XML 信封作为有效负载的 HTTP POST
SOAP 消息支持 Web 服务体系结构中的发布、查找和绑定操作
概念
简单对象访问协议 SOAP(Simple Object Access Protocol)
是在松散的、分布的环境中使用XML交换结构化的和类型化的信息的一种简单协议。
用于应用程序之间的通信、是一种用于发送消息的格式
被设计用来通过因特网进行通信
独立于平台、独立于语言、基于 XML、SOAP 很简单并可扩展、SOAP 允许您绕过防火墙、SOAP 属于W3C 标准
SOAP的设计目标
简单性和可扩展性
这意味着传统的消息系统和分布对象系统的某些性质不是SOAP规范的一部分
SOAP没有定义任何底层的传输协议
可以使用HTTP、FTP、SMTP或者JMS,甚至是自定义协议来传输SOAP报文
一般使用HTTP协议
SOAP的调用效率比较低
HTTP不是高效率的通信协议
XML需要额外的文件解析
SOAP 模块
一条 SOAP 消息就是一个普通的 XML 文档,包含下列元素:
必需的 Envelope 元素,用于把 XML 文档标识为一条 SOAP 消息
可选的 Header 元素,包含头部信息
必需的 Body 元素,包含所有的调用和响应信息
可选的 Fault 元素,提供有关在处理此消息所发生错误的信息
重要的语法规则
SOAP 消息必须用 XML 来编码
SOAP 消息必须使用 SOAP Envelope 命名空间
SOAP 消息必须使用 SOAP Encoding 命名空间
SOAP 消息不能包含 DTD(文档类型定义)引用
SOAP 消息不能包含 XML 处理指令
SOAP 消息的基本结构
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
...
...
</soap:Header>
<soap:Body>
...
...
<soap:Fault>
...
...
</soap:Fault>
</soap:Body>
</soap:Envelope>
SOAP Envelope 元素
SOAP 的 Envelope 元素是 SOAP 消息的根元素。
它可把 XML 文档定义为 SOAP 消息。
请注意 xmlns:soap 命名空间的使用。它的值应当始终是:
http://www.w3.org/2001/12/soap-envelope
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
...
Message information goes here
...
</soap:Envelope>
xmlns:soap 命名空间
SOAP 消息必须拥有与命名空间 "http://www.w3.org/2001/12/soap-envelope" 相关联的一个 Envelope 元素。
如果使用了不同的命名空间,应用程序会发生错误,并抛弃此消息
encodingStyle 属性
语法:soap:encodingStyle="URI"
SOAP Header 元素
可选的
可包含应用程序专用信息(比如认证、支付等)。
如果 Header 元素被提供,则它必须是 Envelope 元素的第一个子元素。头元素的所有直接子元素称作条目。
注:所有 Header 元素的直接子元素必须是合法的命名空间。
SOAP为相互通信的程序之间提供了一种很灵活的机制:
在无须预先协定的情况下,以分散但标准的方式扩展消息。
可以在SOAP头中添加条目实现这种扩展,典型的例子有认证,事务管理,支付等等。
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
<m:Trans
xmlns:m="http://www.w3school.com.cn/transaction/"
soap:mustUnderstand="1">234</m:Trans>
</soap:Header>
...
</soap:Envelope>
上面的例子包含了一个带有一个 "Trans" 元素的头部,它的值是 234,此元素的 "mustUnderstand" 属性的值是 "1"。
SOAP 在默认的命名空间中 ("http://www.w3.org/2001/12/soap-envelope") 定义了三个属性:actor、 mustUnderstand 以及 encodingStyle。
这些在 SOAP 头部的属性定义了如何对 SOAP 消息进行处理。
actor 属性
一个消息从始点到终点可能经过多个中间结点,
如果一个SOAP消息的某部分要传给消息路径上的一个或多个中间结点,则可用actor 指定。
SOAP 的 actor 属性可被用于将 Header 元素寻址到一个特定的端点
语法:soap:actor="URI"
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
<m:Trans
xmlns:m="http://www.w3school.com.cn/transaction/"
soap:actor="http://www.w3school.com.cn/appml/ ">
234
</m:Trans>
</soap:Header>
......
</soap:Envelope>
URI " http://www.w3school.com.cn/appml/"指出了第一个处理这个消息的SOAP应用程序需要这个头元素。省略SOAP actor属性表示接收者是SOAP消息的终节点。
mustUnderstand 属性
SOAP mustUnderstand全局属性用来指示接受者在处理消息时这个条目是否必须处理
假如在 Header 元素的某个子元素添加了 mustUnderstand="1"
那么条目的接受者必须
或者遵守语义(如以元素的全名传送)并按照语义正确的处理
或者放弃处理消息。
语法:soap:mustUnderstand="0|1"
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
<m:Trans
xmlns:m="http://www.w3school.com.cn/transaction/"
soap: mustUnderstand ="1">
234
</m:Trans>
</soap:Header>
...
...
</soap:Envelope>
SOAP Body
SOAP Body 元素包含实际的 SOAP 消息。
SOAP Body 元素的直接子元素可以是合法的命名空间。
SOAP 在默认的命名空间 "http://www.w3.org/2001/12/soap-envelope"中定义了 Body 元素内部的一个元素-- Fault 元素,用于指示错误消息。
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body>
<m:GetPrice xmlns:m="http://www.w3school.com.cn/prices">
<m:Item>Apples</m:Item>
</m:GetPrice>
</soap:Body>
</soap:Envelope>
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body>
<m:GetPriceResponse xmlns:m="http://www.w3school.com.cn/prices">
<m:Price>1.90</m:Price>
</m:GetPriceResponse>
</soap:Body>
</soap:Envelope>
SOAP Fault 元素
是可选的
用于指示错误消息。
如果提供了 Fault 元素,则它必须是 Body 元素的子元素。在一条 SOAP 消息中,Fault 元素只能出现一次。
SOAP 的 Fault 元素拥有下列子元素:
子元素 | 描述 |
<faultcode> | 供识别故障的代码 |
<faultstring> | 可供人阅读的有关故障的说明 |
<faultactor> | 有关是谁引发故障的信息 |
<detail> | 存入涉及 Body 元素的应用程序专用错误信息 |
下面定义的是可能出现在faultcode中信息
错误 | 描述 |
VersionMismatch | SOAP Envelope元素的无效命名空间 |
MustUnderstand | Header元素的一个直接子元素(带有设置为 "1" 的 mustUnderstand 属性)无法被理解 |
Client | 消息被不正确地构成,或包含了不正确的信息。 |
Server | 服务器有问题,因此无法处理进行下去 |
例:<faultcode>SOAP:Client</faultcode>
SOAP编码格式基于一个简单的类型系统
概括了程序语言,数据库和半结构化数据等类型系统的共同特性。
一个类型或者是一个简单的(标量的)类型,或者是由几个部分组合而成的复合类型,其中每个部分都有自己的类型。
XML中的类型编码规则
XML允许非常灵活的数据编码方式,但SOAP定义了一个较小的规则集合,下面的术语用来描述编码规则:
“value”是一个字符串(string),一个可量度对象(数字、日期、枚举)的名字、或是数个简单值的组合。所有的值都有明确的类型。。
“simple value”是一个不可分的值,它没有名部分, 如特定的字符串,整数,枚举值等等。
“compound value”是相关的值的结合,如定单,股票报表,等。
在“compound value”中,每个相关的值都潜在的以名,序数或这两者来区分,这叫作“accessor”(访问器)。
“array”是一个复合值,成员值按照在数组中的位置相互区分。
“struct”也是一个复合值,成员值之间的唯一区别是accessor名,accessor名互不相同。
“simple type”是简单值的类,如叫做"string" "integer"的类,还有枚举类等等。
“compound type”是复合值的类。复合类型的例子有定单类,它们有相同的accessor名(shipTo, totalCost等),但可能会有不同的值(可能以后被设置为确定的值)。
简单类型(simple type)
SOAP采用了"XML Schema Part 2: Datatypes"规范[11]"Built-in datatypes"节中的所有类型作为简单类型,包括值和取值范围(int float negativeInteger string)
在XML Schema规范中声明的数据类型可以直接用在元素schema中,也可以使用从这些类型衍生的新类型
Enumerations
"Enumeration"作为一个概念表示不同的名字的集合。
一个枚举就是对应于基类型的不同的值的列表
<element name="EyeColor" type="tns:EyeColor" />
<simpleType name="EyeColor base="xsd:string" >
<enumeration value="Green" />
<enumeration value="Blue" />
<enumeration value="Brown" />
</simpleType>
<Person>
<Name>Henry Ford</Name>
<Age>32</Age>
<EyeColor>Brown</EyeColor>
</Person>
复合类型
Struct
其成员的存取标识名是相互区别的唯一标志,应彼此各不相同。
Array
其成员的顺序位置是相互区别的唯一标志。
复合值及对值的引用
复合值的成员被编码为存取标识元素。
存取标识由他们的名字来相区别(例如在struct里面),而元素名就是存取标识名。
存取标识名是局部的,作用域是包含他们的类型中,具备一个未修饰的元素名,而其他则有完全修饰名。
<e:Book xmlns:e="http://example.org/2001/06/books" >
<author>Henry Ford</author>
<preface>Prefactory text</preface>
<intro>This is a book.</intro>
</e:Book>
<xs:element name="Book"
xmlns:xs='http://www.w3.org/2001/XMLSchema' >
<xs:complexType>
<xs:sequence>
<xs:element name="author" type="xs:string" />
<xs:element name="preface" type="xs:string" />
<xs:element name="intro" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
数组
数组被定义为类型为“enc:Array”
数组值的是一个该数组组成元素的一个有序序列。
一个数组值的元素名可以是任意,因为数组值通过位置区分。
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:enc="http://www.w3.org/2001/06/soap-encoding" >
<xs:import namespace="http://www.w3.org/2001/06/soap-encoding" />
<xs:element name="myFavoriteNumbers" type="enc:Array" />
</xs:schema>
根据上面的模式,给数组赋值
<myFavoriteNumbers
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:enc="http://www.w3.org/2001/06/soap-encoding"
enc:arrayType="xs:int[2]" >
<number>3</number>
<number>4</number>
</myFavoriteNumbers>
4.RESTful WebService
客户端使用GET、POST、PUT、DELETE,4个表示操作方式的动词对服务端资源进行操作;
使用URI来定位每个资源;
资源的表现形式是HTML或XML;
客户端与服务端之间的交互在请求之间是无状态的。
REST是一种网络应用程序的设计风格。
REST用URI来代表资源
每个资源必须至少有一个URI
URI应具有良好的结构及描述性(易于阅读)
示例:
http://www.ex.com/software/releases/latest.tar.gz
http://www.ex.com/search/cs578
http://www.ex.com/sales/2012/Q1
http://www.ex.com/relationships/Alice;Bob
GET:请求指定的资源。
POST:向指定资源提交数据,请求服务器进行处理。
PUT:向指定资源位置上传其最新内容。
DELETE:请求服务器删除所指定的资源。
REST特性
关注点分离:服务端专注数据存储,提升了简单性;前端专注用户界面,提升了可移植性;
无状态:每次请求必须包括所有信息;
缓存:服务端响应都被标为可缓存或不可缓存;
统一接口:接口与实现解耦,简单、可见;
分层系统:每层只知道相邻的一层,耦合度小,开发简单;
按需代码:客户端可以运行服务端传来的代码。
REST优点
RPC Web Service
少量的URI,大量的操作方法
musicPort.getRecordings(“beatles”)
用HTTP传输SOAP消息
RESTful Web Service
大量的资源(URI),统一固定的操作
GET /music/artists/beatles/recordings
将HTTP协议利用到了极致
RESTful Web Service开发更加简便
客户端不需要使用专门的API
可基于标准HTTP协议
可以使用浏览器进行调试
统一性
使用URI对资源进行统一描述
使用统一的HTTP操作接口
脚本语言更加友好
REST提供了一种面向资源架构(ROA)的系统构造方案
可寻址:资源通过URI暴露,可被外界访问;
无状态:服务端不保存状态,易于提升应用的规模,具有更高的可靠性;
统一接口:统一性使系统具有更好的兼容性;
连通性:资源通过其表示可以彼此连接。
软件服务开发技术对比
CORBA(Common Object Request Broker Architecture)
公共对象请求代理体系结构,分布的、可以互操作的对象利用ORB构造可以互操作的应用
DCOM(Distributed Component Object Model)
分布式组件对象模型标准,支持在局域网、广域网甚至Internet上不同计算机的对象之间的通讯
XML-RPC
远程过程调用协议,通过HTTP传输XML来实现远程过程调用的RPC
兼容性更好,能够跨域不同的操作系统、不同的编程语言进行远程过程调用
适合有一定接口要求或安全性要求的服务
SOAP Service
一种跨编程语言和跨操作系统的远程调用技术
平台独立的,低耦合的,基于Web的应用程序
可使用开放的XML来描述、发布、发现、协调和配置这些应用程序
RESTful
一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件
结构简单,易于开发
适合安全要求不高的资源型信息发布服务
三、分布式服务框架
1.分布式服务框架理论
背景
垂直应用架构面临的挑战
§ 复杂应用的开发和维护成本变高,部署效率逐渐降低。
§ 团队协作效率差,部分公共功能重复开发代码重复率居高不下。
§ 维护和定制困难。大的业务进行拆分代码修改困难,牵一发而动全身,维护和定制都非常麻烦。
§ 新功能上线周期变长。
分布式部署
§ 系统开发维护成本高,部署效率低,应用数量膨胀,数据库连接数持续变高
§ 代码复用难,导致开发、测试、维护等工作烦、难、杂
§ 难以适应敏捷持续交付的挑战
业务纵向拆分
§ 按业务进行梳理,根据业务的特性把应用拆开,不同的业务模块独立部署。
业务横向拆分
§ 将核心的、公共的业务拆分出来,用分布式服务框架对业务进行服务化,消费者通过标准的契约来消费服务。
§ 服务提供者独立打包、部署和演进,与消费者解藕。
服务治理问题成为了亟待解决的问题
§ 服务治理的目标:有效管控服务,提升服务运行质量。
§ 生命周期的管理:需要规范化上线审批、测试、发布流程、下线通知等。
§ 服务容量规划:需要能够采集服务综合性能指标,分析并识别服务容量瓶颈,合理分配服务容量。
§ 运行时治理:在线调整服务级别。
§ 服务安全:身份验证与权限验证。
分布式服务框架解决方案
§ 阿里巴巴——Dubbo (开源)
§ 当当网——DubboX (开源)
§ 淘宝——HSF (面向移动互联)
§ 亚马逊——Coral Service
§ 华为——DSF (面向电信服务)
§ Facebook——Thrift (开源)
§ Twitter——Finagle (开源)
§ Spring Cloud
分布式服务框架
当服务越来越多,容量扩展、服务管理等问题日趋严重,此时需增加调度中心对服务进行实时管理,提高服务可用性和集群利用率。
分布式服务框架:在服务式应用架构基础上,引入服务注册中心,并对服务进行运行时治理,实现自动化服务体系框架。
服务注册中心
§ 负责服务的发布和通知,通常支持对等集群部署,某一个服务注册中心宕机并不会导致整个服务注册中心集群不可用。Dubbo默认使用ZooKeeper。
服务治理中心
§ 通常包含服务治理接口和服务质量Portal,架构师、测试人员和系统运维人员通过服务治理Portal对服务的运行状态、历史数据、健康度和调用关系等进行可视化的分析和维护,目标就是要持续化服务,防止服务架构腐化,保证服务高质量运行。
分布式服务框架特性
服务订阅发布
§ 配置化发布和引用服务:支持通过XML配置的方法发布和导入服务,降低对业务代码的侵入。
§ 服务自动发现机制:支持服务实时自动发现,由注册中心推送服务地址,服务地址透明化。
§ 服务在线注册和去注册:支持运行注册新服务,也支持运行态取消某个服务的注册。
服务路由
§ 路由策略:默认提供随机路由、轮循、基于权重的路由策略。
§ 粘滞连接:总是向同一个提供方发起请求,除非此提供方宕机,再切换到另一台。
§ 路由定制:支持用户自定义路由策略,扩展平台功能。
集群容错
§ Failover:失败自动切换,当出现失败,重试其他服务器。
§ Failback:失败自动恢复,后台记录失败请求,定时重发。
§ Failfast:快速失败,只发起一次调用,失败立即报错。
服务调用
§ 同步调用:消费者发起服务调用后,同步阻塞等待服务端响应。
§ 异步调用:消费者发起服务调用之后,不阻塞立即返回,由服务端返回应答后异步通知消费者。
§ 并行调用:消费者同时对多个服务提供者批量发起服务调用请求,然后集中等待应用。
多协议
§ 私有协议:支持二进制等私有协议,支持私有协议定制和扩展。
§ 公有协议:提供Web Service等公有协议,用于外部服务对接。
序列化方式
§ 二进制类序列化:支持Thrift等二进制协议,提升序列化性能。
§ 文本类序列化:支持JSON、XML等文本类型的序列化方式,提升通用性和可读性。
统一配置
§ 本地静态配置:安装部署修改一次,运行态不修改的配置。
§ 基于配置中心的动态配置:运行态需要调整的参数,统一放到配置中心(服务注册中心),修改之后统一下发,实时生效。
应用服务化之后,由原来的本地API调用变成跨进程远程服务调用,网络通信、消息序列化和反序列化、反射调用和动态代理等都会导致性能损耗、时延增加。
分布式服务性能特性
§ 高性能:同等资源占用情况下,单服务提供者的TPS要尽量高。
§ 低时延:同等资源占用情况下,服务调用时延尽量低。
§ 性能线性增长:扩展服务提供者,性能要能线性增长。
分布式服务框架可靠性
由单机调用演进到分布式部署之后,由于网络故障、服务提供者故障等因素,会导致业务失败率增加,分布式服务框架需要具备很强的可靠性。
服务注册中心
§ 服务健康状态检测:注册中心通过心跳检测服务提供者的存在。服务提供者宕机,注册中心将立即推送事件通知消费者。
§ 故障切换:注册中心对等集群,任意一台宕掉后,将自动切换到另一台。
消除单点故障
§ 服务无状态:服务提供者无状态,任意一台宕机,不影响使用
§ 服务集群容错:只要集群中有一台机器的服务提供者可用,业务就不会中断。
链路健壮性
§ 心跳检测:链路空闲时没有业务消息,通过定时心跳检测链路是否可用。
§ 断连重连机制:链路断连之后,根据客户端配置的重连策略定时重连。
2.Zookeeper
ZooKeeper是一个开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现
主要是用来解决分布式应用中经常遇到的一些数据管理问题,如统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。
ZooKeeper主要提供的功能为文件系统和通知机制。
ZooKeeper 是分布式集群的管理者,监视着集群中各个节点的状态,根据节点提交的反馈进行下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
它能提供基于类似于文件系统的目录节点树方式的数据存储, ZooKeeper 作用主要是用来维护和监控存储的数据的状态变化,通过监控这些数据状态的变化,从而达到基于数据的集群管理。
ZooKeeper的元素
ZooKeeper作为一个分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等。
ZooKeeper通过左图所示的层级树状结构对原语进行实现,从而实现对数据节点(znode)的操作和维护。
Znode树可以包含多个节点和多层级节点。
NameService(命名服务)
§ 在ZooKeeper文件系统里创建一个目录,即有唯一的path。上游程序与下游程序约定好path,通过path即能互相发现。
Configuration(配置管理)
§ 配置文件保存在 ZooKeeper 某个目录节点中,所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到通知,然后从 ZooKeeper 获取新配置信息。
GroupMembers(集群管理)
§ 机器退出和加入:所有机器在父目录GroupMembers创建临时目录节点,然后监听目录节点的变化。一旦有机器宕机,该机器与 ZooKeeper连接断开,其临时目录节点删除,所有其他机器都收到通知。新机器加入类似。
§ 选举master :所有机器创建临时顺序编号目录节点,通过master选算法选举出来。
Apps(应用)
§ 保存所有在集群中管理的应用。
Zookeeper作为注册中心
Znode的类型
§ PERSISTENT:持久化目录节点
• 客户端与ZooKeeper断开连接后,该节点依旧存在
§ PERSISTENT_SEQUENTIAL:持久化顺序编号目录节点
• ZooKeeper给该节点名称进行顺序编号,客户端与ZooKeeper断开连接后,该节点依旧存在
§ EPHEMERAL:临时目录节点
• 客户端与ZooKeeper断开连接后,该节点被删除
§ EPHEMERAL_SEQUENTIAL:临时顺序编号目录节点
• 客户端与ZooKeeper断开连接后,该节点被删除,只是ZooKeeper给该节点名称进行顺序编号
Znode的操作原语
§ create/path data:创建一个名为/path的znode节点,并包含数据data。
§ delete/path:删除名为/path的znode。
§ exists/path:检查是否存在名为/path的节点。
§ setData/path data:设置名为/path的znode的数据为data。
§ getData/path:返回名为/path节点的数据信息。
§ getChildren/path:返回/path节点的所有子节点列表。
ZooKeeper中的角色
ZooKeeper采用Server-Client方式管理服务节点
Server
§ ZooKeeper中的一个节点,为Client提供所需的服务,给Client回应信息表明自己是存活的。
Client
§ 分布式中的一个节点,访问服务器的配置信息,周期性向Server发送心跳包,Server向Client回应确认,如果Client没有收到回应,则重定向到另一个Server。
Leader
§ Leader作为整个ZooKeeper集群的主节点,负责响应所有对ZooKeeper状态变更的请求。
§ 它会将每个状态更新请求进行排序和编号,以便保证整个集群内部消息处理的FIFO。连接任何一个节点,如果节点出现故障,Leader自动修复,在service启动时完成Leader的选举。
Follower
§ 听从Leader的指令,完成选举工作。
Leader的主要功能
§ 恢复数据
§ 维持与Follower的心跳,接收Follower请求并判断Follower的请求消息类型
§ Follower的消息类型主要有:PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理。
§ 当Leader崩溃或者Leader失去大多数的Follower,这时候ZooKeeper进入恢复模式,需要重新选举出一个新的Leader,让所有的 Server都恢复到一个正确的状态。
Leader的选举流程:fast paxos算法
§ 选举过程中,某Server首先向所有Server提议自己要成为Leader,当其它Server收到提议以后,解决zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后选举出Leader。
§ 要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于n+1。
1. 选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;
2. 选举线程首先向所有Server发起一次询问(包括自己);
3. 选举线程收到回复后,验证是否是自己发起的询问,然后获取对方的id(myid) 并存储到当前询问对象列表中,最后获取对方提议的Leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
4. 收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;
5. 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数, 设置当前推荐Leader为获胜的Server,根据获胜的Server相关信息设置自己的状态,否则继续这个过程,直到Leader被选举出来。
Follower主要有四个功能:
§ 向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
§ 接收Leader消息并进行处理;
§ 接收Client的请求,如果为写请求,发送给Leader进行投票;
§ 返回Client结果。
ZooKeeper的消息同步
ZooKeeper中的Watcher
§ Watcher是ZooKeeper用来实现distribute lock、 distribute configure、distribute queue等应用的主要手段。
§ 要监控data_tree上任何节点的变化都可以在获取该数据时注册一个Watcher,类似Listener模式。
§ 该节点数据变化,Follower会发送notification response,client收到notification响应,则会查找对应的Watcher并回调他们。
§ Client可以在某个Znode上设置一个Watcher,来监听该Znode上的变化。如果该Znode上有相应的变化,就会触发这个Watcher,把相应的事件通知给设置Watcher的Client。
§ 需要注意的是,ZooKeeper中的Watcher是一次性的,即触发一次就会被取消,如果想继续Watch的话,需要客户端重新设置Watcher。
Watcher的特性
§ 注册只能确保一次消费
• 无论是服务端还是客户端,一旦一个 Watcher 被触发,ZooKeeper 都会将其从相应的存储中移除。这样的设计有效地减轻了服务端的压力。
§ 客户端串行执行
• 客户端 Watcher 回调的过程是一个串行同步的过程,这为我们保证了顺序,同时需要注意的是,千万不要因为一个 Watcher 的处理逻辑影响了整个客户端的 Watcher 回调。
§ 轻量级设计
• WatchedEvent 是 ZooKeeper 整个 Watcher 通知机制的最小通知单元,这个数据结构中只包含三部分的内容:通知状态、事件类型和节点路径。
• Watcher 通知非常简单,只会告诉客户端发生了事件,而不会说明事件的具体内容。
• 例如针对 NodeDataChanged 事件,ZooKeeper 的Watcher 只会通知客户指定数据节点的数据内容发生了变更,而对于原始数据以及变更后的新数据都无法从这个事件中直接获取到,而是需要客户端主动重新去获取数据。
消息同步的特性
§ 最终一致性:无论哪个Server,对外展示的均是同一视图。
§ 实时性:保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。
§ 可靠性:消息被一个Server接收就会被所有Server接收。
§ 等待无关性:慢的或者失效的Client不得干预快速的Client的请求,使得每个Client都能有效的等待。
§ 原子性:更新只能成功或者失败,没有中间状态。
§ 顺序性:客户端的更新顺序与它们被发送的顺序相一致。
ZooKeeper的服务注册
ZooKeeper用来注册服务和进行负载均衡,哪一个服务由哪一个机器来提供必需让调用者知道,简单来说就是IP地址和服务名称的对应关系。
ZooKeeper通过心跳机制可以检测宕机的机器并将宕机机器的IP和服务对应关系从列表中删除。
ZooKeeper支持高并发,简单说就是横向扩展,在不更改代码 的情况通过添加机器来提高运算能力。通过添加新的机器向ZooKeeper注册服务。
负载均衡:当服务的访问量过大时就需要进行负载均衡,一个ZooKeeper群配合相应的Web应用就可以很容易达到负载均衡。
资源同步:实现负载均衡的同时,节点之间的数据和资源
需要同步,ZooKeeper集群天然具备有这样的功能。
命名服务:将树状结构用于维护全局的服务地址列表,服务提供者在启动 的时候,向ZooKeeper上的指定节点/dubbo/${serviceName}/providers目录下写入自己的URL地址,这个操作就完成了服务的发布。
其他特性还有Master选举,分布式锁等。
分布式CAP理论
一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)
CAP原则的精髓就是要么AP,要么CP,要么AC,但是不存在CAP
3.Dubbo
Dubbo基本概念
§ Dubbo是分布式系统中的一种RPC技术,通过它可以实现系统或应用之间的通信,实现应用间的解耦合等。
§ 阿里巴巴公司开源的高性能服务框架,使应用可通过高性能和透明化的 RPC远程调用方案实现服务输出和输入功能。
§ Dubbo可以和spring框架无缝集成,其功能主要包括:高性能NIO通讯及多协议集成,服务动态寻址与路由,软负载均衡与容错,依赖分析与降级等。
§ Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个核心服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。
Web平台架构演进
§ 单一应用架构
§ 应用和数据库单独部署
§ 应用和数据库集群部署
§ 数据库读写分离
§ 使用缓存技术加快速度
§ 数据库分库分表
§ 应用分为不同类型拆分
复杂架构的问题
§ 服务 URL 配置管理变得非常困难,F5 硬件负载均衡器的单点压力也越来越大。
§ 服务依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动。
§ 服务的调用量越来越大,服务的容量问题就暴露出来。
Dubbo解决的问题
§ 服务动态注册、服务发现、服务位置透明
§ 服务间依赖关系管理
§ 服务治理,如服务SLAs管理、服务容量监测与优化等
Dubbo基本架构
(1)节点角色
§ Provider: 暴露服务的服务提供方
§ Consumer: 调用远程服务的服务消费方
§ Registry: 服务注册与发现的注册中心
§ Monitor: 统计服务的调用次数和时间的监控中心。
§ Container: 服务运行容器
(2)调用关系
0. 服务容器启动、加载、运行服务提供者。
1. 服务提供者在启动时,向注册中心注册。
2. 服务消费者在启动时,向注册中心订阅自己所需的服务。
3. 注册中心返回服务提供者地址给消费者,如有变更,注册中心将推送变更数据给消费者。
4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
Dubbo的特性
§ 面向接口代理的高性能RPC调用
§ 智能负载均衡
§ 服务自动注册与发现
§ 高度可扩展能力
§ 运行期流量调度
§ 可视化的服务治理与运维
Dubbo与Spring Cloud
§ 通信方式不同
• Dubbo 使用的是 RPC 通信,而Spring Cloud 使用的是HTTP RESTFul 方式。
§ 组成不同
• Dubbo的服务注册中心为Zookeerper,服务监控中心为Dubbo-monitor,无消息总线、服务跟踪、批量任务;
• Spring-Cloud服务注册中心为Enruka,服务监控中心为Spring-Boot Admin,有消息总线、数据流、服务跟踪、批量任务等组件。
Dubbo总体架构
Dubbo框架设计共划分为10层
服务接口层(Service):该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。
配置层(Config):配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过Spring解析配置生成配置类。
服务代理层(Proxy):服务接口代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory。
服务注册层(Registry):封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory、Registry和RegistryService。可能没有服务注册中心,此时服务提供方直接暴露服务。
集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心。将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。
监控层(Monitor):RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory、Monitor和MonitorService。
远程调用层(Protocol):封装RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter。
信息交换层(Exchange):封装请求响应模式,同步转异步,以Request和Response为中心,扩展接口为Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer。
网络传输层(Transport):抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel、Transporter、Client、Server和Codec。
数据序列化层(Serialize):可复用的一些工具,扩展接口为Serialization、 ObjectInput、ObjectOutput和ThreadPool。
Dubbo框架的伸缩与拓展
§ 注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心。
§ 服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者。
基于Dubbo的服务系统开发
因为Dubbo无缝地集成了Spring,会大量使用Spring实现相关功能间的依赖配置,所以需要了解Spring中的控制反转模式/依赖注入。
Spring的IoC属于属性方式注入
首先通过XML配置文件,将对象和依赖对象都配置到某个XML文件中,当然该XML文件需要符合Spring指定的规范,然后通过架构中的BeanFactroy类,来自动实现上文所述注入过程
Spring中的控制反转模式/依赖注入的好处:
充分解耦
实现细节透明化->进而便于重用、自治,易于维护
对于服务实现的好处:实现了服务提供类、服务接口、以及服务消费类之间的解耦。服务消费类只需要获得服务接口,就可以实现对服务提供类的使用。
Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。
Dubbo中配置Zookeeper
Ø 配置Zookeeper的IP
Ø 指定使用Zookeeper协议
除了Spring配置之外,Dubbo还支持属性配置,注解配置,API配置。
Dubbo运行JDK1.5之上,缺省依赖javassist、netty、spring等包,但不是必须依赖,通过配置Dubbo可不依赖任何三方库运行。
Dubbo不可能覆盖所有需求,但Dubbo保持平等对待第三方理念,即所有功能,都可以在不修改Dubbo原生代码的情况下,在外围扩展,包括Dubbo自己内置的功能,也和第三方一样,是通过扩展的方式实现。
4.Netty
Dubbo底层通信各层职责
§ 远程调用层(Protocol):封装RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter。
§ 信息交换层(Exchange):封装请求响应模式,同步转异步,以Request和Response为中心,扩展接口为Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer。
§ 网络传输层(Transport):抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel、Transporter、Client、Server和Codec。
§ 数据序列化层(Serialize):可复用的一些工具,扩展接口为Serialization、 ObjectInput、ObjectOutput和ThreadPool。
Dubbo框架数据通信的特点
§ 基于RMI机制的远程调用
§ 并发访问量高
§ 数据吞吐量大
§ 非阻塞式的多线程异步通信
Java NIO等传统框架无法满足要求
Java NIO
§ Java原生IO的阻塞式通信和慢速的磁盘读写,严重影响CPU的使用效率。
§ JDK 1.4 发布了 NIO 包,NIO 文件读写设计颠覆了传统 IO 的设计,采用“通道”+“缓存区”使 IO 操作直接面向缓存区,并且是非阻塞的,大幅提升通信效率。
Java 原生 NIO 的问题
§ NIO 的类库和 API 繁杂,使用麻烦,需要熟练掌握Selector、SocketChannel、ByteBuffer 等。
§ 需要具备其他的额外技能,如 Java 多线程编程等,才能编写出高质量的 NIO 程序。
§ 可靠性能力补齐的开发工作量和难度都非常大:例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常码流的处理等等。
§ JDK NIO存在Bug:例如臭名昭著的 Epoll Bug,它会导致 Selector 空轮询,最终导致 CPU 100%。
Netty的好处
Netty是由JBOSS提供的一个java开源框架,现为Github上的独立项目。
Netty对JDK 自带 NIO 的 API 进行了封装,解决了NIO的一些问题。
Netty在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。
Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
阻塞型I/O模型
§ 每个请求都需要独立线程完成数据 Read、业务处理、数据 Write 的完整操作。
§ 连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在 Read 操作上,造成线程资源浪费。
§ 并发数较大时,需创建大量线程来处理连接,系统资源占用较大。
I/O复用模型
Netty的I/O复用
§ Netty的IO 线程 NioEventLoop 聚合了多路复用器Selector,可以同时并发处理成百上千个客户端连接。
§ 当线程从某客户端 Socket 通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务。
§ 读写操作都是非阻塞的,充分提升 IO 线程运行效率,避免由于频繁 I/O 阻塞导致的线程挂起。
§ 一个 I/O 线程可以并发处理 N 个客户端连接和读写操作,架构的性能、弹性伸缩能力和可靠性都得到了极大的提升。
事件处理模型
§ 轮询方式:线程不断轮询访问相关事件发生源有没有发生事件,如发生事件就调用事件处理逻辑。
§ 事件驱动方式:发生事件时,主线程把事件放入事件队列,在另外线程不断循环消费事件列表中的事件,调用事件对应的处理逻辑处理事件。事件驱动方式也被称为消息通知方式,其实是设计模式中观察者模式的思路。
§ 事件驱动模型的优点:可扩展性好,事件处理器之间高度解耦,可以方便扩展事件处理逻辑;性能高,基于队列暂存事件,能方便并行异步处理事件。
Reactors 多线程模型
§ MainReactor 负责客户端的连接请求,并将请求转交给SubReactor;
§ SubReactor 负责相应通道的 IO 读写请求;
§ 非 IO 请求(具体逻辑处理)的任务直接写入队列,等待 worker threads 进行处理。
Netty主要模块组件
§ Bootstrap、ServerBootstrap:Bootstrap 是客户端程序启动引导类,ServerBootstrap 是服务端启动引导类。
§ Future、ChannelFuture:注册监听,当操作执行成功或失败时监听会自动触发注册的监听事件。
§ Channel:网络通信组件,用于执行网络 I/O 操作。
§ Selector:一个线程监听多个连接 的Channel 事件。
§ NioEventLoop:维护了一个线程和任务队列,支持异步提交执行任务。
NioEventLoopGroup 相当于 1 个事件循环组,这个组里包含多个事件循环 NioEventLoop,每个 NioEventLoop 包含 1 个 Selector 和 1 个事件循环线程。
每个 Boss NioEventLoop 循环执行的任务包含 3 步:
§ 轮询 Accept 事件;
§ 处理 Accept I/O 事件,与 Client 建立连接,生成NioSocketChannel,并将 NioSocketChannel 注册到某个 Worker NioEventLoop 的 Selector 上;
§ 处理任务队列中的任务,runAllTasks。任务队列中的任务包括用户调用 eventloop.execute 或 schedule 执行的任务,或者其他线程提交到该 eventloop 的任务。
Worker NioEventLoop 循环执行任务包含 3 步:
§ 轮询 Read、Write 事件;
§ 处理 I/O 事件,即 Read、Write 事件,在NioSocketChannel 可读、可写事件发生时进行处理;
§ 处理任务队列中的任务,runAllTasks。
Netty的性能
§ 处理大容量数据流更简单
§ 处理协议编码和单元测试更简单
§ I/O超时和idle状态检测
§ 应用程序的关闭更简单,更安全
§ 更可靠的OutOfMemoryError预防
Netty的应用场景
§ 互联网行业:Netty 作为异步高性能的通信框架,作为基础通信组件被各种 RPC 框架使用。
§ 游戏行业:账号登陆服务器、地图服务器之间可以方便的通过 Netty 进行高性能的通信。
§ 大数据领域:经典的 Hadoop 的高性能通信和序列化组件 Avro 的 RPC 框架,默认用 Netty 进行跨节点通信。
§ 企业软件:企业和 IT 集成需要 ESB,Netty 对多协议支持、私有协议定制的简洁性和高性能是 ESB RPC 框架的首选通信组件。
四、微服务架构
1.微服务基本理论
概念
§ 传统的IT行业软件大多都是各种独立系统的堆砌,存在扩展性差,可靠性不高,维护成本高等问题。
§ 后来引入了SOA服务化,但是 SOA 早期均使用了总线模式,这种模式是与某种技术栈强绑定的,如J2EE。导致很多企业的遗留系统对接难度高,切换时间长,成本高,新系统稳定性收敛也需要较长时间。
§ 最终 SOA 看起来很美,但却成为了企业级奢侈品,中小公司都望而生畏。
微服务是一种架构设计模式。在微服务架构中,业务逻辑被拆分成一系列小而松散耦合的分布式组件,共同构成了较大的应用。每个组件都被称为微服务。
每个微服务都在整体架构中执行着单独的任务,或负责单独的功能。
每个微服务可能被一个或多个其他微服务调用,以执行较大应用需要完成的具体任务。
系统为任务执行(比如搜索或显示图片任务)或者其他可能需要多次执行的任务提供了统一的解决处理方式,并限制应用内不同地方生成或维护相同功能的多个版本。
微服务是围绕业务功能构建的,可以通过全自动部署机制进行独立部署。这些服务的集中化管理已经是最少的,它们可以用不同的语言编写,并使用不同的数据存储技术
微服务需要做到
§ 负责单个功能
§ 单独部署
§ 包含一个或多个进程
§ 拥有自己的数据存储
§ 一支小团队能维护几个微服务
§ 可替换的
通过分解巨大单体应用为多个服务的方法解决了系统复杂性问题。在功能不变的情况下,应用被分解为多个可管理的分支或服务。每个服务都有一个用RPC或者消息驱动API定义清楚的边界。
微服务架构使得每个服务都可以有专门开发团队来开发,开发者可以自由选择开发技术,提供 API 服务。
微服务架构模式使得每个微服务独立部署,开发者不再需要协调其它服务部署对本服务的影响。
微服务架构模式使得每个服务独立扩展,可以根据每个服务的规模来部署满足需求的实例。
微服务强调了服务大小,实际开发者可能过度强调小,或者并不明确粒度的标准。所以应该秉持一个原则,即微服务的目的是有效的拆分应用,实现敏捷开发和部署。
微服务应用是分布式系统,必然带来固有的复杂性。开发者需要在 RPC 或者消息传递之间选择并完成进程间通讯机制。此外,他们必须写代码来处理消息传递中速度过慢或者不可用等局部失效问题。
分区的数据库架构也会为微服务带来挑战。同时更新多个业务主体的事务很普遍。在微服务架构应用中,需要更新不同服务所使用的不同的数据库。
测试一个基于微服务架构的应用也是很复杂的任务,如面向多业务协同的单元测试,以及集成测试的规划。
微服务的自治管理较为复杂,一个单体应用只需要在复杂均衡器后面部署各自的服务器,但微服务中每个服务应用实例是需要配置诸如数据库和消息中间件等基础服务。每个服务都有多个实例,这就形成大量需要配置、部署、扩展和监控的部分。
微服务还需要一个服务发现机制,以用来发现与它通讯服务的地址(包括服务器地址和端口)。
微服务组织架构
§ 从传统职能型到跨职能产品型
微服务架构与中台战略
§ 将传统前后台体系中的后台进行细分,强化业务和技术中台,把前端应用变得更小更灵活。
微服务与SOA
SOA:是一种设计方法,服务之间通过相互依赖最终提供一系列的功能。一个服务通常以独立的形式存在与操作系统进程中。各个服务之间通过网络调用。
微服务架构:其实和 SOA 架构类似,微服务是在 SOA 上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”,原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。
微服务架构 = 80%的SOA服务架构思想 + 100%的组件化架构思想 + 80%的领域建模思想
SOA的关注点
§ 系统集成:从系统角度,解决企业信息系统间的通信问题,把原先散乱、无规划的系统间网状结构,梳理成有规律的、可治理的系统间星形结构,并引入合理的中间件以及规范标准进行管理,如ESB、技术规范、服务管理规范等。核心目标-有序化。
§ 系统的服务化:从功能的角度,把业务逻辑抽象成可复用、可组装的服务,通过服务的编排实现业务的快速重构。把遗存固有的系统功能转变为通用的业务服务,实现业务逻辑的快速复用。核心目标-复用化。
§ 业务的服务化:从企业的角度,把企业职能抽象成可复用、可组装的服务。把原先职能化的企业架构转变为服务化的企业架构,进一步提升企业的对外服务能力。核心目标-高效化。
微服务的关注点
§ 去中心化
• 每个微服务有自己私有的数据库持久化业务数据。
• 每个微服务只能访问自己的数据库,而不能访问其它服务的数据库。
• 数据的去中心化,进一步降低了微服务之间的耦合度,不同服务可采用不同数据库技术(SQL、NoSQL等)。在复杂的业务场景下,如果包含多个微服务,通常在客户端或者中间层(网关)处理。
§ 服务组件化
• 开发者不再需要协调其它服务部署对本服务的影响。
• 按业务能力来划分服务和开发团队开发者可以自由选择开发技术,提供 API 服务。
§ 基础设施自动化(DevOps、自动化部署)
• 传统的Java EE部署架构,通过展现层打包WARs,业务层划分到JARs最后部署为EAR一个大包,而微服务把应用拆分成为单个独立微服务,应用Docker技术,不依赖任何服务器和数据模型。
• 每个服务运行在自己的进程中,通过轻量的通讯机制联系,这些服务基于业务能力构建,能实现集中化管理。
微服务设计原则
(1)围绕业务概念建模
§ 限界上下文(Boundary Context):一个由显式边界限定的特定职责。每个上下文都有明确的接口,该接口定义了它会暴露哪些模型给其他的上下文。
§ 围绕业务的限界上下文定义的接口,比围绕技术概念定义的接口更加稳定。
§ 松耦合和高内聚:松耦合的服务应该尽可能少地知道与之协作的那些服务的信息;高内聚则是要求把相关的行为聚集在一起,把不相关的行为放在别处。
(2)接受自动化文化
§ 微服务引入了很多复杂性,其中的关键部分是,我们不得不管理大量的服务。引入持续集成、持续交付这些元素势在必行。自动化测试也必不可少。
§ 通过调用统一的命令,以相同的方式把系统部署到各个环境是一个很有用的实践,也是采用持续交付对每次提交后的产品质量进行快速反馈的一个关键部分。
§ 通过把配置都存到版本控制中,我们可以自动化重建服务,甚至重建整个环境。
(3)隐藏内部实现细节
§ 为了使一个服务独立于其他服务,最大化独立演化的能力,隐藏实现细节至关重要。
§ 服务应该隐藏它们的数据库,以免陷入数据库耦合。
§ 对于服务间的交互,应尽量选用与技术无关的 API,从而让你能在不同的服务内自由选择不同的技术栈。
(4)让一切去中心化
§ 类似企业服务总线或服务编配系统的方案,会导致业务逻辑的中心化,应该避免使用它们。使用协同来代替编排,在服务限界内能保持服务的内聚性。
§ 构建微服务不仅要从技术的角度去思考,更得从团队的角度入手。为了最大化微服务能带来的自治性,我们需要持续寻找机会,给拥有服务的团队委派决策和控制权。
(5)可独立部署
§ 应始终努力确保微服务可独立部署。这会使得无论微服务本身 ,还是团队,都越来越具有自治性。
§ 蓝/绿部署:部署两份软件,但只有一个接受真正的请求。在新版本部署之后,首先对其运行一些测试,等测试没有问题后,再切换生产负荷到新版本上。
§ 金丝雀发布:通过将部分生产流量引流到新部署的系统,来验证系统是否按预期执行。新旧版本共存的时间更长,而且经常会调整流量。
(6)隔离失败
§ 超时:应给所有的跨进程调用设置超时,并选择一个默认的超时时间。当超时发生后,记录到日志里看看发生了什么,并相应地调整它们。
§ 断路器:当对一个下游资源的请求发生一定数量的失败后,应采取一种“断路”机制,对接下来继续涌入的请求采取快速失败的做法,以免整个系统崩溃。
§ 舱壁:把自己从故障中隔离开的一种方式。
(7)高度可观察
§ 通过注入合成事务到系统中,模拟真实用户的行为,从而使用语义监控来查看系统是否运行正常。
§ 聚合日志和数据,这样当遇到问题时,就可以深入分析原因。
2.微服务消息机制
点对点方式 :直接调用服务,每个微服务都开放REST API,并且调用其它微服务的接口。在比较简单的微服务应用场景下,这种方式还可行,随着应用复杂度的提升,会变得越来越不可维护,这时尽量不采用点对点的集成方式。
消息代理方式:微服务也可以集成在异步的场景下,通过队列和订阅主题,实现消息的发布和订阅。一个微服务可以是消息的发布者,把消息通过异步的方式发送到队列或者订阅主题下。消费者微服务可以从队列或者主题共获取消息。通过消息中间件把服务之间的直接调用解耦。通常异步的生产者/消费者模式,通过AMQP、MQTT等异步消息规范。
同步消息与异步消息
同步消息 – REST、Thrift
§ 同步消息指客户端需要保持等待直到服务器返回应答。REST是微服务中默认的同步消息方式,它提供了基于HTTP协议和资源API风格的简单消息格式,多数微服务都采用这种方式。
§ Thrift机制采用接口描述语言定义并创建服务,支持可扩展的跨语言服务开发,所包含的代码生成引擎可以在多种语言中创建高效的、无缝的服务,传输数据采用二进制格式,相对XML和JSON体积更小。对于高并发、大数据量和多语言的环境更有优势。
异步消息 – AMQP、STOMP、MQTT
§ 异步消息指客户端不需要一直等待服务应答,有应到后会得到通知。一般采用AMQP、STOMP、MQTT。
§ AMQP:一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。
§ STOMP:一个简单的可互操作的协议, 被用于通过中间服务器在客户端之间进行异步消息传递。
§ MQTT:IBM开发的一个即时通讯协议,可能成为物联网的重要组成部分。
消息接口
消息中间件(MQ)
§ 提供可靠传输的产品;
§ 是消息总线的基础;
§ 建立网络通信的通道,进行数据发送,屏蔽网络通信的复杂度。
消息格式 – JSON、XML、Thrift等
§ 消息格式是微服务中另外一个很重要的因素。SOA的web服务一般采用文本消息,基于复杂的消息格式SOAP和消息定义(xsd)。微服务采用简单的文本协议JSON和XML,基于HTTP的资源API风格。
§ 如果需要二进制,通过用到Thrift、ProtoBuf、Avro。
服务定义接口 – Swagger、RAML、Thrift IDL
§ 如果把功能实现为服务并发布,需要定义一套约定。单体架构中,SOA采用WSDL,WSDL过于复杂并且和SOAP紧耦合,不适合微服务。
§ REST设计的微服务,通常采用Swagger、RAML、YAML定义约定。
§ 对于不是基于REST设计的微服务,比如Thrift,通常采用IDL(Interface Definition Languages),比如Thrift IDL。
3.Docker
服务器运行环境
HTTP Server
§ 通常叫做Web服务器“Web Server”
§ 用于处理HTTP消息,处理HTML文件
§ WEB服务器与客户端打交道,它要处理的主要信息有:session、request、response、HTML、JS、CS等
§ 常用的Http Server有:Apache HTTP Server、IIS
Application server
§ 为不同的应用提供“生存环境”
§ 允许不同的用户进行应用请求连接
§ 用于处理非常规性WEB页面(JSP文件),他动态生成WEB页面,生成的WEB页面在发送给客户端
§ 常用的Application Server有: Weblogic、Tomcat、Jboss
§ 在服务计算中,服务处理引擎如,SOAP engine,就运行在应用服务器中
服务执行引擎(以SOAP Engine为例)
§ 负责处理SOAP的消息请求与消息回复
§ 为每一个服务生成一个服务桩以处理对应服务请求
§ 负责对SOAP数据包进行封装和解析
§ 常用的Http Server有:XFire,Apache Axis等
Web Service
§ Web Service的实现并不管SOAP请求包的解析,以及SOAP回复包的生成
Docker概念
背景
§ 云时代采用标配硬件来降低成本,采用虚拟化手段来满足用户按需使用的需求以及保证可用性和隔离性。
§ 然而无论是KVM还是Xen,在Docker看来,都在浪费资源,因为用户需要的是高效运行环境而非OS,GuestOS既浪费资源又难于管理,更加轻量级的LXC更加灵活和快速。
概念
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。
Docker 是 PaaS 提供商 dotCloud 开源的一个基于LXC(Linux Container)的高级容器引擎,源代码托管在 Github 上,基于go语言并遵从Apache2.0协议开源
LXC(LinuX Containers)
§ 一种操作系统层虚拟化技术,将应用软件系统打包成一个软件容器,内含应用软件本身的代码以及所需的操作系统核心和库,创造出应用程序的独立沙箱运行环境。
LXC的移动性
§ LXC在 linux 2.6 的 kernel 里就已经存在,但其设计之初并非为云计算考虑的,缺少标准化的描述手段和容器的可迁移性,构建出的环境难于迁移和标准化管理。
§ Docker 就在这个问题上做出实质性的革新。
虚拟机的Guest OS即为虚拟机安装的操作系统,是一个完整操作系统内核;虚拟机的Hypervisor层可以理解为硬件虚拟化平台,它在Host OS是以内核态的驱动存在的。
Docker有着比虚拟机更少的抽象层。由于Docker不需要Hypervisor实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上Docker将会在效率上有优势,
在IO设备虚拟化上,Docker的镜像管理有多种方案,比如利用Aufs文件系统或者Device Mapper实现Docker的文件管理,各种实现方案的效率略有不同。
Docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个容器时,Docker不需要和虚拟机一样重新加载一个操作系统内核。
引导、加载操作系统内核是一个比较费时费资源的过程,新建一个虚拟机需要加载Guest OS,这个新建过程是分钟级别的。Docker由于直接利用宿主机的操作系统,则省略了这个过程,因此新建一个容器只需要几秒钟。
现代操作系统是复杂的系统,在一台物理机上新增加一个操作系统的资源开销是比较大的,因此,Docker对比虚拟机在资源消耗上也占有比较大的优势。
Docker的特点
更快速的交付和部署
§ Docker在整个开发周期都可以完美的辅助团队实现快速交付。Docker允许开发者在装有应用和服务本地容器做开发。可以直接集成到可持续开发流程中。
高效的部署和扩容
§ Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。
§ Docker的兼容性和轻量特性可以很轻松的实现负载的动态管理。可以快速扩容或方便的下线应用和服务,这种速度趋近实时。
更高的资源利用率
§ Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。
§ 容器除了运行其中的应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。
更简单的管理
§ 使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的管理。
相对于虚拟机,Docker还存在着以下几个缺点:
§ 资源隔离不如虚拟机,Docker是利用cgroup实现资源限制的,只能限制资源消耗的最大值,而不能隔绝其他程序占用自己的资源。
§ 安全性问题,Docker目前并不能分辨具体执行指令的用户,只要一个用户拥有执行Docker的权限,那么他就可以对Docker的容器进行所有操作,不管该容器是否是由该用户创建,存在一定的安全风险。
§ Docker还在版本的快速更新中,细节调整比较大。一些核心模块依赖于高版本内核,存在版本兼容问题。
Docker架构
Docker引擎
§ Docker引擎是C/S结构的应用
§ Server是一个常驻进程
§ REST API 实现了Client和Server间的交互协议
§ CLI 实现容器和镜像的管理,为用户提供统一操作界面
Docker使用C/S架构,Client 通过接口与Server进程通信实现容器的构建、运行和发布。Client和Server可以运行在同一台主机,也可以通过跨主机实现远程通信。
Docker 镜像(Image)
§ 一个只读的模板,例如:一个镜像可以包含一个完整的操作系统环境,里面仅安装了 Apache 或用户需要的其它应用程序。
§ 镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。
§ Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。
§ 镜像就是一堆只读层(read-only layer)的统一视角。
§ 这些只读层,它们重叠在一起。除了最下面一层,其它层都会有一个指针指向下一层。
§ 这些层是Docker内部的实现细节,并且能够在Docker宿主机的文件系统上访问到。统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统
仓库(Repository)
§ 集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
§ 仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供下载。国内的公开仓库包括时速云 、网易云等,可以提供更稳定快速的访问。
§ 用户也可以在本地网络内创建一个私有仓库。
§ 当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。
§ Docker 仓库的概念跟 Git 类似,注册服务器可以理解为 GitHub 这样的托管服务。
容器(container)
§ Docker 利用容器(Container)来运行应用。容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
§ 一个运行态容器被定义为一个可读写的统一文件系统加上隔离的进程空间和包含其中的进程。
§ 容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
§ 文件系统隔离技术使得Docker成为了一个非常有潜力的虚拟化技术。一个容器中的进程可能会对文件进行修改、删除、创建,这些改变都将作用于可读写层。
Docker客户端与Docker服务器进行交互,Docker服务端负责构建、运行和分发 Docker 镜像
4.调度工具
因为容器没有操作系统或者 hypervisor,容器没有独立运作的能力,所以,它们需要有自己的调度管理工具。
主要任务就是负责在最合适的主机上启动容器,并且将它们关联起来。必须能够通过自动的故障转移(fail-overs)来处理错误,并且当一个实例不足以处理/计算数据时,能够扩展容器来解决问题。
主流容器调度工具
§ Docker开发了Swarm,已被整合进 Docker Toolbox。
§ Apache Mesos & Mesosphere Marathon,目标建立一个高效可扩展容器调度系统
§ Google开源的Kubernetes,是一种较为成熟的容器管理器。
三种工具都能解决缺乏独立运行能力的问题,通过提供一个能跨多主机、多数据中心、多云环境运行的系统。
Kubernetes
一个开源的可以用来自动部署、伸缩和管理容器化应用的系统。Kubernetes集群包含一些基本组成部分:
§ Kubernetes成组地部署和调度容器,这个组叫Pod,常见的Pod包含一个到五个容器,它们协作来提供一个 Service。
§ Kubernetes默认使用扁平的网络模式,让在一个相同 Pod 中的容器共享一个 IP 并使用 localhost 端口,允许所有 Pod 彼此通讯。
§ Kubernetes 使用 Label 来搜索和更新多个对象,就好像对一个集合进行操作一样。
§ Kubernetes 会搭设一个 DSN 服务器来供集群监控新的服务,然后可以通过名字来访问它们。
§ Kubernetes 使用 Replication Controller 来实例化的 Pod,这些控制器对一个服务的中运行的容器进行管理合监控。
Master节点:集群控制节点,管理和控制整个集群,基本上k8s的所有控制命令都发给它,它负责具体执行过程。在Master上主要运行:
§ Kubernetes Controller Manager(kube-controllermanager):k8s中所有资源对象的自动化控制中心,维护管理集群的状态,比如故障检测,自动扩展,滚动更新等。
§ Kubernetes Scheduler(kube-scheduler): 负责资源调度,按照预定的调度策略将Pod调度到相应机器上。
§ etcd:保存整个集群的状态。
Node节点:除了master以外的节点被称为Node节点。每个Node都会被分配一些工作负载,当某个Node宕机时,该节点上的工作负载就会被Master自动转移到其它节点上。在Node上主要运行着:
§ kubelet:负责Pod对应的容器的创建、启停等任务,同时与Master密切协作,实现集群管理的基本功能。
§ kube-proxy:实现service的通信与负载均衡。
§ docker(Docker Engine):Docker引擎,负责本机的容器创建和管理。
Kubernetes使用label和pod的概念来将容器划分为逻辑单元。Pods是同地协作容器的集合,这些容器被共同部署和调度,形成了一个服务,这是Kubernetes和其他两个框架的主要区别。相比于基于相似度的容器调度方式(就像Swarm和Mesos),这个方法简化了对集群的管理。
Kubernetes调度器的任务是寻找那些PodSpec.NodeName为空的pods,然后对它们赋值来调度对应集群中的容器。
相比于Swarm和Mesos,Kubernetes允许开发者通过定义PodSpec.NodeName来绕过调度器。调度器使用谓词(predicates)和优先级(priorites)来决定一个pod应该运行在哪一个节点上。
谓词是强制性的规则,能够用来调度集群上一个新的pod。如果没有任何机器满足该谓词,则该pod会处于挂起状态,直到有机器能满足条件。
§ Predicate:节点的需求
§ PodFitPorts:没有任何端口冲突
§ PodFitsResurce:有足够的资源运行pod
§ NoDiskConflict:有足够空间来满足pod和链接数据卷
§ MatchNodeSelector:能够匹配pod中的选择器查找参数
§ HostName:能够匹配pod中的host参数
优先级用来判别哪一个才是最适合运行pod的机器。优先级是一个键值对,key表示优先级的名字,value是该优先级的权重。
§ Priority:寻找最佳节点
§ LeastRequestdPriority:需要的CPU和内存在当前节点可用资源的百分比,具有最小百分比的节点最优
§ BalanceResourceAllocation:拥有类似内存和CPU使用的节点。
§ ServicesSpreadingPriority:优先选择拥有不同pods的节点。
5.DevOps
概念
DevOps(Development和Operations的组合词):是一组过程、方法与系统的统称,用于促进开发部门、技术运营和质量保障部门之间的沟通、协作与整合。
它是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或管理。通过自动化“软件交付”和“架构变更”的流程,使得构建、测试、发布软件能够更加地快捷、频繁和可靠。
它的出现是由于软件行业日益清晰地认识到:为了按时交付软件产品和服务,开发和运营工作必须紧密合作。
微服务与持续集成
持续集成(CI)是一种开发实践,是指开发人员每天多次将代码整合到共享的代码库中,然后通过自动化构建验证每次提交,使团队能够及早发现问题。
持续交付(CD)是指通过自动化在比较短的一个个迭代中快速发布软件的做法,允许团队更频繁地交付可以工作的软件产品。 其重点——持续整合,内置测试,持续监控和分析反馈都指向软件行业的整体趋势:提高应变能力。
持续集成的最佳实践
§ 维护单一代码库
§ 自动化构建
§ 使构建能够自我测试
§ 保持构建速度
§ 在生产环境相同的产品环境中测试
§ 任何人都要以轻松获得最新的可执行文件
§ 每个人都可以看到发生了什么
§ 自动部署
持续交付流程
1. 提交代码:在本地构建并通过单元测试之后,可以将代码提交到代码仓库的开发分支中。
2. 自动构建:包括编译,链接,打包,在一些大型项目中这个速度往往需要几十分钟以上。
3. 自动代码检查:各种语言都有各自的代码静态检查工具,检查出严重的错误则立即终止构建流水线。
4. 自动执行单元测试:确保这次提交不会造成其他模块的单元测试失败,任何一条单元测试不通过,都会终止构建流水线。
5. 自动生成文档:利用自动文档生成工具,分析代码并生成 API 和帮助文档。
6. 自动部署在测试环境:利用部署脚本将软件部署到测试环境,注入预设的配置变量并启动服务。
7. 自动执行功能测试:在测试环境中,自动运行所有需要依赖外部环境的 API 和 E2E(端到端)的测试。
8. 将代码合并入主分支:由产品负责人决定是否合并到主分支。
9. 自动运行性能测试:生成性能测试和剖析报告,包括吞吐量、最耗时模块、以及对系统资源消耗的各种指标。
10. 探索性测试:手工进行一些探索性测试。
Jenkins
§ 提供了一种易于使用的持续集成系统,使开发者从繁杂的集成中解脱出来,专注于更为重要的业务逻辑实现。
Jenkins应用场景
§ 集成SVN/git客户端实现源代码下载检出
§ 集成maven/ant等构建工具实现源码编译打包单元测试
§ 集成sonarqube对源代码进行质量检查
§ 集成SaltStack/Ansible实现自动化部署发布
§ 集成Jmeter/Soar/Kubernetes
五、服务质量评估
1.服务质量概念
质量(QoS)是反映实体满足明确或隐含需要能力的特性的总和。[ ISO8402 ]
§ “实体”(Entity)是能够单独描述和考虑的对象。任何“实体” 都是为满足用户的“需要”而生产的。
§ 质量定义中的“需要”有两种情况,即“明确的需要”和“隐含的需要”。
§ “能力”(Ability)是指一个实体进行指定的活动并获得符合规定要求结果的本领。
产品质量:附着于有形的产品上,比较容易度量
服务质量:服务本身的“无形性”决定了服务质量的无形性
§ 所提供的服务对顾客带来外在及隐含利益的程度
§ 顾客对服务的期望与顾客接触服务后实际感知到的服务之间的差距,即:
• 期望的服务(ES) – 感知到的服务(PS)
2.服务质量特征
服务质量的两个方面
§ 过程质量(Process quality):在服务过程中,顾客对此服务的主观评价
§ 产出质量(Output quality):顾客对服务成果的衡量
服务质量的四大特征
§ 服务质量是一种“主观质量”
§ 服务质量是一种“互动质量”
§ “过程质量”在服务质量构成中占据及其重要的地位
§ 对服务质量的度量,无法采用制造业中所采用的方法
商务服务质量的维度
§ 可靠性(Reliability):可靠地、准确地履行服务承诺的能力。
§ 快速响应性(Responsiveness):帮助顾客并迅速提供服务愿望。
§ 保证性(Assurance):服务人员的友好态度、所需的技能和知识,以增强顾客对服务质量的信心感。
§ 移情性(Empathy):设身处地为顾客着想,把每一位顾客当作独特、重要的个人,给予个性化的服务。
§ 有形性(Tangibles):有形的设施、设备、人员的外表。
§ 可访问性(Access):服务可被顾客方便地、容易地获取的程度。
§ 礼貌(Courtesy):服务人员优雅、尊敬、体谅、友好。
§ 沟通(Communications):以顾客能够理解的语言进行交流,针对不同的顾客使用不同的沟通方式。
§ 可信性(Credibility):公司的信息、声望、服务者的个人品质等。
§ 安全性(Security):较低的危险、风险和疑问。
§ 理解性(Understanding):正确理解用户的个性化需求。
在IT服务系统中,被评价者为通过互联网向外提供服务的Web Services
仍可用传统的质量评价指标
§ 可靠性 (Reliability)
§ 快速响应性 (Responsiveness)
§ 保证性 (Assurance)
§ 移情性 (Empathy)
§ 有形性 (Tangibles)
其他QoS指标:可互操作性、可用性、可访问性、可持续性、响应时间、延迟、吞吐率、可靠性、安全性、价格等
3.服务质量指标
服务性能:指根据吞吐量和延迟对服务进行测量
§ 吞吐量较大且延迟值较小,表示 Web 服务性能良好。 吞吐量表示在给定时间内被服务的 Web 服务请求数。
§ 延迟是发送请求和接收响应之间的往返时间。
可用性:Web 服务是否存在或是否已就绪可供立即使用
§ 可用性表示服务可用的可能性。高值表示服务一直可使用,低值表示无法预知在某个特定时刻服务是否可用。
§ 与可用性有关的还有修复时间(Time-To-Repair,TTR)。 TTR表示修复已经失效的服务要花费的时间。理想情况下,较低的 TTR 值是合乎需要的。
可访问性:表示能够为 Web 服务请求提供服务的程度。
§ 它可表示为一种可能性尺度,用来表示在某个时间点上成功地实例化服务的成功率或机会。
§ 可能存在Web 服务可用,但却无法访问的情形。通过构建一个可高度伸缩的系统使 Web 服务得到很高的可访问性。
§ 可伸缩性是指不管请求量如何变化,都能够始终如一地为请求服务的能力。
安全性:指通过验证涉及到的各方、对消息加密以及提供访问控制来提供机密性和不可抵赖性。
§ 由于 Web 服务调用是发生在公共互联网上,安全性非常重要。根据服务请求者的不同,服务提供者可以用不同的方法来提供安全性,所提供的安全性也可以有不同的级别。
可靠性:指表示能够维护服务和服务质量的程度。
§ 每月或每年的失效次数是衡量 Web 服务可靠性的尺度。
§ 另一种意义上,可靠性是指服务请求者和服务提供者发送和接收消息的有保证和有序传送。
完整性:指 Web 服务如何维护正确的交互性。
§ 适当地执行 Web 服务事务会实现正确的交互。一个事务是指一系列将被当作单个工作单元的活动。
§ 要使事务成功,必须完成所有的活动。如果一个事务未完成,那么所做的全部更改都要被回滚。
4.服务质量监控与评价
5.服务级协议
服务等级协议SLA:Service Level Agreement
§ 服务提供者与顾客双方之间通过协商所确定的一种正式的协议或合同,描述了对服务相关功能、质量、服务双方的责任与义务等信息。
§ SLA也包含了一系列质量相关参数 (QoS parameters),用于度量服务的预期目标。
§ SLA代表了顾客的声音(Voice of Customer, VOC)。
在服务系统全生命周期内,这些质量需求应始终被充分地考虑,以使得服务系统能够满足顾客需求,达到较高的服务满意度。
服务系统在设计过程中要经历多个阶段
§ 收集顾客需求;
§ 服务建模(多层模型);
§ 选择服务构件并进行组合;
§ 生成服务系统。
在各阶段之间存在“信息的损失”,导致5个Gap产生,从而使得最终服务系统无法100%与顾客声音VoC一致。
如何减小/消除这些Gap?
§ 采用Top-Down的途径,将SLA/QoS从顾客需求出发,逐渐向下转化到各层服务模型的质量,最终落实到服务系统的质量上去。