SOA

SOA是Service Oriented Architecture的缩写,面向服务架构。Bezos(亚马逊CEO)将Amazon的软件架构完全转换为SOA,它是如此关键,从某种程度上改变了亚马逊 Amazon 的命运。

思想

SOA的精髓是严格的松散耦合,不允许直接访问其它服务的数据,大家按照一个契约或标准(service interface)来进行交流。

百科解释:

面向服务的体系结构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种这样的系统中的服务可以以一种统一和通用的方式进行交互。

优点

  1. 松耦合
  2. 易上手
  3. 可复用(DRY原则 Don’t Repeat Yourself)
  4. 组件化
  5. 跨平台

松耦合

之前的所有操作集成于某个功能模块,包括数据操作、逻辑处理等等。当项目一旦大起来,可能一次操作要操作多个功能模块,那么这种嵌套关系就变得很复杂,导致相互依赖,那么之前所有的东西修改起来都会影响到其它业务的执行,这样维护起来变得相当困难。

而松耦合恰好就是解决这种依赖关系,通过接口访问数据信息。不允许直接访问其它服务的数据,因为它破坏了封装性,造成了一种内部依赖。当服务的内部状态发生改变,则这改变带来的影响会散播到所有依赖该服务的地方 —— 做软件的人都知道,这是最头疼的事情,各种莫名的bug往往在这种情况下产生。

组件化

laravel的composer组件库、ruby的gem组件库、jquery组件库等等, 组件之所以为组件,是因为当下载或拉取之后,能够通过很简单的东西实现某一功能。

可复用

SOA架构是面向服务的架构设计,它通过封装一个服务,所有的操作数据功能,都只能用给定的接口使用。当需要扩展一个功能时,如果已存在相应接口,那么只需要调取相应的接口即可。

跨平台、跨语言

Service层可以用任何语言来实现,也可以使用多种语言,实现物尽其用的原则,比如PHP擅长处理逻辑、Ruby语言擅长高并发、java大数据等。但提供的接口统一,不管服务层如何实现,应用层只需要调用接口即可。

易上手

何为易上手?
当进入到一个公司,首先要做的是熟悉代码,少则四五天,多则七八天,因为嵌套太多,要屡清楚层层的关系。而SOA架构呢,服务层跟应用层分离,刚进入公司,你直接可以写东西,接口数据唯一,你只需要了解都有啥接口,然后这些接口传递参数、返回的数据就可以了。

问题

为什么不在每个模块中封装API接口呢,供给其他模块使用?而是要单独抽离服务层出来呢?只要API不发生变化,无论library怎么折腾,都不会影响依赖于该library的地方啊?


考虑一下这样一个功能:给定一张图片的路径,获取里面的exif信息。这个功能使用python实现再简单不过了:

import exifread
import urllib
def get_exif(path):if path.startswith('http'):path, _ = urllib.urlretrieve(path)f = open(path, 'rb')return exifread.process_file(f, details=False)

当然,这个实现并不完善,而且对http不友好(整个文件被download下来,写入磁盘然后再被读出),但基本可用。

如果我们把它作为一个package给其它人用,似乎也没有什么大问题。姑且这么做吧。

后来随着系统的扩张,某个新功能X选择用go语言实现。不巧的是,X也需要从图片里读取exif信息这个功能。go语言无法直接调用python代码,如果要坚持使用static linking的方式,摆在面前有两个选择:

  • 用go语言把相同的服务重新实现一遍
  • 用c重写获取exif信息这个功能的核心代码,然后分别创建python和go语言的对应的方法。
  • 在python模块中封装API,供其它人调用。

方法一自然不好,违反了DRY (Don’t Repeat Yourself) principle。

方法二虽然理论上可行,但是在给自己挖坑 —— 本来只需要维护几行代码的,现在变成了三种语言的三套代码。

方法三是将它作为一种服务,提供对应的接口,实现对应功能,但是当将来发展时,python模块因为版本更迭,要去除。这时,提供的接口也相应会被砍掉,从而导致了管理空难。

最好的方式就是单独抽离一层出来,做成一个服务,所有模块的增加与去除都不影响该项服务的任何功能。
如果我们把获取exif信息这个功能做成一个服务,该怎么做?以下是一个方案

import exifread
import urllib
import zmqENDPOINT = "tcp://*:5555"def main_loop():ctx = zmq.Context()sock = ctx.socket(zmq.REP)sock.bind(ENDPOINT)print("Listen to %s" % ENDPOINT)while True:cmd, path = sock.recv_string().split()[:2]print("Got request: %s %s" % (cmd, path))if cmd == 'EXIF':if path.startswith('http'):path, _ = urllib.urlretrieve(path)f = open(path, 'rb')tags = exifread.process_file(f, details=False)tags = dict(map(lambda (k,v): (k, str(v)), tags.iteritems()))print("Sending response: %s" % tags)sock.send_json(tags)if __name__ == '__main__':main_loop()

exif服务和该服务的调用者之间的约定是:

  1. 调用者向5555端口发送 CMD PATH(如:EXIF http://domain.com/img.jpg)
  2. exif服务会返回json格式的exif信息
    如果用go语言访问该服务,则非常简单:
package mainimport (zmq "github.com/pebbe/zmq4""log"
)func main() {sock, err := zmq.NewSocket(zmq.REQ)if err != nil {log.Printf("err create: %v", err);return}defer sock.Close()err = sock.Connect("tcp://127.0.0.1:5555")if err != nil {log.Printf("err connect: %v", err);return}_, err = sock.Send("EXIF https://farm8.staticflickr.com/7163/6602016347_24803ae230_o.jpg", zmq.DONTWAIT)if err != nil {log.Printf("err send: %v", err);return}msg, err := sock.Recv(zmq.Flag(0))if err != nil {log.Printf("err recv: %v", err);return}log.Printf("exif: %v\n", msg);
}

这样做除了把服务和其调用者使用的语言解耦外,还有很多其它好处:

  1. 服务本身非常专一,不会混入乱七八糟的逻辑,因而更容易定位问题。
  2. 服务本身很好测量,接口并发、负载等。测量是优化的前提,一旦有好的测量手段,那么优化只是一个时间问题,总能想到办法(甚至可以换一种语言重写)。
  3. 有一天我们发现这个服务不但可以内部使用,还可以公开给第三方获得收入,只需要再添加一个新的服务调用者,然后把获取的数据通过http service发布即可。

多说几句「把服务和调用者使用的语言解耦」的重要性。

从软件工程的角度来说,这有助于项目的快速高质完成。我们知道,每种语言(及其类库)都有其优缺点,在需要glue language的场景下使用c而不是python,在需要高性能高并发的场景下使用ruby而不是go语言,都只能是事倍功半。

从软件工程师的角度来说,他们可以不必深深陷入已有系统的泥沼中,完整了解整个系统的来龙去脉,代码的曲折历史就能开始做他们该做的活。理想情况下,做一个新的功能,有80%和老代码解耦,只有20%通过接口耦合。如果对于一个已经在同行业里浸淫过的人来说,一个系统需要花至少三个月的时间培训和学习才能开始上手,那么这一定是系统架构出了问题。

有人认为SOA无法适用于对性能要求很高的场景,这是一个误区。任何系统都有一个现实的性能指标,而非毫无目标的越高越好。如果是那样,撇开操作系统提供的服务,所有代码直接用汇编构造理论上能榨干硬件最大的能力。但除非极少数项目,没有人会那么做。有了可参照的性能指标,服务需要做的就是达成这个性能指标。硬件的选择,开发语言的选择,并发模型的选择,各种工具的选择,直至消息传递方案的选择,都可以帮助达成约定的性能指标。使用SOA反倒促成了这种多样的选择,同时其松散的结构让大刀阔斧地调优成为可能。如果系统是紧密耦合的,即便有测量的手段感知到影响性能的关键路径,但由于「牵一发而动全身」,反倒不好处理。

最后,SOA的思想其实对软件工程师的职业生涯大有裨益。你不必被「锁定」在某个公司使用的某只语言,某个平台,或者某种框架上,而是可以依行业的「最佳实践」,进行「自由裁量」。某个公司总有倒掉的那一天,某种技术总有会没落的那一刻,不变的只有变化和思想

【微服务】什么是SOA服务架构?相关推荐

  1. 【软件定义汽车】【服务篇】SOA服务及接口设计、服务部署、序列化

    目录 一.服务及服务接口设计 二.服务接口部署: 三.服务接口序列化属性定义:

  2. 规划 SOA 参考架构

    这阵子参与编写一本SOA 专刊,因篇幅关系,部分内容无法纳入,在此将其以博客形式发表. SOA 参考架构 (Reference Architecture) 是一个框架,使各个项目都有一个遵从的依据,借 ...

  3. 微服务(MSA) 和 面向服务架构(SOA) 的区别和联系

    文章目录 微服务(MSA) 和 面向服务架构(SOA) 的区别和联系 1.相似之处 2.区别和联系 2.1.基于SOA的架构 2.2.基于微服务的架构 微服务(MSA) 和 面向服务架构(SOA) 的 ...

  4. 微服务是否使SOA变得无关紧要?

    服务导向架构(简称SOA,service-oriented architecture)已经死亡?你可能会这么想. 但其实不然.的确,随着新技术的出现,SOA本身的价值可能已经大不如前,但是SOA的遗产 ...

  5. springcloud全局过滤_微服务技术SpringCloud 互联网网站架构演变过程

    网站架构演变过程 传统架构 传统的SSH架构,分为三层架构 web控制层.业务逻辑层.数据库访问层. 传统架构也就是单点应用,就是大家在刚开始初学JavaEE技术的时候SSH架构或者SSM架构,业务没 ...

  6. 【转载】SOA 服务架构之简介及理解

    [转载]SOA 服务架构之简介及理解 自:https://blog.csdn.net/lch_2016/article/details/81062351 扩展阅读: SOA架构和微服务架构的区别:(推 ...

  7. 微服务开发中的数据架构设计

    前言 微服务是当前非常流行的技术框架,通过服务的小型化.原子化以及分布式架构的弹性伸缩和高可用性,可以实现业务之间的松耦合.业务的灵活调整组合以及系统的高可用性.为业务创新和业务持续提供了一个良好的基 ...

  8. 基于微服务的电商系统架构

    分层 微服务设计 微服务微内核 基于微服务的电商系统架构 转载于:https://www.cnblogs.com/davidwang456/articles/9221369.html

  9. Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲

    Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲 Java生鲜电商平台:   微服务是当前非常流行的技术框架,通过服务的小型化.原子化以及分布式架构的弹性伸缩和高可用性, ...

  10. 微服务架构-服务注册中心和服务网关(6.8) (转载)

    原文链接:微服务架构-服务注册中心和服务网关(6.8) 这篇文章还是基于SpringCloud开源框架体系来谈下对Eureka服务注册中心和Zuul服务网关在使用上的一些理解和说明.在使用微服务架构进 ...

最新文章

  1. Effective C# 原则13:用静态构造函数初始化类的静态成员(译)
  2. Oracle 12c 安装(内附软件包)
  3. java 判断 中文字符_java中判断字符串中是否有中文字符
  4. nslang oracle_RAC11g+DG 高可用容灾方案部署
  5. Git ----fatal: unable to access ‘https://gitee.com/***.git/‘: SSL certificate problem: unable
  6. rshd: 0826-813 Permission is denied.
  7. P - C语言实验——某年某月的天数
  8. 二分法其实很简单,为什么老是写不对!!!
  9. 查看计算机桌面隐藏文件夹,怎么查看隐藏文件?2种方法教你查看电脑中的隐藏文件...
  10. 用the_excerpt处理中文文章字数限制的方法
  11. 「鹿班智能设计平台」是如何工作的
  12. 20个最佳的flash游戏教程
  13. mysql按 结束不了语句_每一条 mysql 命令必须以( )结束,否则系统判断语句尚未结束,暂不执行_大学计算机A1重修答案_学小易找答案...
  14. mysql只能存1000条数据_为什么我mysql的表添加了1000条记录之后就存不进去数据了,客户端也没报错...
  15. python模块-----pyqrcode
  16. 艺术画笔见乾坤—Matplotlib
  17. 图书借阅管理系统的设计与实现(Java+SSH+MySQL)
  18. 中小企业怎样搭建软件安全开发流程和规范
  19. mybatis与ibatis区别
  20. 代码高亮插件SyntaxHighlighter

热门文章

  1. 数据结构与算法分析(五)队列
  2. 开源首发!Android入门“神器“——《Android编程入门教程》,理论与实战齐飞!
  3. 110KV降压变电所电气一次部分及防雷保护设计
  4. sniffer与网络执法官,p2p终结者的简单对比
  5. AEAI CRM 客户关系管理系统项目介绍
  6. 第十一章.软件工程(上)
  7. windows系统上删除顽固文件
  8. 基于S7-200 PLC控制的小型自动化立体仓
  9. 如何准备PMP新版大纲考试?
  10. 【个人经验】3个步骤教你拿到软件著作权证书