前言
微服务架构的概念,现在对于大家应该都不陌生,无论使用 Apache Dubbo、还是 Spring Cloud,都可以去尝试微服务,把复杂而庞大的业务系统拆分成一些更小粒度且独立部署的 Rest 服务。但是你了解微服务的发展背景吗?接下来,咱们一块深入微服务的发展背景,也帮大家夯实一下微服务架构的技术发展。
面向服务的架构
1996年,Gartner 公司首次提出了面向服务的架构(Service-Oriented Architecture, SOA)这一软件设计思想。 其核心理念是将一个个的业务功能包装成一个个的标准服务, 为这些服务定义良好的接口和服务契约,以便在需要的时候可以重用和水平伸缩。通过将这些服务进行组合和编排,可以创建新的业务流程,或者灵活地修改现有流程,以适应不断变化的业务需求,让我们的系统功能更丰富、结构更灵活、更易于扩展。同时,让系统规模能够根据需要弹性伸缩,最大限度地利用现有资产,提高效率,降低成本。总之,要使我们的系统能更灵活、更快地响应不断变化的需求。
不过,受到当时计算机水平的限制,面向服务的架构思想在诞生之初,并没有得到广泛的关注和发展。随着软件系统的规模越来越大、越来越复杂,软件系统的架构也在不断地演进,
面向服务的架构开始受到人们的关注和认可。目前,大型软件系统的服务端架构多数都是面向服务的架构,或者正在朝这一架构迁移。要明确的是,面向服务的架构中的“服务”虽然也包括系统对外提供的服务,但更多的是指系统内部的各个“模块”或“组件”的“服务化”,以及模块(服务)之间的相互调用与协同。它是“分布式”与“服务化”两个技术发展趋势合流的产物。
分布式系统
所谓的“分布式”是相对于“集中式”的一种应用系统内部组织结构。相对于传统的集中式系统(单机应用系统和集群式应用系统都属于集中式系统),分布式系统将原本集中在一个服务端应用中的功能模块拆分出来,分为多个系统组件或应用,分散部署在多个服务器上,并通过网络将它们连接起来协同工作。而客户端系统感觉不到服务端系统内部的这种变化,仍然和原来调用集中式系统一样。
分布式设计使得原本集中在单个服务器上进行的计算或存储需求被分散到了多个服务器上,从而降低了我们对单一服务器的性能要求。这样就让我们能用相对廉价的PC服务器代替昂贵的传统服务器,并通过水平扩容的方式继续提升系统的处理能力。
分布式系统并没有约定其内部的各个组件或应用之间应采用什么样的形式来实现彼此通信。早期人们使用DCOM、CORBA等技术实现组件的暴露和远程访问。这便是分布式系统的早期形态。但是这些技术比较复杂且十分笨重,只在大型系统和企业级应用中被使用。尽管之后又出现了COM+、RMI、EJB 等技术,但仍然比较笨重和难用。
服务化
早期的系统都是相互独立的。受限于计算机的处理能力,其规模都比较小。比如,财务系统和人力资源管理系统分别是两个不同的系统。它们可能由不同的软件厂商,采用不同的开发语言和技术开发,并运行在各式各样的操作系统和硬件设备上。随着企业发展的需要,人们试着在两个系统间建立通信,尝试让它们彼此协同。双方的通信方式和协议由厂商之间彼此协商来制定,开发起来成本很高。各个厂商都试图制定自己的通信技术标准和协议,并力争成为业内标准。显然,如果所有厂商都遵循同一套技术标准和通信协议,就能大大地降低开发成本,让各个系统彼此更容易地互联互通。
随着基于Web的应用的普及,以及XML技术的出现和成熟,出现了基于HTTP、XML的服务暴露与远程访问方式,这就是Web Services.但Web Services 的协议和实现方式很多,技术标准也多种多样。企业内部各系统之间的互联互通仍然比较麻烦。于是,企业服务总线(Enterprise Service Bus,ESB) 系统被设计来实现各系统之间的服务接口适配和管理,以便各系统能够用自己熟悉的技术、标准和规范来相互调用彼此的服务。随着时间的推移,简单对象访问协议( Simple Object Acess Protocol, SOAP)、 Web服务描述语言( Web Services Description Language, WSDL), 以及通用描述、发现与集成服务(Universal Description, Discovery and Integration,UDDI) 协议逐渐成为主流的Web Services 标准和规范。
后来,随着互联网技术的发展,基于HTTP RESTful的轻量级Web Services 逐渐取代了基于SOAP的传统WebServices技术成为主流。由于HTTPRESTful服务暴露和调用开销比SOAP小很多,且速度更快,这就使得我们可在大型系统内部也大量使用,以作为各子系统之间,尤其是异构子系统之间最佳的通信形式。
面向服务
当我们将系统中的模块或组件服务化,代替COM+、RMI、 EJB等分布式领域的组件通信技术后,系统架构就转变为面向服务的架构。当然,分布式系统中的很多组件是难以服务化的。
不是所有的模块和组件都适合服务化。比如,有些模块的调用频率很高,接口复杂,转变成服务后,访问性能可能无法满足设计要求。又比如,有些模块与模块之间的耦合度较高,如果不进行重构来解耦,那么是无法单独作为服务暴露的。还有些模块的重用度不高或调用频率过低,没有服务化的必要。在对系统进行SOA改造时,一定要分析清楚。
综上所述,面向服务的架构是分布式架构中的-种。面向服务的架构一定是分布式架构,但分布式架构不一定面向服务。能够对外提供服务的系统并不一定是面向服务的架构,面向服务架构的系统也不一定对外暴露服务。
什么是微服务
顾名思义,微服务就是指粒度较小的服务。这意味着我们要对现有的分布式系统进行进一步的拆分,将其划分为更多、更小的服务来进行设计或重构。“微服务”的概念源于2014年3月Martin Fowler所写的一篇文章Microservices.它扩大了面向服务架构中“服务”的概念。不再局限于系统与系统之间的接口调用,也不局限于某种具体的服务形式。系统中凡是可被复用的功能模块都可以被“服务化”,转变为“服务”。这些服务可以对外暴露,也可能仅限于在系统内部使用。这对面向服务架构提出了更高的设计要求。由于服务数量更多、粒度更小,因此管控难度会更大,对性能的要求也更高。
那么,我们为什么要将系统拆分成一个个的微服务呢?
微服务的好处
1.方便编排和重用
当我们在开发新功能时,可能需要复用现有的模块。以往我们需要将可复用的代码放到jar包中,并在工程中引用。这容易导致依赖关系的复杂和混乱,而且每次都需要重新编译和打包,也很不方便,更不要说对现有的模块进行编排和组合了。将这些模块转变为服务后,我们只需要调用这些服务,而不需要关心服务的具体实现、依赖和提供者。同时还能够使用服务编排工具将现有服务编排到新的流程中,组合成为新的服务,或者修改现有的服务流程。
2.方便开发和调试
每一个微服务专注于单- -功能,并通过定义良好的接口来清晰表述它的边界。服务越小,复杂度越低,开发起来也就越简单、越快,调试和维护也更方便。这就缩短了服务开发和修改的周期,使程序能更快地迭代。
3.方便部署与更新
微服务一般随应用部署。 一个系统中有若干可独立运行的应用,每个应用通常提供了一个或多个微服务。当某个微服务发生变更时,只需编译和部署相应的应用,而不用重新编译和部署整个系统。这使得部署发布更加高效,同时也缩小了每次变更和部署的影响范围,降低了风险。
4.系统集成更方便
使用不同语言、不同技术栈开发的服务,只要按照统一的协议暴露, 比如统一使用HTTP RESTful形式暴露为服务,就可以方便地相互调用和协同。这使得我们能够将各类系统轻松集成在一起。
5.提高容错能力
某一模块或组件发生故障时,容易导致整个系统变得不可用。比如,某个模块的内存泄漏可能导致整个应用因内存不足而崩溃。由于微服务架构中的服务粒度很小,且相互隔离,因此即使某个服务出现问题,处理起来也相对容易,影响范围有限。微服务系统可以通过失败重试、失败转移、服务降级等机制实现容错处理,避免问题扩大,微服务系统甚至能自动从故障中恢复(自愈)。
6.方便横向扩展
当某个服务出现性能瓶颈时,我们只需要增加此服务所属应用的部署数量,而不用增加整个系统的部署。而且,由于不同的服务对资源的要求不同,我们可以根据实际情况灵活地对服务进行混合部署,以便更合理地分配服务器资源。
RPC与微服务
微服务环境下服务的粒度更细,调用频率也更高,一.般用于系统内部的面向服务架构,而不是直接对外提供服务。在这种场景下,Web Services 的跨语言、跨平台优势不再那么重要,WebServices的易用性问题和性能问题反而变得突出起来。
随着Socket、多线程、序列化等技术的发展,涌现出了很多优秀的RPC框架,以代替传统的RMI等技术。与WebServices偏向对外暴露服务与远程调用不同,RPC框架专注于细粒度(方法级别)的、系统内部模块或组件之间的相互调用与协同。由于多数RPC框架采用Socket 长连接和二进制协议,因此其性能比基于HTTP协议的Web Services 要高几个数量级。再加上,RPC可以做到对应用的零侵入,因此其在易用性方面也要强得多。
由于RPC在易用性和性能方面优势明显,因此在系统内部,使用远程方法调用(RPC)形.式暴露和引用服务要比WebServices更合适。对外暴露和引用服务时(跨系统调用)再采用Web Services的形式。当然,如果对性能要求不高,也可以一律采用HTTP RESTful方式。有些RPC框架,如gRPC、Thrif, 支持跨语言调用,也可以被用于跨系统的服务调用,对外提供服务。
由于我们总是能轻松地将系统内部的服务以Web Services形式对外暴露,因此,建议优先考虑内部服务调用的性能和易用性,选用RPC作为微服务的核心和基础。
微服务框架
在微服务领域,比较流行的几个关键词是Spring Cloud、Dubbo. Docker. Kubernetes. Service Mesh。其中SpringCloud是目前最接近完整微服务框架的产品。它是一个基于Java语言的微服务开发框架,面向的是有Spring开发经验的Java语言开发者。但它真的只是一个“框架”性的东西,还需要集成- -系列的第三方组件才能发挥作用。Netfix 公司为其开发了一套组件,并成为Spring Cloud的推荐或默认实现。
Dubbo是阿里巴巴开源的分布式服务框架。其本质上是一个高性能二进制RPC框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。其功能主要包括高性能NIO通信及多协议集成、服务动态寻址与路由、软负载均衡与容错、依赖分析与服务降级等。可以看出Dubbo有着自己的多层架构体系,涵盖了Spring Cloud中的一-部分内容。它虽然算不上一个完整的微服务框架,但却比较实用,未来可能会支持与Spring Cloud的集成,融入Spring Cloud生态圈。
Docker是一个应用容器引擎,允许我们将要部署的应用和运行时环境打包成--个镜像文件,部署到Docker容器中。Rocket 是与之类似的另一款应用容器引擎。
Kubernetes是Google开源的一个自动化容器操作平台,简称K8S。它可以编排并自动执行容器(如Docker、Rocket)的部署、复制等操作,随时扩展或收缩容器规模,并提供容器间的负载均衡,监控容器的状态,自动升级或替换容器。由此可见,Kubernetes 不是面向开发者的平台,而是面向IT基础设施运维人员的。
Spring Cloud和Dubbo同属于PaaS (Platform as a Service, 平台即服务),而Docker和Kubernetes同属于laas ( Infrastructure as a Service,基础设施即服务)。由于微服务平台中服务的载体是应用,而环境中要部署的应用实例众多,因此使用Docker 和Kubernetes, 通过整合Spring Cloud、Docker 和Kubernetes,可以构建更加完整和强大的微服务架构程序。
不过,应用的部署并不一定需要Docker这样的容器,Linux自身就支持进程间的资源隔离。通过一个简单应用代理服务(Agent) 加Shell脚本即可实现应用的部署。本书所介绍的示例微服务系统正是使用了这一方式,效果也很好。使用这种方式可以实现应用的部署、启停、更新、JVM监控、资源监控等功能,扩展也更方便。
Service Mesh 则还是一个比较新的概念。它可将微服务间的调用、限流、熔断和监控等功能需求提炼为一个通用的中间层基础服务,甚至下沉到基础设施层。Spring Cloud、Kubernetes和Istio似乎都正在朝这一方向努力。
看到这里,是不是感觉要成为架构师,自己要走的路还很长啊?没关系,小编今天是有备而来,特意为大家整理了这份由IBM高级架构师撰写的Java多线程和Socket,实战微服务框架的学习秘籍,相信各位小伙伴看完后一定会大有裨益。
特色简介
本篇从实战角度出发,首先介绍Java多线程、Socket、 Spring、 动态代理、动态字节码、序列化等技术在构建分布式微服务框架中的应用。然后介绍一种微服务框架的架构设计与编程实践,并将这一微服务框架分解为底层Socket通信、服务注册与发现、服务暴露与引用、远程方法调用等层面,逐一深入讲解。 这里重点介绍作者如何活用相关技术一步步地构建微服务框架的基础RPC框架并分享了相应的性能调优经验。最后介绍微服务架构中配套的服务治理系统的设计与实现方案,包括服务的设计、配置、管理与监控。
本篇适合有一定Java基础且有志成为架构师的开发人员阅读。一个优秀的架构师必须要有扎实的编程功底和丰富的理论知识,不光要能完成架构设计,更要有能力将设计转换为实际的产品。不会写代码、纸上谈兵的“架构师”设计出来的“架构”是靠不住的。因此,本篇将从相关的基础知识讲起,通过剖析一个小巧精练的微服务框架的核心,介绍这些基础知识是如何在实践中被灵活、适当地运用的。
另外,本篇不是关于微服务的理论书籍,也不是某个微服务框架的使用手册。微服务涉及的范围很广,我们很难在一篇里讲清楚微服务的方方面面。
第1章:多线程基础
多线程的概念
进程与线程
并发与并行
线程状态
Thread 线程类,
wait 和sleep的区别
sleep和yield的区别
Runnable接口,
线程池
Callable 与Future.
线程安全与效率
线程同步
饥饿与公平
锁与死锁
线程中断
编程进阶
第2章:Socket基础
TCP与Socket
TCP的通信过程
通信方式
长连接与短连接
线程模型
拆包与组包
断包与粘包
数据包的结构
BIO
BIO简介
典型编程模型
关键 API概述.
字符流传输
AIO
AIO 简介
关键API概述
示例代码
第3章:Spring和Spring cloud
Spring简介
IoC容器
IoC 的概念
Spring 中的bean
BeanFactory 与FactoryBean
ApplicationContext 与ApplicationContex
动态注册bean配置
ApplicationListener 与容器事件.
bean的基本配置
scope属性
依赖注入
注解注入
Spring Boot.
Spring Cloud
Spring Cloud简介
第4章:动态代理
代理模式
静态代理
类的装载
Java反射
JDK动态代理
CGLIB动态代理
Java Compiler API
Javassist动态代理
第5章:对象序列化
什么是序列化
Java序列化
基本用法
关于serialVersionUID
自定义序列化
封装实现代码
Hessian序列化.
Kryo序列化
FST序列化
其他序列化组件
集成与扩展
优雅地集成
使用 Java SPI
使用 spring
第6章:框架设计
总体结构
逻辑架构,
框架设计概述
RPC原理
初始化过程
Spring 配置
应用节点的启动
Web容器的启动.
RpcCore 的初始化
RpcContext 的初始化
服务的暴露
服务暴露配置
方法配置与 ID
服务提供方本地调用器
服务提供方代理生成器
服务的引用
服务引用配置
注册本地引用工厂
本地引用与方法 ID
优雅地停机
第7章:方法调用
方法调用类型
同步调用
同步调用的时序
同步调用的发起
负载均衡
指定服务 提供者
失败转移
发送调用请求
处理调用请求
处理调用响应
异步调用
异步调用的时序
异步调用的发起
异步调用的执行
方法调用对象
同步/异步通知
异步回调
广播调用与广播通知
广播示例
广播代码
第8章:通信层实现
Socket通信框架
Netty与Mina
为什么要自己写
是NIO还是AIO
设计思路
实际结构
通信协议
传输对象
数据包结构
拆包与发送
接收并组包
连接的建立
工作模型
开始监听
发起连接
绑定连接
断线检测
第9章:性能测试与调优
性能调优概述
性能指标
性能瓶颈
环境因素
压力测试
测试方法
场景设计
测试环境
Dubbo配置
测试程序
线程池调优
调整线程池的大小
选择合适的队列
优化线程同步
减少上下文切换
避免线程滥用
避免过多的锁
缩小锁的范围和粒度
线程分析工具
JVM调优
堆与栈 .
JVM 内存的分代
GC分类.
GC 算法.
分代CG
内存大小设置
内存调优工具
其他优化内容
避免使用反射
对象池
缓冲区队列
使用直接内存
缓存其他对象
协调与平衡
第10章:服务治理
服务治理概述
什么是服务治理
服务治理架构
服务治理接口
服务识别
接口定义
版本管理.
协议适配
服务设计
服务的实现
依赖关 系管理
服务的部署
服务的部署方式
自动化部署
注册与发现
WSDL与UDDI
ZooKeeper 的方案
Eureka 的方案
Consul 的方案
etcd 的方案
注册中心集成方案
服务的控制
服务状态
为了大家更好的阅读体验,小编只是截取了章节的部分截图,有兴趣深度了解学习的朋友,请帮忙转发文章,并关注小编,私信回复【学习】即可哦~~~
总结
目前微服务相关的主流框架是Spring Cloud和Dubbo。虽然Spring Cloud和Dubbo都很强大,但这个世界上从来没有最好,只有更好,因此我们永远不要停下自己创新的脚步。我们依然可以有自己的想法,并勇于尝试、付诸实践。事实上SpringCloud和Dubbo都存在各自的问题和不足。我们通过对它们的学习和研究,站在巨人的肩膀上,吸取它们的优点再加以创新,是完全有可能做到青出于蓝而胜于蓝的。
授人以鱼不如授人以渔,希望大家通过这一学习过程,深刻掌握Java多线程、Socket、动态代理等相关技术,最终能够做到举一反三, 灵活地运用它们,从而提升自身的Java编程水平,并为进一步学习和研究Java分布式技术与微服务框架打下基础。
喜欢请多多点赞评论转发,关注小编,后续小编会再带来更丰富的学习内容更新,希望能够帮到大家更好的学习提升~~~