电商网站前端架构设计,网站重新接入备案,网站在网络文化建设方面的成果,郑州企业排名第1章云原生时代下的微服务
微服务架构是一种将单个应用程序开发为一组小型服务的方法#xff0c;每个服务在自己的进程中运行#xff0c;并通过轻量级的通信机制#xff08;如HTTP API#xff09;进行交互。这些服务围绕业务功能构建#xff0c;可以通过完全自动化的部署…第1章云原生时代下的微服务
微服务架构是一种将单个应用程序开发为一组小型服务的方法每个服务在自己的进程中运行并通过轻量级的通信机制如HTTP API进行交互。这些服务围绕业务功能构建可以通过完全自动化的部署机制独立部署。服务可以使用不同的编程语言并使用不同的数据存储我们可以以一个非常轻量级的中心化管理方式来协调服务。
1.1.1 微服务架构的关键特性
1.服务组件化
2.基于业务能力构建系统
3.去中心化治理和数据分治
分散的服务带来的另一个特征就是去中心化。
一个应用所包含的各个业务需求必然是各不相同的而不同的业务模型必然有最适合的技术方案。通过拆分我们实现不同的服务时在技术方案上可以有不同的选择这就是所谓的异构。使用合适的方案比使用统一的方案更重要因为这样效率更高。例如使用面向对象语言构建有复杂业务模型且适合建模的服务使用Golang语言构建中间件服务。在数据层面也是如此对于有级联关系的业务模型使用MongDB这种文档化的存储方案更合适对于大数据离线分析业务使用列式数据仓库方案更合适。对于团队来讲这种去中心化的构建方式也更加灵活。
4.基础设施自动化
5.面向失败设计和演进式设计 将业务模块拆分成服务后因为交互方式的改变服务间的调用很有可能会因为各种原因而失败比如网络抖动、上游服务不可用、流量过载、路由出错等。这就要求我们在构建微服务应用过程中充分考虑这些问题想办法在失败时尽可能降低对用户的影响。很显然这将增加开发负担我们需要再应用中添加更多的非功能性需求或者说控制逻辑而这应该是微服务这种分布式架构之于单体应用最大的劣势。
为了解决微服务的这一问题服务治理以及通过服务网格技术更轻松地管理服务间的通信成了重要课题。当面对失败时最重要的及时能够及时检测和发现故障并自动恢复。在云原生技术的加持下实现面向失败设计变得不再困难比如我们可以基于基础设施的探针和运行策略完成自动化重启也可以通过日志、指标和追踪构建完善的服务监控能力。
简单来说服务网格就是一个用来管理服务间通信的基础设施层通过一组边车代理提供的能力进行服务间流量的管理。如果将k8s称作云原生应用的操作系统那么服务网格就是云原生应用的网络层为微服务应用解决流量管理难题。随着服务的增多微服务需要进行治理和管控服务网格正是用来管理服务间通信的解决方案。
以服务网格为例要实现上面的重试功能应用本身不需要做任何代码层面的修改只需要在服务网格的路由配置中增加与重试相关的配置即可服务代理会根据这个配置在请求失败的时候自动进行重试。这就是云原生技术的能力其理念是将非功能性需求下沉到基础设施让应用只关注业务实现。
我们还以Spring Cloud为例它是一个强大的微服务开发框架提供了很多具有服务治理能力的组件。
框架几乎可以满足我们所有的需求但本质上他还是以类库方式运行的。
微服务应用基于业务进行服务拆分通过服务间的交互实现应用的整体功能。开发应用时除了要考虑实现功能性需求还要考虑实现非功能性需求。而在云原生架构中非功能性需求通常交由基础设施负责。下沉非功能性需求可让开发人员只关注业务这就是我们在前面提到的云原生技术愿景。因此从这一宏观层面上来看开发人员要有思想上的转变在架构设计、技术选型等方面从云原生的理念出发构建出面向未来的云原生应用。
利用k8s这一类基础设施完成应用的编排和调度管理使大量的非功能性需求被剥离出来交由k8s实现。
现代应用程序的构建趋势是“微服务云原生”即从微服务应用转变为云原生应用。
第2章 微服务的应用设计方法
2.1应用架构设计
架构描述的是在更高层次上将应用拆分为子系统或模块的方法以及这些子系统之间的交互关系。开发过程中的一个基本问题是理解底层的软件架构在考虑使用何种技术或工具前必须首先考虑总体的架构。
在分解复杂的软件系统时最常用的设计手段就是分层。比如TCP/IP网络模型上层使用下层定义的服务下层对上层隐藏自己的实现细节。
20世纪90年代前后两层结构是一种比较先进的设计例如客户端/服务端架构。
使用两层结构经常要面对的一个问题是业务逻辑写在哪层。如果应用的数据操作是简单的增删改查选择两层结构式合理的。一旦业务逻辑变得复杂这些代码写到哪一层都不太合适。出现这一问题的原因是缺乏领域建模。
随着业务的变更和发展最初设计的数据库表常常无法准确呈现出当前的业务状况这时转到三层结构是更好的选择。通过引入一个中间层可以解决业务逻辑的归属问题我们可以将这一层称为领域层或者业务逻辑层。
如果我们将展示层看作前端与网页相关的部分那么业务逻辑层和数据访问层就是后端。后端可以分为两层不过一个更常见的分层方式是将后端也分为三层比如下面这样。
接口层或者应用层负责与前端对接完成从前端请求参数到业务数据对象编解码工作处理通信层面的功能调用下层真正的业务逻辑。构建这一层的目的是避免将非业务功能引入领域层保证领域层中业务逻辑的纯粹性。这一层通常可以使用门面模式来构建这样就可以对接不同的展示层比如网页、移动端App等。
领域层领域相关的业务逻辑部分其中只包含相对纯粹的业务代码。
数据访问层与数据源对接将业务对象转换为存储数据并保存到数据库中这个过程可简单理解为“对象-关系映射”ORM。
在讨论分层结构的时候我们需要明确层的粒度问题。而我们讨论的主要是layer所代表的层是基于代码层面的一种隔离。
对于微服务而言服务发现的重要性不言而喻的。
通常一个服务发现系统有如下三个角色。
服务提供者可以理解为一个Web服务协议可以多样化对外暴露一些API有一个IP地址和端口作为服务地址。在微服务应用中可以认为服务提供者就是上游服务即被调用的服务。
服务消费者消费服务的一方通过访问服务提供者的API来获取数据实现功能。在微服务应用中可以认为服务消费者就是下游服务即调用者。
注册中心也叫注册表可以理解为一个中心化的数据库用来存储服务地址信息是服务提供者和服务消费者之间的桥梁。
如果一个服务既要访问上游服务又要提供API给下游服务那么它既是服务的提供者也是服务消费者。微服务应用中有很多服务都具有这样的特性。
服务发现机制的模式主要有两种。
1.客户端发现模式
在这种模式下服务启动时会将自己的地址注册到注册中心客户端访问注册中心获取要访问的服务地址然后向服务提供者发起请求。
2.服务端发现模式
相对客户端发现模式而言服务端发现模式最主要的变化是增加了一个中心化的代理将服务信息的拉取、负载均衡集中到了一起。服务消费者发起的请求会由代理接管代理从注册中心查询到服务提供者的地址然后根据地址将请求发送给服务提供者。它带来的缺点是因为引入了代理请求会多转发一次增加了服务响应的延迟。对于k8s为基础的云原生应用来说使用默认的服务发现机制是首选策略但如果你的应用是混合部署的比如既有k8s集群内的服务也有集群外的服务且它们之间还需要交互那么就要考虑服务发现的集成方案。比如Consul项目就可以与k8s集成。他提供的Helm Chart可以让你方便地在集群中安装Concul并提供了k8s服务与Consul的自动同步机制。这些特性可以让应用很好地工作在跨集群或者异构的工作负载环境中为服务间通信提供了便利。 通信协议和格式
REST/HTTP
REST是一组架构设计的约束条件和原则基于REST风格设计的API称为RESTful API。它以资源这个概念为核心配合使用HTTP的方法从而实现对资源数据的操作。比如下面的URL代表使用HTTP的GET方法来获取订单数据。
GET /orders/{id}
RESTful API有很多优点简单易读很容易设计测试方便可以用curl之类的命令或工具直接测试实现容易只要构建一个Web服务器就可以使用HTTP应用广泛更容易集成。
当然它也有缺点比如工作在七层需要多次交互才能建立连接性能稍逊一筹只支持一对一的通信如果想在单一请求中获取多个资源需要通过API聚合等方式实现。
尽管如此RESTful API依然是构建Web应用的事实标准对内负责前后端的请求和响应对外负责定义API接口供第三方使用。
RPC即远程过程调用它的工作方式是使用一种接口定义语言IDL来定义接口和请求响应消息然后渲染出对应的服务端和客户端桩Stub程序客户端可以通过这个桩程序像调用本地方法一样去调用远端服务。
RPC一般包含传输协议和序列换协议。RPC比HTTP封装性更好更符合面向领域建模理念。
使用RPC也很简单并且因为具有很多语言SDK的支持也可以认为它不会受到语言限制。另外RPC通常优先选择二进制格式进行传输虽然二进制数据不可读但传输效率要高于HTTP/JSON这样的明文格式数据。RPC的通信机制也更丰富不仅仅支持请求/响应这种一去一回的方式比如gRPC还支持流式传输。
RPC更适合服务之间的调用或者组织内部各个系统之间调用。对于需要暴露给外界的OpenAPI还是要优先选择使用RESTful API。原因很简单基于HTTP的RESTful API对调用方的技术栈是没有任何要求的而RPC因为需要特定的IDL语言渲染出桩程序调用方需要在自己的应用中引入桩程序因此会产生依赖另外如果将IDL源文件共享给调用方也会有安全方面的隐患。
3.基于服务网格的流量管理
微服务应用一般会有三种请求来源来自外界的请求比如对外提供的API、来自组织内部其他存量系统的访问请求以及微服务应用内部服务之间的请求。这些流量都需要管理比如实现动态路由、按比例切分或者添加超时、重试这些弹性能力。一些传统的基于公共库的解决方案如Spring Cloud已经提供了非常完善的流量管理功能不过相对于服务网格这样的云原生解决方案还存在一些劣势。 缓存
缓存是计算机软硬件系统广泛存在的一类组件和设计模式存储层的典型代表是内存key-value型数据库它比读写磁盘数据库快可以作为中间件挡在主数据库的前面产生以小硬件撬动大流量的杠杆效应。完全在内存中处理数据虽然快但代价是机器停电或者进程重启会导致数据丢失。为了解决易失性问题有些缓存如Redis也提供了数据持久化方案。
缓存的主要设计指标之一是命中率命中率越高说明缓存的作用越大另一方面也预示着缓存被击穿时对数据库的影响越大。缓存的另一个设计指标是流量分布的均衡性。如果某个key承载了过大的流量热点容易造成存储硬件内存、网卡的损坏热点击穿甚至可能引发新的热点造成系统雪崩。
应用要使用缓存需要允许缓存中的数据和数据库的数据出现短暂的不一致。应用可以选择伴随写数据库的操作之前、之后均可更新缓存也可以选择伴随数据库的操作来更新缓存并设置缓存的过期时间甚至可以选择离线定期更新缓存在线只读取缓存未命中也不穿透到数据库。如果应用设置了缓存过期时间还要小心处理在缓存过期到缓存更新的间隙中数据库的流量尖峰。
队列
队列作为先进先出的数据结构是各种数据库系统的持久化、跨节点同步和共识机制的实现基础保证了进入数据库的数据不丢失、不乱序。