• 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();
  • 相关阅读:
    C#实现根据域名查询ip实例
    Ajax: 一个建立Web应用的新途径(转)
    CRC循环校验的具体算法(转)
    生成静态文件的新闻系统核心代码(.net C#)
    一个ajax的例子
    使用 JavaScript 实现 XMLHttpRequest,在IE,FireFox 上测试通过
    微软SQL Server 2005的30项顶尖特性(转)
    利用XMLHTTP无刷新自动实时更新数据(转)
    五子棋的核心算法(转)
    编写安全的SQL Server扩展存储过程(转)
  • 原文地址:https://www.cnblogs.com/allenwas3/p/8384206.html
Copyright © 2020-2023  润新知