SOA架构,微服务,技术实践汇总
2016-11-11 10:47
621 查看
service-oriented architecture,SOA SOA架构,是一种粗粒度、开放式、松耦合的服务结构,要求软件产品在开发过程中,按照相关的标准或协议,进行分层开发。 通过这种分层设计或架构体系可以使软件产品变得更加弹性和灵活,且尽可能的与第三方软件产品互补兼容,以达到快速扩展,满足或响应市场或客户需求的多样化、多变性。
SOA是面向服务的架构,每个厂商都有自己的定义和解释。有人说是一种架构,有人说是一种方法论。
SOA体系架构带来的主要观点是业务驱动IT,即业务驱动和业务更加紧密地联系在一起。以粗粒度的业务服务作为基础来对公司业务进行建模, 这样就可以产生简洁的业务和系统视图;以业务服务为基础来实现的IT系统更灵活、更易于重用、也更快地应对企业业务需求的变化;以业务服务为基础, 通过显式地方式来定义、描述、实现和管理业务层次的粗粒度服务(包括业务流程),提供了业务服务模型和相关IT业务之间提供了更好的"可追溯性"
SOA的目标在于让IT变得更有弹性,以更快地响应业务单位的需求,实现实时企业。 ESB全称为Enterprise Service Bus,即企业服务总线。 它是传统中间件技术与XML、Web服务等技术结合的产物。ESB提供了网络中最基本的连接中枢,是构筑企业神经系统的必要元素。
微服务(Microservice)架构
作者:何明璐 链接:https://www.zhihu.com/question/37808426/answer/93335393
微服务是指开发一个单个 小型的但有业务功能的服务,每个服务都有自己的处理和轻量通讯机制,可以部署在单个或多个服务器上。
微服务也指一种种松耦合的、有一定的有界上下文的面向服务架构。也就是说,如果每个服务都要同时修改,那么它们就不是微服务,
因为它们紧耦合在一起;如果你需要掌握一个服务太多的上下文场景使用条件,那么它就是一个有上下文边界的服务,这个定义来自DDD领域驱动设计。
3.微服务优点是什么?
每个微服务都很小,这样能聚焦一个指定的业务功能或业务需求。
微服务能够被小团队单独开发,这个小团队是2到5人的开发人员组成。
微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的。
微服务能使用不同的语言开发。
微服务允许容易且灵活的方式集成自动部署,通过持续集成工具,如Jenkins, Hudson, bamboo 。
一个团队的新成员能够更快投入生产。
微服务易于被一个开发人员理解,修改和维护,这样小团队能够更关注自己的工作成果。无需通过合作才能体现价值。
微服务允许你利用融合最新技术。
微服务只是业务逻辑的代码,不会和HTML,CSS 或其他界面组件混合。
微服务能够即时被要求扩展。
微服务能部署中低端配置的服务器上。
易于和第三方集成。
每个微服务都有自己的存储能力,可以有自己的数据库。也可以有统一数据库。
4. 微服务架构的缺点是什么?
微服务架构可能带来过多的操作。
需要DevOps技巧 (http://en.wikipedia.org/wiki/DevOps).
可能双倍的努力。
分布式系统可能复杂难以管理。
因为分布部署跟踪问题难。
当服务数量增加,管理复杂性增加。
5. 微服务适合哪种情况?
当你需要支持桌面 web 移动 智能电视 可穿戴时都是可以的,甚至将来你可能不知道但需要支持的某种环境。
API 网关是一个服务器,也可以说是进入系统的唯一节点。这与面向对象设计模式中的 Facade 模式很像。
API网关封装内部系统的架构,并且提供 API给各个客户端。它还可能还具备授权、监控、负载均衡、缓存、请求分片和管理、静态响应处理等功能。
API网关的优点和缺点
对于API网关的优点,其实是类似传统ESB企业服务总线的优点,即实现服务透明,同时对于服务运行过程中的日志,
安全,路由,缓存等问题进行统一配置和处理,而不需要每个微服务API实现时都去考虑。如开源的Dubbo服务总线即可以看作是一个API网关的实现。
API网关和ESB的一些重要区别点在于API网关更加轻量和高性能,它不需要去考虑太多遗留系统和诸多协议的适配,其次也不需要考虑服务集成过程中的大量数据转换和映射。
同时为了提升服务网关的性能,一般API网关在实现过程中不会去记录详细的数据传输日志,或者类似Dubbo架构数据传输根本就不会通过API网关。
使用 API 网关的最大优点是,它封装了应用程序的内部结构。客户端只需要同网关交互,而不必调用特定的服务。API网关也有一些不足。
它增加了一个我们必须开发、部署和维护的高可用组件。还有一个风险是,API 网关变成了开发瓶颈。
简单来说,在我们期望的去中心化和全分布式架构中,网关又成了一个中心点或瓶颈点,正是由于这个原因我们在网关设计的时候必须考虑即使APIGateway宕机也不要影响到服务的调用和运行。
作者:何明璐 链接:https://www.zhihu.com/question/37808426/answer/93335393
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
第四篇 服务发现的可行方案以及实践案例
首先还是先说场景,看似简单的服务注册和服务目录库管理为何会变复杂,其主要的原因还是在结合了云端PaaS和Docker容器部署后,对于微服务模块部署完成后提供出来的IP地址是动态在变化的,包括模块在进行动态集群扩展的时候也需要动态接入新的服务提供IP地址。正是由于这个原因引入了服务发现和管理的困难度。
在文章中提到了两种服务发现模式,即客户端发现模式和服务端发现模式,分开描述如下:
服务客户端发现模式
使用客户端发现模式时,客户端决定相应服务实例的网络位置,并且对请求实现负载均衡。客户端查询服务注册表,后者是一个可用服务实例的数据库;然后使用负载均衡算法从中选择一个实例,并发出请求。客户端从服务注册服务中查询,其中是所有可用服务实例的库。客户端使用负载均衡算法从多个服务实例中选择出一个,然后发出请求。
注:这是类似Dubbo实现机制一样的两阶段模式,即任何一个服务的消费都需要分两个步骤进行,第一步首先是访问服务注册库(更多是APIGateWay提供的一个能力)返回一个已经动态均衡后的服务可用地址,第二步即客户端和该地址直接建立连接进行服务消费和访问。
在这种模式的实现中有两个重点,其一是动态负载均衡算法,其二是服务网关需要能够对原始服务提供点进行实时的心跳检测以确定服务提供的可用性。
Netflix OSS 是客户端发现模式的绝佳范例。Netflix Eureka是一个服务注册表,为服务实例注册管理和查询可用实例提供了 REST API 接口。Netflix Ribbon 是 IPC 客户端,与Eureka 一起实现对请求的负载均衡。
缺点:底层的IP虽然动态提供出去了,但是最终仍然暴露给了服务消费方,再需要进一步做安全和防火墙隔离的场景下显然是不能满足要求的。
服务端发现模式
客户端通过负载均衡器向某个服务提出请求,负载均衡器查询服务注册表,并将请求转发到可用的服务实例。如同客户端发现,服务实例在服务注册表中注册或注销。在原文中有图示,基本看图就清楚了,即在服务注册库前新增加了一个LoadBalancer节点。注:这两个节点感觉是可以合并到API GateWay的能力中去的。
服务端发现模式兼具优缺点。它最大的优点是客户端无需关注发现的细节,只需要简单地向负载均衡器发送请求,这减少了编程语言框架需要完成的发现逻辑。并且如上文所述,某些部署环境免费提供这一功能。这种模式也有缺点。除非负载均衡器由部署环境提供,否则会成为一个需要配置和管理的高可用系统组件。
服务注册表
服务注册表需要高可用而且随时更新。客户端能够缓存从服务注册表中获取的网络地址,然而,这些信息最终会过时,客户端也就无法发现服务实例。因此,服务注册表会包含若干服务端,使用复制协议保持一致性。
首先可以看到服务注册表本身不能是单点,否则存在单点故障,当服务注册表有多台服务器的时候同时需要考虑服务注册库信息在多台机器上的实时同步和一致。我们操作和配置服务注册信息的时候往往只会在一个统一的服务管控端完成。
其次如果服务注册服务器宕机是否一定影响到服务本身的消费和调用,如果考虑更高的整体架构可用性,还可以设计对于服务注册库信息在客户端本地进行缓存,当服务注册表无法访问的时候可以临时读取本地缓存的服务注册库信息并发起服务访问请求。
对于服务注册表,文章提供了三种选择,感觉最常用的实现仍然是基于ZooKeeper进行的。
Etcd – 高可用、分布式、一致性的键值存储,用于共享配置和服务发现。
Consul – 发现和配置的服务,提供 API 实现客户端注册和发现服务。
Apache ZooKeeper – 被分布式应用广泛使用的高性能协调服务。
如前所述,服务实例必须在注册表中注册和注销。注册和注销有两种不同的方法。方法一是服务实例自己注册,也叫自注册模式(self-registrationpattern);另一种是采用管理服务实例注册的其它系统组件,即第三方注册模式。(原文有详细机制描述,不再累述)
虽然方法一把服务实例和服务注册表耦合,必须在每个编程语言和框架内实现注册代码。但是在自己实现完整微服务架构中,考虑到PaaS平台下微服务模块的动态部署和扩展,采用方法1相当来说更加容易实现。但是方法1仍然不能代替服务注册库本身应该具备的服务节点的心跳检测能力。
Dubbo官网链接:http://dubbo.io
Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度来看,Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。关于注册中心、协议支持、服务监控等内容
需求
(#)在大规模服务化之前,应用可能只是通过RMI或Hessian等工具,简单的暴露和引用远程服务,通过配置服务的URL地址进行调用,通过F5等硬件进行负载均衡。
(1) 当服务越来越多时,服务URL配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。
此时需要一个服务注册中心,动态的注册和发现服务,使服务的位置透明。
并通过在消费方获取服务提供方地址列表,实现软负载均衡和Failover,降低对F5硬件负载均衡器的依赖,也能减少部分成本。
(2) 当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。
这时,需要自动画出应用间的依赖关系图,以帮助架构师理清理关系。
(3) 接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?
为了解决这些问题,第一步,要将服务现在每天的调用量,响应时间,都统计出来,作为容量规划的参考指标。
其次,要可以动态调整权重,在线上,将某台机器的权重一直加大,并在加大的过程中记录响应时间的变化,直到响应时间到达阀值,记录此时的访问量,再以此访问量乘以机器数反推总容量。
成熟度
(+) (#)功能成熟度
(#)Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
并发控制 | Tested | 并发控制 | 试用 | ||
连接控制 | Tested | 连接数控制 | 试用 | ||
直连提供者 | Tested | 点对点直连服务提供方,用于测试 | 测试环境使用 | Alibaba | |
分组聚合 | Tested | 分组聚合返回值,用于菜单聚合等服务 | 特殊场景使用 | 可用于生产环境 | |
参数验证 | Tested | 参数验证,JSR303验证框架集成 | 对性能有影响 | 试用 | LaiWang |
结果缓存 | Tested | 结果缓存,用于加速请求 | 试用 | ||
泛化引用 | Stable | 泛化调用,无需业务接口类进行远程调用,用于测试平台,开放网关桥接等 | 可用于生产环境 | Alibaba | |
泛化实现 | Stable | 泛化实现,无需业务接口类实现任意接口,用于Mock平台 | 可用于生产环境 | Alibaba | |
回声测试 | Tested | 回声测试 | 试用 | ||
隐式传参 | Stable | 附加参数 | 可用于生产环境 | ||
异步调用 | Tested | 不可靠异步调用 | 试用 | ||
本地调用 | Tested | 本地调用 | 试用 | ||
参数回调 | Tested | 参数回调 | 特殊场景使用 | 试用 | Registry |
事件通知 | Tested | 事件通知,在远程调用执行前后触发 | 试用 | ||
本地存根 | Stable | 在客户端执行部分逻辑 | 可用于生产环境 | Alibaba | |
本地伪装 | Stable | 伪造返回结果,可在失败时执行,或直接执行,用于服务降级 | 需注册中心支持 | 可用于生产环境 | Alibaba |
延迟暴露 | Stable | 延迟暴露服务,用于等待应用加载warmup数据,或等待spring加载完成 | 可用于生产环境 | Alibaba | |
延迟连接 | Tested | 延迟建立连接,调用时建立 | 试用 | Registry | |
粘滞连接 | Tested | 粘滞连接,总是向同一个提供方发起请求,除非此提供方挂掉,再切换到另一台 | 试用 | Registry | |
令牌验证 | Tested | 令牌验证,用于服务授权 | 需注册中心支持 | 试用 | |
路由规则 | Tested | 动态决定调用关系 | 需注册中心支持 | 试用 | |
配置规则 | Tested | 动态下发配置,实现功能的开关 | 需注册中心支持 | 试用 | |
访问日志 | Tested | 访问日志,用于记录调用信息 | 本地存储,影响性能,受磁盘大小限制 | 试用 | |
分布式事务 | Research | JTA/XA三阶段提交事务 | 不稳定 | 不可用 |
策略成熟度
(#)Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
Zookeeper注册中心 | Stable | 支持基于网络的集群方式,有广泛周边开源产品,建议使用dubbo-2.3.3以上版本(推荐使用) | 依赖于Zookeeper的稳定性 | 可用于生产环境 | |
Redis注册中心 | Stable | 支持基于客户端双写的集群方式,性能高 | 要求服务器时间同步,用于检查心跳过期脏数据 | 可用于生产环境 | |
Multicast注册中心 | Tested | 去中心化,不需要安装注册中心 | 依赖于网络拓普和路由,跨机房有风险 | 小规模应用或开发测试环境 | |
Simple注册中心 | Tested | Dogfooding,注册中心本身也是一个标准的RPC服务 | 没有集群支持,可能单点故障 | 试用 | |
Feature | Maturity | Strength | Problem | Advise | User |
Simple监控中心 | Stable | 支持JFreeChart统计报表 | 没有集群支持,可能单点故障,但故障后不影响RPC运行 | 可用于生产环境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Dubbo协议 | Stable | 采用NIO复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率,性能较好(推荐使用) | 在大文件传输时,单一连接会成为瓶颈 | 可用于生产环境 | Alibaba |
Rmi协议 | Stable | 可与原生RMI互操作,基于TCP协议 | 偶尔会连接失败,需重建Stub | 可用于生产环境 | Alibaba |
Hessian协议 | Stable | 可与原生Hessian互操作,基于HTTP协议 | 需hessian.jar支持,http短连接的开销大 | 可用于生产环境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Netty Transporter | Stable | JBoss的NIO框架,性能较好(推荐使用) | 一次请求派发两种事件,需屏蔽无用事件 | 可用于生产环境 | Alibaba |
Mina Transporter | Stable | 老牌NIO框架,稳定 | 待发送消息队列派发不及时,大压力下,会出现FullGC | 可用于生产环境 | Alibaba |
Grizzly Transporter | Tested | Sun的NIO框架,应用于GlassFish服务器中 | 线程池不可扩展,Filter不能拦截下一Filter | 试用 | |
Feature | Maturity | Strength | Problem | Advise | User |
Hessian Serialization | Stable | 性能较好,多语言支持(推荐使用) | Hessian的各版本兼容性不好,可能和应用使用的Hessian冲突,Dubbo内嵌了hessian3.2.1的源码 | 可用于生产环境 | Alibaba |
Dubbo Serialization | Tested | 通过不传送POJO的类元信息,在大量POJO传输时,性能较好 | 当参数对象增加字段时,需外部文件声明 | 试用 | |
Json Serialization | Tested | 纯文本,可跨语言解析,缺省采用FastJson解析 | 性能较差 | 试用 | |
Java Serialization | Stable | Java原生支持 | 性能较差 | 可用于生产环境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Javassist ProxyFactory | Stable | 通过字节码生成代替反射,性能比较好(推荐使用) | 依赖于javassist.jar包,占用JVM的Perm内存,Perm可能要设大一些:java -XX:PermSize=128m | 可用于生产环境 | Alibaba |
Jdk ProxyFactory | Stable | JDK原生支持 | 性能较差 | 可用于生产环境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Failover Cluster | Stable | 失败自动切换,当出现失败,重试其它服务器,通常用于读操作(推荐使用) | 重试会带来更长延迟 | 可用于生产环境 | Alibaba |
Failfast Cluster | Stable | 快速失败,只发起一次调用,失败立即报错,通常用于非幂等性的写操作 | 如果有机器正在重启,可能会出现调用失败 | 可用于生产环境 | Alibaba |
Failsafe Cluster | Stable | 失败安全,出现异常时,直接忽略,通常用于写入审计日志等操作 | 调用信息丢失 | 可用于生产环境 | Monitor |
Failback Cluster | Tested | 失败自动恢复,后台记录失败请求,定时重发,通常用于消息通知操作 | 不可靠,重启丢失 | 可用于生产环境 | Registry |
Forking Cluster | Tested | 并行调用多个服务器,只要一个成功即返回,通常用于实时性要求较高的读操作 | 需要浪费更多服务资源 | 可用于生产环境 | |
Broadcast Cluster | Tested | 广播调用所有提供者,逐个调用,任意一台报错则报错,通常用于更新提供方本地状态 | 速度慢,任意一台报错则报错 | 可用于生产环境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Random LoadBalance | Stable | 随机,按权重设置随机概率(推荐使用) | 在一个截面上碰撞的概率高,重试时,可能出现瞬间压力不均 | 可用于生产环境 | Alibaba |
RoundRobin LoadBalance | Stable | 轮循,按公约后的权重设置轮循比率 | 存在慢的机器累积请求问题,极端情况可能产生雪崩 | 可用于生产环境 | |
LeastActive LoadBalance | Stable | 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差,使慢的机器收到更少请求 | 不支持权重,在容量规划时,不能通过权重把压力导向一台机器压测容量 | 可用于生产环境 | |
ConsistentHash LoadBalance | Stable | 一致性Hash,相同参数的请求总是发到同一提供者,当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动 | 压力分摊不均 | 可用于生产环境 | |
Feature | Maturity | Strength | Problem | Advise | User |
条件路由规则 | Stable | 基于条件表达式的路由规则,功能简单易用 | 有些复杂多分支条件情况,规则很难描述 | 可用于生产环境 | Alibaba |
脚本路由规则 | Tested | 基于脚本引擎的路由规则,功能强大 | 没有运行沙箱,脚本能力过于强大,可能成为后门 | 试用 | |
Feature | Maturity | Strength | Problem | Advise | User |
Spring Container | Stable | 自动加载META-INF/spring目录下的所有Spring配置 | 可用于生产环境 | Alibaba | |
Jetty Container | Stable | 启动一个内嵌Jetty,用于汇报状态 | 大量访问页面时,会影响服务器的线程和内存 | 可用于生产环境 | Alibaba |
Log4j Container | Stable | 自动配置log4j的配置,在多进程启动时,自动给日志文件按进程分目录 | 用户不能控制log4j的配置,不灵活 | 可用于生产环境 | Alibaba |
Dubbo支持多种协议,如下所示:
Dubbo协议
Hessian协议
HTTP协议
RMI协议
WebService协议
Thrift协议
Memcached协议
Redis协议
在通信过程中,不同的服务等级一般对应着不同的服务质量,那么选择合适的协议便是一件非常重要的事情。你可以根据你应用的创建来选择。例如,使用RMI协议,一般会受到防火墙的限制,所以对于外部与内部进行通信的场景,就不要使用RMI协议,而是基于HTTP协议或者Hessian协议
如何做服务降级
一般需要针对业务进行服务分级
比如分为一级服务,二级服务,三级服务
比如在紧急情况下面,务必保证一级服务的稳定性,然后可以牺牲二级三级服务,这个就是服务降级 — 黑夜路人 分享下我们的方案
原理很简单 利用nginx lua 和缓存
lua里做个监控,对一定时间内的服务器500或者其他错误做技术,如果超过一定的频率就直接从缓存中取出数据丢给用户
这样在瞬时流量过来的时候能够保证段时间内恢复服务
如果再做的友好点,就在lua中加个白名单,保证直接丢缓存内容也不会有大影响,一些有状态的不能缓存可以直接过
还有就是梳理关键路径
在可预测的大流量是,把非关键路径的服务关了
相关文章推荐
- 一起谈.NET技术,使用WCF实现SOA面向服务编程—— 架构设计
- 七牛技术总监肖勤:微服务架构实践经验分享(摘抄)
- 基于微服务架构的技术实践(附PPT)
- 微服务架构设计实践系列之十:技术架构
- 译著出版:《SOA概念、技术与设计》 - 面向服务的架构
- 大型分布式网站架构设计与实践 第一章《面向服务的体系架构(SOA)》1.1基于TCP协议的RPC
- 360搜索在微服务架构下的技术平台实践(二) -- 微服务架构
- 七牛技术总监肖勤:微服务架构实践经验分享
- 译著出版:《SOA概念、技术与设计》 - 面向服务的架构
- 容器SDN技术与微服务架构实践
- 容器SDN技术与微服务架构实践
- 360搜索在微服务架构下的技术平台实践(一) -- 单体架构
- “.NET技术”使用WCF实现SOA面向服务编程—— 架构设计
- 大型互联网架构师教你如何实践微服务架构全方位的技术
- 微服务架构实践-七牛技术总监肖勤
- 七牛技术总监肖勤:微服务架构实践经验分享
- 大型分布式网站架构设计与实践 第一章《面向服务的体系架构(SOA)》
- 译著出版:《SOA概念、技术与设计》 - 面向服务的架构
- 360搜索在微服务架构下的技术平台实践(三) -- Thor
- 搞有中国特色的SOA(面向服务架构)——1