Java识堂
这个作者很懒,什么都没留下…
展开
-
Dubbo实战:Dubbo的前世今生
分布式系统的架构演进过程Dubbo框架的出现是分布式系统演进的结果,我们先来回顾一下分布式系统的演进过程1 单应用架构2 应用服务器和数据库服务器分离单机负载越来越来,所以要将应用服务器和数据库服务器分离3 应用服务器做集群每个系统的处理能力是有限的,为了提高并发访问量,需要对应用服务器做集群分布式和集群的概念经常被搞混,现在一句话让你明白两者的区别。分布式:一个业务拆分成多个子业务,部署在不同的服务器上集群:同一个业务,部署在多个服务器上例如:电商系统可以拆分成商品,订单,用户等.原创 2021-06-12 20:58:31 · 510 阅读 · 3 评论 -
Dubbo实战:5分钟极速入门Dubbo使用
介绍在使用Dubbo开发时,我们一般将项目分为如下3个模块api:将服务提供者和服务消费者都需要用到的接口放在api层consumer:服务消费者producer:服务提供者假如有如下一个场景,我们需要查询用户的信息,用户请求发送到consumer这个服务,然后consumer这个服务调用producer这个服务获取到用户信息,并返回给用户Api模块实现用户信息封装到UserInfo类中,因为需要网络传输,所以需要实现序列化接口public class UserInfo implemen.原创 2021-05-29 16:37:49 · 580 阅读 · 8 评论 -
Dubbo实战:如何高效的测试Dubbo接口
Dubbo Admin 使用我们可以用新版的Dubbo Amind来测试Dubbo接口我们在本地启动一个Dubbo Admin来演示一下用法github地址:https://github.com/apache/dubbo-admingit clone https://github.com/apache/dubbo-admincd dubbo-adminmvn clean package -DskipTests=truecd dubbo-admin-distribution/targetj.原创 2021-06-02 15:42:52 · 733 阅读 · 9 评论 -
Dubbo实战:微服务项目(Spring Cloud,Dubbo)如何自测?
前言测试框架有很多,Junit,EasyMock,PowerMock,TestNG,DBUnit等。建议重要的业务流程写单测,使用Junit,EasyMock测试框架假如业务类为A,单测类的命名方式为ATest,ATest类和A类的包结构保持一致,测试的方法名保持一致IDEA快速生成Test类所在类按快捷键Win:Ctrl + Shift + TMac:⇧ + command + T选中要单测的方法点击OK即可EasyMock在微服务应用中,有时候需要调用别人的服务,在别人接口没开原创 2020-08-22 14:23:04 · 2066 阅读 · 0 评论 -
Dubbo实战:如何保证接口幂等
介绍幂等性就是同一个操作执行多次,产生的效果一样。如http的get请求,数据库的select请求就是幂等的在分布式系统中,保证接口的幂等性非常重要,如提交订单,扣款等接口都要保证幂等性,不然会造成重复创建订单,重复扣款,那么如何保证接口的幂等性呢?Dubbo在进行服务调用的时候,如果调用失败,默认会重试2次,此时保证接口的幂等性就非常重要了。前端保证幂等性的方法按钮只能点击一次用户点击按钮后将按钮置灰,或者显示loading状态RPG模式即Post-Redirect-Get,当客户提交表.原创 2021-06-17 15:59:08 · 1210 阅读 · 0 评论 -
手写RPC框架:如何手写一个RPC框架?
介绍当开发一个单体项目的时候,大家肯定都写过类似的代码。即服务提供方和服务调用方在一个服务中public interface HelloService { public String sayHello(String content);}public class HelloServiceImpl implements HelloService { @Override public String sayHello(String content) { retu.原创 2020-11-26 15:14:55 · 1615 阅读 · 0 评论 -
手写RPC框架:极简版
思路分析前面的文章我们详细分析了如何实现一个RPC框架,后面几个章节,我们就自己来写一个RPC框架。框架先实现一个最基本的功能,然后不断迭代,完善这些功能。首先我们需要封装一个请求对象,包含要调用方法的基本信息,producer端收到这些请求后,找到对应的服务和方法,执行方法调用,将结果返回consumer端。consumer端组装请求和网络调用的过程交给动态代理对象来完成,这样就可以接耦方法调用和网络请求因为是极简版,所以本节我们只实现点对点调用的过程,不涉及注册中心的内容封装网络请求对象.原创 2021-05-29 15:42:15 · 266 阅读 · 2 评论 -
手写RPC框架:5分钟极速入门Netty的使用
介绍当我们用Netty开发网络应用程序时,一般只需要写对应的ChannelHandler即可,在ChannelHandler中处理业务逻辑Channel是网络通信的载体,你可以把它认为是一个实际的物理连接,Channel有很多种事件,如连接建立,连接关闭,数据读取。随着事件的发生会让Channel处于不同的生命周期,当对应的事件发生时,会回调ChannelHandler接口的对应方法事件回调方法解释channelRegisteredChannel创建后被注册到EventLoop.原创 2021-06-02 19:37:36 · 290 阅读 · 2 评论 -
手写RPC框架:Netty高性能的秘密是?
介绍Netty是一个高性能的NIO网络框架,极大的的降低了网络编程的门槛,并且提供了简单易用的api。客户端和服务端的启动是一个很简单的模版代码,我们更多的精力是的写处理业务逻辑的ChannelHandler,看几个Demo你就能写一个简单的Http服务器,Im系统等。相对于Java nio原生api来说,Netty有如下的优点提供的简单易用的api,实现同一个功能你可以用java nio和netty都实现一下,就知道netty用起来是有多爽了稳定性高,如解决了jdk select空轮询的bu.原创 2020-11-26 16:07:20 · 1197 阅读 · 0 评论 -
手写RPC框架:详解ZooKeeper和客户端框架Curator
Zookeeper介绍zookeeper的数据模型和文件系统类似,每一个节点称为znode,是zookeeper中的最小数据单元,每一个znode上可以报存数据和挂载子节点,从而构成一个层次化的属性结构zookeeper可以创建如下几种类型节点节点类型解释持久节点将节点创建为持久节点,数据会一直存储在zookeeper服务器上,即使创建该节点的客户端与服务端的会话关闭了,该节点依然不会被删除持久顺序节点在持久节点的基础上增加了节点有序的特性临时节点将节点创建为临.原创 2020-11-21 16:14:22 · 778 阅读 · 0 评论 -
手写RPC框架:Spring Bean 生命周期详解
基本概念我们将自己写的RPC框架和Spring进行整合,分析Dubbo源码的时候,都要对Spring Bean的生命周期有一个清晰的理解,所以这一节我们就分析一下Spring Bean的生命周期Spring是一个IOC容器当我们不用Spring进行开发时,我们需要在代码中设置对象的依赖关系。当我们用了Spring之后,由Spring来管理这种依赖关系,当我们想使用对象时,直接从Spring容器中获取即可BeanDefinition在Spring中对象被叫做Bean,因为Spring Bean在J.原创 2021-06-16 21:09:19 · 301 阅读 · 0 评论 -
手写RPC框架:可扩展性神器 Java SPI
SPI设计Java SPI的作用非常简单,就是根据配置文件决定接口的实现类,典型的策略模式我先演示一下Java SPI的使用demo,项目结构如下public interface Car { void getBrand();}public class BenzCar implements Car { public BenzCar() { System.out.println("BenzCar"); } @Override pub.原创 2021-05-31 22:32:00 · 498 阅读 · 8 评论 -
手写RPC框架:基于Java SPI的可扩展版
封装服务接口在之前的章节中,我们基于Java Socket实现了一个极简版本的RPC框架,了解了其实现的大概套路,本节我们就基于Java SPI写一个可扩展的RPC框架。各种组件都有对应的接口,如果你想替换某一个组件的实现,只需要重写接口的实现类,配置一下即可。老规矩,先封装一个获取学生信息的公共接口public interface StudentService { Student getStudentInfo(Integer id);}@Data@Builder@NoArgsC.原创 2021-06-05 15:21:16 · 437 阅读 · 6 评论 -
手写RPC框架:基于RPC框架封装一个spring-boot-starter
介绍整合的逻辑非常简单,只写了2个注解,1个自动装配的类和2个扩展类开发注解服务引入注解,用在需要进行远程调用的接口上@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface RpcReference {}服务导出注解,我这里取巧了一波,在这个注解上加了@Component注解,这样被这个注解标记的类就能被注入到spring容器中。更优雅的实现方式是,自己扫描加了RpcService.原创 2021-06-04 16:55:26 · 620 阅读 · 7 评论 -
手写单点登陆starter:什么是单点登陆?
单系统登陆在企业的发展初期,系统不是很多,每个系统也比较独立,每个系统都有各自的登陆模块,各类工作人员每天只登陆自己负责的系统即可。这个时候登陆的实现比较简单,基于cookie和session就能实现。多系统登陆随着企业的发展,系统越来越多,并且信息化程度也越来越高。各种系统之间的数据逐渐打通,工作流程形成闭环,这时系统逐渐微服务化。但是用户用着不爽了,每天工作得登录好几个系统,超级麻烦啊,能不能登陆一次就能在多个系统之间随意访问。为了应对这种场景,就得新建一个登陆服务比如我访问财务系统,没.原创 2021-05-31 14:23:55 · 284 阅读 · 2 评论 -
手写单点登陆starter:如何手写一个Spring Boot starter?
蛮荒的年代最近用了一些spring-boot-starter-data的组件(redis,mongodb,jpa,elasticsearch等),才意识到Spring Boot真是极大的简化了开发的流程。以演进的视角来分享一下spring boot是如何通过自动装配来简化开发的XML配置Spring是一个容器,里面保存了你所需要的对象和对象之间的依赖关系。当我们需要对象A时,不用从头开始new,只需要告诉Spring把A给我,Spring就会把对象A给你,即IOC。刚开始这些对象以及对象之间的依赖关.原创 2021-05-31 14:06:04 · 191 阅读 · 0 评论 -
手写单点登陆starter:Spring Boot 自动装配是如何实现的?
Enable注解是如何实现的?当我们使用Spring Boot的时候,只需要在启动类上加@SpringBootApplication注解即可,非常方便。@SpringBootApplication是一个复合注解@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan其中自动装配的功能就是由@EnableAutoConfiguration注解实现的,那么@EnableAutoConfiguration是如何实现这个神奇的功能的?.原创 2021-05-31 14:10:43 · 155 阅读 · 0 评论 -
手写单点登陆starter:用mybatis generator快速生成dao层
介绍后面一节写登陆端的接口时,需要用mybatis generator生成dao层,所以本节介绍一下mybatis generator的使用MyBatis Generator的作用就是根据数据库中的表结构,帮我们自动生成和表结构相同的实体类,mapper接口,包含基本增删改查语句的XML文件,我以一个例子演示如何优雅的使用MyBatis Generator,我会把例子放在GitHub上,所以不用担心配置看不全的问题。造数据,新建一个Spring Boot项目建一个学生表,插入四条数据CREATE.原创 2021-05-31 14:03:37 · 209 阅读 · 0 评论 -
手写单点登陆starter:基于dubbo开发单点登陆starter
基于dubbo开发单点登陆starter项目总共分为3个模块sso-spring-boot-starter:单点登陆starter模块,引入这个模块即可实现单点登陆sso-server:用户登陆的服务端sso-sample:单点登陆starter模块使用demo开发sso-server模块当我们定义好sso-servere模块的用户表后,就可以使用我们之前介绍的mybatis generator生成项目的dao层CREATE TABLE `user_info` ( `id` int(1.原创 2021-05-31 15:49:20 · 709 阅读 · 9 评论 -
Dubbo源码解析:5分钟了解 Dubbo SPI 的特性
介绍最近看了一下Dubbo的源码,国人写的框架和国外的果然是两种不同的风格,Dubbo的源码还是比较清晰容易懂的。Spring框架一个Bean的初始化过程就能绕死在源码中.Dubbo的架构是基于分层来设计的,每层执行固定的功能,上层依赖下层,下层的改变对上层不可见,每层都是可以被替换的组件Service和Config为API接口层,让Dubbo使用者方便的发布和引用服务其他各层均为SPI层,意味着每层都是组件化的,可以被替换例如,注册中心可以用Redis,Zookeeper。传输协议可以用dub原创 2020-08-08 17:51:16 · 11023 阅读 · 0 评论 -
Dubbo源码解析:Dubbo SPI是如何实现 AOP,IOC,自适应,自动激活的?
ExtensionLoader的工作原理Dubbo在启动的时候默认会扫描这三个目录下的配置,以加载需要的扩展类/META-INF/services/META-INF/dubbo/META-INF/dubbo/internalExtensionLoader是Dubbo SPI中用来加载扩展类的,有如下三个重要方法,搞懂这3个方法基本上就搞懂Dubbo SPI了。加载扩展类的三种方法如下getExtension(),获取普通扩展类getAdaptiveExtension(),获取自适应扩展类.原创 2021-06-17 11:54:46 · 544 阅读 · 3 评论 -
Dubbo源码解析:基于XML配置原理解析
步骤编写XML Schema文件,定义XML结构自定义NamespaceHandler实现自定义BeanDefinitionParser,将XML解析为BeanDefinition注册到Spring容器扩展Spring XML元素项目结构如下编写XML Schema文件@Data@ToStringpublic class User { private Long id; private String name;}users.xsd<?xml ver.原创 2021-03-12 14:15:58 · 2877 阅读 · 6 评论 -
Dubbo源码解析:基于注解配置原理解析
使用注解开发一个Dubbo应用客户端@Component("demoServiceComponent")public class DemoServiceComponent implements DemoService { @Reference private DemoService demoService; @Override public String sayHello(String name) { return demoService.sayHe.原创 2021-06-16 21:00:39 · 275 阅读 · 2 评论 -
Dubbo源码解析:Dubbo服务导出过程
相关知识Dubbo URL看Dubbo源码时经常看到URL这个参数,所以先分享一下Dubbo URLurl即一个资源在互联网上的地址,在Dubbo中它被用做配置总线的功能,和服务相关的配置都放在这个总线上。一个标准格式的URL如下protocol://username:password@host:port/path?key=value&key=valueDubbo中URL对象的构造函数如下public URL(String protocol, String username, Str.原创 2020-11-14 15:28:28 · 750 阅读 · 0 评论 -
Dubbo源码解析:服务提供方接收请求及返回结果
介绍上一篇文章说到我们启动了一个NettyServer,写过Netty程序的小伙伴都知道我们是通过实现ChannelHandler接口来处理业务逻辑的,然后将ChannelHandler增加到ChannelPipeline上,一个请求被ChannelPipeline上的ChannelHandler依次处理,典型的责任链模式但是在上一节NettyServer启动的时候,我们看到了ChannelPipeline上只加入了一个ChannelHandler即NettyServerHandler(实现了io.原创 2020-11-14 17:42:20 · 888 阅读 · 0 评论 -
Dubbo源码解析:线程模型和线程池策略
为什么有这么多线程模型和线程池策略?在网络通信过程中,会发生很多事件,如连接事件,读取到消息的事件。当读取到这个事件的时候,我们是将事件直接在IO线程上执行,还是放到线程池中执行?是需要我们根据业务的场景来进行配置的,这样能最大限度的提高吞吐量如果事件处理的逻辑能迅速完成,并且不会发起新的 IO 请求,比如只是在内存中记个标识,则直接在 IO 线程上处理更快,因为减少了线程池调度。但如果事件处理逻辑较慢,或者需要发起新的 IO 请求,比如需要查询数据库,则必须派发到线程池,否则 IO 线程阻塞,将导.原创 2020-11-08 15:12:37 · 931 阅读 · 0 评论 -
Dubbo源码解析:BeanFactory,封装复杂Bean的创建过程
创建Bean的方式常见的创建Bean的方式有如下四种通过构造器通过静态工厂方法通过Bean工厂方法通过FactoryBean@Data@ToStringpublic class User { private Long id; private String name; public static User createUser() { User user = new User(); user.setId(1L); user.setName("li"); retu.原创 2021-06-17 20:36:16 · 288 阅读 · 0 评论 -
Dubbo源码解析:Dubbo服务引入过程
介绍服务引入无非就是在客户端生成一个代理对象,这个代理对象帮我们组装调用参数,发起网络调用,接收请求等。我们调用一个接口的方法时,就像调用本地方法一样。放一个Dubbo服务导出的简略图,后面分析的时候不至于绕晕。按照服务导出的套路来分析服务引入。在引入服务的时候,需要配置如下内容,这个配置会被解析为一个ReferenceBean对象<dubbo:reference id="demoService" check="false" interface="org.apache.dubbo.demo.原创 2020-11-21 21:12:47 · 670 阅读 · 0 评论 -
Dubbo源码解析:服务目录和路由
介绍之前的文章我们详细说了服务调用的过程,今天我们就来细化一下MockCluster到FailoverClusterInvoker的调用过程。当我们有多个服务提供者时,需要根据不同的策略从众多的提供者中选出合适的Invoker来发起调用,那么这些Invoker存放在哪?就在服务目录中。服务目录还会根据路由策略策略对最终返回的Invoker进行再次过滤。比如ip为A的Consumer只能让它调用ip为B的producer,路由的配置有很多方式,我们详聊。整体的流程下如图所示Invoker从D.原创 2021-06-12 10:29:53 · 458 阅读 · 1 评论 -
Dubbo源码解析:注册中心
介绍Dubbo可以用zookeeper,reids,nacos来实现注册中心Registry继承了RegistryService接口,RegistryService接口定义了对注册中心的基本操作public interface RegistryService { // 注册 void register(URL url); // 注销 void unregister(URL url); // 订阅 void subscribe(URL url, No原创 2020-11-22 16:19:16 · 615 阅读 · 0 评论 -
Dubbo源码解析:客户端服务调用过程
介绍其实客户端服务调用过程和服务端执行请求处理的过程很类似,搞懂请求经过的Channelhandler,就明白了一大半。如果你没有看过Dubbo源码解析:服务提供方接收请求及返回结果建议先看一下,这样你就能理解清楚Dubbo和Netty中Channelhandler的不同。Netty中的Channelhandler用的是责任链模式,而Dubbo中的Channelhandler用的是装饰者模式。常用的Handler如下ChannelHandler作用NettyClientH.原创 2020-11-22 20:56:54 · 670 阅读 · 0 评论 -
Dubbo源码解析:Dubbo是如何同时支持同步调用和异步调用的?
介绍前面一篇文章说到,我用CompletableFuture将调用2个服务的过程异步化了一下。其实Dubbo接口本身就支持异步调用,我们可以直接获取一个CompletableFuture对象,不用自己去新建。来演示一下同步调用和异步调用的两种方式同步调用DemoService demoService = context.getBean("demoService", DemoService.class);String hello = demoService.sayHello("world");/原创 2020-09-12 18:34:19 · 3685 阅读 · 0 评论 -
Dubbo源码解析:详解集群容错和负载均衡策略
介绍前面我们说过,集群容错的过程就是从一堆Invoker中,根据负载均衡策略选出最终发起调用的Invoker,然后发起调用。所以我们今天看一下集群容错策略和负载均衡策略有哪些?集群容错策略实现类解释AvailableCluster找到一个可用的节点,直接发起调用FailoverCluster失败重试(默认)FailfastCluster快速失败FailsafeCluster安全失败FailbackCluster失败自动恢复ForkingCl.原创 2020-11-22 18:37:19 · 659 阅读 · 1 评论 -
Dubbo源码解析:Dubbo过滤器
自定义Filter我们先手动定义一个Filter,用来统计服务端每个接口的执行时间。实现Filter接口在resources/META-INF/dubbo文件夹下新建org.apache.dubbo.rpc.Filter文件在org.apache.dubbo.rpc.Filter文件中写上Filter的路径@Slf4j@Activate(group = PROVIDER)public class CostFilter implements Filter { @Override.原创 2020-11-24 00:00:12 · 1142 阅读 · 1 评论 -
Dubbo源码解析:从头走一遍Dubbo的执行流程
RPC框架的实现一个RPC调用的过程如下调用方发送请求后由代理类将调用的方法,参数组装成能进行网络传输的消息体调用方将消息体发送到提供方提供方将消息进行解码,得到调用的参数提供方反射执行相应的方法,并将结果返回因为是极简版,所以本节我们只实现点对点调用的过程,不涉及注册中心的内容手写一个简单的PRC框架封装网络请求对象@Data@Builder@NoArgsConstructor@AllArgsConstructorpublic class RpcRequest implem原创 2022-02-09 17:14:28 · 1168 阅读 · 1 评论 -
Dubbo面试:高频面试题汇总
Dubbo服务注册和发现的流程各种角色如下Provider:暴露服务的服务提供方Consumer:调用远程服务消费方Registry:服务注册与发现注册中心Monitor:监控中心和访问调用统计Container:服务运行容器Dubbo服务注册和发现的流程如下服务容器Container负责启动,加载,运行服务提供者。服务提供者Provider在启动时,向注册中心注册自己提供的服务。服务消费者Consumer在启动时,向注册中心订阅自己所需的服务。注册中心Registry返回服.原创 2021-06-16 14:39:39 · 403 阅读 · 3 评论 -
Dubbo面试:Dubbo中用到了哪些设计模式?
介绍策略模式这个毫无争议,Dubbo是基于SPI来扩展的,SPI就是典型的策略模式。Dubbo中可替换的组件太多了,例如负载均衡策略实现类解释RandomLoadBalance随机策略(默认)RoundRobinLoadBalance轮询策略LeastActiveLoadBalance最少活跃调用数ConsistentHashLoadBalance一致性hash策略工厂模式简单工厂模式:提供一个方法,返回创建好的对象public clas.原创 2021-06-07 14:37:38 · 665 阅读 · 4 评论 -
生产问题:线程池被打满
线程池被打满的原因有哪些当系统中接口的响应时间过长或者直接拒绝响应时,你此时里面就应该想到的是Dubbo线程池是否被打满了?然后去监控系统看一下线程池的活跃连接数。Dubbo线程池被打满应该是一个很常见的问题,那么线程池为什么会被打满呢?public class FixedThreadPool implements ThreadPool { @Override public Executor getExecutor(URL url) { String name = .原创 2021-06-13 14:23:01 · 1205 阅读 · 4 评论 -
生产问题:@Reference注入为空
线上发生事故了有一次我负责的系统和收银系统同时上线一波(用的是Dubbo)。然后很神奇的事情发生了,收银系统用@Reference注解注入我的接口,然后这个接口的实现类居然为空。其实我们当时没排查出来是什么原因?重启了一下就好了,毕竟重启大法好。 但本着不能给用户充钱的路上造成阻碍,还是要排查一波这个代理对象为空是如何造成的。线上dubbo的版本为2.8.9,注意包名是(com.alibaba)为了方便大家理解我说的内容,简单说一下RPC框架的执行流程。Server将服务信息注册到Regi.原创 2021-06-13 14:23:58 · 642 阅读 · 0 评论