公证服务信息_使用多个公证员提高网络吞吐量

公证服务信息

您是否需要高吞吐量的Corda网络? 网络的吞吐量是否稳定? 您是否已经从其他领域挤出了所有可能的表现? 如果您对这些问题的回答是“是”,那么我可能会为您提供一些有用的信息。 我列出了这些问题,以减少您过早优化Corda网络/应用程序的机会。 如果它是处理请求/事务中最慢的部分之一,则切换到使用多个公证人只会对性能产生显着影响。 在考虑使用多个公证人之前,很可能需要改进其他方面。

在我继续之前。 我真的需要这么说。 在本文中,我并不是在谈论使用公证集群,该公证集群由相互沟通以就是否使用过国家达成共识的公证人组成。 我说的是有多个公证人,每个公证人都有自己的身份,这些公证人仅与向其发送交易以进行验证的节点进行交互。 这种区别必须加以区分,并且应该消除对我将在本文中准确描述的任何混淆。

在撰写本文时,Corda的当前版本为:

  • 开源3.3
  • 企业3.2

我为什么要这样做?

好吧 让我们真正深入探讨为什么要使用多个公证人。 图表最能做到这一点,所以让我们使用一个:

多个公证人

具有一个公证人的网络的简单视图

这种情况看起来不太好。 但是,实际上可能并不那么糟糕。 如果网络的吞吐量不是很高,则此体系结构应该能够处理通过公证人的事务。

如引言中所述。 当发送到公证人的交易率变得很高时,这成为一个问题。 一旦达到这一点,公证人将开始落后。 因为它不能足够快地验证事务中的状态。 如果性能对网络很重要,那么这是检查的好地方。

从代码角度来看,这是您可能已经在编写CorDapps的标准格式。 您可以根据特定条件选择公证人,然后在其中发送交易。 您所处理的整个网络中甚至可能只有一个公证人。 例如,在编写类似于以下代码的代码之前,在我编写的所有代码示例中,它们仅依赖于网络中的单个公证人,每次都盲目地使用那个。

private fun notary(): Party = serviceHub.networkMapCache.notaryIdentities.first()

切换到多个公证人

从依赖一个公证人的网络过渡到一个由许多公证人组成的设计,从根本上讲,需要两件事:

  • 网络中有多个公证人。
  • 一种选择向哪个公证人发送交易的算法。

此外,如果使用状态,则将来的交易会参考为交易选择的公证人。 如果最终遇到消耗了来自不同公证人的输入状态的情况,则必须执行公证人变更事务。 稍后我将讨论这个主题。

下面是如何将先前的设计更改为使用一些公证人的方法:

多个公证人

具有多个公证人的网络的简化视图

关于此图的最好之处在于,它说明了向网络添加另一个公证人并在其中重新分配负载是多么简单。 没有什么可以阻止我们向网络中添加越来越多的公证人。 但是,在某些情况下添加更多内容不会导致性能提高。 这一直回到我之前提到的内容。 添加更多的公证人只会在公证人本身达到饱和时增加吞吐量。

为发行交易选择公证人

以下是选择使用哪种公证人的可能算法:

private fun transaction(): TransactionBuilder =TransactionBuilder(notary()).apply {addOutputState(message, MessageContract.CONTRACT_ID)addCommand(Send(), message.participants.map(Party::owningKey))}private fun notary(): Party {val index = message.type.hashCode() % serviceHub.networkMapCache.notaryIdentities.sizereturn serviceHub.networkMapCache.notaryIdentities.single { it.name.organisation == "Notary-$index" }
}

在此示例中,事务根据输入状态的属性之一的hashCode和网络中的公证人数来选择要使用的公证人。

选择公证人的方式可以根据需要简单或复杂。 这将取决于要求,例如对于提议的交易仅信任一部分公证人,或者对网络变化中的公证人具有弹性。

从同一公证人消费状态时选择公证人

这是很好而且很简单的…如果所有输入状态都引用同一个公证人。 下面是它的外观(此示例仅使用一个输入…,因为我懒于编写另一个版本):

private fun transaction(response: MessageState): TransactionBuilder =TransactionBuilder(notary()).apply {addInputState(message)addOutputState(response, MessageContract.CONTRACT_ID)addCommand(Reply(), response.participants.map(Party::owningKey))}private fun notary(): Party = message.state.notary

如您所见,所有事务要做的就是检索与输入状态相关的公证人并将其用于自身。 可以提取此信息,因为messageStateAndRef ,访问其state属性将返回TransactionState 。 遵循这种格式。 创建消耗状态并产生大量输出的新事务非常简单。 此格式对于多个输入状态也有效。 当且仅当它们都引用同一个公证人。

因此……讨论所有带有不同公证人的输入状态。 我可能应该进一步讨论。

消费来自不同公证人的状态时选择公证人

在这里我们必须要小心,否则我们将看到类似以下错误:

java.lang.IllegalArgumentException: Input state requires notary "O=Notary-1, L=London, C=GB" which does not match the transaction notary "O=Notary-0, L=London, C=GB".

该错误表明输入状态与包含它的事务没有相同的公证人。

要解决此错误,我们需要使用公证更改交易。 根据文档:

“用于更改州公证人的流程。 这是必需的,因为事务的所有输入状态必须指向同一公证人。”

我想把它放在那里,以防万一你以为我是个骗子!

执行公证变更交易的代码如下所示:

@Suspendable
private fun notaryChange(message: StateAndRef<MessageState>,notary: Party
): StateAndRef<MessageState> =if (message.state.notary != notary) {subFlow(NotaryChangeFlow(message,notary))} else {message}

我相信您可以弄清楚自己的状况,但是要使自己变得更加聪明……我将告诉您。 message表示输入状态, notary是新交易将使用的公证人。 如果公证人相同,则可以返回状态,因为无需对其进行任何操作。 如果它们确实不同,则调用NotaryChangeFlow ,它接受传递给原始函数的两个参数。 这将返回一个新的StateAndRef ,然后从函数中返回它。

然后可以将从此函数返回的StateAndRef放入事务中。

如果您不确定传递到事务中的状态是否来自同一公证人,那么建议您坚持使用本节中的代码。 选择事务将使用的公证人(无论是特定的还是从输入状态中获取的公证人),然后对任何需要进行公证的事务执行公证变更事务。 例如,我认为类似于下面的代码将提供一个通用且健壮的解决方案:

@Suspendable
private fun transaction(): TransactionBuilder {val messages = getMessageStates()val notary = notary()return TransactionBuilder(notary).apply {messages.forEach {addInputState(notaryChange(it, notary))}addCommand(Delete(),(messages.flatMap { it.state.data.participants }.toSet() + ourIdentity).map(Party::owningKey))}
}@Suspendable
private fun notaryChange(message: StateAndRef<MessageState>,notary: Party
): StateAndRef<MessageState> =if (message.state.notary != notary) {subFlow(NotaryChangeFlow(message,notary))} else {message}// however you want to choose your specific Notary
private fun notary(): Party =serviceHub.networkMapCache.notaryIdentities.single { it.name.organisation == "Notary-1" }

在这里,为交易选择了一个特定的公证人,如果需要,每个输入的公证人都将更改为所选公证人,并且签名者包括消费状态的所有参与者。 这可能不适合您自己的用例。 很好。 但是,这在为不断变化的公证人服务时(主要是为了提高性能)应该是一个很好的起点。

稍稍更改此解决方案,我们可以改为根据输入状态参考的“公证人”来选择“公证人”。 由于只有notary功能确实需要更改,因此我从示例中排除了其余代码。

private fun notary(messages: List<StateAndRef<MessageState>>): Party =messages.map { it.state.notary }.groupingBy { it }.eachCount().maxBy { (_, size) -> size }?.key ?: throw IllegalStateException("No Notary found")

此功能选择的公证人是根据输入状态共享的最常见的公证人来决定的。 这样一来,所需的公证变更交易就更少了,因为大多数输入已经引用了所选公证。 如果您不知道输入引用的是哪个公证人,这应该提供最佳性能。

结论

在Corda网络中实现高性能取决于消除系统中的瓶颈和其他常规性能调整。 公证人就是这样一个瓶颈。 在非常高的吞吐量通过公证人的情况下,网络的性能将开始达到平稳状态。 公证人不能以传入的速率足够快地处理请求。移动使用共享请求负载的多个公证人将提高网络的性能。 这在确定使用哪个公证人时带来了额外的复杂性,并可能需要公证人变更事务。 但是,如果您的网络确实需要实现高吞吐量。 这将是一个值得研究的领域。

我将在这里发表最后的评论。 随着公证人内部性能的提高,对这种体系结构的需求将减少。 甚至可能达到这样一个程度,即一个公证人能够完全处理大量传入请求。 随着Corda不断提高其整体性能,这是一个值得关注的领域。

这篇文章中使用的代码可以在我的GitHub上找到 。

翻译自: https://www.javacodegeeks.com/2018/11/increasing-network-multiple-notaries.html

公证服务信息

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/332803.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java判断手机号_java使用正则表达式判断手机号的方法示例

本文实例讲述了java使用正则表达式判断手机号的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;要更加准确的匹配手机号码只匹配11位数字是不够的&#xff0c;比如说就没有以144开始的号码段&#xff0c;故先要整清楚现在已经开放了多少个号码段&#xff0c;国家号…

Spring JDBC的学习

文章目录介绍使用步骤常用方法示例代码介绍 所谓 Spring JDBC&#xff0c;是 Spring 框架对 JDBC 的简单封装。提供了一个 JdbcTemplate 对象简化 JDBC 的开发。 使用步骤 步骤&#xff1a; 1.导入相关的 jar 包 2.创建 JdbcTemplate 对象&#xff0c;依赖于数据源 DataSo…

编写脚本电脑怎么编写界面_在任何无法理解的情况下,请编写脚本

编写脚本电脑怎么编写界面脚本编写是使您的应用程序在运行时就可根据客户需求进行调整的最流行的方法之一。 与往常一样&#xff0c;此方法不仅带来好处&#xff0c;例如&#xff0c;在灵活性和可管理性之间存在众所周知的折衷方案。 本文不是从理论上讨论优缺点的文章之一&…

stack java实现_Stack (堆栈)使用JAVA实现

代码如下&#xff1a;import java.util.AbstractList;import java.util.Arrays;import java.util.Iterator;import java.util.List;import java.util.RandomAccess;public class Stack extends AbstractListimplements List, RandomAccess, Cloneable, java.io.Serializable{pr…

HTML特殊符号/特殊字符

注&#xff1a;实体名称大小写敏感 点击查看更多特殊字符

访客模式 无痕模式 区别_旧访客设计模式的新生活

访客模式 无痕模式 区别介绍 访客 [1、2]是众所周知的经典设计模式。 有很多资源对其进行了详细说明。 在不深入研究实现的情况下&#xff0c;我将简要提醒一下该模式的概念&#xff0c;解释其优点和缺点&#xff0c;并提出一些可以使用Java编程语言轻松应用于其的改进。 古典…

HTML的图片标签img的图片地址

使用相对路径&#xff0c;例如&#xff0c;当前目录中的子目录 image 中的图片 1.jpg&#xff0c;可以写成 ./image/1.jpg&#xff0c;其中 ./ 表示当前目录&#xff0c;可以省略不写。 <img src"image/1.jpg"/>实际上HTML文档数据写入到 Response 中时&#…

java swing 左上角图标_科学网—Matlab: 学习GUI(修改窗口左上角图标而不warning) - 刘磊的博文...

网上常用的方法&#xff1a;if ~isdeployednewIconjavax.swing.ImageIcon(.piciap.jpg);elsenewIconjavax.swing.ImageIcon(iap.jpg);endjFrame get(hObject,javaframe);jFrame.setFigureIcon(newIcon);运行后warning&#xff1a;Warning: figure JavaFrame property will be …

pbfunc外部扩展函数_从外部CorDapp扩展和覆盖流

pbfunc外部扩展函数Corda 4于上周&#xff08;2月21日&#xff09;发布&#xff0c;带来了大量的新功能&#xff0c;使Corda更加令人愉快。 老实说&#xff0c;我有点假设有很多新功能。 我快速浏览了变更日志&#xff0c;主要是看到我的贡献被引用&#xff0c;但是我记得看到很…

表单项标签的input标签的单选框(radio)

<input type"radio" name"gender" value"male"> 男 <input type"radio" name"gender" value"female"> 女1.单选框需要注意的是&#xff0c;如果是属于一组的选项&#xff0c;那么 name 属性的值必须相…

java 6 update 3_Java(TM) 6 Update(java运行环境) V 6.0.450.6 官方版

Java(TM) 6 Update是个JAVA辅助软件&#xff0c;它具备高度的安全性以及跨平台的特性&#xff0c;能让你的电脑或手机运行java程序&#xff0c;用户可使用Java(TM) 6 Update来搭建甚至运行整个ava程序&#xff0c;注意&#xff1a;卸载后JAVA环境的程序将无法运行。过去很可能会…

jep290涉及jdk版本_JDK 9 / JEP 280:字符串串联永远不会相同

jep290涉及jdk版本JEP 280 &#xff08;“ Indify String Concatenation”&#xff09;是与JDK 9一起实现的&#xff0c;根据其“摘要”部分&#xff0c;“更改了javac生成的静态String concatenation字节码序列&#xff0c;以使用对JDK库函数的invokedynamic调用。 ” 通过查看…

label标签/标记

label 标签用于指定表单项的文字描述信息&#xff0c;如下所示&#xff1a; <label for"username">用户名称&#xff1a;</label> <input id"username" name"username">label 标签 的 for 属性指定的值与 input 标签的 id 属…

矩阵累积相乘 java_累积:轻松自定义Java收集器

矩阵累积相乘 javaAccumulative是针对Collector<T, A, R>的中间累积类型A提出的接口Collector<T, A, R>以使定义自定义Java Collector更加容易。 介绍 如果您曾经使用过Java Stream &#xff0c;那么很可能会使用了一些Collector &#xff0c;例如&#xff1a; C…

java socket 传输压缩文件_java基于socket传输zip文件功能示例

本文实例讲述了java基于socket传输zip文件的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;服务器端程序&#xff1a;import java.io.*;import java.net.*;import java.io.BufferedInputStream;public class SocketServer {ServerSocket ssnull;Socket snull;Dat…

css的学习

文章目录内联样式内部样式外部样式CSS语法格式选择器基本选择器ID 选择器元素选择器类选择器不带标签名带标签名通用选择器并集选择器选择器的优先级扩展选择器组合选择器属性选择器伪类选择器伪元素选择器css 是 Cascading Style Sheets&#xff0c;层叠样式表。 层叠含义是多…

java throws catch_java异常处理throws throw try-catch实例

java异常处理throws throw try-catch实例。throw用于方法中&#xff0c;我们可以预见的错误。比如&#xff1a;if(age<0){Exception e new Exception();//创建异常对象throw e;//抛出异常}在java代码中如果发生异常的话&#xff0c;jvm会抛出异常对象&#xff0c;导致程序代…

java 开发人员工具_每个Java开发人员都应该知道的10个基本工具

java 开发人员工具大家好&#xff0c;我们已经到了2019年的第二个月&#xff0c;我相信你们所有人都已经制定了关于2019年学习以及如何实现这些目标的目标。 我一直在撰写一系列文章&#xff0c;为您提供一些知识&#xff0c;使您可以学习和改进以成为2019年更好的全方位开发人…

SpringBoot2.x+mybatis plus3.x集成Activit7版本

文/朱季谦 在Activiti6版本当中&#xff0c;若要集成到Springboot里&#xff0c;需要写一些额外的配置类&#xff0c;我曾经在Activiti工作流框架学习笔记&#xff08;二&#xff09;之springboot2.0整合工作流Activiti6.0一文当中总结过相关配置过程&#xff0c;感兴趣的同学…

camel apache_Apache Camel 3的工作终于开始了

camel apache我们正在开始Apache Camel 3的工作。 我们正在多方面努力改善骆驼并引入新功能。 Guillaume Nodet实际上是在10月初开始了第一项工作&#xff0c;他通过清理代码库&#xff0c;删除不推荐使用的代码和组件&#xff0c;改进了路由引擎和核心中的其他内部组件开始了…