从0到1实现RPC
文章平均质量分 64
子夜2104
这个作者很懒,什么都没留下…
展开
-
从0到1实现RPC | 接入Apollo配置中心
添加apollo客户端的依赖和spring配置相关依赖通过实现ApplicationContextAware接口,获取Spring上下文。使用@ApolloConfigChangeListener注解监听命名空间rpc-demo-provider.yaml和默认的application.properties。监听逻辑是当配置中心的属性发生变化时,通过事件发布的形式更新bean的赋值。服务提供者provider和服务消费者consumer两端都需要接入配置中心。原创 2024-04-20 19:15:00 · 594 阅读 · 1 评论 -
从0到1实现RPC | 12 限流
循环请求指定服务,每秒请求一次,限流配置参数为30s内超过20个请求就会被限流。观察日志,在30s内连续请求20次后第21次的请求就被限流了。限流:指定时间内请求数超过指定阈值时就抛出异常。原创 2024-04-13 22:29:56 · 287 阅读 · 0 评论 -
从0到1实现RPC | 11 丰富测试案例
List参数类型转换,主要实现逻辑都在TypeUtils工具类中。对象数组参数类型转换,主要实现逻辑都在TypeUtils工具类中。对象参数类型转换,主要实现逻辑都在TypeUtils工具类中。数组参数类型转换,主要实现逻辑都在TypeUtils工具类中。数组参数类型转换,主要实现逻辑都在TypeUtils工具类中。参数类型转换,主要实现逻辑都在TypeUtils工具类中。参数类型转换,主要实现逻辑都在TypeUtils工具类中。参数类型转换,主要实现逻辑都在TypeUtils工具类中。原创 2024-04-14 19:00:00 · 292 阅读 · 0 评论 -
从0到1实现RPC | 10 灰度发布
在配置信息中添加实例元信息,其中gray为灰度标识,值为true表示灰度版本,值为false表示正式版本。在实际应用中,小流量严重发现没有问题,就会逐步放大灰度比例,热更新灰度应用表示,直到全部转为正式。当发布新版本时,采用灰度发布的方式,把流量逐步发开到新新版本,可以有效保证发版的顺利。总共三个实例,灰度应用是8081,正常应用是8082,8083,灰度比例是33%。在动态代理类中执行时,会先从一堆实例中选择路由,在这里就有可能选择到灰度实例。在服务注册的时候,将服务原配置添加到注册中心上去。原创 2024-04-12 18:30:00 · 740 阅读 · 0 评论 -
从0到1实现RPC | 09 故障隔离与恢复
为了能够拿到故障的实例,使用了halfOpenProviders,里面存储的就是故障的实例,使用定时任务,10s后启动,每隔60s执行一次半开逻辑:从故障实例中添加到半开实例中,用于请求探活。当某次调用出现异常时,使用滑动窗口记录该实例的异常调用次数,每发生一次异常就记录一次,当发生的异常次数达到指定阈值后,就隔离该实例。再进行一次请求时,会进行探活,尝试调用8081,传入参数id=1,调用成功,故障实例8081又重新添加到正常实例providers当中,故障实例成功恢复。轮询调用的是8082和8083.原创 2024-04-11 18:30:00 · 545 阅读 · 1 评论 -
从0到1实现RPC | 08 异常码和异常超时
当请求到8081 时,发生网络超时,自动进行了一次重试,第二次重试,在负载均衡时采用的是轮询,所以重试选择了8083,请求成功了。在代理类中,通过传入指定参数retry控制重试次数,使用while()循环进行重试,只对网络超时进行重试,其他异常直接抛出去。从服务消费者发起请求,睡眠时间是2秒,okhttp的连接超时时间设置为1秒,重试次数为1次。在测试方法中通过睡眠模拟网络超时。特别的,只有8081请求端口访问时才超时,其他不会。在发生网络超时的时候,可以进行重试,保证业务请求不因为网络原因而中断。原创 2024-04-10 18:30:00 · 316 阅读 · 0 评论 -
从0到1实现RPC | 07 支持MockFilter和CacheFilter
MockUtils的实现逻辑:对基本类型进行mock,对String类型进行mock,对一般类进行mock,还没有实现数组、集合、Map等复杂数据类型。Mock过滤器应用场景是:当发现微服务间调用异常时,开启MockFilter可以对服务请求进行mock,排查是哪个微服务发生了问题。调用findById()方法,第一次生成对象后,多次调用,返回的时间戳是一样的,证明缓存过滤器起作用了。CacheFilter的应用场景是:对调用过的请求进行缓存,不再发起远程调用,起缓存作用。原创 2024-04-08 19:30:00 · 304 阅读 · 0 评论 -
从0到1实现RPC | 07a 更新pom依赖方式
在consumer和provider两个模块使用依赖管理,导入spring的各个依赖。没有了paren引入的依赖,就需要通过这种方式引入依赖管理。使用命令mvn clean install -Dmaven.test.skip=true 再次编译,先忽略测试案例。默认在根pom文件中引入了spring的parent,导致子模块都是web项目,所以需要更新pom文件。没有了统一的版本号,需要各模块自己指定。原创 2024-04-09 21:00:00 · 219 阅读 · 0 评论 -
从0到1实现RPC | 06 代码重构
这样带来的问题是当整个服务停止时,销毁方法先执行,客户端和zk服务端已经断开连接,而服务取消注册的逻辑再执行时,就不会成功。同理,使用InstanceMeta代替String类型,来表示一个实例的元数据,表达含义更加丰富,支持更多非功能性场景。使用ServiceMeta代替String类型,来表示一个服务的元数据,表达含义更加丰富,支持更多非功能性场景。由于取消注册使用的是quietly()方式,出错了也不会报错,最终就是服务没有取消成功,消费者还可能调用到。重构后,注册中心先启动成功,在进行服务注册。原创 2024-04-07 20:15:00 · 355 阅读 · 0 评论 -
从0到1实现RPC | 05 基于ZooKeeper的注册中心
在服务消费者consumer启动的过程中,向注册中心获取服务接口实例信息,放到代理类中。同时,完成注册中心的订阅,有节点发生变动,就会清空当前已经获取到的服务节点信息,然后再次获取最新的实例信息。使用@PreDestory注解,当服务停止时,便取消服务注册,使用注册中心RegisterCenter的unregister()方法。Spring 的所有bean加载完成,项目启动成功才进行服务注册,防止启动过程中就注册,然后启动失败了,已经注册的可能会被调用。原创 2024-04-06 19:30:00 · 555 阅读 · 0 评论 -
从0到1实现RPC | 04 负载均衡和静态注册中心
在消费者启动类ConsumerBootstrap中, 把路由器router和负载均衡器loadBalancer封装到RpcContext中。在创建代理对象时,通过注册中心获取到所有的服务提供者providers,然后联合上下文信息RpcContext一起传递给代理类。同一个接口连续调用三次,可以看到返回结果,依次访问的是8081,8082,8083这三个服务,使用轮询负载均衡的目的已经成功了。在消费者配置类ConsumerConfig中创建Bean,包括注册中心,路由器和负载均衡器(这里使用的是轮询)。原创 2024-04-05 20:15:00 · 681 阅读 · 0 评论 -
从0到1实现RPC | 03 重载方法和参数类型转换
在Provider端接受到的是一个Double类型,这是因为web应用接收的请求后处理的类型。processArgs()方法负责处理请求每个请求参数,传入的参数和方法参数类型匹配处理。在Provider端创建的时候使用完整的方法签名替换方法全限定名。同理,在Consumer端需要对返回的结果类型进行参数处理。2.处理数组类型:是一个什么样的数组,对每个值进行处理;在Consumer端封装请求参数时,传入方法签名即可。在Provider端进行反射之前,处理请求参数。假设定义的接口如下,参数是float类型。原创 2024-03-22 20:53:23 · 685 阅读 · 0 评论 -
从0到1实现RPC | 02 RpcConsumer的远程调用
查找bean中的字段是否使用了@RpcConsumer注解,通过循环遍历的方式进行判断。在启动方法中注入业务服务接口UserService和OrderService,使用的注解是@RpcConsumer,本文主要的功能就是如何实现这个注解。主要的依赖是rpc-demo-api,即业务服务定义的api接口,rpc-core是核心依赖包。RpcRequest封装了远程调用消费者端请求的数据结构:接口全限定名称、方法名称、方法参数。六、代理对象RpcInvocationHandler中定义了远程调用方法的逻辑。原创 2024-03-22 20:51:46 · 784 阅读 · 0 评论 -
从0到1手把手实现RPC|01 RpcProvider本地实现
使用 ApplicationContextAware接口是为了获取Spring的应用上下文ApplicationContext,从里面获取bean。请求调用,根据服务全限定名(就是一个类的全名)去map存找对应的类,找到后,通过反射发起方法调用。启动类在创建的过程,会将带有@RpcProvider注解的类存放到Map中。RpcProvider是自定义的一个注解,用来表示这个类是一个服务提供者。响应类RpcResponse统一封装结果,返回状态,响应结果数据。一个服务提供者,订单服务实现类。原创 2024-03-10 11:46:14 · 370 阅读 · 0 评论