手写RPC框架,真不是为了装13!
面试中,很容易被面试官问到:
如何设计一个RPC框架?
你可能没有被问到过,可能是运气好,也可能是你还没到这个级别。通常月薪20k以上,基本上都会问一些设计性的题目。
站在面试官角度:问这类题目,总比一个八股文强,这里面会涉及到很多技术点。比如:设计模式、通信协议、动态代理、虚拟化、线程池等知识。
好吧,不扯远了,我们开始聊今天的话题。
RPC全程为Remote procedure call 远程过程调用,这几个字很多人可能并不是特别的理解,再简单的说就是:
像调用本地方法一样调用远程服务。
比如,下面一个案例:一个用户操作服务:
public interface UserService{ String findUserNameById(Integer userId); } @Service public class UserServiceImpl implements UserService{ String findUserNameById(Integer userId){ //查数据或查缓存获取到用户名 return "田哥" } }
现在一个controller里想调用UserServiceImpl的findUserNameById方法获取用户名。
@RestController public class UserController{ @Resource private UserService userService; @GetMapping("/test") public String test(){ return userService.findUserNameById(1); } }
假设UserController、UserServiceImpl、UserService三个类都在同一个项目里,controller想调用findUserNameById方法是非常简单的。
但是,如果controller是另外一个项目,也想像上面那样调用(细微的不同,感觉还是一样),这时候我们就可以用到了RPC框架。
1、需要把接口UserService放在一个单独项目里,我们通常称之为api项目。
2、需要把UserServiceImpl放在一个单独项目里,我们通常称之为叫做provider项目。
3、controller嘛,通过是web之类的(consumer)项目里
4、把api打成jar包,然后consumer项目、provider项目都引用它。
市面上的RPC框架,比如说:Dubbo (阿里)、Thrift(FaceBook)、gRpc(Google)、brpc (百度)等都在不同侧重点去解决最初的目的,有的想极致完美,有的追求极致性能,有的偏向极致简单。
RPC原理
回到前面我们说的像调用本地一样的调用远程服务,到底需要哪些技术支撑呢?
动态代理,因为我们consumer项目里只有接口 UserService
定义,没有实现类,想要调用一个接口的方法?那就只能搞个代理对象了。编解码,也就是consumer需要把请求参数传到provider里去,网络传输过程先把我们的参数进行编码,然后传到provider,provider再对传过来的参数进行解码。 网络通信,跨进程肯定就会涉及到网络通信。 网络传输协议,consumer和provider 对于来回的参数信息,肯定得有有个标准,你按照什么样的方式传给我,不然我怎么知道你想表达什么。 序列化和反序列化 数据压缩,在进行数据网络传输时,如果数据太大了,我们得考虑能不能对数据进行压缩。 注册中心,如果provider 进行集群部署(同样服务部署多个机器上),这时候我们需要在consumer进行手工维护,如果量一旦大起来了,这工作量可想而知。 动态感知服务上下线,如果provider 存在宕机或者部署了新的节点,这时候consumer就需要知道哪些服务下线了,哪些服务上线了。 动态路由,如果provider 进行集群部署(同样服务部署多个机器上),我们不可能让consumer都落在同一个节点上,这样资源不能充分利用了,古代皇帝的雨露均沾。动态路由那就会涉及到各种各样的算法,比如随机,轮询,权重等。
为什么需要注册中心,我之前分享过:
造轮子
根据上面的这些原理,田哥也搞了一个RPC框架,命名为mink(一个动物的名称)。
--mink ----mink-rpc rpc基本功能 ----mink-registry 服务注册与发现 ----mink-spring 集成SpringBoot
然后,我们把mink-spring打成jar包,服务发布和服务引用都把这个jar给依赖进去。
框架使用
上面,我们创造了轮子,下面,我们就来看如何使用。
mink-demo就是一个Spring Boot项目,有三个module。
我们把mink-api
打成jar包,共consumer和provider使用。
也就是我们在consumer和provider都引入:
<dependency> <groupId>com.tian</groupId> <artifactId>mink-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
下面,我们来看看provider端的代码:
<dependency> <groupId>com.tian</groupId> <artifactId>mink-spring</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.tian</groupId> <artifactId>mink-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.5.4</version> </dependency>
我们的mink框架,只需要引入mink-spring依赖即可。
接着就是properties的配置:
mink.rpc.servicePort=20880 mink.rpc.registryType=0 mink.rpc.registryAddress=127.0.0.1:2181
再来看看具体服务实现类:
package com.tian.service; import com.tian.annotation.MinkService; /** * @author tianwc 公众号:java后端技术全栈、面试专栏 * @version 1.0.0 * @description 用户服务 * @createTime 2022年08月23日 18:16 */ @MinkService public class UserServiceImpl implements UserService { @Override public String findUserNameByiD(Integer id) { System.out.println("服务调用"); return "tian"; } }
这一步,我们只需要在实现类上加上注解@MinkService
即可。
最后就是项目启动类:
@ComponentScan(basePackages = {"com.tian.service","com.tian"}) @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
我们启动项目(注册中心用的是zookeeper):
从日志中可以看出,我们的服务已经成功注册到注册中心了。
下面,我们来看看consumer端代码。
首先来看看依赖:
<dependency> <groupId>com.tian</groupId> <artifactId>mink-spring</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.tian</groupId> <artifactId>mink-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.5.4</version> </dependency>org.springframework.boot spring-boot-starter-web 2.5.4
这依赖也很简单,没什么好说的。
再来看看properties配置项:
mink.rpc.registryType=0 mink.rpc.registryAddress=127.0.0.1:2181 server.port=8090
是不是也很简单?
再来看看我们的controller代码:
package com.tian.controller; import com.tian.annotation.MinkReference; import com.tian.service.UserService; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author tianwc 公众号:java后端技术全栈、面试专栏 * @version 1.0.0 * @description 消费端 * @createTime 2022年08月23日 23:08 */ @RestController public class UserController { @MinkReference private UserService userService; @RequestMapping("/test") public String test() { return userService.findUserNameByiD(1); } }
需要用到对应服务,只需要添加注解@MinkReference
即可。
最后就是项目启动类,简单的不行。
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
启动日志:
访问:http://localhost:8090/test
成功!整个过程,非常轻松地集成mink框架并在业务代码中使用。
总结起来,其实就三步:
1、pom中添加依赖
2、properties文件中配置注册中心信息
3、使用的时候加上注解@MinkReference
或 @MinkService即可
以上是手写RPC框架,真不是为了装13!的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

你可能没有被问到过,可能是运气好,也可能是你还没到这个级别。通常月薪20k以上,基本上都会问一些设计性的题目。站在面试官角度:问这类题目,总比一个八股文强,这里面会涉及到很多技术点。比如:设计模式、通信协议、动态代理、虚拟化、线程池等知识。

RPC 是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而开发人员无需额外地为这个交互编程。

一、RPC框架的概念在分布式系统中,常常需要在不同的服务端和客户端之间传递数据,RPC(RemoteProcedureCall)框架是一种常用的技术手段。RPC框架允许应用程序通过远程消息传递调用另一个执行环境的函数或方法,从而使程序能够在不同的计算机上运行。目前市面上有很多RPC框架,如Google的gRPC、Thrift、Hessian等,本文主要介

RPC(RemoteProcedureCall),是一种进程间通信协议,它允许不同的进程在不同的物理机器上通过网络进行通信和协作。RPC框架越来越受到关注,因为它可以帮助开发者轻松地实现分布式系统的开发。在本篇文章中,我们会一步一步地介绍如何使用PHP进行RPC框架的开发。一、什么是RPC框架?RPC框架就是一个用于实现远程过程调用的框架。在基于RPC的

rpc框架有:1、gRPC,由Google开发的高性能,开源的RPC框架;2、Apache Thrift,由Facebook开发和开源的跨语言RPC框架;3、Apache Dubbo,一款高性能,轻量级的RPC框架,适用于大规模分布式系统;4、Apache Axis2,一款基于Web服务标准的RPC框架;5、Spring Cloud,一套构建分布式系统的开源框架。

Go语言作为一种举足轻重的现代编程语言,其在分布式系统开发中的应用愈发广泛。而在构建分布式系统时,RPC(远程过程调用)框架的选择往往是至关重要的。本文将对当前主流的Go语言RPC框架进行一次横向评估,比较它们在性能、易用性和社区支持等方面的优缺点,并附上具体的代码示例。1.性能对比在分布式系统中,性能往往是开发者们关注的首要指标之一。以下是几个主

如何在Go语言中实现高并发的RPC框架简介:随着互联网的快速发展,高并发应用越来越受到关注。采用RPC(RemoteProcedureCall)框架是一种常见的解决方案。本文将介绍如何在Go语言中实现高并发的RPC框架,并且会附带代码示例。RPC框架简介:RPC是一种通信协议,它允许一个计算机程序调用另一个地址空间(通常位于远程计算机上)的子程序,而不需

随着计算机技术的不断发展,分布式系统已成为主流,而远程过程调用(RPC)则是实现分布式系统的重要手段。PHP作为一种流行的Web编程语言,也有着自己的RPC框架,其中在PHP7.0版本中引入了一些新的RPC框架。本文将介绍PHP7.0中常见的RPC框架及其特点。PHPRemoteProcedureCall(phpRPC)phpRPC是一款轻量级的RP