应用架构演进《一》
传统的项目遗留额外难题:
代码重复率高; |
需求变更(开发维护)困难; |
部署效率低; |
学习成本高; |
团队协作效率差,部分功能重复开发; |
系统可靠性变差; |
维护和定制困难; |
新功能上线周期变长; |
缺乏统一的RPC框架:由于web框架只提供了HTTP/https协议,例如soap,smpp等协议栈需要业务自行集成第三方的开源库,超时重发,网络断连等底层故障需要在应用上层统一封装和处理,工作繁琐而且容易出错,对业务开发人员的技能要求也非常高。 |
为了应对复杂的业务,通过业务公共能力抽象成原子服务,对复杂应用进行水平拆分和服务化,实现服务消费者和应用者的解耦。公共能力抽取和复用,可以有效降低公共模块重复开发建设的成本。
传统的垂直应用架构【LAMP】:
linux+apache+php+mysql(读写分离); |
spring+struts+ibatis+hibernate+tomcat ; |
EJB |
在高并发,大流量的应用场景中,需要做集群,通常的组网方案是前端通过F5等负载均衡做七层负载均衡(或者使用SLB等软负载),后端做对等集群部署。
RPC: | remote procedure call ,它是一种进程间通信方式。允许像调用本地服务一样调用远程服务。它的具体实现方式可以不同,例如:spring的http invoker,facebook 的thrift 二进制私有协议通信。 |
RPC 的原理: | RPC框架的目标就是让远程过程(服务)调用更加简单,透明,RPC框架负责屏蔽底层的传输方式(TCP/UDP),序列化方式(xml/json二进制)和通信方式。 |
PRC框架的核心技术点:
远程服务提供者需要以某种形式提供服务调用相关的信息,包括但不限于服务接口定义,数据结构,或者中间态的服务定义文件。例如thrift 的IDL文件,ws-rpc的wsdl文件定义,甚至也可以是服务端的接口说明文档;服务调用者需要通过一定的途径获取远程服务调用相关信息,例如服务端接口定义jar包导入,获取服务端IDL文件等。 | |
远程代理对象: | 服务调用者调用的服务实际是远程服务的本地代理,对于Java语言,它的实现就是JDK的动态代理,通过动态代理的拦截机制,将本地调用封装成远程服务调用。 |
通信: | RPC框架与具体的协议无关,例如spring 的远程调用支持http invoke,rmi invoke,messagepack 使用的是私有的二进制压缩协议。 |
序列化: | 远程通信,需要将对象转换成二进制码流进行网络传输,不同的序列化框架,支持的数据类型,数据包大小,异常类型及性能等都不同。不同的RPC框架应用场景不同,因此技术选择也会存在很大差异。 |
微服务简介《一》
1.微服务的诞生:
越来越多的用户参与 |
业务场景越来越复杂 |
传统的单体架构已经很难满足互联网技术的的发展要求 |
代码的可维护性,扩展性和可读性在降低 |
维护系统的成本,修改系统的成本在提高。 |
微服务:是著名的OO(面向对象Object oriented)专家Martin fowler提出的。
传统的单体应用:
表示层,业务逻辑层,数据访问层都放在一个工程中,最终经过编译,打包,部署在一台服务器上。
随着业务的扩展,大多数公司会将应用进行集群部署,并增加负载均衡服务器。还需要增加集群部署的缓存服务器和文件服务器,并将数据库读写分离,以应对用户量的增加而带来的高并发访问量。用负载均衡服务器分发高并发的网络请求,用户的访问被分派到不同的应用服务器,应用服务器的负载均衡不再成为瓶颈,用户量增加时,添加应用服务器即可。通过添加缓存服务器来缓解数据库的 数据以及数据库读取数据的压力。
单体应用,大量的业务必然会有大量的代码,代码的可读性和可维护性依然很差 |
面对海量的用户,数据库将会成为瓶颈,解决方案将使用分布式数据库,即给你数据库进行分库分表。 |
持续交付能力差,业务越复杂,代码越多,修改代码和添加代码所需的时间越长。 |
2.如何理解微服务:
按业务划分为一个独立运行的程序,即服务单元。 |
服务之间通过HTTP协议相互通信。 |
自动化部署 |
可以用不同的变成语言。 |
服务集中化管理 |
微服务是一个分布式系统。 |
按业务划分的微服务单元独立部署,运行在独立的进程中。这些微服务单元是高度组件化的模块,并提供了稳定的模块边界,服务与服务之间没有任何 耦合,有非常好的扩展性和复用性。
微服务通过HTTP来互相通信:
按照业务划分的微服务单元独立部署,并运行在各自的进程中。微服务单元之间的通信方式一般倾向HTTP通信。更多的时候是使用restful api。这种接受请求,处理业务逻辑,返回数据的HTTP模式非常高效,并且这种通信机制与平台和语言无关。
服务与服务之间也可以通过轻量级的消息总线来通信。例如:rabbitMq ,kafaka等。通过发送消息或者订阅消息来达到服务与服务之间通信的目的。
服务与服务通信的数据格式,一般为JSON, XML 。这两种数据格式与语言,平台,通信协议无关。一般来说,JSON格式比XML轻量,并且可读性也比XML要好。另外一种就是用protobuf进行数据序列化,经过序列化的数据为二进制数据,它比JSON更轻量。用protobuf序列化的数据为二进制,可能性非常差,必须进行反序列化才能够读懂。由于protobuf序列化的数据更轻量,所以用protobuf 在通信协议和数据存储上十分受欢迎。
服务与服务之间通过HTTP或者消息总线的方式进行通信,这种方式存在弊端,其通信机制是不可靠的,虽然成功率很高,但还是会失败的。
3.微服务的数据库独立:
在单体架构中,所有 的业务都共用一个数据库。业务量的增加,表的数量增加,数据量的增加会导致查询速度越来越慢。
微服务的一个特点就是按照业务划分服务,服务与服务之间无耦合,就是数据库也是独立的。一个典型的微服务架构就是每一个微服务都有自己独立的数据库,数据库之间没有任何联系。
好处:
随着业务的不断扩张,服务与服务不需要提供数据库集成,而是提供API接口相互调用; |
数据库独立,单业务的数据量少,易于维护,数据库性能有着明显的优势,数据库的迁移也很方便。 |
数据库的存储方式不仅仅局限于关系型数据库,非关系型数据库的应用也非常广泛,mongDB,redis它们有着良好的读写性能。
4.微服务的自动化部署:
微服务架构中,系统会被拆分成若干个微服务,每一个微服务又是一个独立的应用程序。单体架构的应用程序只需要部署一次,而微服务架构有多少个服务就需要部署多少次。业务粒度划分的越细,微服务的数据就越多,这时就需要更稳定的部署机制。Docker,jenkins 都是比较不错的。
自动化部署可以提高部署的效率,减少人为的控制,部署过程中出现的错误的概率降低,部署过程的每一步自动化,提高软件的质量。
5.服务集中化管理:
微服务系统是按业务单元划分服务 的,服务数量越多,管理起来越 复杂,因此微服务必须使用集中化管理。目前流行的微服务框架中,例如spring cloud 采用eureka 来注册服务和发现服务。另外,zookeeper,consul 等都是非常优秀的服务集中化管理框架。
6.分布式架构:
分布式系统是集群部署 的,由很多计算机相互协作共同构成,它能够处理海量的用户请求。分布式系统通过网络协议来通信,所以分布式系统在空间上没有任何限制,即分布式服务器可以部署不同的机房和不同的地区。
微服务架构是分布式架构,分布式系统比单体系统更加复杂,主要体现在服务的独立性和服务相互调用的可靠性,以及分布式事务,全局锁,全局ID等,而单体系统不需要考虑这些复杂性。
分布式系统的应用都是集群化部署,会给数据一致性带来困难。分布式系统中的服务通信依赖于网络。网络不好,会对分布式系统带来很大的影响。在分布式系统中,服务之间相互依赖,如果一个服务出现了故障或者网络延迟,在高并发的情况下,会导致线程阻塞,在很短的时间内该服务的线程资源会消耗殆尽,最终使得该服务不可用。这就是“雪崩效应”。为了防止雪崩,分布式可以采用“熔断机制”。
7.熔断机制:为了防止雪崩效应,分布式系统采用“熔断机制”。在用spring cloud 构建的微服务系统中,采用了熔断器(hystrix组件的circuit breaker)去做熔断。
当别的服务都依赖某一个服务时,当该服务发生故障时,请求失败次数超过设定的阀值之后,该服务就会开启熔断机制,该服务不再进行任何的业务逻辑操作,执行快速失败,直接返回请求失败的信息。熔断器还有另外一个机制:自我修复的机制。这种自我修复机制在微服务架构中有着重要的意义,一方面,它使程序更加健壮,另一方面,为开发和运维减少很多不必要的工作。
熔断组件往往会提供一系列的监控,例如服务可用于否,熔断器是否被打开,目前的吞吐量,网络延迟状态的监控等。从而很容易的让开发人员和运维人员实时的了解服务的状态。
8.微服务的优势:
将一个复杂的业务分解成若干个小的业务,每一个业务拆分成一个服务,服务的边界明确,将复杂的问题简单化。服务按照业务拆分,编码也是按照业务拆分,代码的可读性和可扩展性增加。 |
由于微服务系统是分布式系统,服务与服务之间没有任何的耦合。随着业务的增加可以根据业务再拆分成服务,具有极强的横向扩展能力。随着用户量的增加,并发量增加,可以将微服务集群化部署,从而增加系统的负载能力。 |
服务与服务之间通过HTTP网络通信协议来通信,单个微服务内部高度耦合,服务与服务直接完全独立,无耦合。这使得微服务可以采用任何的开发语言和技术来实现。 |
单体应用,由于业务的复杂性,代码的耦合性,以及可能存在的历史问题。再重写一个单体应用时,开发人员要熟悉所有的业务。重写的风险相当高。微服务是按照业务进行拆分的,并且有服务边界,所以重写某个服务相当于重写某个业务的代码,就非常简单。 |
微服务的每个服务单元都是独立部署的,即独立运行在某个进程里。微服务的修改和部署对其他服务没有影响。 |
微服务在CAP理论中采用的是AP架构,即具有高可用和分区容错的特点。高可用主要体现在系统7×24小时不间断的服务,它要求系统有大量的服务器集群,从而提高了系统的负载能力。另外,分区容错也使得更加健壮。 |
9.微服务的不足:
微服务的复杂度 |
分布式事务 |
服务的划分 |
服务的部署 |
10.分布式事务:微服务架构所涉及的系统是分布式系统。分布式系统有一个著名的CAP理论,即同时满足“一致性”,“可用性”,“分区容错”时意见不可能的事情。设计时应该有所取舍。
Consistency: | 数据的强一致性。如果写入某个数据成功,之后读取,读到的都是新写入 的数据;如果写入失败,之后读取的都不是写入失败的数据。 |
Availability: | 服务的可用性。 |
Partition-tolerance: | 指分区容错。 |
在分布式系统中,P是基本要求,而单体服务是CA系统。微服务系统通常是一个AP系统,即同时满足了可用性和分区容错。
解决事务问题:
第一阶段,service-account发起一个分布式事务,交给事务协调器TC处理,事务协调器TC向所有参与事务的节点发送处理事务操作的准备的操作。所有的参与节点执行准备操作。将Undo 和Redo 信息写进日志,并向事务管理器返回准备操作是否成功。 |
第二阶段,事务管理器收集所有节点的准备操作是否成功,如果都成功,同通知所有的节点执行提交操作;如果有一个失败,则执行回滚操作。 |
两阶段提交,将事务分成两部分能够大大提高分布式事务的成功的概率。如果在第一阶段都成功了,而执行第二阶段的某一个节点失败,仍然导致数据的不准确,这时一般需要人工去处理,这就是当初在第一步记录日志的原因。 |
spring cloud 作为Java语言的微服务框架,它依赖于springboot ,有快速开发,持续交付和容易部署等特点。spring cloud 的组件非常多,涉及微服务的方方面面。
微服务具有以下的特点:
按照业务来划分服务,单个服务代码量小,业务单一,易于维护。 |
每个微服务都有自己独立的基础组件,例如数据库,缓存等,且运行在独立的进程中。 |
微服务之间的通信时通过HTTP协议或者消息组件,且具有容错能力。 |
微服务有一套服务治理的解决方案,服务之间不耦合,可以随时加入和剔除服务。 |
单个微服务能够集群化部署,并且有负载均衡的能力。 |
整个微服务系统应该有一个完整的安全机制,包括用户验证,权限验证,资源保护等。 |
整个微服务系统有链路追踪的能力。 |
有一套完整的日志系统。 |
微服务的功能主要体现在:
服务的注册和发现 |
服务的负载均衡 |
服务的容错 |
服务网关 |
服务配置的统一管理 |
链路追踪 |
实时日志。 |
2.服务的注册与发现:
服务注册是指向服务注册中心一个服务实例,服务提供者将自己的服务信息告知服务注册中心,服务发现是指当服务消费者需要消费另外一个服务时,服务注册中心能够告知服务消费者它所要消费服务的实例信息。通常一个服务即是服务提供者,又是服务消费者。富足注册中心会提供服务的健康检查方案,检查被注册的服务是否可用。通常一个服务实例注册后,会定时向服务注册中心提供心跳,以表明自己还处于可用的状态。当一个服务实例停止向服务注册中心提供心跳一段时间后,那么,服务注册中心会人为该服务实例不可用,会将该服务实例从服务注册列表中剔除。
服务的负载均衡:
在微服务架构中,服务之间的相互调用一般是通过HTTP通信协议来实现的。网络往往具有不可靠性,为了保证服务的高可用,服务单元往往是集群化部署。
服务的负载均衡,就是所有的服务都向服务注册中心注册,服务注册中心持有每个服务的应用名和IP,同时每个服务也会获取所有的服务注册列表信息。服务消费者集成负载均衡组件,该组件会向服务消费者获取服务注册列表信息,并每隔一段时间重新刷新获取该列表。当服务消费者消费服务时,负载均衡组件获取服务提供者所有实例的注册信息,并通过一定的负载均衡策略,选择一个服务提供者的实例,向该实例进行服务消费,这样就实现了负载均衡。
服务注册中心不但要定时接受每个服务的心跳,而且每个服务会定期获取服务注册列表的信息。当服务实例数量很多时,服务注册中心承担了非常大的负载。由于服务注册中心在微服务系统中祈祷了至关重要的作用,所以要实现高可用。一般的做法是将服务注册中心集群化,每个服务注册中心的数据实时同步。
服务的容错:
为了解决防止雪崩效应的出现,分布式系统引进了熔断器机制。当一个服务的处理请求的失败次数在一定时间内小于设定的阀值时,熔断器处于关闭状态,服务正常。当服务处理用户请求的失败次数大于设定的阀值时,说明服务出现了故障,打开熔断器,这时所有的请求会执行快读失败,不执行业务逻辑。
熔断机制的意义,不仅能够防止系统的雪崩效应,还具有:
资源进行隔离 | 将资源进行隔离,如果某个服务里的某个API接口出现了故障,指挥隔离该API接口。不会影响到其他API接口。被隔离的api接口会执行快速失败的逻辑,不会等待,请求不会阻塞。如果不进行这样隔离,请求会一直处于阻塞状态,直到超时。若有大量的请求同时涌入,都处于阻塞的状态,服务器的线程资源,迅速被消耗完。 |
服务降级的功能 | 服务降级的功能。当服务处于正常的状态时,大量的请求在短时间内同时涌入,超过了服务的处理能力,这时熔断器会被打开,将服务降级,以免服务器因负载过高而出现故障。 |
自我修复能力 | 自我修复能力。当因某个微小的故障,例如网络服务商的问题,导致网络在短时间内不可用,熔断器被打开。如果不能自我监控,自我检测和自我修复,那么需要开发人员手动的去关闭熔断器,那么就会增加开发人员的 工作量。 |
服务网关:微服务系统通过将资源以API接口的形式暴露给外界来提供服务。在微服务系统中,API接口资源通常是由服务网关统一暴露,内部服务不直接对外提供API资源的暴露。保证了微服务系统 的安全,通常情况,网关层以集群的形式存在。在服务网关之前,可能需要加上负载均衡层,通常为Nginx双机热备,通过一定的路由策略,将请求转发到网关层。
网关的意义:
1.网关将所有的服务API接口资源统一聚合,对外统一暴露,外界系统调用的API接口都是网关对外暴露的API接口。 |
2.网关可以做一些用户身份认证,权限认证,防止非法请求操作API接口,对内部服务起到保护作用。 |
3.网关可以实现监控功能,实时日志输出,对请求进行记录。 |
4.网关可以用来做流量监控,在高流量的情况下,对服务进行降级。 |
5.API接口从内部服务分离出来,方便做测试。 |
服务配置的统一管理:
在实际开发过程中,每个服务都有大量的配置文件,例如数据库的配置,日志输出级别的配置等。在微服务架构中,需要有统一管理配置文件的组件,例如spring cloud 的config 组件,阿里的diamond 等。
spring cloud : spring cloud 是基于spring boot 的,简化了开发和部署的过程,简化了spring 复杂的配置和依赖管理,通过起步依赖和内置servlet 容器能够使开发者迅速搭起一个web 工程。
spring cloud 的首要目标就是通过提供一系列开发组件和框架,帮助开发者迅速搭建一个分布式的微服务系统。spring cloud 是通过包装其他技术框架来实现的。例如包装开源的Netflix OSS组件,实现了一套通过基于注解,Java配置和基于模板开发的微服务框架。spring cloud 提供了开发分布式微服务系统的一些常用组件,例如服务注册和发现,配置中心,熔断器,智能路由,微代理,控制总线,分布式会话等。
常用组件:
1.服务注册和发现组件Eureka
利用Eureka 组件可以很轻松的实现服务的注册和发现的功能。Eureka 组件提供了服务的健康检测,以及界面友好的UI。通过Eureka 组件提供的UI,eureka 组件可以让开发人员随时了解服务单元的运行情况。另外,spring cloud 也支持consul 和zookeeper ,用于注册和发信啊服务。
2.熔断组件Hystrix
Hystrix 是一个熔断组件,它除了有一些基本的熔断器功能外,还能够实现服务降级,服务限流的功能。另外,Hystrix提供了熔断器的健康检测,以及熔断器健康数据的API接口。Hystrix Dashboard 组件提供了单个服务熔断器的健康状态数据的界面展示功能,Hystrix Turbine 组件提供了多个服务的熔断器的健康状态数据的界面展示功能。
负载均衡组件Ribbon:
Ribbon 是一个负载均衡组件,它通过和Eureka,zuul,restTemplate,feign配合使用。ribbon 和zuul 配合,很容易做到负载均衡。将请求根据负载均衡策略分配到不同的服务实例种。ribbon 和restTemplate,feign 配合,再消费服务时能够做到负载均衡。
路由网关Zuul:
路由网关Zuul 有智能路由和过滤的功能。内部服务的API接口通过Zuul网关统一对外暴露,内部服务的API接口不直接暴露,防止了内部服务敏感信息对外暴露。默认情况下,zuul 和ribbon 组合,能够做到负载均衡,智能路由。zuul 的过滤功能是通过拦截请求来实现的,可以对一些用户的角色和权限进行判断,起到安全验证的作用,同时也可以用于输出实时的请求日志。
spring cloud config:
spring cloud config组件提供了配置文件统一管理的功能。spring cloud config包括server 端和client端。server端读取本地仓库或者远程仓库的配置文件,所有的client向sever读取配置信息,从而达到配置文件统一管理的目的。通常情况下,spring cloud config 和spring cloud bus 相互配合刷新指定client或所有的client 的配置文件。
spring cloud security:
spring cloud security 是对spring security 组件的封装,spring cloud security向服务单元提供了用户验证和权限认证。一般来说,单独在微服务系统中使用spring cloud security是很少见的,一般它会配合spring security oauth2组件一起使用,通过搭建授权服务,验证token 或jwt (java web token)这种形式对整个微服务系统进行安全验证。
spring cloud sleuth:
spring cloud sleuth 是一个分布式链路追踪组件,它封装了dapper,zipkin,kibana 等组件,通过它可以直到服务之间的相互依赖关系,并实时观察链路的调用情况。
spring cloud stream:
spring cloud stream是spring cloud 框架的数据流操作包,可以封装rabbitMQ,activeMQ,kafka,redis等消息组件,利用spring cloud strem 可以实现消息的接收和发送。
spring cloud config | 服务配置中心,将所有的服务的配置文件放到本地仓库或者远程仓库,配置中心负责读取仓库的配置文件,其他服务向配置中心读取配置。spring cloud config 使得服务的配置统一管理,并可以在不人为重启服务的情况下进行配置文件的刷新。 |
spring cloud netflix | 通过包装了Netflix 公司的微服务组件实现的,也是spring cloud核心的核心组件,包括eureka,hystrix,zuul,archaius等。 |
eureka | 服务注册和发现组件 |
hystrix | 熔断器组件。hystrix通过控制服务的api接口的熔断来转移故障,防止微服务系统发生雪崩。hystrix能够起到服务限流和服务降级的作用。使用hystrix dashboard 组件监控单个服务的熔断器的状态,使用turbine组件可以聚合多个服务的熔断器的状态。 |
zuul | 智能路由网关组件。Netflix zuul能够起到智能路由和请求过滤的作用,是服务接口统一暴露的关键模块,也是安全验证和权限控制的一道门。 |
feign | 声明式远程调度组件 |
ribbon | 负载均衡组件 |
archaius | 配置管理api的组件,一个基于Java的配置管理库,主要用于多配置的动态获取 |
spring cloud bus | 消息总线组件,常和spring cloud config 配合使用,用于动态刷新服务的配置 |
spring cloud sleuth | 服务链路追踪组件,封装了dapper,zipkin,kibana 等组件,通过它可以直到服务之间的相互依赖关系,并实时观察链路的调用情况。 |
spring cloud data flow | 大数据操作组件,spring cloud data flow 是spring xd的替代品,也是一个混合计算的模型,可以通过命令行的方式操作数据流 |
spring cloud security | 安全模块组件,是对spring security的封装,配合spring security oauth2组件一起使用,通过搭建授权服务,验证token 或jwt (java web token)这种形式对整个微服务系统进行安全验证。 |
spring cloud consul | 该组件是spring cloud 对consul的封装,和eureka 类似,它是另一个服务注册和发现组件。 |
spring cloud zookeeper | 该组件是spring cloud 对zookeeper的封装,和eureka,consul 类似,它是另一个服务注册和发现组件。 |
spring cloud stream | spring cloud stream是spring cloud 框架的数据流操作包,可以封装rabbitMQ,activeMQ,kafka,redis等消息组件,利用spring cloud strem 可以实现消息的接收和发送。 |
spring cloud cli | 该组件是spring cloud 对spring boot cli 的封装,可以让用户以命令行方式快速运行和搭建容器 |
spring cloud task | 该组件基于spring task ,提供了任务调度和任务管理的功能。 |
spring cloud connectors | 用于paas 云平台连接到后端。 |
dubbo:
dubbo 是阿里巴巴开源的一个分布式服务框架,致力于提高性能和透明化是RPC远程服务调用方案,以及SOA服务治理方案。
RPC远程调用 | 封装了长连接NIO框架,如netty,mina等,采用的是多线程模式 |
集群容错 | 提供了基于接口方法的远程调用的功能,并实现了负载均衡策略,失败容错等功能 |
服务发现 | 集成了apache 的zookeeper组件,用于服务的注册和发现。 |
dubbo架构的流程如下:
1.服务提供者向服务中心注册服务 |
2.服务消费者订阅服务 |
3.服务消费者发现服务 |
4.服务消费者远程调度服务提供者进行服务消费,在调度过程中,使用了负载均衡策略,容错失败的功能。 |
5.服务消费者和提供者,在内存中记录服务的调用次数和调用时间,并定时每分钟发送一次统计数据到监控中心。 |
连通性 | 注册中心负责服务的注册。监控中心负责收集调用次数,调用时间;注册中心,服务提供者,服务消费者为长连接。 |
健壮性 | 监控中心宕机不影响其他服务的调用;注册中心集群,任意一个实例宕机自动切换到另一个注册中心实例;服务实例集群,任意一个实例宕机,自动切换到另外一个可用的实例。 |
伸缩性 | 可以动态增减注册中心和服务的实例数量 |
升级性 | 服务集群升级,不会对现有的架构造成压力。 |
微服务关注点 | spring cloud | dubbo |
配置管理 | config | - |
服务发现 | eureka,consul,zookeeper | zookeeper |
负载均衡 | ribbon | 自带 |
网关 | zuul | - |
分布式追踪 | spring cloud sleuth | - |
容错 | hystrix | 不完善 |
通信方式 | http ,message | RPC |
安全模块 | spring cloud security | - |
配置 | pring cloud 基于spring boot ,spring boot采用的是基于注解和java been配置方式的敏捷开发。 | dubbo 更倾向于spring xml 的配置方式,dubbo官方也推荐这种方式 |
通信方式&语言平台相关性 | spring cloud 的通信方式大多数是基于http restful 风格的,服务与服务之间完全无关,无耦合。由于采用的是http rest ,因此服务无关语言和平台,只需要提供相应api接口就可以相互调用。 | dubbo 的通信方式基于rpc远程调用,对接口,平台,和语言有强依赖性。 |
kubernates:
kubernates 是一个容器集群管理系统,为容器化的应用程序提供部署运行,维护,扩展,资源调度,服务发现等功能。
构建微服务的准备《三》
idea 启动多个实例:
选中项目--》edit configuration-->选中项目--》取消single instance only 即可。
maven 可以管理项目 的整个生命周期,包括清理clear ,编译compile,打包package,测试test等环节。
maven 添加阿里云镜像:
<mirror>
<!--This sends everything else to /public -->
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
validate | 验证工程你的完整性 |
initialize | 初始化 |
generate-sources | 生成源码 |
process-sources | 处理源码 |
generate-resources | 生成所有源码 |
process-resources | 处理所有源码 |
compile | 编译 |
process-classes | 处理class文件 |
generate-test-sources | 生成测试源码 |
process-test-sources | 处理测试源码 |
generate-test-resources | 生成所有测试源码 |
process-test-resources | 处理所有测试源码 |
test-compile | 测试编译 |
process-test-classes | 处理所有测试源码 |
test | 测试 |
prepare-package | 预打包 |
package | 打包 |
pre-integration-test | 预集成测试 |
integration-test | 集成测试 |
post-integration-test | 完成集成测试 |
verify | 验证 |
install | 安装到本地仓库 |
deploy | 提交到远程仓库 |
开发框架spring boot 《四》
spring boot :自动配置,起步依赖,actuator对运行状态的监控。
@SpringBootApplication 注解包含了@springBootConfiguration ,@EnableAutoConfiguration , @ComponentScan ,开启了包扫描,配置和自动配置的功能。
@RestController 注解表名这个类是一个restController 。@RestController 是spring4.0版本的一个注解,它的功能相当于@Controller和@ResponseBody 注解之和。
@RequestMapping 注解是配置请求地址的URL映射。
在测试类上加上web 测试环境的端口为随机端口的配置。TestRestTemplate 类为RestTemplate测试类,RestTemplate用于远程调用Http API 接口。(详情见代码)
spring boot 可以通过@Value("${my.name}") private String name;将配置文件yml(properties)读出来。但多个属性时,逐个读取属性会显得麻烦,通常的做法会把这些属性名作为变量名来创建一个javaBean 的变量,并将这些属性值赋值给JavaBean的变量。
在JavaBean 类上加@ConfigurationProperties表明该类为配置类,并加上配置的prefix(prefix = "my")。加上@Component注解,spring boot 在启动时通过包扫描将该类作为一个Bean注入IOC容器中。
在controller 类上加上@EnableConfigurationProperties({ConfigBean.class})注解,并指明ConfigBean 类。
将配置文件properties 赋值给类,见UserInfo 类。
运行状态监控Actuator: spring boot 的 Actuator提供了运行状态监控的功能,Actuator的监控数据可以通过rest ,远程shell,jxm 方式获得。
通过rest 方式查看Actuator 的节点方法时最常见且简单的方法。在pom.xml引入文件。控制台可以看到效果。
spring boot 整合JPA。
JPA (java persistence api),它是一个数据持久化的类和方法 的集合。JPA的目标是指定一个由很多数据库供应商实现的API。开发人员可以通过编码实现该API 。
在pom 文件引入相关文件。
项目示例:GitHub - waitforyouwtt/springbootweb: 深入理解微服务
服务注册和发现Eureka《五》
eureka 是一个微服务注册和发现的组件。分为eureka server 和 eureka client 。eureka server 为eureka 服务注册中心,eureka client 为eureka 客户端。
eureka 是spring cloud 首推的服务注册和发现组件,与spring cloud 其他组件无缝对接。eureka 和其他组件:负载均衡组件 ribbon,熔断器hystrix,熔断器监控组件hystrix dashboard 组件,熔断器聚合监控turbine 组件,以及网关zuul 组件相互配合,能够很容易实现服务注册,负载均衡,熔断和智能路由等功能,这些组件都是由Netflix 公司开源的,一起被称为Netflix oss 组件。
register service | 服务注册中心,它是一个eureka server,提供服务注册和发现的功能 |
provider service | 服务提供者,它是一个eureka client ,提供服务 |
consumer service | 服务消费者,它是一个eureka client ,消费服务 |
服务消费的基本过程:
1.搭建一个服务注册中心eureka server
2.服务提供者eureka client 向服务注册中心eureka server 注册,将自己的信息(服务名/ip)通过rest api 的形式提交给eureka server 。
3.服务消费者eureka client 向服务注册中心eureka server 注册,同时服务消费者获取一份注册列表的信息,该列表包含了所有向服务注册中心eureka server 注册的服务信息。
4.获取服务注册列表信息之后,服务消费者就知道服务提供者的ip 地址,可以通过http 远程调度来消费服务提供者的服务。
项目实战:
1.利用maven 创建一个空项目
2.在主项目下创建模块,引入相关依赖。
3.如果报错:K/V [说明依赖报错],String ---Map 说明yml 文件格式错误。
4.直到项目正常启动。【项目启动有先后顺序,先启动eureka server,再启动eureka client ,不然报错:找不到注册中心】
register:服务注册: | 当eureka client 向eureka server 注册时,eureka client 提供自身的元数据:ip,端口,运行状态的url ,主页地址等。 |
Renew:服务续约: | eureka client 默认情况下每30秒发送一次心跳进行服务续约。通过服务续约告知eureka server 该eureka client 可用,未故障。正常情况下,如果eureka server 90秒内未收到eureka client 的心跳,eureka server 会将eureka client 实例从注册列表中删除【一般不建议更改服务续约时间哦】 |
Fetch Registries:获取服务注册列表信息 | eureka client 从eureka server 获取服务注册表信息,并将其缓存到本地。eureka client会使用服务注册列表信息查找其他服务的信息,从而进行远程调用。该注册列表信息定时(每30秒)更新一次,每次返回注册列表信息可能与eureka client 缓存信息不同,eureka client 会自己处理这些信息。如果由于某些原因导致注册列表信息不能及时匹配,eureka client 会重新获取整个注册表信息。eureka server 缓存了所有的服务注册列表信息,并将整个注册列表信息以及每个应用程序的信息进行了压缩,压缩内容和未压缩的内容完全相同。eureka client 和eureka server 可以使用json 和 xml 数据格式进行通信,默认情况下,eureka client 使用json 的格式来获取服务注册列表的信息。 |
cancel:服务下线 | eureka client 再程序关闭时可以向eureka server 发送下线请求。发送请求后,该客户端的实例信息将从eureka server 的服务注册列表中删除。该下线请求不会自动完成,需要在程序关闭时调用以下代码:DiscoveryManager.getInstance().shutdownComponent(); |
eviction:服务剔除 | 默认情况下,如果eureka server 90秒内未收到eureka client 的心跳,eureka server 会将eureka client 实例从注册列表中删除。 |
register 服务注册:
服务注册,即eureka client 向eureka server 提交自己的服务信息(ip,端口,serviceId)等,如果eureka client 在配置文件中没有配置serviceId ,则默认为配置文件中国配置的服务名,即${spring.application.name}的值。
发送心跳时间每30秒,剔除时间90秒,如果你真的需要更改,则在application.yml 加以下的配置:
eureka.instance.leaseRenewalIntervalInSeconds
eureka.instance.leaseExpirationDurationInSeconds
eureka client 的注册延时 | eureka client 启动之后,不是立即向eureka server 注册的,而是有一个延时向服务端注册的时间,源码显示,默认的延迟时间为40秒 |
eureka server的相应缓存 | eureka server维护每30秒更新一次相应缓存,可通过更改配置eureka.server.responseCacheUpdateIntervalMs来修改。所以即使是刚刚注册的实例,也不会立即出现在服务注册列表中。 |
eureka client 的缓存 | eureka client 保留注册表信息的缓存,该缓存每30秒更新一次,因此,eureka client 刷新本地缓存并发现其他新注册的实例可能需要30秒 |
loadBalancer的缓存 | ribbon 的负载均衡从本地的eureka client 获取服务注册列表信息。ribbon本身还维护了缓存,以避免每个请求都需要哦才能够eureka client 获取服务注册列表。 |
eureka 的自我保护模式:
当有一个新的eureka server 出现时,它尝试从相邻peer 节点获取所有服务实例注册表信息,如果从相邻的 peer 节点获取信息时出现了故障,eureka server 会尝试从其他 的peer 节点。如果eureka server 能够成功获取所有的服务实例信息,则根据配置信息设置服务续约的阈值。在任何时间,如果 eureka server 接收到的服务续约低于该值配置的百分比(默认为15分钟内低于85%),则服务器开启自我保护模式,即不再剔除注册列表的信息。
eureka 的自我保护模式的好处是:如果eureka server 自身的网络问题而导致eureka client无法续约。eureka client 的 注册列表信息不再被删除,即eureka client 还可以被其他服务消费。
默认情况下,eureka server 的自我模式是开启的,如果需要关闭,则在配置文件加以下代码:
eureka:
server:
enable-self-preservation:false
构建高可用的eureka server 集群:
配置文件中,定义了两个profile 文件,分别为peer1 和 peer2,它们的 hostname 分别为:peer1 和peer2.
在实际开发中,可能是具体的服务器Ip 地址。
在本地搭建eureka server 集群,需要修改本地的host 。windows 系统在C:\Windows\System32\drivers\etc\hosts 修改:
127.0.0.1 peer1
127.0.0.1 peer2
看成果:
项目打包,运行jar 包:
Java -jar xxx.jar --spring.profiles.active=peer1
java -jar xxx.jar --spring.profiles.active=peer2
启动eureka client
eureka client 指向的是peer1,peer2 也看到了。这就是注册列表同步。
项目展示:springcloud模块化-高可用部署_springcloud模块化-Java代码类资源-CSDN下载