一、dubbo是什么? Dubbo是一个分布式RPC中间件。RPC(Remote Procedure Call) 远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,atv直播, 而不需要了解底层网络技术的协议。RPC可以认为是普通的c/s模式,服务提供方作为服务端,服务调用方作为客户端。 通常的RPC过程如下图: 二、如何实现一个Rpc 服务端代码通过监听一个端口暴露服务: public static void export(final Object service, int port) throws Exception { ServerSocket server = new ServerSocket(port); for (; ; ) { try { final Socket socket = server.accept(); new Thread(new Runnable() { @Override public void run() { try { try { ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); try { String methodName = input.readUTF(); Class[] parameterTypes = (Class[]) input.readObject(); Object[] arguments = (Object[]) input.readObject(); ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); try { Method method = service.getClass().getMethod(methodName, parameterTypes); Object result = method.invoke(service, arguments); output.writeObject(result); } catch (Throwable t) { output.writeObject(t); } finally { output.close(); } } finally { input.close(); } } finally { socket.close(); } } catch (Exception e) { e.printStackTrace(); } } }).start(); } catch (Exception e) { e.printStackTrace(); } } } 客户端根据服务提供者IP和端口,进行服务引用 @SuppressWarnings("unchecked") public static <T> T refer(final Class<T> interfaceClass, final String host, final int port) throws Exception { if (interfaceClass == null) { throw new IllegalArgumentException("Interface class == null"); } if (!interfaceClass.isInterface()) { throw new IllegalArgumentException( "The " + interfaceClass.getName() + " must be interface class!"); } if (host == null || host.length() == 0) { throw new IllegalArgumentException("Host == null!"); } if (port <= 0 || port > 65535) { throw new IllegalArgumentException("Invalid port " + port); } System.out.println( "Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port); 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); try { ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); try { output.writeUTF(method.getName()); output.writeObject(method.getParameterTypes()); output.writeObject(arguments); ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); try { Object result = input.readObject(); if (result instanceof Throwable) { throw (Throwable) result; } return result; } finally { input.close(); } } finally { output.close(); } } finally { socket.close(); } } }); } 可以看到,直播,最简单的RPC方式,不需要太多的代码。但是在最简单的RPC实现模型中,有一些问题: 1.服务端的状态变化(不可用,对客户端的权限变化),怎么通知到客户端? 2.服务的增减(可扩展性) 3.调用关系拓扑? 4.服务端永远不知道谁会对它提供的服务感兴趣。 5.服务质量保证 ....... 总之有很多可用性、可扩展性、可管理等许多问题无法解决。 三、RPC改进一点 普通的RPC有诸多缺陷,但我们期望的是高可用、高性能、高度可扩展的系统。而这些特性恰是分布式系统的设计目标。 我们如何做分布式的应用: 普通的C/S模型实现是一个server端,而在分布式中,采用的多节点集群;不论是客户端还是服务端,都是多节点集群,而且各个节点是动态可增减的。为此我们引入了注册中心的概念。注册中心将服务端和客户端解耦,工作方式大体如下: 四、更具体一些 在dubbo中,其实是服务提供者在zk进行Path的创建,Path中包含了服务相关的配置信息(服务名、消费白名单、序列化协议、服务器地址等),如下: 同时,客户端需要上报自己引用了哪些服务。相比服务发布,订阅服务麻烦得多,dubbo服务订阅的实现方式是:通过监听provide目录和configurators目录;provide目录,就是所有注册同一服务的提供者都会在这个目录下创建Path;configurations一般由服务订阅者初始化创建,控制台来修改里面的内容(增删path,如序列化协议、负载均衡算法、超时控制等)。具体如下: 客户端上报服务的具体例子: 客户端调用具体流程: (责任编辑:本港台直播) |