<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> <exclusions> <exclusion> <artifactId>spring</artifactId> <groupId>org.springframework</groupId> </exclusion> </exclusions> </dependency>
public interface DemoService { String syncSayHello(String name); String asyncSayHello(String name); }
public class DemoServiceImpl implements DemoService { @Override public String syncSayHello(String name) { return "sync Hello " + name; } @Override public String asyncSayHello(String name) { return "async Hello " + name; } }
<? xml version="1.0" encoding="UTF-8"?> <beans xmlns=" http://www.springframework.org/schema/beans " xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance " xmlns:dubbo=" http://code.alibabatech.com/schema/dubbo " xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd "> <!-- The provider application information is used to calculate dependency --> <dubbo:application name="hello-world-app" /> <!-- Use the zookeeper registry to expose the service address --> <dubbo:registry address=" zookeeper://127.0.0.1:2181 " /> <!-- Use the dubbo protocol to expose services -->on port 20880 <dubbo:protocol name="dubbo" port="20880" /> <!-- Declare the service interface to be exposed --> <dubbo:service interface="org.dubboProvider.DemoService" ref="demoService" /> <!-- Implement services like local beans --> <bean id="demoService" class="org.dubboProvider.DemoServiceImpl" /> </beans>
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Provider { public static void main(String[] args) throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( new String[] { "dubbo-provider.xml" }); context.start(); System.in.read(); // press any key to exit } }
<? xml version="1.0" encoding="UTF-8"?> <beans xmlns=" http://www.springframework.org/schema/beans " xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance " xmlns:dubbo=" http://code.alibabatech.com/schema/dubbo " xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd "> <!-- Consumer application name, used to calculate dependency, is not a matching condition, and should not be the same as the provider --> <dubbo:application name="consumer-of-helloworld-app" /> <dubbo:registry address=" zookeeper://127.0.0.1:2181 " /> <!-- To generate a remote service proxy, you can use demoService -->like a local bean <dubbo:reference id="demoService" interface="org.dubboProvider.DemoService" > <dubbo:method name="syncSayHello" async="false" /> <dubbo:method name="asyncSayHello" async="true" /> </dubbo:reference> </beans>
import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import org.dubboProvider.DemoService; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.alibaba.dubbo.rpc.RpcContext; public class Consumer { public static void main(String[] args) throws InterruptedException, ExecutionException { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "dubbo-consumer.xml"); context.start(); DemoService demoService = (DemoService) context.getBean("demoService"); // Get Remote Service Proxy System.out.println(demoService.syncSayHello("world")); System.out.println(demoService.asyncSayHello("world")); Future<String> futrue = RpcContext.getContext().getFuture(); System.out.println(futrue.get()); } }
sync Hello world null async Hello world
protected void doRegister(URL url) { try { zkClient.create(toUrlPath(url), url.getParameter(Constants. DYNAMIC_KEY, true)); } catch (Throwable e) { throw new RpcException("Failed to register " + url + " to zookeeper " + getUrl() + ", cause: " + e.getMessage(), e); } }
public AbstractClient(URL url, ChannelHandler handler) throws RemotingException { //... Omit connect(); //... Omit }
protected void doConnect() throws Throwable { long start = System.currentTimeMillis(); ChannelFuture future = bootstrap.connect(getConnectAddress()); //... Omit NettyClient.this.channel = newChannel; //... Omit }
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) { return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker)); }
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); Class<?>[] parameterTypes = method.getParameterTypes(); if (method.getDeclaringClass() == Object.class) { return method.invoke(invoker, args); } if ("toString".equals(methodName) && parameterTypes.length == 0) { return invoker.toString(); } if ("hashCode".equals(methodName) && parameterTypes.length == 0) { return invoker.hashCode(); } if ("equals".equals(methodName) && parameterTypes.length == 1) { return invoker.equals(args[0]); } return invoker.invoke(new RpcInvocation(method, args)).recreate(); }
public class RpcInvocation implements Invocation, Serializable { private static final long serialVersionUID = -4355285085441097045L; private String methodName; private Class<?>[] parameterTypes; private Object[] arguments; private Map<String, String> attachments; private transient Invoker<?> invoker; ......//The following is omitted
protected Result doInvoke(final Invocation invocation) throws Throwable { RpcInvocation inv = (RpcInvocation) invocation; final String methodName = RpcUtils.getMethodName(invocation); inv.setAttachment(Constants. PATH_KEY, getUrl().getPath()); inv.setAttachment(Constants. VERSION_KEY, version); ExchangeClient currentClient; if (clients.length == 1) { currentClient = clients[0]; } else { currentClient = clients[index.getAndIncrement() % clients.length]; } try { boolean isAsync = RpcUtils.isAsync(getUrl(), invocation); boolean isOneway = RpcUtils.isOneway(getUrl(), invocation); int timeout = getUrl().getMethodParameter(methodName, Constants.TIMEOUT_KEY,Constants.DEFAULT_TIMEOUT); if (isOneway) { boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false); currentClient.send(inv, isSent); RpcContext.getContext().setFuture(null); return new RpcResult(); } else if (isAsync) { ResponseFuture future = currentClient.request(inv, timeout) ; RpcContext.getContext().setFuture(new FutureAdapter<Object>(future)); return new RpcResult(); } else { RpcContext.getContext().setFuture(null); return (Result) currentClient.request(inv, timeout).get(); } } catch (TimeoutException e) { throw new RpcException(RpcException. TIMEOUT_EXCEPTION, "Invoke remote method timeout. method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e); } catch (RemotingException e) { throw new RpcException(RpcException. NETWORK_EXCEPTION, "Failed to invoke remote method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e); } }
if (clients.length == 1) { currentClient = clients[0]; } else { currentClient = clients[index.getAndIncrement() % clients.length]; }
public ResponseFuture request(Object request, int timeout) throws RemotingException { if (closed) { throw new RemotingException(this.getLocalAddress(), null, "Failed to send request " + request + ", cause: The channel " + this + " is closed!"); } // create request. Request req = new Request(); req.setVersion("2.0.0"); req.setTwoWay(true); req.setData(request); DefaultFuture future = new DefaultFuture(channel, req, timeout); try{ channel.send(req); }catch (RemotingException e) { future.cancel(); throw e; } return future; }
public Object get(int timeout) throws RemotingException { if (timeout <= 0) { timeout = Constants.DEFAULT_TIMEOUT; } if (! isDone()) { long start = System.currentTimeMillis(); lock.lock(); try { while (! isDone()) { done.await(timeout, TimeUnit.MILLISECONDS); if (isDone() || System.currentTimeMillis() - start > timeout) { break; } } } catch (InterruptedException e) { throw new RuntimeException(e); } finally { lock.unlock(); } if (! isDone()) { throw new TimeoutException(sent > 0, channel, getTimeoutMessage(false)); } } return returnFromResponse(); }
public boolean isDone() { return response != null; }