继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

微博Motan初识

small_925_ant
关注TA
已关注
手记 69
粉丝 6396
获赞 157
关于Motan的设计可以参考这篇手记:https://www.imooc.com/article/18750

这里对源码进行简单的学习记录:

1-从github上面下载下来后源码目录:

https://img4.mukewang.com/5b76741a00019fa202740302.jpg

2-入口

我们从Motan本身提供的demo进行开始简单的学习

首先启动服务类:

com.weibo.motan.demo.server.MotanApiExportDemo
public static void main(String[] args) throws InterruptedException {
    ServiceConfig<MotanDemoService> motanDemoService = new ServiceConfig<MotanDemoService>();

    // 设置接口及实现类
    motanDemoService.setInterface(MotanDemoService.class);
    motanDemoService.setRef(new MotanDemoServiceImpl());

    // 配置服务的group以及版本号
    motanDemoService.setGroup("motan-demo-rpc");
    motanDemoService.setVersion("1.0");
    // 配置注册中心直连调用
    RegistryConfig registry = new RegistryConfig();
    registry.setRegProtocol("local");
    motanDemoService.setRegistry(registry);
    // 配置RPC协议
    ProtocolConfig protocol = new ProtocolConfig();
    protocol.setId("motan");
    protocol.setName("motan");
    motanDemoService.setProtocol(protocol);
    motanDemoService.setExport("motan:8004");
    motanDemoService.export();
    MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true);
    System.out.println("server start...");
}
这段代码主要完成的是服务的注册和暴露,提供给客户端进行RPC的调用
可以修改motanDemoService.setExport("motan:8004");端口号,启动多个服务注册

然后我们启动客户端

com.weibo.motan.demo.client.
public static void main(String[] args) {
    RefererConfig<MotanDemoService> motanDemoServiceReferer = new RefererConfig<MotanDemoService>();
    // 设置接口及实现类
    motanDemoServiceReferer.setInterface(MotanDemoService.class);
    // 配置服务的group以及版本号
    motanDemoServiceReferer.setGroup("motan-demo-rpc");
    motanDemoServiceReferer.setVersion("1.0");
    motanDemoServiceReferer.setRequestTimeout(1000);
    // 配置注册中心直连调用
    List<RegistryConfig>registryConfigList=new ArrayList<>();
    RegistryConfig registry = new RegistryConfig();
    //use direct registry
    registry.setRegProtocol("direct");
    registry.setAddress("127.0.0.1:8002");
    RegistryConfig registry1 = new RegistryConfig();
    //use direct registry
    registry1.setRegProtocol("direct");
    registry1.setAddress("127.0.0.1:8003");
    registryConfigList.add(registry);
    registryConfigList.add(registry1);
    motanDemoServiceReferer.setRegistries(registryConfigList);
    // 配置RPC协议
    ProtocolConfig protocol = new ProtocolConfig();
    protocol.setId("motan");
    protocol.setName("motan");
    motanDemoServiceReferer.setProtocol(protocol);
    // motanDemoServiceReferer.setDirectUrl("localhost:8002");  // 注册中心直连调用需添加此配置
    // 使用服务
    MotanDemoService service = motanDemoServiceReferer.getRef();
    System.out.println(service.hello("motan"));
    System.out.println(service.hello("motan121212"));
    System.exit(0);
}
这段代码首先是配置参数包括要调用的接口,和对应的服务地址
MotanDemoService service = motanDemoServiceReferer.getRef();这里是重要的方法会返回一个
代理对象。(如果是和spring结合使用,这里应该是注入的方式,spring会帮我们生成代理对象.)
生成代理对象的同时会做一些初始化的处理,比如netty channel池的构建,会先初始化两个已经获取
到连接的channel。这样真正后续的请求,会直接从channel缓存池中获取。通过实现自己的SharedObjectFactory
来实现的对象池。

 点进去可以看到:

ref = configHandler.refer(interfaceClass, clusters, proxy);
继续跟进去
@Override
public <T> T refer(Class<T> interfaceClass, List<Cluster<T>> clusters, String proxyType) {
    ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getExtension(proxyType);
    return proxyFactory.getProxy(interfaceClass, clusters);
}
最后会返回jdk的动态代理类
public class JdkProxyFactory implements ProxyFactory {

    @Override
    @SuppressWarnings("unchecked")
    public <T> T getProxy(Class<T> clz, List<Cluster<T>> clusters) {
        return (T) Proxy.newProxyInstance(clz.getClassLoader(), new Class[]{clz}, new RefererInvocationHandler<>(clz, clusters));
    }
}

获取到代理类后会进行调用具体的方法

service.hello("motan")
此时会执行com.weibo.api.motan.proxy.RefererInvocationHandler类的invoke方法

会调用response = cluster.call(request);
然后会代理给com.weibo.api.motan.cluster.support.ClusterSpi
继续调用return haStrategy.call(request, loadBalance);
此时会根据Ha策略的配置进行走不同的逻辑:
FailfastHaStrategy:失败会马上报异常
Referer<T> refer = loadBalance.select(request);//根据配置的策略选择一个服务地址
return refer.call(request);//进行具体的调用

还有一种Ha策略:
FailoverHaStrategy具体含义可以参考文章开头推荐的文章,很详细

后续会继续进一步的分析。











打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP