Dubbo/Dubbox的dubbo协议实现(一)-服务端启动

Dubbo的介绍以及Dubbox的区别 Dubbo官网:  http://dubbo.io/ Dubbox官网: https://github.com/dangdangdotcom/dubbox Dubbo 是阿里巴巴公司开源的一个基于Java的高性能开源RPC框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。后来因为某些原因没有维护,于是当当网在这之上推出了自己的Dubbox。 D... 阅读详情

之前已经分析的dubbo的服务的发现和注册,这里先看一下dubbo协议是如何实现的,之前已经知道了,调用DubboProtocol类的export来暴露服务的,协议实现比较复杂,这里只关系主体实现即排除一些特性功能的处理代码

本章主要处理服务端对应的暴露流程,继续回到···com.alibaba.dubbo.config.ServiceConfig···的doExportUrlsFor1Protocol方法(487行附近)

Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
Exporter<?> exporter = protocol.export(invoker);
exporters.add(exporter);

proxyFactory 是一个全局变量(自适应扩展点),之前已经反复复习不多说明了
proxyFactory.getInvoker实现如下,该方法内部会调用一个封装类com.alibaba.dubbo.common.bytecode.Wrapper,该类封装了实例的方法调用。proxyFactory.getInvoker 会返回一个

public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
        // TODO Wrapper类不能正确处理带$的类名
        final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? proxy.getClass() : type);
        return new AbstractProxyInvoker<T>(proxy, type, url) {
            @Override
            protected Object doInvoke(T proxy, String methodName,
                                      Class<?>[] parameterTypes,
                                      Object[] arguments) throws Throwable {
                return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
            }
        };
    }

这里com.alibaba.dubbo.common.bytecode.Wrapper类不做过多说明,其会生成有一个名为invokeMethod封装方法,invokeMethod 方法根据传入实例和方法名,调用实例对应的方法,invokeMethod方法签名如下:

  /**
     *
     * @param o 接口类实例
     * @param n 方法名
     * @param p 参数类型
     * @param v 参数值
     * @return
     * @throws java.lang.reflect.InvocationTargetException
     */
    public Object invokeMethod(Object o, String n, Class[] p, Object[] v) throws java.lang.reflect.InvocationTargetException

所以到这里可以发现,对于服务的提供者来说通过com.alibaba.dubbo.rpc.Invoker的 protected Object doInvoke(T proxy, String methodName,Class

public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
        /*url此刻内容如下。
        *dubbo://ip:port/服务接口?anyhost=true&application=dsp-ad&default.timeout=10000&dubbo=2.8.4&generic=false&
        *interface=服务接口&logger=log4j&methods=接口方法名&organization=company&owner=weiythi&pid=5948&revision=1.6.1&serialization=kryo&side=provider&timestamp=1511849953486
        */
        URL url = invoker.getUrl();

        // export service.
        // serviceKey为 服务接口类名:端口号
        String key = serviceKey(url);
        //DubboExporter 实现接口 com.alibaba.dubbo.rpc.Exporter ,会在抽象实现com.alibaba.dubbo.rpc.protocol.AbstractExporter 的基础上维护exporterMap ,key
        DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);
        exporterMap.put(key, exporter);
        //省略......export an stub service for dispaching event......//

        //开启服务
        openServer(url);

        // modified by lishen 序列化优化相关,暂不去了解
        optimizeSerialization(url);

        return exporter;
    }

这里先找到最关心的点“openServer(url);”,其是dubbo协议服务暴露的入口,其实现如下:

private void openServer(URL url) {
        // find server.
        // 这里是ip:port
        String key = url.getAddress();
        //client 也可以暴露一个只有server可以调用的服务。
        boolean isServer = url.getParameter(Constants.IS_SERVER_KEY,true);
        if (isServer) {//true
            //按照ip:port为key 找到信息交换层的服务端
            ExchangeServer server = serverMap.get(key);
            if (server == null) {//如果木有创建过server端,则创建并将服务端缓存
                serverMap.put(key, createServer(url));
            } else {
                //server支持reset,配合override功能使用
                server.reset(url); //这个暂时木有看懂,等回过头来看
            }
        }
    }

注意这里serverMap虽说不是一个static域,但基于扩展点机制的实现,貌似都是单例的,所以这里一个服务端进程可以为多个provider提供服务,那么createServer(url)是如何开启服务的呢?
createServer(url)的方法实现如下, 注意该方法会通过url总线的server参数来决定使用dubbo的协议实现,dubbox这里默认nio框架是netty

private ExchangeServer createServer(URL url) {
        //默认开启server关闭时发送readonly事件
        url = url.addParameterIfAbsent(Constants.CHANNEL_READONLYEVENT_SENT_KEY, Boolean.TRUE.toString());
        //默认开启heartbeat
        url = url.addParameterIfAbsent(Constants.HEARTBEAT_KEY, String.valueOf(Constants.DEFAULT_HEARTBEAT));
        //获得协议的server实现,默认netty
        String str = url.getParameter(Constants.SERVER_KEY, Constants.DEFAULT_REMOTING_SERVER);

        if (str != null && str.length() > 0 && ! ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str))
            throw new RpcException("Unsupported server type: " + str + ", url: " + url);

        url = url.addParameter(Constants.CODEC_KEY, Version.isCompatibleVersion() ? COMPATIBLE_CODEC_NAME : DubboCodec.NAME);
        ExchangeServer server;
        try {
            //注意这里的requestHandler 是一个com.alibaba.dubbo.remoting.exchange.ExchangeHandler 的接口实现。
            server = Exchangers.bind(url, requestHandler);
        } catch (RemotingException e) {
            throw new RpcException("Fail to start server(url: " + url + ") " + e.getMessage(), e);
        }
        str = url.getParameter(Constants.CLIENT_KEY);
        if (str != null && str.length() > 0) {
            Set<String> supportedTypes = ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions();
            if (!supportedTypes.contains(str)) {
                throw new RpcException("Unsupported client type: " + str);
            }
        }
        return server;
    }

在方法中能注意到一个闪闪亮的语句,server = Exchangers.bind(url, requestHandler); 这里传入了一个参数requestHandler,requestHandler在此类是一个com.alibaba.dubbo.remoting.exchange.ExchangeHandler的接口实现,看了下源码这里又引入了一系列暂时不知道用处的类,所以此处暂时忽略接口实现,既然其是一个handler所以接到consumer的调用之后必然会执行的,先放在一边。我们接数据的时候一起看。
com.alibaba.dubbo.remoting.exchange.Exchangers 类主要有两个功能,即服务器的绑定和客户端的连接功能
Exchangers.bind(url, requestHandler); 内部又涉及一系列的扩展点,不贴代码出来了。简单介绍一下, 这里肯定实现的功能就是服务器的绑定了
1.bind方法会根据URL总线的exchanger参数获得一个com.alibaba.dubbo.remoting.exchange.Exchanger 扩展点实例,本例实例为(com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchanger),嗯 目前已知的扩展点实现也就这一个。
2.Exchanger?在一个框架中我们通常把负责数据交换和网络通信的组件叫做Exchanger ,接下来调用 ExchangeServer bind(URL url, ExchangeHandler handler) 方法,注意这里又是一个自适应扩展点。

接下来进入到Exchanger仅有的一个实现com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchanger

    public ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException {
        return new HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler))));
    }

可见在该方法中,创建了一个com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeServer 对象,当然根据方法定义该类肯定实现接口com.alibaba.dubbo.remoting.exchange.ExchangeServer 这里先暂时不关心该接口行为,因为创建对象前,先对handler进行了两层封装,然后使用com.alibaba.dubbo.remoting.Transporters的bind方法,进行绑定。
对handler的封装可能会绝对handler调用前或调用后的行为,设置决定了handler的调用方式,那么先去确定com.alibaba.dubbo.remoting.transport.DecodeHandler 的运作情况。
额,点开看了一下貌似也挺复杂,因为这个类一顿继承啊~,找一下自己关心的两个东东,分别是,我家的HeaderExchangeHandler在哪里?有木有能让我接受到消息调用到的方法。
然后发现这两个重点是这样的

public DecodeHandler(ChannelHandler handler) {
        super(handler); //父类构造器
    }

    public void received(Channel channel, Object message) throws RemotingException {
        if (message instanceof Decodeable) {
            decode(message);
        }

        if (message instanceof Request) {
            decode(((Request)message).getData());
        }

        if (message instanceof Response) {
            decode( ((Response)message).getResult());
        }
        //调用received方法,既然我们的类已经被封装了两层,那么这里应该调用的是HeaderExchangeHandler
        handler.received(channel, message);
    }

    private void decode(Object message) { //这个方法没有任何handler相关处理,暂不去关心。
        if (message != null && message instanceof Decodeable) {
            try {
                ((Decodeable)message).decode();
                if (log.isDebugEnabled()) {
                    log.debug(new StringBuilder(32).append("Decode decodeable message ")
                                  .append(message.getClass().getName()).toString());
                }
            } catch (Throwable e) {
                if (log.isWarnEnabled()) {
                    log.warn(
                        new StringBuilder(32)
                            .append("Call Decodeable.decode failed: ")
                            .append(e.getMessage()).toString(),
                        e);
                }
            } // ~ end of catch
        } // ~ end of if
    } // ~ end of method decode

那么再去看看 HeaderExchangeHandler 是个啥
这里写图片描述
还有既然会调用received方法,主要去看看received的实现。点开一看略复杂、、、、好多东东,看到这里还不能理解,所以又去敲Transporters.bind的门,因为已经先行忽略了handler这个,这里只关心服务是怎么被open的
代码里又耍流氓了,又是自适应扩展点,但是我已不怕,打开看配置文件直接锁定实现com.alibaba.dubbo.remoting.transport.netty.NettyTransporter 然后去看bind方法(等等索性直接看了)

/*
 * Copyright 1999-2011 Alibaba Group.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.dubbo.remoting.transport.netty;

import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.remoting.ChannelHandler;
import com.alibaba.dubbo.remoting.Client;
import com.alibaba.dubbo.remoting.RemotingException;
import com.alibaba.dubbo.remoting.Server;
import com.alibaba.dubbo.remoting.Transporter;

/**
 * @author ding.lid
 */
public class NettyTransporter implements Transporter {

    public static final String NAME = "netty";

    public Server bind(URL url, ChannelHandler listener) throws RemotingException {
        return new NettyServer(url, listener);
    }

    public Client connect(URL url, ChannelHandler listener) throws RemotingException {
        return new NettyClient(url, listener);
    }

}

这个很明显么,直接new了一个com.alibaba.dubbo.remoting.transport.netty.NettyServer 出来,那么问题简单了,直接去看构造函数

public NettyServer(URL url, ChannelHandler handler) throws RemotingException{
        super(url, ChannelHandlers.wrap(handler, ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME)));
    }

调用了父类的构造器

public AbstractServer(URL url, ChannelHandler handler) throws RemotingException {
        // 哭 handler又甩给上层了
        super(url, handler);
        localAddress = getUrl().toInetSocketAddress();
        String host = url.getParameter(Constants.ANYHOST_KEY, false)
                        || NetUtils.isInvalidLocalHost(getUrl().getHost())
                        ? NetUtils.ANYHOST : getUrl().getHost();
        bindAddress = new InetSocketAddress(host, getUrl().getPort());
        this.accepts = url.getParameter(Constants.ACCEPTS_KEY, Constants.DEFAULT_ACCEPTS);
        this.idleTimeout = url.getParameter(Constants.IDLE_TIMEOUT_KEY, Constants.DEFAULT_IDLE_TIMEOUT);
        try {
            //好吧,偷偷的调用了doOpen 害我好找
            doOpen();
            if (logger.isInfoEnabled()) {
                logger.info("Start " + getClass().getSimpleName() + " bind " + getBindAddress() + ", export " + getLocalAddress());
            }
        } catch (Throwable t) {
            throw new RemotingException(url.toInetSocketAddress(), null, "Failed to bind " + getClass().getSimpleName()
                                        + " on " + getLocalAddress() + ", cause: " + t.getMessage(), t);
        }

        executor = (ExecutorService) ExtensionLoader.getExtensionLoader(DataStore.class)
                .getDefaultExtension().get(Constants.EXECUTOR_SERVICE_COMPONENT_KEY, Integer.toString(url.getPort()));
    }

主要关注两个事,就是我们的handler哪去了,后面可能还要用呢,还有服务在哪开的?
首先看那第一行,调用父类的构造器,一直跟着找,发现handler在com.alibaba.dubbo.remoting.transport.AbstractPeer 中维护了,然后AbstractPeer又是一个ChannelHandler ,好吧这个关系很混乱。先记着这个关键点,上一次看见类似风格是在RegistryDictory中
既然调用了doOpen,这个就不用想了,方法的实现就在NettyServer里啊,但是netty之前没玩过,所以只能看个热闹

@Override
    protected void doOpen() throws Throwable {
        NettyHelper.setNettyLoggerFactory();
        ExecutorService boss = Executors.newCachedThreadPool(new NamedThreadFactory("NettyServerBoss", true));
        ExecutorService worker = Executors.newCachedThreadPool(new NamedThreadFactory("NettyServerWorker", true));
        ChannelFactory channelFactory = new NioServerSocketChannelFactory(boss, worker, getUrl().getPositiveParameter(Constants.IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS));
        bootstrap = new ServerBootstrap(channelFactory);
        // 这里的NettyHandler 封装了一个this? 这个this是什么?
        final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);
        channels = nettyHandler.getChannels();
        // https://issues.jboss.org/browse/NETTY-365
        // https://issues.jboss.org/browse/NETTY-379
        // final Timer timer = new HashedWheelTimer(new NamedThreadFactory("NettyIdleTimer", true));
        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() {
                NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec() ,getUrl(), NettyServer.this);
                ChannelPipeline pipeline = Channels.pipeline();
                /*int idleTimeout = getIdleTimeout();
                if (idleTimeout > 10000) {
                    pipeline.addLast("timer", new IdleStateHandler(timer, idleTimeout / 1000, 0, 0));
                }*/
                pipeline.addLast("decoder", adapter.getDecoder());
                pipeline.addLast("encoder", adapter.getEncoder());
                pipeline.addLast("handler", nettyHandler);
                return pipeline;
            }
        });
        // bind
        channel = bootstrap.bind(getBindAddress());
    }

因为35太难了,我学不会,而且server开启之后只要能一直提供服务就OK,我只能关注另一个点就是接到消息后怎么处理的。所以这里跟消息有关的就一个nettyHandler ,其初始化是通过这样的语句完成的,这里传入了一个this,我们要知道这个this是什么。

final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);

@Sharable
public class NettyHandler extends SimpleChannelHandler {

    private final Map<String, Channel> channels = new ConcurrentHashMap<String, Channel>(); // <ip:port, channel>

    private final URL url;

    private final ChannelHandler handler;
    //.......//
    public NettyHandler(URL url, ChannelHandler handler){
            if (url == null) {
                throw new IllegalArgumentException("url == null");
            }
            if (handler == null) {
                throw new IllegalArgumentException("handler == null");
            }
            this.url = url;
            this.handler = handler;
        }
}

好吧,很巧妙的方式,因为NettyServer他是一个ChannelHandler啊,是一个ChannelHandler啊…啊。
迷只混乱,只能拿出他家家谱,然后默默流眼泪
这个家谱里貌似没有我们熟悉的朋友。
这里写图片描述
看看他的长辈有没有人认识我们上文忽略的com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeServer,因为是这么个关系new HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler)))); 所以去看看他的构造器

public HeaderExchangeServer(Server server) {
        if (server == null) {
            throw new IllegalArgumentException("server == null");
        }
        this.server = server;
        this.heartbeat = server.getUrl().getParameter(Constants.HEARTBEAT_KEY, 0);
        this.heartbeatTimeout = server.getUrl().getParameter(Constants.HEARTBEAT_TIMEOUT_KEY, heartbeat * 3);
        if (heartbeatTimeout < heartbeat * 2) {
            throw new IllegalStateException("heartbeatTimeout < heartbeatInterval * 2");
        }
        startHeatbeatTimer();
    }

参数正好是NettyServer所实现的接口com.alibaba.dubbo.remoting.Server ,到这里我们就返回一个ExchangeServer了,不过好像目前为止并没有有什么实质性的动作,回到createServer

好吧,到这一个服务就创建完了。总结一下开启服务这一部的调用关系(引用大佬的)

openServer netty server打开侦听服务,并缓存服务。
dubbo -> export() -> openServer() -> createServer() -> Exchangers.bind()(HeaderExchanger) -> NettyTransporter -> NettyServer.open()(编码解码采用exchange)
netty ChannelFactory(boss worker) ChannelPipeline(责任链模式) ChannelHandler(处理器) — 反应器模式

springboot整合dubbox 简介今天咱们来看看怎么利用Spring Boot整合Dubbox来开发去中心化的微服务。系统环境本文基于Jdk1.8/Maven 3.3.9/Spring Boot 1.4.2.RELEASE/Dubbo 2.8.5.SNAPSHOT(Dubbox后续开源版本)/ZooKeeper3.4.8Zookeeper环境搭建下载并安装启动下载 wget http://mirrors.hust.edu.cn 阅读详情

相关推荐

思科路由器、交换机组网实验报告

通过思科模拟器搭建路由交换网络

ghj528的博客 1335

Dubbox多协议支持:Dubbo、REST、WebService对比评测

在分布式系统开发中,协议选择是架构设计的核心环节。Dubbox作为阿里巴巴开源的分布式服务框架,提供了强大的多协议支持能力,让开发者能够根据业务需求灵活选择最适合的通信协议。本文将深入分析Dubbox支持的三种主流协议:Dubbo协议、REST协议和WebService协议,帮助您做出更明智的技术选型决策。 ## Dubbo协议:高性能的默认选择 Dubbo协议是Dubbox框架的默认协议,专

gitblog_00724的博客 499

异步复位同步释放:如何确保复位信号的可靠性与时序安全

本文深入探讨了异步复位同步释放技术在数字电路设计中的关键作用,详细分析了复位信号的可靠性与时序安全问题。通过对比异步复位与同步复位的本质区别,揭示异步复位的优势与潜在风险,并提供了标准的Verilog实现方案。文章还涵盖了多时钟域下的复位同步策略、复位网络时序约束方法以及实际工程中的经验教训,为数字系统设计者提供了全面的复位信号处理指南。

weixin_29213655的博客 399

dubbo--03--- dubbo 支持的9种协议

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档。

时光里的博客 2256

Unity游戏开发实战:如何用科大讯飞离线语音合成SDK实现NPC对话(附完整代码)

本文详细介绍了如何在Unity游戏开发中使用科大讯飞离线语音合成SDK实现NPC对话系统。通过完整的代码示例和优化技巧,开发者可以快速集成本地语音合成功能,提升游戏沉浸感,同时避免网络延迟问题。文章涵盖SDK集成、核心语音合成模块实现以及高级应用技巧,特别适合RPG游戏开发者参考。

weixin_29268385的博客 182

记一次网络风暴/网络环路

环境: win10 x64 ,联想云教室,电子教室,华三交换机。 状况描述: 最开始开机,一直卡在PXE启动界面,进不去系统。电脑技术张工说,先开教师机后开学生机。因为学生机开机需要读取教师机的镜像。但是状况依旧。 开始排查网络,重启交换机后,发现陆续有几台电脑能登陆进系统桌面了,但很慢起码过了5分钟以上才能进去。 教师机一直都是正常的,然后我在教师机部署电子教室。技术说这电子 教室与云教室IP冲突。 (那之后我查了下这两款软件的PID和端口,所占端口不一样,那没冲突) 我说不可能吧,这套软件在

Nightwish5的博客 2865

Dubbo-聊聊Dubbo协议

SPI实现部分Dubbo-SPI机制Dubbo-Adaptive实现原理Dubbo-Activate实现原理注册中心Dubbo-聊聊注册中心的设计Dubbo-时间轮设计通信Dubbo-聊聊通信模块设计在网络交互中是以字节流的形式传递的,对于字节流都是二进制格式,这样我们就面临一个问题就是如何转化为我们可以识别的字符,协议就是来解决这个问题的,协议用通俗易懂地解释就是通信双方需要遵循的约定。在日常开发中,我们常见的网络传输协议有TCP、UDP、HTTP。

weixin_38592881的博客 2288

ComfyUI的G-Dino模型加载器报错解决方案:从崩溃到重生

遇到G-Dino模型加载器报错不要慌,按照本文的步骤操作,99%的问题都能解决。模型文件正确下载到指定位置segment_anything节点安装完整且无冲突需要补充更多细节或故障排除方法吗?可以随时告诉我。

2301_78150483的博客 4023

Dubbox介绍

1. Dubbox介绍 2. Dubbox工作流程 3. Dubbox的工作原理 4. dubbo支持哪些通信协议?支持哪些序列化协议? 5. dubbo负载均衡策略和集群容错策略都有哪些?动态代理策略呢? 6. dubbo的服务治理、降级、重试 1. Dubbox介绍 Dubbox是一个远程服务调用的分布式框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA的服务治理 Du...

暗余的博客 874

Vue2 - 实现全景图Vr 720°全景效果查看预览功能,3D全景图流畅不卡顿渲染+手势拖拽+悬浮工具按钮,vue实现vr看720度全景效果方案讲解及示例代码(兼容电脑PC网页+手机H5移动端页面)

vue全景VR图,vue h5实现全景720预览,vue加载720全景图_vue怎么加载vr图片,vue实现vr全景看房,vue2实现全景效果,加载很慢卡怎么办,实现全景预览的插件,vue显示720度全景图,720°全景图显示,在h5中展示720°全景图,浏览全景图,基于vue实现vr全景预览,加载全景图,vue全景预览pannellum插件,vue实现3D全景图,实现720°全景图展示,在VUE 中使用three.js实现全景视频播放,vue项目中使用photo-sphere-viewer实现vr720度

🏆 前端领域优质创作者 3317

SIMULINK开发项目实例 1000 例专栏之第847例--基于飞行控制与稳定性的场景实例:多旋翼无人机在风扰动下的稳定性分析

本文介绍了使用Simulink进行多旋翼无人机风扰动稳定性分析的完整流程。首先建立包含动力学模型、控制系统和环境模拟三大模块的仿真系统,其中动力学模型基于牛顿-欧拉方程,控制系统采用PID调节器。重点展示了MATLAB函数实现的风扰动模型和姿态控制算法,通过设置输入信号和输出显示模块完成闭环仿真。最后通过多次风速条件下的仿真测试评估控制系统的抗干扰能力和稳定性表现,为无人机控制系统设计提供了有效的仿真验证方法。

xiaoheshang_123的博客 322

Dubbo协议详解

Dubbo协议是一种高性能、轻量级的开源RPC框架,主要设计目的是解决分布式系统中服务调用的一些常见问题,例如服务负载均衡、服务注册中心、服务的远程调用等。它支持多种语言,例如Java、Python、Ruby等,使得各种编程语言之间的服务调用变得更加灵活。

技术人集结地 1866

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Dubbo 和 Dubbox 之间的区别

Dubbo 最早由阿里巴巴在 2011 年开源,是一个用于微服务架构的分布式服务框架。Dubbo 提供了高效的远程服务调用、服务注册与发现、负载均衡、服务容错等功能,帮助开发者构建和管理分布式系统。然而,在 2014 年左右,阿里巴巴停止了对 Dubbo 的维护。这段时间内,尽管 Dubbo 仍然在许多企业中广泛使用,但由于缺乏官方更新和维护,社区对 Dubbo 的发展感到担忧。Dubbo 和 Dubbox 都是强大的分布式服务框架,各自有其独特的功能和应用场景。

Flying_Fish_roe的博客 1075

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Dubbo进阶(十一)—— Dubbo与DubboX区别_dubbox和dubbo的区别

Dubbox(即)是当当网Fork基于dubbo2.x的升级版本,兼容原有的dubbox。其中升级了zookeeper和spring版本,并且支持restfull风格的远程调用。

2401_87389836的博客 521

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

idea下用maven创建并搭建dubbox微服务环境项目(一)

提醒:各位看官,这个项目环境搭建将采用分时完成,因为有很多技术需要学习补充,也是对自己的检验,所以需要持续更新! 前提准备: 1.概述 1.1 传统架构(B/S):传统架构即单体架构。开发中控制器、service等都在一个项目中开发,一起部署在一个服务器上。 1.2 微服务架构(B/S):将控制器、service等分布式开发,隔离部署,通过通信中间件(我们的tomcat、maven、z...

gaofengyan的博客 5273

Dubbo与DubboX的区别

Dubbo与DubboX区别前世今生:Dubbo源于阿里的淘宝网开源的分布式的服务架构,致力于提供高性能和透明化的RPC远程服务调用方案,是SOA服务化治理方案的核心框架。淘宝网将其开源之后,得到了很多的拓展和支持(比较出名的有:当当网的扩展版本dubbox,京东的扩展版本jd-hydra等) Dubbox(即Dubbo eXtensions)是当当网Fork基于d...

ChauncyNong's 优快云 Blog 2万+

Dubbo与DubboX区别

前世今生: Dubbo源于阿里的淘宝网开源的分布式的服务架构,致力于提供高性能和透明化的RPC远程服务调用方案,是SOA服务化治理方案的核心框架。淘宝网将其开源之后,得到了很多的拓展和支持(比较出名的有:当当网的扩展版本dubbox,京东的扩展版本jd-hydra等)           Dubbox(即Dubbo eXtensions)是当当网Fork基于dubbo2.x的升级版本,兼容原有的d...

呼吸的小鱼博客 715

dubbo kryo序列化_Dubbo与Dubbox的区别

Dubbo 是阿里巴巴公司开源的一个基于Java的高性能开源RPC框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。后来因为某些原因没有维护,于是当当网在这之上推出了自己的Dubbox。Dubbox 和Dubbo本质上没有区别,名字的含义扩展了Dubbo而已,以下扩展出来的功能,也是选择Dubbox很重要的考察点。支持REST风格远程调用(...

weixin_30010599的博客 247

使用Dubbox为dubbo提供REST服务

Dubbo 是阿里多年前开源的一套服务治理框架,在众多互联网企业里应用广泛。当当在dubbo的基础上开发了 dubbox (Dubbo eXtensions),支持REST风格远程调用。本文在 服务治理框架dubbo上手指南 的基础上使用dubbox提供的REST服务。  准备环境 首先参考 服务治理框架dubbo上手指南 ,实现自己的dubbo服务。在此基础上,让我们来看看在Dubbo中...

gqsunrise 242

Dubbo进阶(十一)—— Dubbo与DubboX区别

Dubbo进阶(十)—— Dubbo与DubboX区别 前世今生 &amp;nbsp;&amp;nbsp;Dubbo源于阿里的淘宝网开源的分布式服务架构,致力于提供高性能和透明化的RPC远程服务调用方案,是SOA服务化治理方案的核心框架。淘宝网将其开源之后,得到了很多的拓展和支持(比较出名的有:当当网的扩展版本dubbox,京东的扩展版本jd-hydra等)。 &amp;nbsp;&amp;nbsp;Dubbox(即Dubbo ...

IT全栈 华强工作室 8936

dubbox + springMVC

公告 Dubbo开源项目将得到官方重点维护,我们期待这个优秀的开源项目在未来持续保持活力,引领开源服务框架 Alibaba Dubbo Team 2017.07.31

曾经沧海难为水的博客 1178

浅谈Dubbox原理

Dubbox介绍 Dubbox是一个分布式服务框架,前身是阿里旗下的开源项目Dubbo,后来阿里停止维护,当当网在Dubbo的基础上进行优化,并继续维护,为了与原来的Dubbo区分故将其改名为Dubbox,当当网在其原有的基础上实现了一些新功能REST(Representational State Transfer)风格,REST调用也是的Dubbox可以对当今特别流行的&quot;微服务&quot;架构提供支持...

迷途的博客 3218

Dubbox框架使用手册

本文是自己初次学习dubbox时撰写的可能存在很多不足之处,希望各位大佬留言指点。

羽流云的博客 1950
上一篇: Dubbo架构设计详解
下一篇: 深度解析Java 8:JDK1.8 AbstractQueuedSynchronizer的实现分析(上)
weiythi
博客等级 码龄16年 23粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值