一、SOA是什么?
SOA本质是一种组件模型。下面看一下百度的定义:
面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言(与平台无关,与语言无关,与操作系统无关)。这使得构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。
SOA的应用场景:
(1)一开始我们的系统可能是这样的:
当我们的项目比较小时,我们只有一个系统,并且把他们写到一起,放在一个服务器上,但是随着平台越来越大,数据量越来越大,我们不得不通过分库,把多个模块的数据库分别放在对应得服务器上,每个模块调用自己的子系统即可。
随着我们系统的进一步复杂度的提示,我们不得不进一步对系统的性能进行提升,我们将多个模块分成多个子系统,多个子系统直接互相调用(因为SOA一般用于大型项目,比较复杂,所以一般总系统不会再集成,会拆分多个,分别做成服务,相互调用)。当我们的电商UI进行一个下订单的任务时,多个服务直接互相调用,系统通过数据总线,分别调用对于的子系统即可。
企业数据总线:企业数据总线不是对多个子模块的集成,他在这里充当数据通道的作用,数据总线不关心业务,数据总线根据给的地址和协议去调服务,上端不关心服务在哪里是什么,只找数据总线。
上面几个图应该算是比较清楚了,随着业务的深入,我们不得不对系统进行调整,分别是对数据和业务的拆分,最后每个子系统对面提供服务。
SOA主要的使用场景:
通过上面的图我们可以看出,多个子系统直接相互交互,相互调用非常凌乱,这样我们就很不爽,所以我们就用到了我们的SOA架构,SOA又叫服务治理,SOA就是帮助我们把服务之间调用的乱七八糟的关系给治理起来,然后提供一个统一的标准,把我们的服务治理成下图所示,以前我们的服务是互相交互,现在是只对数据总线进行交互,这样系统就变得统一起来。
统一标准:各系统的协议、地址、交互方式。
新的交互方式:各个系统分别根据统一标准向数据总线进行注册,各子系统调用其他子系统时,我们并不关心如果找到其他子系统,我们只招数据总线,数据总线再根据统一标准找其他子系统,所以数据总线在这里充当一个只路人的作用。
数据总线是什么?
其实我在上面写了,数据总线是起到调度服务的作用,数据总线不是集成服务,数据总线更新一个调度框架,每个服务需要根据约定向数据总线注册服务,那么如何注册那?其实数据总线就像一个字典结构,
数据总线里面一个key对于一个value,key指的是服务名,value则是服务的调度方式,还有一点需要说明的是,数据总线只是指路人,服务是不经过数据总线的,如上图的黄色线的路径。
数据总线通过域名解析实现:一个域名绑定多台服务器,ajax也可以,dns也可以,解析域名嘛。
其实数据总线还有一些高级应用,比如心跳检测,实现负载均衡等等,就不细说了,目前应用数据总线的有阿里的dubbo,还有zookeeper,以及Spring Cloud的Eureka
SOA最显著的优势:
(1)SOA具有低耦合性特点,业务伙伴对整个业务系统的影响较低
(2)SOA与平台无关,减少了业务应用实现的限制
更深入理解SOA,请看这篇文章:https://www.cnblogs.com/renzhitian/p/6853289.html
SOA与微服务架构的区别:
从下面一张图基本可以看出微服务架构的区别:
我觉得SOA与微服务的区别在于如下几个方面:
微服务相比于SOA更加精细,微服务更多的以独立的进程的方式存在,互相之间并无影响;
微服务提供的接口方式更加通用化,例如HTTP RESTful方式,各种终端都可以调用,无关语言、平台限制;
微服务更倾向于分布式去中心化的部署方式,在互联网业务场景下更适合;
二、WebService是什么?
关于WebSerivce和Soap的发展历史,可以看一下这篇文章:https://blog.csdn.net/cxboyee/article/details/77802849
我们看看百度百科对WebService的定义:
Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。 [1]
Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。Web Service是自描述、 自包含的可用网络模块, 可以执行具体的业务功能。Web Service也很容易部署, 因为它们基于一些常规的产业标准以及已有的一些技术,诸如标准通用标记语言下的子集XML、HTTP。Web Service减少了应用接口的花费。Web Service为整个企业甚至多个组织之间的业务流程的集成提供了一个通用机制。
所以WebService是一种技术,比如可以让使用.NET开发的应用程序调用使用Java开发的应用程序的接口,互相交换数据或集成,或者反过来。
所以只要是能够平台独立,无关语言,无关操作系统,基于XML作为数据交换格式的应用程序都可以叫做Web Service。
要实现Web Service,需要一套协议来支持(WebService三要素:SOAP、WSDL、UDDI):
(1) SOAP:
SOAP(Simple Object Access Protocol:简单对象访问协议)是微软、IBM等大公司联合制定的一个协议规范。SOAP是交换数据的一种协议规范,是一种轻量的、简单的、基于XML(标准通用标记语言下的一个子集)的协议,它被设计成在WEB上交换结构化的和固化的信息。
(2)WSDL
Web Service描述语言WSDL,用于描述Web Service及其函数、参数和返回值(也就是描述如何访问具体的接口)。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的。
(3)UDDI
UDDI 的目的是为电子商务建立标准;UDDI是一套基于Web的、分布式的、为Web Service提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提供的Web Service注册,以使别的企业能够发现的访问协议的实现标准。(简单一句话概括就是:用来管理,分发,查询webService)
三、什么是RPC?
简单来说:SOAP=HTTP+XML,HTTP是基于TCP的超文本传送协议。
RPC(remote procedure call:远程过程调用):简单的说,RPC就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法(可以统称为服务)并得到返回的结果。
RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯)
RPC 是一个请求响应模型。客户端发起请求,服务器返回响应(类似于Http的工作方式)
RPC 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)
RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
RPC工作原理:
运行时,一次客户机对服务器的RPC调用,其内部操作大致有如下十步:
1.调用客户端句柄;执行传送参数
2.调用本地系统内核发送网络消息
3.消息传送到远程主机
4.服务器句柄得到消息并取得参数
5.执行远程过程
6.执行的过程将结果返回服务器句柄
7.服务器句柄返回结果,调用远程系统内核
8.消息传回本地主机
9.客户句柄由内核接收消息
10.客户接收句柄返回的数据
JAVA能够使用的远程调用技术:
远程方法调用(Remote Method Invocation,RMI)
Caucho的Hession和Burlap(Hession是二进制协议,而Burlap是基于XML的)
Spring基于HTTP的远程服务HttpInvoker
使用JAX-RPC和JAX-WS的Web Service(基于SOAP的web服务)
注意:RPC都是同步返回技术,也就是说程序会一直等待,直到超时或者得到返回结果。JMS(具体实现有ActiveMQ等),AMQP(具体实现有RabbitMQ等)才是异步返回技术
不管我们使用哪种远程调用技术,Spring为使用这几种不同的技术访问和创建远程服务都提供了广泛的支持。
四、什么是RMI?
RMI是Java最初的远程方法调用技术。RMI最初在JDK1.1被引入到Java平台中,它为Java开发者提供了一种强大的方法来实现Java程序间的交互。在RMI之前,对于Java开发者来说,远程调用的唯一选择就是CORBA(在当时,需要购买一种第三方产品,叫做Object Request Broker[ORB]),或者手工编写Socker程序。
但是开发和访问RMI服务是非常乏味无聊的,它涉及到好几个步骤,包括程序的和手工的。Spring简化了RMI模型,简化了RMI的使用。
如果你曾经创建过RMI服务,应该会知道这会涉及如下几个步骤:
1.编写一个服务实现类,类中的方法必须抛出java.rmi.RemoteException异常;
2.创建一个继承于java.rmi.Remote的服务接口;
3.运行RMI编译器(rmic),创建客户端stub类和服务端skeleton类;
4.启动一个RMI注册表,以便持有这些服务;
5.在RMI注册表中注册服务。
哇!发布一个简单的RMI服务需要做这么多的工作。除了这些必需的步骤外,你可能注意到了,会抛出相当多的RemoteException和MalformedURLException异常。虽然这些异常通常意味着一个无法从catch代码块中恢复的致命错误,但是我们仍然需要编写样板式的代码来捕获并处理这些异常——即使我们不能修复它们
这些步骤和原生的jdbc一样难用。。。。不能重复造轮子,所以用Spring吧。
RMI是一种实现远程服务交互的好办法,但是RMI有一些缺点和不足:
RMI很难穿越防火墙。因为RMI使用任意端口来交互——这是防火墙通常所不允许的。如果是内网,就不需要担心这个问题。如果是在互联网上运行,这就麻烦了。
RMI是基于JAVA的,使用了JAVA的序列化机制,所以通过网络传输的对象类型必须要保证在调用两端的Java运行时中是完全相同的版本。所以就意味着客户端和服务端都必须使用JAVA来开发才行。这就是一个限制了。
五、什么是Rest?
REST全称:Representational State Transfer。Rest不是协议也不是规范,而是一种接口、服务、系统之间通讯的风格。
REST可以用来替代传统的SOAP Web服务。SOAP一般会关注行为和处理(比如RMI,Hessian,Spring的HttpInvoker,jaw-xs,知名的XFile(新的如CXF)、Axis1、Axis2 等等),而REST关注的是要处理的数据。
REST与RPC几乎没有任何关系。RPC是面向服务的,并关注于行为和动作;而REST是面向资源的,强调描述应用程序的事物和名词。REST就是将资源的状态以最适合客户端或服务端的形式从服务器端转移到客户端(或者反过来)。
在REST中,资源通过URL进行识别和定位。
举个栗子:
Marcus是一个农民,他有4头牛,12只鸡和3头奶牛。他现在模拟一个REST API,而我是客户端。如果我想用REST来请求当前的农场状态,我仅会问:“State?”Marcus会回答:“4头猪、12只鸡、3头奶牛”。
这是REST最简单的一个例子。Marcus使用表征来传输农场状态。表征的句子很简单:“4头猪、12只鸡、3头奶牛”。
再往下看,看我如何让Marcus用REST方式添加2头奶牛?
按照常理,可以会这样说:Marcus,请在农场你再添加2头奶牛。难道这就是REST方式吗?难道就是通过这样的表征来传输状态的吗?不是的!这是一个远程过程调用,过程是给农场添加2头奶牛。
Marcus很愤怒地响应到:“400,Bad Request”,你到底是什么意思?
所以,让我们重新来一次。我们怎样做到REST方式呢?该怎样重新表征呢?它应该是4头猪、12只鸡、3头奶牛。好,让我们再次重新表征……
我:“Marcus,……4头猪、12只鸡、5头奶牛!”
Marcus:“好的”。
我:“Marcus,现在是什么状态?”
Marcus:“4头猪、12只鸡、5头奶牛”。
我:“好!”
看到了吗?就这样简单。
为什么RPC也不够好?
从逻辑角度来看,为什么会更加青睐REST而不是RPC(Remote Procedure Call,远程过程调用 ),因为它极大的降低了我们沟通的复杂度,通过把表征作为唯一的沟通的方式。无需去讨论过程(添加一头牛?增加一种动物类型?给鸡的数量翻倍还是卖掉所有猪?)我们只需讨论表征,并且使用这个表征来达到我们想要的目标,很简单,不是吗?我不希望和Marcus的沟通失败,因为我们彼此的理解过程会不一样,所以只需要知道最后的状态就行。但这仅仅是创建RPC会产生许多问题之一。如果你使用RPC,你需要设计一些程序嵌入到某种结构中。这种结构需要存储参数、错误的代码、返回值等。
总结:
SOA和微服务架构都是一种组件模型,一种架构方式,不依赖于任何技术,因此SOAP、RPC、REST是对SOA和微服务架构的组件或服务之间通信方式的不同实现。