目录
RPC原理
造轮子
框架使用" >框架使用
首页 常见问题 手写RPC框架,真不是为了装13!

手写RPC框架,真不是为了装13!

Aug 16, 2023 pm 05:01 PM
rpc框架

面试中,很容易被面试官问到:

如何设计一个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给依赖进去。

手写RPC框架,真不是为了装13!

手写RPC框架,真不是为了装13!

手写RPC框架,真不是为了装13!


框架使用

上面,我们创造了轮子,下面,我们就来看如何使用。

手写RPC框架,真不是为了装13!

mink-demo就是一个Spring Boot项目,有三个module。

手写RPC框架,真不是为了装13!


我们把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):

手写RPC框架,真不是为了装13!


从日志中可以看出,我们的服务已经成功注册到注册中心了。

下面,我们来看看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);
    }
}
登录后复制

启动日志:

手写RPC框架,真不是为了装13!

访问:http://localhost:8090/test

手写RPC框架,真不是为了装13!

成功!整个过程,非常轻松地集成mink框架并在业务代码中使用。

总结起来,其实就三步:

1、pom中添加依赖

2、properties文件中配置注册中心信息

3、使用的时候加上注解@MinkReference@MinkService即可

以上是手写RPC框架,真不是为了装13!的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
威尔R.E.P.O.有交叉游戏吗?
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

手写RPC框架,真不是为了装13! 手写RPC框架,真不是为了装13! Aug 16, 2023 pm 05:01 PM

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

阿里面试官:你给我手写个RPC框架看看 阿里面试官:你给我手写个RPC框架看看 Aug 17, 2023 pm 04:24 PM

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

Go语言中的RPC框架原理与应用 Go语言中的RPC框架原理与应用 Jun 01, 2023 pm 03:01 PM

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

PHP中如何进行RPC框架的开发? PHP中如何进行RPC框架的开发? May 13, 2023 pm 03:22 PM

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

有哪些rpc框架 有哪些rpc框架 Aug 03, 2023 am 10:17 AM

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框架横评:性能、易用性、社区支持对比 Feb 27, 2024 pm 09:12 PM

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

如何在go语言中实现高并发的RPC框架 如何在go语言中实现高并发的RPC框架 Aug 05, 2023 pm 12:49 PM

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

PHP7.0中的RPC框架有哪些? PHP7.0中的RPC框架有哪些? May 29, 2023 am 11:10 AM

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