自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(61)
  • 收藏
  • 关注

原创 解析资源库架构模式

架构模式的落地需要具体的开发框架。在上面的例子中,通过findByFirstNameAndLastname这样符合普通语义的方法名,并在参数列表中按照方法名中参数的顺序和名称传入相应的参数,即第一个参数是fistName,第二个参数lastName,Spring Data就能自动组装SQL语句从而实现衍生查询。在接下来的内容中,我们重点讨论的是用于实现关系型数据库访问的Spring Data JPA,在该组件中存在一个JpaRepository接口,该接口是CrudRepository的子接口。

2024-07-24 10:52:47 607

原创 解析数据拆分的实现方法

请注意,上图中所示的跨库查询和跨表查询方案的本质区别在于:位于不同数据库中的数据必须确保严格的边界,而通过接口的方式来获取数据可以做到这一点。在今天的内容中,我们基于主流的微服务架构,以单个数据库拆分的场景为例来开展讨论。针对跨多个业务模块的跨表查询应用场景,我们想要去掉表与表之间的连接也比较简单,因为表连接的本质就是把位于不同表中的数据进行组装,我们可以把这个组装过程放到内存中。可以看到,在这种应用场景下,数据库A和B中同时保存着表1和表2的数据,我们通过定时任务确保这两张表的数据是一致的。

2024-07-23 10:13:25 723

原创 解析服务拆分的实现策略

在上图中,如果服务B无法正常提供功能,则依赖它的服务A的整个业务流程无法正常执行下去,那么即为强依赖关系,也就是说,强依赖关系是服务正常运转的基本单元。一旦我们完成了服务的拆分,原本的单块系统就演变成了多个独立的服务。通常,我们可以对上图中的服务C设置开关,其目的是在极端资源瓶颈出现的时候,使得业务系统能够丢弃一些诸如服务C的弱依赖服务从而保全更关键的强依赖服务B。服务拆分是有方法的。最终,随着时间的推移,新服务的代码迭代的同时就会慢慢具备了原有遗留系统的所有业务功能,从而实现对原有系统的绞杀。

2024-07-22 14:37:12 654

原创 解析DDD中的聚合对象

例如,一种传统的做法是从数据的角度来规划对象的组织形式,先设计数据库模型,然后基于数据库模型设计对象,这些对象内部通常只包含数据属性的定义,也就是说整个开发过程是数据驱动(Data Driven)的。换句话说,对于一个聚合而言,外部组件只能看到一个聚合根对象,而位于聚合边界内部的其他对象只能通过聚合根进行关联,这种关联操作包括对对象的创建、查询、更新和删除。针对系统中的每一个子域以及上下文边界,我们首先对系统中存储的各种对象进行区分,在实体、值对象的集成上抽象聚合概念,确保边界的完整性和对象访问有效性。

2024-07-18 11:07:48 646

原创 解析DDD开发框架Axon

应用服务是我们重构的重点对象之一,因为在Axon中,对命令服务和查询服务所应该具备的操作做了明确的定义,我们需要引入命令总线和查询总线来分派命令和查询操作,并使用命令处理程序和查询处理程序来分别处理命令和查询对象。在上图中,我们看到了一组Axon技术组件,包括领域模型、资源库、命令处理程序和事件处理程序等,这些组件分别与DDD中的领域模型对象、资源库、命令服务、领域事件概念相对应。同时,在上图中,我们也可以看出,位于上半部分的组件能够改变应用程序的状态,而位于下半部分的组件则读取或查询应用程序的状态。

2024-07-16 14:19:16 488

原创 解析CQRS架构模式

让我们一起来看一下。因此,如果我们事先能够对系统中所有的查询操作和命令操作进行区分,那么就可以把安全性控制的重点工作放在命令操作上,确保数据模型的安全性。CQRS模式给我们的启示就在于:当在设计一个方法时,应该严格按照命令操作或查询操作来区分方法的行为,而不推荐设计如上图中所展示的查询+命令型的数据操作方式。CQRS模式的优势的非常明显的,查询操作和命令操作的分离,带来的好处就是有助于系统性能。在我们执行一个具体的数据操作是,如果该操作的结果是返回一个值,它就具有查询(Query)的性质,也就是读的性质;

2024-07-15 17:39:47 660

原创 组件设计原则和度量方法

我们知道,组件(Component)是设计和规划软件系统代码结构的基本单元,而在代码结构设计上最重要的关注点就是耦合(Coupling)度,用来处理组件与组件之间的关系。在软件系统中,如果某一个包被许多其他的软件包所依赖,也就是具有很多输入依赖关系的包就是稳定的,例如下图中的这个X组件。稳定依赖原则,即Stable Dependencies Principle,强调的也是稳定性,认为组件与组件之间的依赖关系应该是有方向的,也就说一个组件只应该依赖于比它更稳定的组件,反之就是不合理的。让我们一起来看一下。

2024-07-10 14:17:53 562

原创 注册中心组成结构和基本原理解析

如果你所开发的系统一直处于上图中的稳定状态,也就是说没有新的服务需要添加,正在运行的服务实例也不会出现宕机等故障,那么一切看上去都没有什么问题。但显然,这是不现实的。这实际上就是一个服务治理的问题,服务治理的需求来自于服务的数量,也来自于服务实例的动态性。上图中,服务消费者可以对这些具体的服务实例节点添加监听器,当这些节点发生变化时(例如图中服务B的第一个实例变得不可用、服务C的第一个实例地址变更、或者是服务D新增了一个实例3),注册中心就能触发监听器中的回调函数确保更新通知到每一个服务消费者。

2024-07-09 15:07:43 1001

原创 什么是企业服务总线?它包含哪些技术组件?

网关用于剥离移动医疗系统后台服务与集成服务之间的耦合,内容扩充器和数据结构转换器可以通过数据转换实现针对医院异构系统的集成和定制化需求,而接收表则根据消息头中携带的目标医院信息自动路由到目标医院所在的医院服务,最后目标医院服务的返回结果将通过网关转回到移动医疗系统,从而实现系统集成的闭环。围绕上述三个问题所得出的答案,我们加以排列组合可以得到多种常见的路由器表现形式,如下表所示,其中有状态的路由器指的就是需要根据消息传递的上下文确定路由结果,通常涉及多个消息,具有较高的复杂性。最后,让我们回到案例系统。

2024-07-08 16:05:16 762

原创 什么是分库分表?它有哪些实现类型?

所谓分库分表,你可以简单理解为:将原来独立的数据库拆分成若干数据库,将原来数据量大的单个表拆分成若干个数据表,使得单一数据库、单一数据表的数据量变得足够小,从而达到提升数据库性能的效果。有时候,我们也把分库分表统称为是一种数据分片技术,因为从概念上讲,无论是分库还是分表,都是把一定数据划分成不同的数据片,并存储在不同的目标对象中。通过垂直分表能得到来一定程度的性能提升,但毕竟拆分后的数据仍然都是位于同一个数据库实例中,每个表还是会竞争同一台数据库服务器中的CPU、内存、网络IO等资源,性能的提升限制很多。

2024-07-03 14:24:10 920

原创 负载均衡类型和算法解析

负载均衡算法可以分成两大类,即静态负载均衡算法和动态负载均衡算法,它们之间的区别在于是否依赖于当前服务的运行时状态,这些状态信息通常包括服务过去一段时间的平均调用时延和所承接的连接数等。显然,在这种负载均衡架构下,在客户端与服务实例之间存在一个独立的负载均衡服务器,然后这台负载均衡服务器负责将接收到的各个请求转发到运行中的某个服务实例上。相比较而言,客户端负载均衡机制的主要优势就是不会出现集中式负载均衡所产生的瓶颈问题,因为每个客户端都有自己的负载均衡器,单个负载均衡器的失效也不会造成严重的后果。

2024-07-02 10:13:47 1284

原创 RPC架构基本结构和核心技术

最后,为了降低开发人员的开发难度,让远程调用的执行过程看上去就先在执行本地方法一样,在主流的RPC实现方法中通常都会在客户端添加代理机制的实现组件RpcProxy,从而提供远程服务本地化访问的入口。长连接和短连接的产生在于客户端和服务器端采取的关闭策略,具体的应用场景采用具体的策略,没有十全十美的选择,只有合适的选择。接下来,如果我们把上图做一些展开。类似的,为了我们更好的区分RPC架构中的角色,我们把真正提供业务服务的组件称为RpcServer,而把发起真实客户端请求的组件称为RpcClient。

2024-06-26 18:13:03 1215

原创 什么是响应式编程

每一种事件会基于用户的操作或者系统自身的行为而被触发,并形成了一个事件的集合。另一方面,响应式编程也不是一种完全颠覆式的技术体系,而是在现有的异步调用、观察者模式、发布订阅模式等的基础上发展起来的一种全新的编程模式,能够会系统带来即时响应性。这种工作方式的优势就在于,生成事件和消费事件的过程是异步执行的,所以线程的生命周期都很短,也就意味着资源之间的竞争关系较少,服务器的响应能力也就越高。为了更好的分析整个调用过程,我们假设服务的提供者为服务A,而服务的消费者为服务B,那么这两个服务的交互过程应该这样的。

2024-06-24 18:02:48 918

原创 什么是OAuth2分布式授权协议?

你可能也已经注意到,虽然说OAuth2协议解决的是授权问题,但它也应用到了认证的概念,因为只有验证了用户的身份凭证,我们才能完成对他的授权。以目前主流的微服架构而言,当我们发起HTTP请求时,关注的是如何通过HTTP协议透明而高效的传递令牌,授权码模式下通过回调地址进行授权管理的方式就不是很实用,密码模式反而更加简洁高效。授权码模式的特点在于当用户同意授权后,授权服务器不是马上返回最终的令牌,而是一个授权码,需要客户端携带授权码去换令牌,这就需要客户端自身具备与授权服务器进行直接交互的后台服务。

2024-06-21 14:28:40 1012

原创 Spring自定义标签体系和应用

所以,如果我们想要实现一个自定的NamespaceHandler,最简单的方法就是继承NamespaceHandlerSupport然后在它的init方法中执行如下所示的registerBeanDefinitionParser方法。事实上,如果我们的目标是开发一个与Spring进行有效集成的自定义框架(例如Dubbo和Mybatis),那么自定义标签可以说是必不可少的一个环节,因为在Spring框架中,我们一般都需要依赖于它的自定义标签体系完成一些配置项的设置和装配工作。让我们回顾Dubbo启动方法。

2024-06-20 09:44:51 1220

原创 Spring事件发布和监听机制详解

通过今天内容的学习,我们掌握了Spring中事件处理的实现过程,这也为实现自定义的事件驱动架构提供了很好的基础,很多实现上的细节可供我们参考。我们已经明白了事件发布的独立过程,现在回到Spring容器来获取用于事件发布的ApplicationEventMulticaster以及各个用于事件监听的ApplicationListener的具体方式。用户发布事件的ApplicationEventPublisher和用于监听事件的ApplicationListener是Spring框架中实现事件驱动编程的核心类。

2024-06-19 10:19:51 1265

原创 Spring的启动扩展点机制详解

通过执行上述的afterPropertiesSet方法,相当于在Dubbo框架启动的同时,执行了Spring容器的初始化过程,并把这里所获取的一组Dubbo对象加载到了Spring容器中。这里,我们不再给出该方法的主体代码结构,而是直接来到该方法的末端,试图找到该方法中最核心的代码。显然,如下所示的就是最核心的代码。我们首先关注ServiceBean 中实现InitializingBean接口的afterPropertiesSet方法,这个方法非常长,但结构并不复杂,我们来展示该方法的结构,如下所示。

2024-06-18 10:44:32 1180

原创 Spring Cloud Config配置信息自动更新原理解析

事实上,Spring Cloud Config作为Spring自研的配置中心框架,其内部大量使用了Spring现有的功能特性,比方说本讲中提到的Spring容器的事件发布和监听机制,又比方说Spring Boot Acuator中的端点机制以及Spring Cloud Bus所具备的消息通信总线机制。事实上,Spring Cloud Config能够做到配置信息的自动更新,是依赖于Spring Cloud中的另一个组件,即Spring Cloud Bus。既然发送了事件,我们就需要寻找该事件的监听者。

2024-06-17 13:59:52 982

原创 剖析框架代码结构的系统方法(下)

正如前面提到的以Dubbo为代表的RPC框架或以MyBatis为代表的ORM框架,可以认为前者的基础架构就是网络通信、序列化、传输协议等组件,而后续则包含数据库连接管理、SQL执行等基础架构组件。我们知道在原生的JDBC编程模型中,想要获取SQL执行的结果,我们一般从ResultSet中提取值并赋值给相应的自定义对象,这个过程重复性高且类型转换容易出错。而在Dubbo中,远程调用存在三种的调用方式,即异步有返回、异步无返回以及异步变同步,其中异步变同步是默认的实现方式。具体来说是这样的代码执行流程。

2024-06-14 11:25:37 751

原创 剖析框架代码结构的系统方法

显然,在上述代码中,MyBatis为我们提供了两个核心的入口,一个是SqlSession,另一个是Mapper,我们将从这两个入口开始切入。在日常开发过程中,通常都是将MyBatis和Spring整合在一起使用,而这种整合在方便开发的同时也屏蔽了部分流程上的细节,一定程度上导致我们对MyBatis的执行过程缺少了全局的理解。那么,对于一个框架而言,什么才是它的主流程呢?这里内容的讨论还是关注于整体的执行流程,上述过程中所涉及的各种设计模式、代理机制、缓存机制等都属于具体的技术实现点,而不是核心的主流程。

2024-06-13 10:40:35 875

原创 GraphQL的优势和开发模式

在日常开发过程中,建议你根据自身业务发展的需求和变化,在合适的场景中引入GraphQL相关技术体系。讲到这里,你可能已经注意到,通过GraphQL发起请求实际上只需要指定一个HTTP端点地址即可,因为我们可以基于同一个端点通过传入不同的参数而获取不同的结果,也就不需要专门设计一批HTTP端点来分别处理不同的请求了。显然,这种请求方式完美解决了前端无法预判响应的数据格式问题,因为前端在请求的同时已经知道从服务端返回的数据字段就是请求中指定的字段,因此前端就不需要再对响应结果进行专门的判断和处理。

2024-06-12 10:33:45 1330

原创 Dubbo集群容错机制

注意到在每一次循环中,我们首先调用父类AbstractClusterInvoker中的select方法,并将该方法返回的Invoker对象保存到一个invoked集合中,表示该Invoker对象已经被选择和使用。换一个角度,Dubbo中的Cluster也相当于是一种代理对象,它在Directory的基础上向开发人员暴露一个具体的Invoker,而在暴露这个Invoker的过程中,万一发生了异常情况,Cluster就会自动嵌入集群容错机制。服务容错是一个相对复杂的话题,也是一个理论性比较强的话题。

2024-06-11 16:19:53 1225

原创 响应式流规范解析

我们首先需要明确,数据流处理过程中的流量控制和背压机制是促使响应式流规范诞生的原因,响应式流规范的目的就是为了更好的处理消费者和生产者之间的数据交互过程。在整个数据流处理过程中,处于数据流下游的Subscriber通过Subscription接口的request方法向Publisher请求数据,这就是一种向上反馈的机制,也是实现背压的关键所在。从数据的流转方向而言,这种反馈机制由位于数据流下游的消费者进行发起,代表着消费者处理数据的压力,所以被称为Back Pressure,翻译成中文就是背压。

2024-06-07 09:55:26 657

原创 轻量级批处理技术解析

今天的内容我们关注Spring家族的Spring Batch框架,可以看到该框架的实现过程和我们的设计思想是高度一致的。因此,在读取数据阶段,读取器(Reader)可以单条执行读取操作,并交由数据处理器(Processor)进行转换或过滤处理,但在写数据的过程中,数据写入器(Writer)往往会以一批数据为基本操作单元。而这三种策略的采用时机也是可以动态调整的,典型的例子包含:但刚开始出现异常情况时,我们可以采用重试机制,但当重试出现三次之后如果仍然抛出异常,那么我们就需要转为采用重启策略了。

2024-06-06 10:56:47 959

原创 Spring家族中的消息通信解决方案

事实上,Spring Cloud中的Spring Cloud Stream是基于Spring Integration实现了消息发布和消费机制并提供了一层封装,很多关于消息发布和消费的概念和实现方法本质上都是依赖于Spring Integration。不知道你有没有发现,在我们每天都在使用到Spring框架中,实际上也包含了一套完整而强大的消息通信机制,被广泛的应用在Spring家族的各个框架中,你可能在不经意中已经在使用这套机制了。消息通道的概念比较抽象,可以简单把它理解为是对队列的一种抽象。

2024-06-05 14:57:07 994

原创 Spring Boot自动配置原理和应用

同时,我们在本讲结尾部分还总结了开发一个Spring Boot Starter的三大步骤,开发一个Spring Boot Starter也是常见的需求,我们在开发过程中可以基于本讲的内容加深对其实现原理的理解。最后,在MybatisAutoConfiguration类上还存在一个@AutoConfigureAfter注解,这个注解可以根据字面意思进行理解,即在完成某一个类的自动配置之后再执行当前类的自动配置,这个需要提前装配的类指的就是DataSourceAutoConfiguration。

2024-06-04 10:53:02 1426

原创 如何正确理解事件溯源架构模式?

在日常开发过程中,针对如何实现事件溯源,我们需要考虑事件的存储、事件的回放等技术组件,同时也需要考虑DDD和事件溯源的整合过程,因为时间溯源的主要应用方式就是在DDD应用程序中。整个执行过程如下图所示。也就是说,事件溯源模式不是保存对象的最新状态,而是保存这个对象所经历的每个事件,所有由对象产生的事件会按照时间先后顺序有序的存放在数据库中。从上图中可以看到,事件溯源的核心设计思想在于:不保存对象的最新状态,而是保存导致对象状态发生变化的所有事件,这样就可以通过对这些事件进行溯源得到对象的最新状态。

2024-06-03 09:31:36 1010

原创 如何掌握Spring事件发布和监听机制?

通过本讲内容的学习,我们掌握了Spring中事件处理的实现过程,这也为实现自定义的事件驱动架构提供了很好的基础,很多实现上的细节可供我们参考。我们已经明白了事件发布的独立过程,现在回到Spring容器来获取用于事件发布的ApplicationEventMulticaster以及各个用于事件监听的ApplicationListener的具体方式。用户发布事件的ApplicationEventPublisher和用于监听事件的ApplicationListener是Spring框架中实现事件驱动编程的核心类。

2024-05-31 10:32:28 1151

原创 如何掌握MyBatis多级缓存机制?

但是,要注意由于一级缓存是独立存在于每个Session内部的,因此,如果我们创建了不同的Session,那么他们之间会使用不同的缓存。例如,完全一样的一个操作,如果在两个不同的Session中进行执行,那就意味着存在两份一样的缓存数据,但分别位于两个Session中,彼此之间不会共享。今天,我们就将讨论其中具有代表性的多级缓存技术。各类缓存实现工具,尽管其支持的数据结构以及数据在内存中的分配和查找方式有所不同,但基本结构模型都与上图类似,从该图中,我们也认识到缓存本质上是一种时间换空间的做法。

2024-05-30 16:20:56 842

原创 如何实现数据的正确拆分?

请注意,上图中所示的跨库查询和跨表查询方案的本质区别在于:位于不同数据库中的数据必须确保严格的边界,而通过接口的方式来获取数据可以做到这一点。在今天的内容中,我们基于主流的微服务架构,以单个数据库拆分的场景为例来开展讨论。针对跨多个业务模块的跨表查询应用场景,我们想要去掉表与表之间的连接也比较简单,因为表连接的本质就是把位于不同表中的数据进行组装,我们可以把这个组装过程放到内存中。可以看到,在这种应用场景下,数据库A和B中同时保存着表1和表2的数据,我们通过定时任务确保这两张表的数据是一致的。

2024-05-29 16:25:23 794

原创 如何理解Spring Boot自动配置原理和应用?

同时,我们在本讲结尾部分还总结了开发一个Spring Boot Starter的三大步骤,开发一个Spring Boot Starter也是常见的需求,我们在开发过程中可以基于本讲的内容加深对其实现原理的理解。最后,在MybatisAutoConfiguration类上还存在一个@AutoConfigureAfter注解,这个注解可以根据字面意思进行理解,即在完成某一个类的自动配置之后再执行当前类的自动配置,这个需要提前装配的类指的就是DataSourceAutoConfiguration。

2024-05-28 09:57:11 1311

原创 如何彻底搞懂组合(Composite)设计模式?

结合组合设计模式的基本结构图,可以认为 SqlNode 相当于是Component接口,MixedSqlNode 相当于是Composite组件,而其它SqlNode的子类则是Leaf组件,最后DynamicSqlSource则是整个模式的Client。显然,这样的实现方法存在一些缺陷,如果从部分到整体的关联关系发生了变化,那么我们可能需要同时调整这两种访问方式,从而对系统的代码结构造成比较大的影响。在今天的内容中,我们对组合模式的基本概念以及在Mybatis中的应用方式进行了详细的展开。

2024-05-27 11:38:07 1691

原创 如何彻底搞懂装饰器(Decorator)设计模式?

实现装饰器模式的前提是我们需要采用面向接口的编程模式,然后对功能的类型和职责进行合理的划分,确保不同的装饰器类能够独立承接不同的业务功能。因为这里实现的是一个先进先出的策略,所有,我们通过使用一个Deque对象来达到这种效果,这也让我们间接掌握了实现FIFO机制的一种实现方案。可以看到,整个PerpetualCache类的代码结构非常明确,除了一个id属性之外,代表缓存的cache属性只是一个HashMap,是一种典型的基于内存的缓存实现方案。现在,新需求来了,我们需要在绘制形状的基础上对该形状添加边框。

2024-05-24 14:18:16 1381 2

原创 如何彻底搞懂门面(Facade)设计模式?

更为重要的是,服务网关能够起到客户端与微服务之间的隔离作用,随着业务需求的变化和时间的演进,网关背后的各个服务的划分和实现可能要做相应的调整和升级,这种调整和升级需要实现对客户端透明。基于上图,我们可以来设计一个简单的案例。另一方面,我们也注意到实现门面模式的关键是需要对系统中的类层结构有一个合理的划分,确保位于底层的类不直接面向客户端,而是统一由门面类进行协调和整合。显然,一旦具备Façade这样的门面类,我们就可以把位于底层的类进行排列组合形成统一的对外访问入口,而原有的各个底层类不需要做任何的调整。

2024-05-23 14:24:30 753

原创 如何彻底搞懂迭代器(Iterator)设计模式?

在Mybatis中,存在一个非常常用的工具类PropertyTokenizer,该类主要用于解析诸如“order[0].address.contactinfo.name”类型的属性表达式,在这个例子中,我们可以看到系统是在处理订单实体的地址信息,Mybatis支持使用这种形式的表达式来获取最终的“name”属性。答案是肯定的,让我们来看一下。在今天的内容中,我们通过详细的示例代码对这一设计模式的基本结构进行了展开,并分析了它在Mybatis框架中的两处具有代表性的应用场景以及实现方式。

2024-05-22 09:17:25 1454

原创 如何把握分布式服务发布和服务引用流程?

接下来,让我们先来看服务的发布流程。如果Dubbo服务本身还没有完全启动成功,那这时候对外暴露服务是没有意义的,我们可以通过设置延迟时间来确保服务在发布的时间点上就是可用的。动态代理是远程过程调用中非常核心的一个技术组件,在服务发布和服务引用过程中都会用到,其主要作用就是为了简化服务发布和引用的开发难度,以及确保能够对发布过程进行扩展和定制。同时,基于这套服务发布和引用流程,我们对Dubbo这款主流的分布式服务框架的内部实现原理,对如何进行远程/本地服务暴露、如何实现对远程服务的调用也进行分析。

2024-05-21 10:05:10 1220

原创 如何设计和实现全局唯一性ID?

在日常开发过程中,存在一些实现全局唯一性ID的解决方案,常见的包括基于UUID的实现机制、采用Snowflake算法,以及改进版的LeafSegment和LeafSnowflake算法。SnowFlake算法是由Twitter开源的分布式ID生成算法,其核心思想是使用一个64bit的long型数字来作为全局唯一ID,且ID 的生成过程中引入了时间戳,基本上能够保持自增。41位的时间戳可以容纳的毫秒数是2的41次幂,一年所使用的毫秒数是365 * 24 * 60 * 60 * 1000,即69.73年。

2024-05-20 13:54:00 870

原创 如何利用管道-过滤器模式实现系统扩展性?

从这个示例中,我们可以看到管道-过滤器模式的特点在于把一系列的定制化需求转换成一种类似数据流的处理方式,数据通过管道流经一系列的过滤器,在每个过滤器中完成特定的业务逻辑。那么,如何实现图中的效果呢?事实上,包含Dubbo在内的很多开源框架中都应用了该模式,而且也都提供了基于过滤器链的实现方式,接下来让我们来看看它在Dubbo中的应用。TokenFilter的作用很明确,即通过Token进行访问鉴权,通过对比Invoker中的Token和初入参数中的Token来判断是否是合法的请求,其代码如下所示。

2024-05-17 10:26:35 697

原创 如何利用OAuth2协议实现分布式授权?

对于某些安全性要求比较高的资源,我们不应该开放资源访问入口给所有的认证用户,而是需要限定访问资源的角色,比方说限定只有角色为“ADMIN”的管理员才能访问该服务中的资源。这个@EnableAuthorizationServer注解的作用在于为微服务运行环境提供一个基于OAuth2协议的授权服务,该服务通过暴露一系列以/oauth为根节点的HTTP端点供OAuth2授权流程进行使用,例如用于生成Token的/oauth/token端点,用于授权的/oauth/authorize端点。

2024-05-16 09:42:45 984

原创 如何解决代码循环依赖问题?

合理的系统架构以及持续的重构优化工作能够减轻这种复杂关系,但如何有效识别系统中存在的循环依赖仍然是开发人员面临的一个很大的挑战。所谓循环依赖,简单来说就是一个类A会引用类B中的方法,而反过来类B同样也会引用类A中的方法,从而导致类A和类B之间存在相互引用,从而形成一种循环依赖。组件之间的循环依赖关系的产生原因在于组件1中的类与组件2中的类之间存在依赖关系,从而导致组件与组件之间产生一种循环依赖。对于循环依赖,JDepend给出了四个子页面,分别是所选中的包、存在循环依赖关系的包、所依赖的包和被依赖的包。

2024-05-15 11:13:21 1128

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除