首页 文章 精选 留言 我的

精选列表

搜索[开源向量数据库],共10000篇文章
优秀的个人博客,低调大师

SDN开源框架:蝇量级选手Dragonflow究竟解决了什么问题

前言 SDN从2008年的openflow论文算起,发展到今天也算是门派众多,百花齐放。以重量级选手ODL,ONOS为代表的站在数据中心的高度对物理网络和虚拟网络进行云网一体化管理的,也有以DragonFlow,OVN为代表的蝇量级选手专注于数据中心虚拟网络管理的。今天的主角dragonflow采用分布式控制器架构,以流表的方式实现了neutron的dhcp、router、Security Group、namespace等,减小了计算资源的开销,缩短了数据包的转发路径,将数据包的转发从内核态抽离出来提高了转发效率。 我们先来简单了解一下neutron的网络方案及存在的问题,再看下dragonflow是怎么解决的。 Neutron 以集中式router下vxlan类型的子网为例 ●vm跨子网通信场景:数据包的转发路径如图中浅蓝色虚线条所示,数据包需要经过tap设备、Linux Bridge、ovs Bridge等设备,同时所有的跨子网东西向流量都要经过网络节点的qrouter转发。 ●南北流量场景:数据包的转发路径如图中红色虚线条所示,数据包同样需要N多虚拟设备,然后通过网络节点qrouer做nat映射后达到外网。 集中式router网络模型存在的问题,经过的网元设备太多,数据包每经过一次Linux类型的网元设备都要重新走一遍Linux内核网络协议栈,降低转发效率,同时跨子网的东西向流量和南北流量都需要汇聚到网络节点进行转发,网络节点必然成为网络带宽的瓶颈。同时由于安全组规则只能应用于Linux设备,qvb显得多余而又不得不存在。网络节点的瓶颈问题业界有一种解决方案是将vlan类型私有网络的网关置于外部物理硬件设备上,舍弃neutron的三层功能,达到vlan直通的效果,来规避这种瓶颈,那网络虚拟化的意义又在哪呢。 以分布式router下vxlan类型子网为例: 东西向流量转发场景:下图中红色和蓝色虚线条分别是同子网跨主机和跨子网跨主机的数据包转发路径,相比集中式router跨子网的场景数据包无需经过网络节点的转发,而是在计算节点的qrouter直接进行转发。 南北向流量转发场景:下图中黑色和绿色虚线条分别是浮动IP和snat南北流量数据包转发路径,浮动IP的南北流量不再需要经过网络节点,直接在计算节点经过qrouter到达fip namespace做nat转发,最终到达外网。snat南北流量和集中式是类似的。 DVR一定程度上缓解了网络节点带宽瓶颈的问题,东西/南北流量的转发也得到了提升,但是数据包经过的虚拟网元设备依然很多,同时namespace占用大量的计算资源。另外两个广播流量大户dhcp和arp,dhcp已经可以通过L2poplation实现vm在本计算节点得到arp响应,但是dhcp数据依然需求到网络节点相对应的dhcp namespace中获取响应,对链路的负载依然会造成影响。ok,dvr解决了一些问题,但依然不是最优的解决方案。那我们再看下dragonflow的解决方案。 Dragonflow 借用官方的一张图看一下dragonflow的架构: Dragonflow通过plugin和neutron对接,将Neutron DB模型转化为Dragonflow DB模型,本地控制器和Distribute DB同步网络拓扑和规则,SB DB Drivers和ovsdb交互,将配置编译成openflow流下发给ovs网元设备。其中L2、L3、dhcp app管理生成对应的流表给ovs网桥,实现与之对应的传统L2、L3、dhcp网络功能。需要指出的是,Dragonflow不需要原生neutron的namespace,iptables的nat以及除了dragonflow以外的任何代理进程。 dragonflow在计算节点用流表实现snat、dnat,dhcp后,网络节点不再需要,我们通过一张图对比一下neutron和dragonflow计算节点的网元图: 通过上图可以清晰的看到,dragonflow将neutron冗长的链路变的简单,缩短后的链路减少了数据包经过Linux device内核协议栈的转发次数。那么谁来实现这些网元设备的功能呢,请看下图。 Dragonflow的pipeline: 此图原链接: https://i.imgur.com/rMEoprK.png 在dragonflow的pipeline中其实就是流量统一导入table0,table0相当于一个流量分类器,将vm port、extenal port、tunnel port的流量进行分类,导入不同的功能table,table5处理port_security、table25处理arp请求、table30处理dhcp,table65 75 105 110 115共同完成东西流量的转发其中也包括安全组的处理等。关于dragonflow pipeline的详细细节在此不做详细说明,需要重点指出的是neutron和dragonflow在数据转发层面的网络模型是基本一致的,而dragonflow的本质就是用ovs 流表实现了传统虚拟网元设备所做的事情。这么做带来的价值是什么,不尽之处还请多加指点: 1.链路缩短一定程度上提高了数据包的转发效率(毕竟不是内核层面的改变), 2.不再需要namespace、iptables节省host的计算资源开销 3.arp,dhcp本地控制器下发流表直接响应,减小广播对物理链路的负载 4.不需要网络节点,节省设备资源 说了那么多的优势和带来的价值,也谈一下个人的一些看法和疑虑吧,比如:dragonflow采用分布式控制器架构,那么各个控制器之间的数据同步在大规模情况下可靠性怎么样?全流表化的实现方式,在数据庞大的数据中心,网络问题该如何快速定位?同时,所有的网络功能实现都依托于ovs,那么ovs的稳定性能不能达到要求。另外还有个问题值得我们思考商榷,sdn在云数据中心领域实现云网一体化这已经是一个明显的趋势,在此基础上个人认为,下一步将是业务管理分发、运维的高度自动化,智能化,便捷化,这个问题上,dragonflow目前或者是掉队了或者是有别的思路,不同的声音同时存在总是好的,谁又能说的准呢。最后,一句话结束此文:路漫漫其修远兮! 原文发布时间为:2018-11-9 本文作者:dragonfly 本文来自云栖社区合作伙伴“SDNLAB”,了解相关信息可以关注“SDNLAB”。

优秀的个人博客,低调大师

伯克利开源DeepMimic

还记得今年4月伯克利BAIR实验室发布的那个会“18般武艺”的DeepMimic模型吗?他们使用强化学习技术,用动作捕捉片段训练模型,教会了AI智能体完成24种动作,走路、跑步就不用说了,还包括翻跟斗、侧翻跳、投球、高踢腿等等高能动作。 体会一下: 训练每一种动作都需要动作捕捉和深度强化学习,而BAIR的研究者创造了一个全新的系统,教会agent完成复杂、逼真的动作任务。 作者Xue Bin Peng等人将这个系统命名为DeepMimic,比已有工作更进一步的是,他们的目标是在训练一个agent完成特定任务的前提下,使它的动作更贴近真实。他们的论文发表在SIGGRAPH 2018。 除了人形机器人外,他们还训练了Atlas机器人、暴龙、龙等形态的agent。 Atlas机器人 整个DeepMimic所需要的input分为三部分:一个被称为Ch

优秀的个人博客,低调大师

java使用比特币开源类库bitcoinj开发比特币入门指南

bitcoinj是一个使用比特币协议的库。它可以维护钱包,发送/接收交易而无需比特币核心的本地副本,并具有许多其他高级功能。它是用Java实现的,但可以通过任何JVM兼容语言中使用:包括Python和JavaScript中的示例。 它附带完整的文档,并建立了许多大型,众所周知的比特币应用程序和服务。下面我们来看看如何使用它。 初始设置 bitcoinj内置了日志记录和断言。无论是否指定了-ea标志,都会默认检查断言。记录由SLF4J库处理。它允许你选择你更喜欢使用的日志系统,例如JDK日志记录,Android日志记录等。默认情况下,我们使用简单的logger来打印stderr感兴趣的大部分内容。你可以通过切换lib目录中的jar文件来选择一个新的logger。 bitcoinj使用Maven作为其构建系统,并通过git分发。你可以使用源代码/ jar下载,但直接从源存储库获取它更安全。 要获取代码并安装它,请抓取Maven或Gradle,并将其添加到你的路径中。还要确保安装了git。可能你的Java IDE也有一些Maven/Gradle和Git集成,但是通过命令行使用它们还是非常有用。 现在获取最新版本的代码。你可以使用使用Maven或使用Gradle页面上的说明——只需在那里运行命令,你就可以获得正确的代码版本(除非此网站本身已被泄露)。这是为了防止受损镜像或源代码下载——因为git使用源树哈希工作,如果以正确的方式获得源哈希,则可以保证最终得到正确的代码。 你可以在这里阅读完整的程序。 基本结构 bitcoinj应用程序使用以下对象: NetworkParameters实例,用于选择你所在的网络(生产或测试)。 用于存储ECKeys和其他数据的Wallet实例。 用于管理网络连接的PeerGroup实例。 一个BlockChain实例,它管理共享的全局数据结构,使比特币工作。 一个BlockStore实例,它将块链数据结构保存在某个位置,就像在磁盘上一样。 WalletEventListener实现,用于接收钱包交易。 为了简化设置,还有一个WalletAppKit对象可以创建上述对象并将它们连接在一起。虽然可以手动执行此操作(对于大多数“真实”应用程序),但此演示应用程序会显示如何使用应用程序工具包。 让我们看看代码,看看它是如何工作的。 设置 我们使用实用程序函数将log4j配置为具有更紧凑,更简洁的日志格式。然后我们检查命令行参数。 BriefLogFormatter.init(); if (args.length < 2) { System.err.println("Usage: address-to-send-back-to [regtest|testnet]"); return; } 然后我们根据可选的命令行参数选择我们将要使用的网络: // Figure out which network we should connect to. Each one gets its own set of files. NetworkParameters params; String filePrefix; if (args[1].equals("testnet")) { params = TestNet3Params.get(); filePrefix = "forwarding-service-testnet"; } else if (args[1].equals("regtest")) { params = RegTestParams.get(); filePrefix = "forwarding-service-regtest"; } else { params = MainNetParams.get(); filePrefix = "forwarding-service"; } 有多个独立的,独立的比特币网络: 人们买卖东西的主要或“生产”网络。 公共测试网络(testnet)不时被重置并存在以供我们使用新功能。 回归测试模式,它不是公共网络,需要你自己运行带有-regtest标志的比特币守护进程。 每个网络都有自己的创世块,自己的端口号和自己的地址前缀字节,以防止你不小心尝试通过网络发送比特币(这将无法正常工作)。这些事实被封装到NetworkParameters单例对象中。如你所见,每个网络都有自己的类,你可以通过在其中一个对象上调用get()来获取相关的NetworkParameters对象。 强烈建议你在testnet上或使用regtest模式开发软件。如果你不小心丢失了测试比特币,这没什么大不了的,因为它们毫无价值,你可以从TestNet Faucet免费获得大量的比特币。确保在完成后将比特币送回水龙头,以便其他人也可以使用它们。 在regtest模式下,没有公共基础设施,但是你可以随时获得一个新的块而不必等待一个通过在regtest模式bitcoind运行的同一台机器上运行bitcoind -regtest setgenerate true。 密钥和地址 比特币交易通常将钱汇入公共椭圆曲线键。发件人创建包含收件人地址的交易,其中地址是其公钥哈希的编码形式。接收者然后签署一个交易,用他们自己的私钥声明比特币。密钥用ECKey类表示。ECKey可以包含私钥,或只包含缺少私有部分的公钥。请注意,在椭圆曲线加密中,公钥是从私钥派生的,因此知道私钥本身也意味着知道公钥。这与你可能熟悉的其他一些加密系统不同,例如RSA。 地址是公钥的文本编码。实际上,它是公钥的160位hash,具有版本字节和一些校验和字节,使用名为base58的比特币特定编码编码到文本中。Base58旨在避免在写下时可能相互混淆的字母和数字,例如1和大写i。 // Parse the address given as the first parameter. forwardingAddress = new Address(params, args[0]); 由于地址对要为其使用密钥的网络进行编码,因此我们需要在此处传递网络参数。第二个参数只是用户提供的字符串。如果构造函数不可解析或者网络错误,它将抛出钱包应用套件例外。 bitcoinj由各种层组成,每层都在比最后一层更低的层次上运行。想要发送和接收资金的典型应用程序至少需要BlockChain,BlockStore,PeerGroup和Wallet。所有这些对象需要相互连接,以便数据正确流动。阅读如何融合在一起,了解有关数据如何通过基于bitcoinj的应用程序流动的更多信息。 为了简化这个过程(通常是样板文件),我们提供了一个名为WalletAppKit的高级打包器。它在简化的支付验证模式(而不是完全验证)中配置bitcoinj,这是此时选择的最合适的模式。除非你是专家并且希望尝试(不完整的,可能是错误的)完整模式,它提供了一些简单的属性和钩子,允许你修改默认配置。 将来,可能会有更多的工具包为不同类型的应用程序配置bitcoinj,这些应用程序可能有不同的需求。但就目前而言,只有一个。 // Start up a basic app using a class that automates some boilerplate. Ensure we always have at least one key. kit = new WalletAppKit(params, new File("."), filePrefix) { @Override protected void onSetupCompleted() { // This is called in a background thread after startAndWait is called, as setting up various objects // can do disk and network IO that may cause UI jank/stuttering in wallet apps if it were to be done // on the main thread. if (wallet().getKeyChainGroupSize() < 1) wallet().importKey(new ECKey()); } }; if (params == RegTestParams.get()) { // Regression test mode is designed for testing and development only, so there's no public network for it. // If you pick this mode, you're expected to be running a local "bitcoind -regtest" instance. kit.connectToLocalHost(); } // Download the block chain and wait until it's done. kit.startAsync(); kit.awaitRunning(); 该工具包有三个参数 - NetworkParameters(几乎所有库中的API都需要这个),一个用于存储文件的目录,以及一个以任何创建文件为前缀的可选字符串。如果你希望保持分隔的同一目录中有多个不同的bitcoinj应用程序,这将非常有用。在这种情况下,文件前缀是“forwarding-service”加上网络名称,如果不是主网络(参见上面的代码)。 它还提供了一个可覆盖的方法,我们可以将自己的代码放入其中,以自定义它为我们创建的对象。我们在这里覆盖它。请注意,appkit实际上将在后台线程上创建和设置对象,因此也会从后台线程调用onSetupCompleted。 在这里,我们只需检查钱包是否至少有一个密钥,如果没有,我们会添加一个新密钥。如果我们从磁盘加载钱包,那么当然不会采用此代码路径。 接下来,我们检查我们是否使用regtest模式。如果我们是,那么我们告诉套件只连接到本地主机,其中预计会在regtest模式下运行bitcoind。 最后,我们调用kit.startAsync()。 WalletAppKit是一种番石榴服务。 Guava是Google广泛使用的实用程序库,它增加了标准Java库以及一些有用的附加功能。服务是一个可以启动和停止的对象(但只能启动一次),并且可以在完成启动或关闭时接收回调。你也可以阻止调用线程,直到它以awaitRunning()启动,这就是我们在这里所做的。 当块链完全同步时,WalletAppKit将认为自己已经启动,这有时需要一段时间。你可以了解如何加快速度,但对于玩具演示应用程序,不需要实现任何额外的优化。 该工具包上有访问器,可以访问它配置的底层对象。在类启动或启动过程之前,你不能调用它们(它们将断言),因为不会创建对象。 应用程序启动后,你会注意到应用程序运行的目录中有两个文件:.wallet文件和.spvchain文件。他们走在一起,决不能分开。 处理交易 我们想知道什么时候收到钱,所以我们可以转发它。这是一个交易,与bitcoinj中的大多数Java API一样,你通过注册事件侦听器event listeners来了解交易,事件侦听器只是实现接口的对象。库中有一些交易监听器接口: WalletEventListener:用于发生在钱包中的事情。 BlockChainListener:用于与块链相关的交易。 PeerEventListener:用于与网络中的对等方相关的交易。 TransactionConfidence.Listener:用于与交易具有的回滚安全级别相关的交易。 大多数应用程序不需要使用所有这些。因为每个接口都提供一组相关交易,你可能并不关心所有这些交易。 kit.wallet().addCoinsReceivedEventListener(new WalletCoinsReceivedEventListener() { @Override public void onCoinsReceived(Wallet w, Transaction tx, Coin prevBalance, Coin newBalance) { // Runs in the dedicated "user thread". } }); bitcoinj中的交易在专用的后台线程中运行,该线程仅用于运行事件侦听器,称为user thread用户线程。这意味着它可以与应用程序中的其他代码并行运行,如果你正在编写GUI应用程序,则意味着你不能直接修改GUI,因为你不在GUI或main主线程中。但是,事件侦听器本身不需要是线程安全的,因为交易将按顺序排队并执行。你也不必担心使用多线程库时通常会出现的许多其他问题(例如,重新进入库是安全的,并且可以安全地执行阻塞操作)。 关于编写GUI应用程序的说明 大多数小工具工具包(如Swing,JavaFX或Android)都具有所谓的线程关联,这意味着你只能在单个线程中使用它们。要从后台线程返回到主线程,通常会将闭包传递给某个实用程序函数,该函数调度在GUI线程空闲时运行的闭包。 为了简化使用bitcoinj编写GUI应用程序的任务,你可以在注册事件侦听器listener时指定任意Executor。将要求该执行程序运行事件侦听器。默认情况下,这意味着将给定的Runnable传递给用户线程,但你可以像这样覆盖: Executor runInUIThread = new Executor() { @Override public void execute(Runnable runnable) { SwingUtilities.invokeLater(runnable); // For Swing. Platform.runLater(runnable); // For JavaFX. // For Android: handler was created in an Activity.onCreate method. handler.post(runnable); } }; kit.wallet().addEventListener(listener, runInUIThread); 现在,listener上的方法将自动在UI线程中调用。 因为这可能会重复且烦人,你还可以更改默认执行程序,因此所有交易始终在你的UI线程上运行: Threading.USER_THREAD = runInUIThread; 在某些情况下,bitcoinj可以非常快速地生成大量交易,这在将块链与具有大量交易的钱包同步时是典型的,因为每个交易都可以生成交易可信度confidence更改交易(因为它们隐藏的很深)。未来钱包交易的工作方式很可能会改变以避免这个问题,但是现在这就是API的工作方式。如果用户线程落后,则当事件侦听器listener调用在堆上排队时,可能会发生内存膨胀。为避免这种情况,你可以使用Threading.SAME_THREAD作为执行程序注册交易处理程序,在这种情况下,它们将立即在bitcoinj控制的后台线程上运行。但是,在使用此模式时必须格外小心——代码中出现的任何异常都可能会解开bitcoinj堆栈并导致对等断开连接,同样,重新进入库可能会导致锁定反转或其他问题。通常你应该避免这样做,除非你真的需要额外的表现,并确切知道你在做什么。 收钱 kit.wallet().addCoinsReceivedEventListener(new WalletCoinsReceivedEventListener() { @Override public void onCoinsReceived(Wallet w, Transaction tx, Coin prevBalance, Coin newBalance) { // Runs in the dedicated "user thread". // // The transaction "tx" can either be pending, or included into a block (we didn't see the broadcast). Coin value = tx.getValueSentToMe(w); System.out.println("Received tx for " + value.toFriendlyString() + ": " + tx); System.out.println("Transaction will be forwarded after it confirms."); // Wait until it's made it into the block chain (may run immediately if it's already there). // // For this dummy app of course, we could just forward the unconfirmed transaction. If it were // to be double spent, no harm done. Wallet.allowSpendingUnconfirmedTransactions() would have to // be called in onSetupCompleted() above. But we don't do that here to demonstrate the more common // case of waiting for a block. Futures.addCallback(tx.getConfidence().getDepthFuture(1), new FutureCallback<TransactionConfidence>() { @Override public void onSuccess(TransactionConfidence result) { // "result" here is the same as "tx" above, but we use it anyway for clarity. forwardCoins(result); } @Override public void onFailure(Throwable t) {} }); } }); 在这里我们可以看到当我们的应用收到钱时会发生什么,我们打印出我们收到了多少,使用静态实用程序方法格式化为文本。 然后我们做了一些更先进的事情。我们称之为这种方法: ListenableFuture<TransactionConfidence> future = tx.getConfidence().getDepthFuture(1); 每个交易都有一个与之关联的confidence对象。confidence的概念体现了比特币是一个全球共识系统这一事实,该系统不断努力就全球交易顺序达成一致。因为这是一个难题(当遇到恶意行为者时),交易可能会被双倍花费(在比特币术语中我们说它已经dead)。也就是说,我们有可能相信我们已经收到了钱,后来我们发现世界其他地方不同意我们的看法。 Confidence对象包含我们可以用来做出基于风险的决策的数据,这些决策是关于我们实际收到钱的可能性。它们还可以帮助我们在信心变化或达到某个阈值时学习。 Futures是并发编程中的一个重要概念,bitcoinj大量使用它们,特别是我们将Guava扩展用于标准的Java Future类,称为ListenableFuture。ListenableFuture表示未来某种计算或状态的结果。你可以等待它完成(阻止调用线程),或者注册将被调用的回调。期货也可能会失败,在这种情况下,你会收到异常而不是结果。 在这里,我们要求depth future。当交易被链中的至少那么多块掩埋时,这个future就完成了。深度为1表示它出现在链中的顶部块中。所以在这里,我们说“当交易至少有一个确认时运行此代码”。通常你会使用一个名为Futures.addCallback的实用工具方法,虽然还有另一种注册监听器的方法,可以在下面的代码片段中看到。 然后,当发送给我们钱的交易确认时,我们只调用一个我们自己定义的方法叫做forwardCoins。 这里有一件重要的事情需要注意。depth future可能会运行,然后交易的depth变为小于future的参数。这是因为在任何时候比特币网络都可能经历“重组”,其中最着名的链从一个切换到另一个。如果你的交易出现在新链中的其他位置,则depth实际上可能会下降而不是向上。处理入库付款时,你应确保如果交易信心下降,你会尝试中止你为该资金提供的任何服务。你可以通过阅读SPV安全模型了解有关此主题的更多信息。 处理re-orgs和double spends是一个复杂的主题,本教程未涉及。你可以通过阅读其他文章了解更多信息。 发送比特币 ForwardingService的最后一部分是发送我们刚刚收到的比特币。 Coin value = tx.getValueSentToMe(kit.wallet()); System.out.println("Forwarding " + value.toFriendlyString() + " BTC"); // Now send the coins back! Send with a small fee attached to ensure rapid confirmation. final Coin amountToSend = value.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE); final Wallet.SendResult sendResult = kit.wallet().sendCoins(kit.peerGroup(), forwardingAddress, amountToSend); System.out.println("Sending ..."); // Register a callback that is invoked when the transaction has propagated across the network. // This shows a second style of registering ListenableFuture callbacks, it works when you don't // need access to the object the future returns. sendResult.broadcastComplete.addListener(new Runnable() { @Override public void run() { // The wallet has changed now, it'll get auto saved shortly or when the app shuts down. System.out.println("Sent coins onwards! Transaction hash is " + sendResult.tx.getHashAsString()); } }); 首先,我们查询我们收到多少钱(当然,由于我们的应用程序的性质,这与上面的onCoinsReceived回调中的newBalance相同)。 然后我们决定发送多少——它与我们收到的相同,减去费用。我们不需要附加费用,但如果我们不这样做,可能需要一段时间才能确认。默认费用很低。 要发送比特币,我们使用钱包sendCoins方法。它需要三个参数:TransactionBroadcaster(通常是PeerGroup),发送比特币的地址(这里我们使用我们之前从命令行解析的地址)以及要发送多少钱。 sendCoins返回一个SendResult对象,该对象包含已创建的交易和一个ListenableFuture,可用于查明网络何时接受付款。如果钱包没有足够的钱,sendCoins方法将抛出一个异常,其中包含一些关于缺少多少钱的信息。 自定义发送过程和设置费用 比特币交易可以附加费用。这对于反拒绝服务机制很有用,但它主要是为了在通货膨胀率下降时激励系统后期的采矿。你可以通过自定义发送请求来控制附加到交易的费用: SendRequest req = SendRequest.to(address, value); req.feePerKb = Coin.parseCoin("0.0005"); Wallet.SendResult result = wallet.sendCoins(peerGroup, req); Transaction createdTx = result.tx; 请注意,在这里,我们实际上设置了每千字节创建的交易的费用。这就是比特币的工作原理——交易的优先级由费用除以大小决定,因此较大的交易要求较高的费用被视为与较小的交易“相同”。 写在最后 bitcoinj还有许多其他功能,本教程不涉及这些功能。你可以阅读其他文章以了解有关完整验证,钱包加密等的更多信息,当然JavaDocs还详细介绍了完整的API。 php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。 java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。 汇智网原创翻译,转载请标明出处。这里是原文

优秀的个人博客,低调大师

开源大数据周刊-2018年08月10日 第96期

资讯 阿里云E-MapReduce新版工作流管理正式上线 新版E-MapReduce工作流管理功能正式发布上线,工作流调度和编排是大数据开发的重要场景。此次升级新增作业DAG执行,作业临时查询等功能,拖拽编辑工作流节点等功能,在作业并行化缩短执行时间,提升了易用性。欢迎了解更多E-MapReduce产品详情。 2018 Gartner全球云存储魔力象限解读:阿里云跃升至挑战者 云存储催热数据湖 7月外媒披露了最新的Gartner全球云存储魔力象限,全球前四依然是亚马逊AWS、微软Azure、谷歌GCP和阿里云,与去年相比最大变化是,谷歌和阿里云各自跃升了一个象限,分别跻身领导者和挑战者象限,这是中国云计算厂商首次进入Gartner云存储挑战者象限。 TensorFlow 版本 1.10.0 发布 TensorFlow 1.10 预构建二进

优秀的个人博客,低调大师

开源大数据周刊-2018年08月03日 第95期

资讯 Apache Kafka 2.0.0 正式发布,分布式消息发布订阅系统 Apache Kafka 2.0.0 已正式发布,这是一个主要版本,新增了许多重要的新功能。此外还包括许多重要的 bug 修复和改进,其中还包括一些严重的错误修复。 如何解决AI的大数据困境?杨强提出联邦迁移学习 2018中国人工智能大会在深圳举行。会上,国际人工智能联合会(IJCAI)主席、AAAI/ACM/IEEE Fellow、香港科技大学教授杨强发表了题为《AI面临的挑战和迁移学习所带来的机遇》的演讲,谈到了AI发展遇到的大数据的困境以及解决办法。 Tableau发布2018.2版本 可拖放第三方应用功能到仪表板 Tableau公司近日推出Tableau 2018.2版本更新,该更新的扩展API能够让用户直接拖放第三方应用功能到仪表板。此外,在新推出的Tab

优秀的个人博客,低调大师

腾讯开源大规模 Node.js 微服务框架 Tars.js

随着互联网的发展,越来越多的业务不仅仅由单一节点(或是单一语言)就可承载,而是趋向多语言分布式协同开发(如接入层由 Node.js 完成,逻辑(数据)层由 C++/GO/Python 实现)并由此组成大型异构系统。 腾讯(现 SuperTeam)基于 Tars 体系研发出 Tars.js 以便用户在不改变异构系统整体架构的情况下快速搭建(迁移) Node.js 服务,并可非常方便的将原来的单一服务拆分为多个(逻辑)子服务。 Tars.js 特性 Tars.js 包含下述特性:● 100% 由 JavaScript 编写,不包含任何 C/C++ 代码。● 多进程负载均衡与管理。● 代码异常监控与重启。● 服务日志搜集与处理。● HTTP(s) 服务监控与用量自动上报,并支持用户自定义维度上报(PP 监控)。● 符合 Tars(IDL) 规范的编解码模块。● 支持 Tars RPC 调用与染色(模调自动上报)。● 支持在线发送管理命令、拉取服务配置。● 独创 LongStackTrace™ 异常跟踪机制。● …… 设计理念 高自由度● 兼容所有(≥0.10)官方 Node.js 版本。● 对 Node.js 源码无侵入无修改。● 底层对上层完全透明,支持各种上层框架,无需变更。 也就是说: 您可以使用任何您熟悉的框架(如 Express.js / Koa.js 等,包括但不仅限于 Web 框架),也无需对框架进行任何修改(无需引入任何中间件)。 即可通过 Tars.js 运行,享受平台提供的各种监控与管理特性。 与此同时,Tars.js 所提供的模块,也可以根据您的需求引入(如未使用到则可不引入)。 高性能Tars.js 为高性能与大并发量而设计,使用了大量的前端(V8)优化技巧(如 FlattenString/FastProperties 等)尽量降低所提供的能力对于业务性能的影响。 经过测试(Web Server),默认的旁路上报与监控对服务性能的影响≤ 5%,常用模块(RPC、日志等)性能位于业界前列。 差异化● Tars.js 根据不同的业务类型提供差异化运营方案:● 高流量业务:尽力降低框架对业务性能的影响。● 低流量业务:充分利用硬件资源提升开发体验。 团队介绍 SuperTeam 来自于腾讯 QQ 浏览器前端团队,由 @SuperZheng 创立于 2017 年。 团队成员均为全栈架构师,熟知 Web(3D) 、终端、后端与大数据计算,并由传统前端向互联网从业者方向发展。 Hello World 1、在 Tars 平台 -> 服务管理 -> 服务上线,上线一个新服务: 服务基本信息:● 服务名称:HelloWorld● 服务类型:NODEJS● 模板名称:tars.default OBJ 部署信息:● OBJ名称:HttpObj● 是TARS:选择否(移除复选框)● 端口:自动生成端口 2、安装 @tars/deploy 打包工具。 npm i -g @tars/deploy 3、根据业务需求以及您的喜好选择框架(!Tars.js 不限制您使用的框架!),编写业务代码: const http = require('http'); const hostname = process.env.IP || '127.0.0.1'; const port = process.env.PORT || 3000; const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello World '); }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); }); 上述为 Node.js 官网 HTTP Server 例子,在 Tars.js 平台上运行只需要修改 IP 和端口即可。 这里在环境变量中获得到的 IP 和 PORT 即为您在第一步配置的 OBJ 部署信息中的 IP 与端口。 在项目根目录下执行打包工具,即可生成发布包 HelloWorld.tgz: tars-deploy HelloWorld 5、在 Tars 平台上选择您刚刚创建的服务 -> 发布管理 -> 手动上传发布包,然后发布此版本即可。 6、通过您在第一步配置的 IP 与 端口即可访问您的服务。 Tars.js应用领域 Tars.js 在腾讯内部经过 5 年多的沉淀与迭代(Node.js@0.10版本即提供支持),广泛运用于腾讯QQ浏览器、腾讯桌面浏览器、腾讯地图、应用宝、腾讯手机管家、互联网+、腾讯医疗、腾讯觅影、保险、彩票等几十个重要业务中,日承担了上百亿流量。 原文发布时间为:2018-08-02本文作者:前端大学本文来自云栖社区合作伙伴“前端大学”,了解相关信息可以关注“前端大学”。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册