1.如何把你的项目从0到1的过程聊出来(项目的正常发展流程是什么?)
大型项目 微服务架构设计
构建团队的时候 先把项目的原型 设计出来
单体架构 演变成 集群架构 补充的操作
同步进行一些业务上的拆分
垂直架构的冗余问题 信息孤岛的问题
soa 面向服务架构 0 ———- 1 - 项目稳定且有含金量 踩过的坑
最开始的时候,我们的项目,就是单体架构 我们花费了3个月的时间,实现了整个项目的基本需求。运行的过程中,会发现不足 ,业务的耦合度增加 项目的关联度增加 ,项目某些功能会出现卡顿。可以采用集群架构来缓解单体架构的压力。为了防止我们的耦合度产生以及信息孤岛的问题 我们采用了SOA架构进行开发,同时进行设计以及编排,我们采用Dubbo+ZK的架构进行设计以及开发
软件架构的发展经历了从单体结构、垂直架构、SOA架构到微服务架构的过程.
1.单体架构
特点:
1、所有的功能集成在一个项目工程中。
2、所有的功能打一个war包部署到服务器。
3、应用与数据库分开部署。
4、通过部署应用集群和数据库集群来提高系统的性能。
优点:
1、项目架构简单,前期开发成本低,周期短,小型项目的首选。
缺点:
1、全部功能集成在一个工程中,对于大型项目不易开发、扩展及维护。
2、系统性能扩展只能通过扩展集群结点,成本高、有瓶颈。
3、技术栈受限。2.集群架构
特点:
在单体架构的基础上进行了水平扩容
3.垂直架构
特点:
1、以单体结构规模的项目为单位进行垂直划分项目即将一个大项目拆分成一个一个单体结构项目。
2、项目与项目之间的存在数据冗余,耦合性较大,比如上图中三个项目都存在客户信息。
3、项目之间的接口多为数据同步功能,如:数据库之间的数据库,通过网络接口进行数据库同步。
优点:
1、项目架构简单,前期开发成本低,周期短,小型项目的首选。
2、通过垂直拆分,原来的单体项目不至于无限扩大。
3、不同的项目可采用不同的技术。缺点:
1、全部功能集成在一个工程中,对于大型项目不易开发、扩展及维护。
2、系统性能扩展只能通过扩展集群结点,成本高、有瓶颈。
4.SOA架构
特点:
1、基于SOA的架构思想将重复公用的功能抽取为组件,以服务的方式给各各系统提供服务。
2、各各项目(系统)与服务之间采用webservice、rpc等方式进行通信。
3、ESB企业服务总线作为项目与服务之间通信的桥梁。解决信息孤岛
优点:
1、将重复的功能抽取为服务,提高开发效率,提高系统的可重用性、可维护性。
2、可以针对不同服务的特点制定集群及优化方案。
3、采用ESB减少系统中的接口耦合。
缺点:
1、系统与服务的界限模糊,不利于开发及维护。
2、虽然使用了ESB,但是服务的接口协议不固定,种类繁多,不利于系统维护。
3、抽取的服务的粒度过大,系统与服务之间耦合性高。
5.微服务架构特点:
1、将系统服务层完全独立出来,并将服务层抽取为一个一个的微服务。
2、微服务遵循单一原则。
3、微服务之间采用RESTful等轻量协议传输。
4、解耦
优点:
1、服务拆分粒度更细,有利于资源重复利用,提高开发效率。
2、可以更加精准的制定每个服务的优化方案,提高系统可维护性。
3、微服务架构采用去中心化思想,服务之间采用RESTful等轻量协议通信,相比ESB更轻量。
4、适用于互联网时代,产品迭代周期更短。
缺点:
1、微服务过多,服务治理成本高,不利于系统维护。
2、分布式系统开发的技术成本高(容错、分布式事务等),对团队挑战大。
微服务与SOA的区别
SOA:解决服务可复用性,信息孤岛
微服务:解耦拓展
微服务解决方案之SpringCloud
构建分布式系统不需要复杂和容易出错。Spring Cloud 为最常见的分布式系统模式提供了一种简单且易
于接受的编程模型,帮助开发人员构建有弹性的、可靠的、协调的应用程序。Spring Cloud 构建于
Spring Boot 之上,使得开发者很容易入手并快速应用于生产中。
我所理解的 Spring Cloud 就是微服务系统架构的一站式解决方案,在平时我们构建微服务的过程中需
要做如 服务发现注册 、配置中心 、消息总线 、负载均衡 、断路器 、数据监控 等操作,而 Spring
Cloud 为我们提供了一套简易的编程模型,使我们能在 Spring Boot 的基础上轻松地实现微服务项目的
构建。
2.如何解决架构的复杂度问题,或者换句话说,如何降低架构的复杂度
我们到底要如何降低系统的复杂度呢?本质思想如上所述,需要加入外力的干预,最好是强力的干预。而这个外力我认为就是架构设计思想和架构解耦工具
1.架构分层
我认为分层几乎是系统设计中最重要的思想,可以参考计算机网络协议和计算机缓存设计等。
三层架构
四层架构 职责单一化
2.领域拆分
良好的领域拆分需要依赖系统设计人员对系统应用场景的深刻理解。且具备很好的抽象能力。
3.服务聚合
同拆分一样,找到同类的功能进行聚合,也是需要对场景的理解,且需要不断优化和尝试。
A +B = C
4.高度自治
系统拆分与聚合清晰后,需要独立模块有高度自治的能力。对外定义控制输入和输出协议,对内实现独立且明确的能力。
5.链路简单清晰
系统链路一定要简化,尤其系统核心链路。简单意味着好理解、易维护、稳定性强、容易扩展。
用户-商品-订单- 库存- 支付 冗余到一起
DDD领域驱动
3.微服务项目中有哪些特殊的解耦方式(代码层面)
解耦工具-主要指常用的代码设计方法
1.事件消息机制
1 | import java.util.ArrayList; |
在这个事件驱动的代码中,我们有一个Event类来表示事件,并具有一个类型属性。我们还有一个EventHandler接口,用于处理事件。最后,我们有一个EventDispatcher类,用于添加处理程序并分派事件。
可以创建不同类型的事件,并创建实现EventHandler接口的处理程序来处理这些事件。然后,可以将处理程序添加到EventDispatcher中以便可以启动事件处理。
例如,我们可以创建一个名为“ButtonClickEvent”的事件,并创建一个名为“ButtonClickEventHandler”的处理程序来处理该事件。然后,可以将该处理程序添加到EventDispatcher中,以便在单击按钮时启动事件处理。
1 | public class ButtonClickEvent extends Event { |
在这个示例中,我们创建了一个名为“ButtonClickEvent”的事件,并创建一个名为“ButtonClickEventHandler”的处理程序来处理它。然后,我们创建了一个事件分派器,并添加了该处理程序。最后,我们分派按钮单击事件,该事件将触发执行单击按钮时要执行的操作。
可以根据需要添加更多的事件和处理程序,并根据事件类型执行不同的操作。
2.策略、责任链等设计模式
在电商场景中,责任链模式可以用于处理订单退款申请。下面是一个简单的电商场景的责任链Java代码实现:
1 | public abstract class RefundHandler { |
在这个责任链的实现中,我们定义了一个抽象的RefundHandler类,它有一个指向下一个处理程序的引用,还有一个处理退款申请的抽象方法handle。如果当前处理程序无法处理退款申请,则将退款请求转发给下一个处理程序。
我们还定义了三个具体的处理程序CustomerServiceHandler、FinanceHandler和LogisticsHandler,它们分别处理不同类型的退款请求。如果一个处理程序可以处理退款请求,则处理该请求并结束责任链。否则,将该请求传递给下一个处理程序。
我们可以将这些处理程序按照责任链的顺序连接起来:
1 | RefundHandler logisticsHandler = new LogisticsHandler(); |
然后,当收到一个退款请求时,我们将它传递给责任链的第一个处理程序:
1 | Order order = getOrder(); |
如果第一个处理程序无法处理该请求,则将其传递给下一个处理程序。如果所有处理程序都无法处理该请求,则在最后提供默认响应。
1 | System.out.println("没有处理该退款请求的处理程序"); |
3.规则引擎
规则引擎可以帮助你将逻辑和数据解耦,数据放入领域模型中,逻辑放入规则中
电商领域的规则引擎可以用来处理价格计算、促销活动、优惠券使用等复杂的业务逻辑。以下是一个电商领域的规则引擎的简单示例代码:
假设我们需要计算某个商品的价格,考虑到会有多种不同的优惠策略,如会员折扣、新用户优惠、满减等,这时我们可以使用规则引擎来实现灵活的计价方案。
首先我们定义一个Rule类,用来表示一个规则:
1 | public abstract class Rule<T> { |
在这里,我们定义了两个抽象方法 evaluate
和 calculate
,分别用来评估当前规则是否适用于给定的对象(如某个订单)以及如何计算折扣后的价格等。
接下来,我们定义一个RuleEngine类,用来实现规则的执行逻辑:
1 | public class RuleEngine<T> { |
在这里,我们定义了一个 addRule
方法和一个 execute
方法。其中 addRule
用来添加规则,而 execute
方法则用来执行规则引擎的逻辑。在 execute
方法中,我们首先对规则按照优先级进行排序,然后依次运行每一个规则。如果当前规则适用于给定的对象,则执行该规则的计算方法,累加价格并返回。
最后,我们可以使用具体的规则来实现价格计算:
1 | public class MemberDiscountRule extends Rule<Order> { |
在这里,我们实现了会员折扣、新用户优惠和满减等三个规则。通过 evaluate
方法判断当前规则是否适用于给定的订单,通过 calculate
计算满足当前规则后的价格。我们可以通过如下方式来应用这些规则:
1 | RuleEngine<Order> engine = new RuleEngine<>(); |
当然,市面上也有一些开源的规则引擎,这个更好用一些,比如drools这种
4.状态机
1 | public enum State { |
在这个状态机中,我们有三个状态: STATE_ONE,STATE_TWO和STATE_THREE。在构造函数中,我们将初始状态设置为STATE_ONE。
processInput方法接受输入,并根据当前状态进行转换。在每个状态中,我们检查输入并根据需要更新状态。
例如,如果我们处于STATE_ONE状态,并且输入是“A”,我们将转换到STATE_TWO状态。如果我们处于STATE_TWO状态并且输入是“B”,我们将转换到STATE_THREE状态。如果我们处于STATE_TWO状态但输入不是“B”,我们将返回到STATE_ONE状态。在STATE_THREE状态中,如果输入是“C”,我们将返回到STATE_ONE状态。否则,我们将保持在STATE_THREE状态中。
可以根据需要修改此状态机,例如,添加更多状态或更改状态之间的转换条件。
4.服务划分原则
在微服务架构中,服务划分可以基于多种因素,例如业务功能、数据域、可扩展性、可维护性等。以下是一些常用的划分方法:
- 基于业务功能:将服务划分为不同的业务功能单元,例如订单服务、支付服务、用户服务等。
使用场景:一般来说,业务功能开发规模较小的时候可以采取这种方式,因为这种情况下可以接受耦合度较高的情况 - 基于数据域:将服务按照数据领域进行划分,例如客户服务(用户中心)、订单服务(订单中心)、库存服务(WMS数据中心)等。
使用场景:一般数据规模比较大,可以采取这种方式,数据之间互相隔离,单独处理,对于实时性要求比较高的海量数据可以有单独处理的方式以及手段,比如证券场景的下单以及结算就是典型的场景 - 基于可扩展性:将服务划分为可以水平扩展的单元,例如将前端服务划分为多个负载均衡的实例,每个实例都可以处理一部分流量。
使用场景:这种其实就是集群的方式,但是相对于常规的集群 这种属于微服务集群,一般用于辅助场景 - 基于可维护性:将服务划分为易于维护和更新的单元,例如将核心服务与辅助服务分离,将通用功能提取为独立的服务。 使用场景:这种其实就是领域驱动的划分方式
举例:
微服务采取领域驱动设计(DDD)的方式进行划分服务,步骤举例:
一、理解DDD的核心概念
- 领域(Domain) :
- 特定的问题范围或业务区域,如电商、金融等。
- 子域(Subdomain) :
- 领域的细分部分,如电商领域的订单、商品、物流等子域。
- 通用语言(Ubiquitous Language) :
- 团队内部达成共识的、能够简单、清晰、准确描述业务涵义和规则的语言。
- 限界上下文(Bounded Context) :
- 封装通用语言和领域对象的上下文环境,确保术语和业务相关对象在领域内有一致的含义。
二、进行领域建模
- 分析领域模型 :
- 识别领域中的实体、值对象、领域服务等。
- 确定聚合边界 :
- 找出业务紧密相关的实体,形成聚合,以降低服务间的耦合。
- 为聚合配备存储仓库 :
- 实现数据持久化,确保领域模型的状态可以被持久保存。
三、划定微服务边界
- 事件风暴 :
- 通过事件风暴会议,识别业务事件和领域对象,梳理出领域实体等领域对象。
- 形成聚合 :
- 根据领域实体之间的业务关联性,将业务紧密相关的实体组合形成聚合。
- 划定限界上下文 :
- 将一个或多个聚合划定在一个限界上下文内,形成领域模型。限界上下文之间的边界可能是未来微服务的边界。
四、设计微服务接口
- 确定服务职责 :
- 每个微服务应负责一个特定的业务领域,并对外提供API接口。
- 设计API接口 :
- 使用RESTful风格或其他适合的接口设计风格,定义清晰、易于理解的API接口。
- 实现服务调用 :
- 使用HTTP、gRPC等协议实现微服务之间的通信和调用。
五、实施微服务拆分
- 拆分原则 :
- 遵循单一职责、高内聚低耦合的原则,确保每个微服务都专注于自己的业务领域。
- 拆分粒度 :
- 服务粒度应适中,既不过细也不过粗。过细的服务会增加通信开销和复杂性,过粗的服务则会影响可维护性和可扩展性。
- 服务依赖 :
- 尽量避免服务之间的循环依赖和双向调用,采用单向调用和异步通信等方式降低服务间的耦合度。
六、持续优化和演进
- 响应业务变化 :
- 随着业务的发展变化,不断调整和优化领域模型和微服务架构。
- 技术升级 :
- 关注新技术的发展动态,适时将新技术引入到微服务架构中,以提高系统的性能和稳定性。
- 监控和治理 :
- 建立完善的监控和治理体系,及时发现和解决微服务架构中的问题。
综上所述,微服务采取DDD的方式进行划分服务需要深入理解DDD的核心概念、进行领域建模、划定微服务边界、设计微服务接口、实施微服务拆分以及持续优化和演进。
在面试时,应该清楚地解释您所选择的划分方法,并说明其优缺点以及在什么情况下该方法适用。此外,您应该能够描述如何将这些服务组合成一个完整的应用程序,并讨论在不同服务之间通信的方式。最后,您可能需要讨论一些与微服务相关的挑战,例如服务发现、服务治理、数据一致性等,并说明您如何解决这些挑战
5.微服务架构设计的优缺点
1.微服务架构的优点
- 灵活性高 :它将应用程序分解为小型服务(松散耦合),使其开发、维护更快,更易于理解,可以提供更高的灵活性;
- 独立扩展 :它使每个服务能够独立扩展,将系统中的不同功能模块拆分成多个不同的服务,这些服务进行独立地开发和部署,每个服务都运行在自己的进程内,这样每个服务的更新都不会影响其他服务的运行;
- 支持多种编程语言 :微服务可通过最佳及最合适的不同的编程语言与工具进行开发,能够做到有的放矢地解决针对性问题;异构开发
- 自动部署与持续集成工具集成 :它允许以灵活的方式将自动部署与持续集成工具集成,例如Jenkins,Hudson等;
- 通用性 :通过服务实现应用的组件化(按功能拆分、可独立部署和维护),围绕业务能力组织服务,根据业务不同的需求进行不同组件的使用,所做产品非项目化,对于平台具有一定的通用性。
2.微服务架构的缺点
- 处理故障难度高 :微服务架构是一个分布式系统,必须构建一个相互通信机制并处理部分故障;
- 部署工作量大 :整体式应用程序可以部署在负载平衡器后面的相同服务器上。但对于微服务,每个服务都有不同的实例,每个实例都需要配置、部署、缩放和监控;
- 测试复杂度高 :微服务在一定程度上也会导致系统变得越来越复杂,增加了集成测试的复杂度;
- 运营成本增加 :整体应用可能只需部署至一小片应用服务区集群,而微服务架构可能变成需要构建/测试/部署/运行数十个独立的服务,并可能需要支持多种语言和环境。这导致一个整体式系统如果由20个微服务组成,可能需要40~60个进程;
- 发布风险高 :把系统分为多个协作组件后会产生新的接口,这意味着简单的交叉变化可能需要改变许多组件,并需协调一起发布。在实际环境中,一个新品发布可能被迫同时发布大量服务,由于集成点的大量增加,微服务架构会有更高的发布风险;
- 分布性系统问题 :作为一种分布式系统,微服务引入了复杂性和其他若干问题,例如网络延迟、容错性、消息序列化、不可靠的网络、异步机制、版本化、差异化的工作负载等,开发人员需要考虑以上的分布式系统问题。
6.你们项目接口性能指标有哪些标准?
互联网项目中,接口性能指标可以从不同的角度进行考虑,以下是一些常用的指标:
- 响应时间:指接口处理请求并返回结果所需的时间。通常,响应时间应该尽可能地短,一般来说不超过1秒,最好控制在0.5秒以内。
- 吞吐量:指接口每秒处理的请求数。高吞吐量可以使系统更有效地使用资源并提高访问效率。对于高并发的应用,吞吐量要求会比较高,需要根据实际情况进行合理的调整。一般项目要求96%以上,但是根据CPU上下文切换时间不同,有所下降
- 并发数:指在同一时间内有多少个请求在处理。并发数过高可能会导致请求响应时间延长或者系统崩溃,需要合理地控制并发数。 2个方向进行控制 hystrix sentinel 并发控制 不限制死 业务服务之后
500个 200个 sentinel 信号量隔离 服务层面 线程池隔离 300 hystrix - 错误率:指接口处理失败或者返回错误结果的概率。错误率应该尽可能低,一般来说不超过1%,同时还需要对错误进行详细记录与分析,及时发现并解决问题。(召回率)
- 延迟分布情况:指接口响应时间在不同请求场景下的分布情况,如 90%的请求响应时间在1秒以内,99%的请求响应时间在2秒以内等。延迟分布情况可以给出更详细的性能数据,并根据数据来判断是否需要调整系统架构或者调整业务流程。
- 网络流量:指网络传输的数据量,可以根据实际情况进行监控和调整。Zabbix进行监控
- 系统资源利用率:指系统使用的CPU、内存、磁盘等资源的利用率,需要根据实际情况进行监控和调整。
综上所述,接口性能指标有很多,需要根据具体业务场景来选择和权衡。在实际项目中,可以使用一些专业的性能测试工具,如JMeter、Gatling等来进行性能测试,并根据测试结果进行适当的调整和优化。
7.在微服务架构下,如何判定性能的标准:
在微服务架构下,判别接口性能的标准一般可以从以下几个方面进行评估:
- 请求响应时间:这是最基本的性能评估指标之一。请求响应时间指的是从客户端发出请求到服务器处理完请求并返回响应所需要的时间。一般来说,请求响应时间越短,说明服务性能越好。
- 吞吐量:吞吐量指的是在一定时间内可以处理的请求数量。一般来说,吞吐量越高,说明服务性能越好。
- 并发能力:并发能力指的是服务器同时处理多个请求的能力。一般来说,服务器的并发能力越强,说明服务性能越好。
- 容错能力:容错能力指的是在出现异常情况时,服务器的自我保护和恢复能力。一般来说,容错能力越强,说明服务性能越好。
- 稳定性:稳定性指的是服务在长时间运行过程中,是否出现过崩溃、死锁等问题。一般来说,稳定性越高,说明服务性能越好。
在实际的性能测试中,除了以上几个方面,还可以根据具体业务需求进行评估。同时,在进行性能测试时,需要考虑到并发场景、请求量、负载均衡、缓存等因素对服务性能的影响,综合评估服务的性能表现。