符合中小企业对网站设计、功能常规化式的企业展示型网站建设
本套餐主要针对企业品牌型网站、中高端设计、前端互动体验...
商城网站建设因基本功能的需求不同费用上面也有很大的差别...
手机微信网站开发、微信官网、微信商城网站...
本篇内容介绍了“java Dubbo是做什么的”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
为岢岚等地区用户提供了全套网页设计制作服务,及岢岚网站建设行业解决方案。主营业务为网站设计、网站制作、岢岚网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
RPC,Remote Procedure Call 即远程过程调用,远程过程调用其实对标的是本地过程调用,本地过程调用你熟悉吧?
想想那青葱岁月,你在大学赶着期末大作业,正在攻克图书管理系统,你奋笔疾书疯狂地敲击键盘,实现了图书借阅、图书归还等等模块,你实现的一个个方法之间的调用就叫本地过程调用。
你要是和我说你实现图书馆里系统已经用了服务化,搞了远程调用了,我只能和你说你有点东西。
简单的说本机上内部的方法调用都可以称为本地过程调用,而远程过程调用实际上就指的是你本地调用了远程机子上的某个方法,这就是远程过程调用。
让我们小结一下,大致上一个 RPC 框架需要做的就是约定要通信协议,序列化的格式、一些容错机制、负载均衡策略、监控运维和一个注册中心!
没错就是简单的实现,上面我们在思考如何设计一个 RPC 框架的时候想了很多,那算是生产环境使用级别的功能需求了,我们这是 Demo,目的是突出 RPC框架重点功能 - 实现远程调用。
所以啥七七八八的都没,并且我用伪代码来展示,其实也就是删除了一些保护性和约束性的代码,因为看起来太多了不太直观,需要一堆 try-catch 啥的,因此我删减了一些,直击重点。
Let's Do It!
首先我们定义一个接口和一个简单实现。
public interface AobingService { String hello(String name); } public class AobingServiceImpl implements AobingService { public String hello(String name) { return "Yo man Hello,I am" + name; } }
然后我们再来实现服务提供者暴露服务的功能。
public class AobingRpcFramework { public static void export(Object service, int port) throws Exception { ServerSocket server = new ServerSocket(port); while(true) { Socket socket = server.accept(); new Thread(new Runnable() { //反序列化 ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); String methodName = input.read(); //读取方法名 Class>[] parameterTypes = (Class>[]) input.readObject(); //参数类型 Object[] arguments = (Object[]) input.readObject(); //参数 Method method = service.getClass().getMethod(methodName, parameterTypes); //找到方法 Object result = method.invoke(service, arguments); //调用方法 // 返回结果 ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); output.writeObject(result); }).start(); } } public staticT refer (Class interfaceClass, String host, int port) throws Exception { return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class>[] {interfaceClass}, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable { Socket socket = new Socket(host, port); //指定 provider 的 ip 和端口 ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); output.write(method.getName()); //传方法名 output.writeObject(method.getParameterTypes()); //传参数类型 output.writeObject(arguments); //传参数值 ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); Object result = input.readObject(); //读取结果 return result; } }); } }
好了,这个 RPC 框架就这样好了,是不是很简单?就是调用者传递了方法名、参数类型和参数值,提供者接收到这样参数之后调用对于的方法返回结果就好了!这就是远程过程调用。
我们来看看如何使用
//服务提供者只需要暴露出接口 AobingService service = new AobingServiceImpl (); AobingRpcFramework.export(service, 2333); //服务调用者只需要设置依赖 AobingService service = AobingRpcFramework.refer(AobingService.class, "127.0.0.1", 2333); service.hello();
看起来好像好不错哟,不过这很是简陋,用作 demo 有助理解还是极好的!
接下来就来看看 Dubbo 吧!上正菜!
Dubbo 是阿里巴巴 2011年开源的一个基于 Java 的 RPC 框架,中间沉寂了一段时间,不过其他一些企业还在用 Dubbo 并自己做了扩展,比如当当网的 Dubbox,还有网易考拉的 Dubbok。
但是在 2017 年阿里巴巴又重启了对 Dubbo 维护。在 2017 年荣获了开源中国 2017 最受欢迎的中国开源软件 Top 3。
在 2018 年和 Dubbox 进行了合并,并且进入 Apache 孵化器,在 2019 年毕业正式成为 Apache 顶级项目。
目前 Dubbo 社区主力维护的是 2.6.x 和 2.7.x 两大版本,2.6.x 版本主要是 bug 修复和少量功能增强为准,是稳定版本。
而 2.7.x 是主要开发版本,更新和新增新的 feature 和优化,并且 2.7.5 版本的发布被 Dubbo 认为是里程碑式的版本发布,之后我们再做分析。
它实现了面向接口的代理 RPC 调用,并且可以配合 ZooKeeper 等组件实现服务注册和发现功能,并且拥有负载均衡、容错机制等。
我们先来看下官网的一张图。
大的三层分别为 Business(业务层)、RPC 层、Remoting,并且还分为 API 层和 SPI 层。
分为大三层其实就是和我们知道的网络分层一样的意思,只有层次分明,职责边界清晰才能更好的扩展。
而分 API 层和 SPI 层这是 Dubbo 成功的一点,采用微内核设计+SPI扩展,使得有特殊需求的接入方可以自定义扩展,做定制的二次开发。
接下来咱们再来看看每一层都是干嘛的。
Service,业务层,就是咱们开发的业务逻辑层。
Config,配置层,主要围绕 ServiceConfig 和 ReferenceConfig,初始化配置信息。
Proxy,代理层,服务提供者还是消费者都会生成一个代理类,使得服务接口透明化,代理层做远程调用和返回结果。
Register,注册层,封装了服务注册和发现。
Cluster,路由和集群容错层,负责选取具体调用的节点,处理特殊的调用要求和负责远程调用失败的容错措施。
Monitor,监控层,负责监控统计调用时间和次数。
Portocol,远程调用层,主要是封装 RPC 调用,主要负责管理 Invoker,Invoker代表一个抽象封装了的执行体,之后再做详解。
Exchange,信息交换层,用来封装请求响应模型,同步转异步。
Transport,网络传输层,抽象了网络传输的统一接口,这样用户想用 Netty 就用 Netty,想用 Mina 就用 Mina。
Serialize,序列化层,将数据序列化成二进制流,当然也做反序列化。
我再稍微提一下 SPI(Service Provider Interface),是 JDK 内置的一个服务发现机制,它使得接口和具体实现完全解耦。我们只声明接口,具体的实现类在配置中选择。
具体的就是你定义了一个接口,然后在META-INF/services
目录下放置一个与接口同名的文本文件,文件的内容为接口的实现类,多个实现类用换行符分隔。
这样就通过配置来决定具体用哪个实现!
而 Dubbo SPI 还做了一些改进,篇幅有限留在之后再谈。
上面我已经介绍了每个层到底是干嘛的,我们现在再来串起来走一遍调用的过程,加深你对 Dubbo 的理解,让知识点串起来,由点及面来一波连连看。
首先 Provider 启动,通过 Proxy 组件根据具体的协议 Protocol 将需要暴露出去的接口封装成 Invoker,Invoker 是 Dubbo 一个很核心的组件,代表一个可执行体。
然后再通过 Exporter 包装一下,这是为了在注册中心暴露自己套的一层,然后将 Exporter 通过 Registry 注册到注册中心。 这就是整体服务暴露过程。
接着我们来看消费者调用流程(把服务者暴露的过程也在图里展示出来了,这个图其实算一个挺完整的流程图了)。
首先消费者启动会向注册中心拉取服务提供者的元信息,然后调用流程也是从 Proxy 开始,毕竟都需要代理才能无感知。
Proxy 持有一个 Invoker 对象,调用 invoke 之后需要通过 Cluster 先从 Directory 获取所有可调用的远程服务的 Invoker 列表,如果配置了某些路由规则,比如某个接口只能调用某个节点的那就再过滤一遍 Invoker 列表。
剩下的 Invoker 再通过 LoadBalance 做负载均衡选取一个。然后再经过 Filter 做一些统计什么的,再通过 Client 做数据传输,比如用 Netty 来传输。
传输需要经过 Codec 接口做协议构造,再序列化。最终发往对应的服务提供者。
服务提供者接收到之后也会进行 Codec 协议处理,然后反序列化后将请求扔到线程池处理。某个线程会根据请求找到对应的 Exporter ,而找到 Exporter 其实就是找到了 Invoker,但是还会有一层层 Filter,经过一层层过滤链之后最终调用实现类然后原路返回结果。
“java Dubbo是做什么的”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!