面试中,很容易被面试官问到:
如何设计一个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框架,命名为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都引入:
com.tian
mink-api
1.0-SNAPSHOT
下面,我们来看看provider端的代码:
com.tian
mink-spring
1.0-SNAPSHOT
com.tian
mink-api
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter
2.5.4
我们的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端代码。
首先来看看依赖:
com.tian
mink-spring
1.0-SNAPSHOT
com.tian
mink-api
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter
2.5.4
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即可
mink框架用到的技术点(后期会加入线程池,其他序列化技术、监控):
工厂模式、动态代理、模板方法模式、注册式饿汉式单列模式
底层通信用的是netty框架、自定义协议、序列化与反序列化(java原生态和json)、编解码
集成SpringBoot、Spring扩展点
集成zookeeper实现服务注册、服务上下线动态感知
自定义注解、自定义String工具类、自定义Collection工具类、自定义数组工具类等。
自己动手写完这个mink框架,面试还是可以吹吹,同时,也意味着你对上面技术点掌握到手,你觉得面试官还不喜欢吗?
我们不是为了装样子而造轮子,而是想通过造轮子这个过程,把我们学到的技术给用进去。学到的技术如果不用,那永远是个半吊子,并且很快就忘掉。
在实现的过程中,有任何问题都可以找我探讨,一方面完善mink框架,一方面技术提升!
原文链接:https://mp.weixin.qq.com/s/Fgzrt9GFMCi2uh2QpZ42BQ
留言与评论(共有 0 条评论) “” |