zoukankan      html  css  js  c++  java
  • RpcContext

    RpcContext内部有一个ThreadLocal变量,它是作为ThreadLocalMap的key,表明每个线程有一个RpcContext。

    public class RpcContext {
        private static final ThreadLocal<RpcContext> LOCAL = new ThreadLocal<RpcContext>() {
            @Override
            protected RpcContext initialValue() {
                return new RpcContext();
            }
        };
    
        //如果get在set之前,则get会返回initialValue()创建的对象
        public static RpcContext getContext() {
            return LOCAL.get();
        }
    }

    1. RpcContext的一种用法是:存放Future。Future封装了consumer的请求和响应,发送请求时会创建Future对象,此时响应是null,而DubboClientHandler线程会设置响应值。

    设置调用方式为异步:

    <dubbo:service interface="com.zhang.HelloService" ref="helloServiceImpl" protocol="dubbo">
        <dubbo:method name="sayHello" retries="0" async="true"></dubbo:method>
    </dubbo:service>

    RpcContext设置Future:

    //DubboInvoker
    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) { //异步调用,设置Future 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) { } catch (RemotingException e) { } }

    调用时直接返回:

    HelloService helloService = (HelloService) appCtx.getBean("hello");
    //返回null
    String str = helloService.sayHello();
    
    Future<String> future = RpcContext.getContext().getFuture();
    //阻塞获取结果
    String str2 = future.get();
  • 相关阅读:
    在SUSE12中使用 Machinery 进行高级系统管理
    有多个git项目要用多个秘钥
    Manage, Administrate and Monitor GlassFish v3 from Java code usingAMX &amp; JMX
    apc smart UPS下使用apcupsd注意事项
    Eclipse用法和技巧二十二:快速调整字体大小
    OpenGL(十三) Alpha测试、剪裁测试
    什么图用什么工具画?
    什么图用什么工具画?
    scipy —— 丰富的子包(io、cluster)
    scipy —— 丰富的子包(io、cluster)
  • 原文地址:https://www.cnblogs.com/allenwas3/p/8384206.html
Copyright © 2011-2022 走看看